Google グループは Usenet の新規の投稿と購読のサポートを終了しました。過去のコンテンツは引き続き閲覧できます。
表示しない

連続したパケットで次々にTTL を変えたい

閲覧: 3 回
最初の未読メッセージにスキップ

MAEDA Tooru

未読、
2003/09/28 0:28:452003/09/28
To:
会津大学の前田と申します。
UNIXに詳しい方のご意見を伺わせてください。

ある実験のためにCでソケットを使ったプログラムを書いています。
それは次のようなものです。
1. 適当なサーバとTCPコネクションを確立する。
2. そのコネクションの上でサーバにメッセージを送る。
3. 続けてもう一度メッセージを送る。
ただし、前のものとはTTLの値を変える。
4. わけあってTTLを2で送ったものの値に戻す。
5. コネクションを切断する。
サーバからの応答などは気にしないことにします。
これを実装した(つもりの)ものが下のプログラムです。
Webサーバを例にしました。簡単のためエラーチェックは行っていません。

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>

int main(void)
{
int s, ttl1, ttl2;
struct sockaddr_in sa = { 0 };
const char request[] = "GET / HTTP/1.0\r\n\r\n";
size_t len = sizeof(request) - 1;

s = socket(PF_INET, SOCK_STREAM, 0);
sa.sin_family = PF_INET;
sa.sin_port = htons(80);
inet_pton(PF_INET, "適当なWebサーバのIPアドレス", &sa.sin_addr);
connect(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in));

ttl1 = 20;
ttl2 = 10;
setsockopt(s, IPPROTO_IP, IP_TTL, &ttl1, sizeof(int));
write(s, request, len); /* (1) */
setsockopt(s, IPPROTO_IP, IP_TTL, &ttl2, sizeof(int));
write(s, request, len); /* (2) */
setsockopt(s, IPPROTO_IP, IP_TTL, &ttl1, sizeof(int));

close(s);
return 0;
}

これを Red Hat Linux 7.3 (kernel 2.4.20-20.7, glibc 2.2.5-43) で
実行し、そのホスト上でパケットのキャプチャを行いました。
すると、(1)と(2)で送られたパケットのTTLの値が共に20に
なっていました。(2)の直後に試しに sleep(1) を入れてみると、
(2)でのパケットのTTLが10に変わっていたことから、
実際にパケットが作られるまで間があり、その間に次のsetsockopt()での
TTLの変更が有効になってしまったのではないかと推測しました。
この解釈は妥当でしょうか?
また、上記の仕様の通りにするにはどのようにしたらよいでしょうか?
できれば、sleep()を入れるなどの時間かせぎは使いたくありません。

よろしくお願い致します。
----
MAEDA Tooru <m506...@u-aizu.ac.jp>

Shinji KONO

未読、
2003/09/28 3:52:372003/09/28
To:
河野真治 @ 琉球大学情報工学です。

In article <20030928132845.1...@u-aizu.ac.jp>, MAEDA Tooru <m506...@u-aizu.ac.jp> writes


> すると、(1)と(2)で送られたパケットのTTLの値が共に20に
> なっていました。(2)の直後に試しに sleep(1) を入れてみると、
> (2)でのパケットのTTLが10に変わっていたことから、
> 実際にパケットが作られるまで間があり、その間に次のsetsockopt()での
> TTLの変更が有効になってしまったのではないかと推測しました。
> この解釈は妥当でしょうか?

おそらく...

> また、上記の仕様の通りにするにはどのようにしたらよいでしょうか?

効かないだろうと思うけど、
if (peer.sin_family == AF_INET)
{
int tmp = 1;

setsockopt (sk, IPPROTO_TCP, TCP_NODELAY,
(char *) &tmp, sizeof (int));
}
は?

---
Shinji KONO @ Information Engineering, University of the Ryukyus,
PRESTO, Japan Science and Technology Corporation
河野真治 @ 琉球大学工学部情報工学科,
科学技術振興事業団さきがけ研究21(機能と構成)

MAEDA Tooru

未読、
2003/09/29 12:41:262003/09/29
To:
会津大学の前田と申します。

In message "Re: 連続したパケットで次々にTTL を変えたい"
on 28 Sep 2003 07:52:37 GMT,
ko...@ie.u-ryukyu.ac.jp (Shinji KONO) wrote:

> 効かないだろうと思うけど、
> if (peer.sin_family == AF_INET)
> {
> int tmp = 1;
>
> setsockopt (sk, IPPROTO_TCP, TCP_NODELAY,
> (char *) &tmp, sizeof (int));
> }
> は?

効きました。本当にありがとうございます。
TCPが原因だったんですね。Nagleアルゴリズムなんて初めて知りました。
キャプチャしたパケットのログを見て、1つ目と2つ目のリクエストの間に
必ずACKが来ていることに気付かなかった自分が情けないです…。
----
MAEDA Tooru <m506...@u-aizu.ac.jp>

Shinji KONO

未読、
2003/09/29 18:37:142003/09/29
To:
河野真治 @ 琉球大学情報工学です。

In article <20030930014126.5...@u-aizu.ac.jp>, MAEDA Tooru <m506...@u-aizu.ac.jp> writes
> 効きました。本当にありがとうございます。

おぉ、ラッキー。僕はTCP_NODELAYは実は信用してない...

> TCPが原因だったんですね。Nagleアルゴリズムなんて初めて知りました。
> キャプチャしたパケットのログを見て、1つ目と2つ目のリクエストの間に
> 必ずACKが来ていることに気付かなかった自分が情けないです…。

なんか、もう少し解説希望...

MAEDA Tooru

未読、
2003/09/29 23:56:552003/09/29
To:
会津大学の前田です。

In message "Re: 連続したパケットで次々にTTL を変えたい"

on 29 Sep 2003 22:37:14 GMT,
ko...@ie.u-ryukyu.ac.jp (Shinji KONO) wrote:

> なんか、もう少し解説希望...

TCP_NODELAYをソケットに設定すると、Nagleアルゴリズムというものが
使用されなくなるそうです。このアルゴリズムは、ACKをもらっていない
小さな(MSS未満のサイズの)セグメントが複数になることを防ぐために
使われ、デフォルトで有効になっています。
つまり、デフォルトでは小さなセグメントについては、
ACKを受信するまで次のセグメントの送信を待つということらしいです。
このアルゴリズムにより、例のプログラムでの
連続した2つのリクエストは次のように扱われます。
1. 1つ目のリクエストを送信(MSS未満のサイズ)
2. 2つ目のリクエストをwrite。
しかし、1つ目に対するACKをまだ受け取っていないので送信しない
3. 1つ目に対するACKが到着
4. 2つ目のリクエストを送る
3を待っている間にTTLが変更されてしまったと思われますので、
待たないようにすると解決した、というわけです。

以下の書籍を参考にしました。
Stevens, W. R., UNIXネットワークプログラミング 第2版 Vol.1,
ピアソンエデュケーション, pp. 196-198.
----
MAEDA Tooru <m506...@u-aizu.ac.jp>

Shinji KONO

未読、
2003/09/30 3:55:042003/09/30
To:
河野真治 @ 琉球大学情報工学です。

In article <20030930125655.4...@u-aizu.ac.jp>, MAEDA Tooru <m506...@u-aizu.ac.jp> writes


> TCP_NODELAYをソケットに設定すると、Nagleアルゴリズムというものが
> 使用されなくなるそうです。このアルゴリズムは、ACKをもらっていない
> 小さな(MSS未満のサイズの)セグメントが複数になることを防ぐために
> 使われ、デフォルトで有効になっています。

あぁ、そうしないとviとかは破綻しちゃうね。

NODELAYだからackを待たないとおもっちゃいかんのか...
TCPは奥が深い。

> 以下の書籍を参考にしました。
> Stevens, W. R., UNIXネットワークプログラミング 第2版 Vol.1,
> ピアソンエデュケーション, pp. 196-198.

これは持っているけど...

新着メール 0 件