TTCP(4)

名称
ttcp - トランスミッションコントロールプロトコルのトランザクション拡張機能

#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/tcp.h> int setsockopt(sock, IPPROTO_TCP, TCP_NOPUSH, &One, sizeof One)
ssize_t sendto(sock, msg, len, MSG_EOF, &sin, sizeof sin)
ssize_t sendto(sock, msg, len, MSG_EOF, 0, 0)

解説
T/TCP は TCP プロトコル ( tcp(4) を参照) への拡張機能の集合です。 本機能により少量のデータを 2 つのパケットの交換でやりとりすることができ、 従って標準の TCP コネクションで本来発生する余分な往復による遅延を無くすことができます。 ソケットインタフェースは T/TCP をサポートするように修正されており、 またここでは明確なケースについて詳述しています。 プロトコルに依存しない部分のサポートについては socket(2) 及び send(2) のマニュアルページで述べられています。 T/TCP は RFC 1644 で定義されています。

T/TCP 特定のコネクションの全セグメントにおいて、あるオプションを いくつか含めることにより、T/TCP 拡張は機能します。 これにより一組のホスト間での最初の接続を除く全ての 3 ウェイハンドシェークを無くすことができます。 さらに同じオプションを用いて、 古い重複したパケットをより確実に判別することが可能であり、 従って TCP プロトコルが接続を閉じた後、状態を保たなければならない 時間を減らすことができます。 “net.inet.tcp.rfc1644” の MIB の変数は実行時に T/TCP ネゴシエーションを無効化するために使用することができます。 しかしながら、本プロトコルは、T/TCP ではないシステムが T/TCP 拡張されたシステムと通信しようとしたときに、 自動的に標準の TCP に戻して通信することを保証するために設計されたものです。

トランザクションモデル
T/TCP で用いられる “トランザクション” のモデルはかなり単純なものです:

1.  クライアントプログラムはサーバに送信する要求を作成します。 それは単一の TCP セグメントに収まるくらい十分小さなものです。 そしてオプションとデータと共に SYN PUSH FIN セグメントをサーバに送ります。

2.  サーバプログラムは標準の TCP 接続と同様に、要求を受け取り解読し、 単一のセグメントに収まる大きさの応答を作成します。 その要求が T/TCP の場合、 応答は、(異なった) オプションとデータと共に 単一の SYN PUSH FIN ACK セグメントでクライアントに返されます。 T/TCP ではない場合は、 (ほぼ) 通常の TCP に戻された接続になります。 サーバはこの時 T/TCP ソケットをクローズします。

3.  クライアントは応答を読み込み、ソケットをクローズします。

クライアントサポート
クライアント側のサポートは、 “暗黙の接続” 及び “送信とシャットダウン” の概念を理解する様に sendto(2) 及び sendmsg(2) システムコールの意味を拡張することにより提供されます。 トランザクションによる要求を送信するには sendto(2) システムコールを通常使用し、次の例の様にします:

    char request[REQ_LEN];
    struct sockaddr_in sin;
    int sock, req_len;
    sock = socket(PF_INET, SOCK_STREAM, 0);
    /* request[] と sin の準備 */
    err = sendto(sock, request, req_len, MSG_EOF,
    	(struct sockaddr *)&sin, sin.sin_len);
    /* エラー処理 */
    req_len = read(sock, request, sizeof request);
    close(sock);
    /* 応答処理 */

sendto() を呼び出すと、その時のソケットの状態は connect(2) 及び shutdown(2) システムコールが使われた時と 同じ状態になることに注意して下さい。 つまり、このソケット上で実行するのに適した操作は、 read(2) および close(2) だけです (クライアントの TCP 送信部はすでにシャットダウンされているので、 このソケットを他の送り先へ connect(2) することはできません)。

サーバサポート
T/TCP を使用する際にサーバで利用可能なオプションが 2 つあります:

1.  TCP_NOPUSH ソケットオプションをセットし、 標準の write(2) コールを使って応答を行って下さい。

2.  クライアントの場合と同様に、 sendto(2) を MSG_EOF フラグと共に使用して下さい。 ただし、送り先は指定しません。

既存のサーバが T/TCP 拡張機能を使用するように変更を行う際には、 最初のオプションを用いるのは一般的に妥当な選択です。 単純に setsockopt(sock, IPPROTO_TCP, TCP_NOPUSH, &One, sizeof One) (ここで One は 0 以外の値の整数の変数です) へのコールを追加するだけだからです。 何かデータが送信される前に (ソケットのバッファが飽和していない限り) サーバ側のソケットは閉じていなければなりません。

2 番目のオプションは、新しいサーバにはより望ましいものです。 場合によっては、古いサーバにも適用できるくらい簡単です。 この場合、応答段階で通常 write() の呼び出しを含んでいますが、 それを次のように置き換えます :

    sendto(sock, buf, len, MSG_EOF, (struct sockaddr *)0, 0)

この場合、応答は直ちに送信されますが、クライアントの場合と同様に、 ソケットはこの時点で何にも使用することは出来ません。 直ちにクローズすべきです。

MIB の変数
T/TCP 拡張機能を利用するには、 適切な TCP オプションを送信するように MIB 変数 “net.inet.tcp.rfc1644” が真であることを必要とします。 詳細は tcp(4) を参照して下さい。

関連項目
send(2), setsockopt(2), inet(4), tcp(4) R. Braden, T/TCP - TCP Extensions for Transactions, RFC 1644.

歴史
T/TCP のサポートは FreeBSD 2.1 で初めて行われました。 それは The University of Southern California の Information Sciences Institute の Bob Braden と Liming Wei が書いたコードを基にしており、 The University of Twente の Andras Olah が移植しました。