Delayed ACK

これも研究関連で,遅延ACK(Delayed ACK)を無効にした状態でデータ通信をする必要がありまして.


今まではFreeBSDのPCで実験を行っていたのでsysctlで一発で無効にできたのですが,Linux系ではどうやらその方法では無理な模様.
それで,JM projectで調べた所どうやらsetsockopt()を用いてquickackモードを有効にすれば良いらしいとの事なので,早速コードを修正して走らせて見たのですが・・・tcpdumpで見てる限り,思いっきり遅延ACKが動作してるぽいんですよね.


試行錯誤したところ,結局↓の説明が曲者だったようで・・・

TCP_QUICKACK
設定されていると quickack モードを有効にし、クリアされると無効にする。通常の TCP 動作では ack は必要に応じて遅延されるのに対し、 quickack モードでは ack はすぐに送信される。このフラグは永続的なものではなく、 quickack モードから/モードへ切り替えるためのものである。これ以降の TCP プロトコルの動作によっては、内部のプロトコル処理や、遅延 ack タイムアウトの発生、データ転送などの要因によって、再び quickack から出たり入ったりする。移植性の必要なプログラムではこのオプションを用いるべきではない。

どうやらこちらの設定後,何らかの条件でシステムが遅延ACKモードに戻してるようです.しかも,性質の悪いことにgetsockopt()で確認しても,quickack モードは有効になってることになっているんですよねー.ウゼー・・・


結局,↓のようにパケットを受信するたびにsetsockopt()で設定する事で逃げました.

if (FD_ISSET(fd, (fd_set*)&mask)) {
    bzero(buf, sizeof(buf));
    
    /* set quickack mode (forbidden delayed ACK) */
    setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &qack, sizeof(qack));

    /* read packet (and throw away) */
    l = read(fd, buf, sizeof(buf));
    
    /* end of connection */
    if (l <= 0) break;
}

もうちょっと良い方法はないものか・・・


関係ないですが,遅延ACKってDelayed ACKと書くんですね.