Japan QualNet Community Forums Japan QualNet Community Forums
Welcome Guest 
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
検索
メインメニュー
アクセスカウンター
2024/05/17:11/12
2024/05/16:22/24

2024/03/18より396/1407
人気モジュール
No.1: フォーラム 96
No.2: QualNet概要 3
No.3: ニュース 2
日曜日からの合計
人気Browser&OS
No.1:巡回ロボット77
No.2:Unknown OS1
No.3:Windows XP1

No.1:どっかの巡回ロボット68
No.2:Majestic-12巡回ロボット6
No.3:Google巡回ロボット3

日曜日からの合計
メイン
   Transport Layer Protocol Implementation & Model Development
     ACKについて
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
junpei
投稿日時: 2005/12/6 15:25
新米
登録日: 2005/10/15
居住地:
投稿: 19
ACKについて
TCPのACK部分をいじってACKを2つ返すというふうにしたいのですが、input.cppでデータを受け取ってから、ACKを返すという記述がどこにあるのかわかりません。そもそもACKというのはどのように定義されているのでしょうか?ACKフラグによってACKと定義されるのでしょうか?

よろしくお願いします。
forum_support
投稿日時: 2005/12/7 19:38
モデレータ
登録日: 2005/5/17
居住地: 東京都中野区中央4-5-3 ?構造計画研究所
投稿: 322
Re: ACKについて
ACKは、仰るようにACKフラグによって定義されています。
このACKフラグは、TCPヘッダ内のコントロールビットフラグです。

ACKフラグを送信セグメントに立てる処理に関しては、後の返信「送信セグメントのACKフラグ設定」をご覧下さい。

ここではまず、主にtcp_input()でのACK処理に関して述べます。

tcp_input()におけるACK処理について

tcp_input.cppに記述されているtcp_input()関数内では、TCP(/IP)ヘッダがセグメントから以下の様に取得されます。

[transport/tcp/tcp_input.cpp]
 ti = (struct tcpiphdr *)tcp_seg;

このヘッダの、TCPヘッダ部分のコントロールビットフラグ

 ti->ti_flags

にACKフラグ”TH_ACK”が設定されていれば、そのセグメントはACKであるという事になります。

なおti_flagsはヘッダファイルtcpip.hで定義されており、ti_t.th_flagsと同じものです。
[transport/tcp/tcpip.h]
 #define ti_flags ti_t.th_flags

(各種の変数定義は、同ディレクトリ以下の各ヘッダファイルもご参照下さい。)


tcp_input()関数では、さらにこの後コネクションのPrococol Control Block (PCB)を以下の様に取得し、

[transport/tcp/tcp_input.cpp]
 inp = in_pcblookup(p_head, &ti->ti_dst, ti->ti_dport,
    &ti->ti_src, ti->ti_sport, INPCB_NO_WILDCARD);

さらにTCPのControl Block(TCPCB)を取得します。

[transport/tcp/tcp_input.cpp]
 tp = intotcpcb(inp);

このTCPCBのフラグに、上記のコントロールビットフラグを参照して、例えば以下の様にACK処理タイプに関するフラグを設定しています。

[transport/tcp/tcp_input.cpp]
 if (tiflags & TH_PUSH) {
   tp->t_flags |= TF_ACKNOW;
   TransportTcpTrace(node, 0, 0, "short path, ACK now");
   tcp_output(node, tp, tcp_now, tcp_stat);
 } else if (!tcpLayer->tcpDelayAcks) {
   tp->t_flags |= TF_ACKNOW;
 } else {
   tp->t_flags |= TF_DELACK;
 }

一方、上記に現れているtcp_output()関数は、以下のような引数を伴って呼び出されます。

[transport/tcp/tcp_output.cpp]
void tcp_output(
  Node *node,
  struct tcpcb *tp,
  UInt32 tcp_now,
  struct tcpstat *tcp_stat)

この第2引数のtpが、tcp_output()関数内でどのように参照されているかを、一度追ってみてください。

tcp_output()関数は、例えば以下のようにして、tp->t_flagsを参照し、セグメントの送信を行っています。

[transport/tcp/tcp_output.cpp]
 if (tp->t_flags & TF_ACKNOW) {
   goto send0;
 }
forum_support
投稿日時: 2005/12/7 19:41
モデレータ
登録日: 2005/5/17
居住地: 東京都中野区中央4-5-3 ?構造計画研究所
投稿: 322
Re: ACKについて
送信セグメントのACKフラグ設定

では、送信されるTCPセグメント(のTCPヘッダ部分の、コントロールビットフラグ)にいつACKフラグが立てられるのかということについてですが、tcp_output()関数内で以下のようにしてセットされています。

[transport/tcp/tcp_output.cpp]
ti = (tcpiphdr*) MEM_malloc((sizeof(tcpiphdr) + optlen));
...
ti->ti_flags = flags;

ここで、flagsという変数は、tcp_output()関数内の以下の箇所でデフォルト値がセットされ、それ以降でさらにそのときの状況に応じて特定フラグを落としたり立てたりします。
どのような場合にどのフラグを立てるのか、ということについては、ソースコードを読むかもしくはTCPの解説本などを参考にしてください。

[transport/tcp/tcp_output.cpp]
flags = tcp_outflags[tp->t_state];

flagsのデフォルト値についても、簡単に解説しておきます。
ここで、tp->t_stateはそのときのTCPの状態であり、とりうる状態の値は
transport/tcp/tcp_proto.hにおいて定義されていますので、そちらをご覧下さい。
tcp_outflagsについても、同ファイルに定義されていますのでご覧ください。
それらによると、各状態とそれに対応するデフォルトのフラグ値は、以下のように定義されていることになります。

State       Default flag
--------------------------------
TCPS_CLOSED      TH_RST|TH_ACK
TCPS_LISTEN       0
TCPS_SYN_SENT     TH_SYN
TCPS_SYN_RECEIVED TH_SYN|TH_ACK
TCPS_ESTABLISHED  TH_ACK
TCPS_CLOSE_WAIT  TH_ACK
TCPS_FIN_WAIT_1   TH_FIN|TH_ACK
TCPS_CLOSING      TH_FIN|TH_ACK
TCPS_LAST_ACK     TH_FIN|TH_ACK
TCPS_FIN_WAIT_2   TH_ACK
TCPS_TIME_WAIT    TH_ACK


以上、ご参考になりますでしょうか?
junpei
投稿日時: 2005/12/8 15:51
新米
登録日: 2005/10/15
居住地:
投稿: 19
Re: ACKについて
詳細な説明ありがとうございます。
とても参考になりました。

またなにかあれば質問させていただきます。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ
Copyright c KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
XOOPS Cube PROJECT