Linux Kernel(2.6)の実装に関するメモ書き

listen backlog 【3.6】


Rev.14を表示中。最新版はこちら

1. 概要

listen()時に指定するbacklogに関するメモ。

2. backlogとsyn backlog

 listen()システムコールでLISTEN状態にあるソケットはbacklogというキューを持つ。backlogにはクライアントからのTCP接続要求が確立(ESTABLISH状態)し、まだaccept()されていない接続が並ぶ。

Listenソケットはbacklog以外にもTCP接続中(SYN_RECV状態)の接続を格納しておくキューがある。各種ドキュメントではキューと呼んでいるが、実際にはハッシュテーブルで実装されている。ここではsyn backlogと呼ぶ。

backlogのキューはinet_csk(sk)->icsk_accept_queueの.rskq_accept_headと.rskq_accept_tailで管理され、syn backlogのハッシュはinet_csk(sk)->icsk_accept_queue.listen_opt->syn_tableで管理される(図1)。

図1 Listenソケットとbacklog

 

3. backlogサイズ

backlogのキュー長はlisten()時に指定されるbacklog引数の値に設定される。ただし、指定値がsysctlのnet.core.somaxconnより大きかった場合は、net.core.somaxconnの値に切り詰められる。

 

4. syn backlogのサイズ(net.ipv4.tcp_syncookies = 0の場合)

syn backlogにSYN_RECVがいくつたまるかはnet.ipv4.tcp_syncookiesの値によって変わる。

net.ipv4.tcp_syncookies = 0の場合、SYN_RECVはnet.ipv4.tcp_max_syn_backlogの3/4まで登録される。これを越えると新たにSYN_RECVは登録せず廃棄する。このため、新たにTCP接続を確立できない。

 

5. syn backlogのサイズ(net.ipv4.tcp_syncookies = 1の場合)

net.ipv4.tcp_syncookies = 1の場合、syn backlogのサイズはbacklogサイズに基づいて決められる。

syn backlogのサイズはbacklog値を8〜net.ipv4.tcp_max_syn_backlogの範囲に収めた後、一つ上の2の階乗の値に切り上げた値になる。例えば、backlog長が200ならsyn backlogサイズは256、backlog長が256ならsyn backlogサイズは512となる(syn backlogの初期化処理はreqsk_queue_alloc()で行っている)。

表1 syn backlogサイズ計算例(tcp_max_syn_backlog = 400の場合)

backlogサイズsyn backlogサイズ
200 256
256 512
512 512

 

SYN_RECVがsyn backlogのサイズを越えると、SYN Flood攻撃と判断し、SYN cookiesの動作が始まる。

net.ipv4.tcp_syncookies = 1の場合、syn backlogのサイズを大きくしようとするには、以下の点に注意する。

(a) net.ipv4.tcp_max_syn_backlogを大きくする

(b) listen()で指定するbacklog値を大きくする(apacheならListenBackLogディレクティブで指定できる)

(c) backlogの値自体はnet.core.somaxconnに切り詰められるため、net.core.somaxconnの方も大きくしておく。

syn backlogの最大サイズはbacklogサイズに基づいて決まるため、net.ipv4.tcp_max_syn_backlogを大きくするだけでなく、backlog自体が大きくなるように(b),(c)も行う必要がある。


最終更新 2015/04/16 00:08:27 - kztomita
(2015/04/14 23:22:48 作成)
添付ファイル
backlog.png - kztomita


リンク
最近更新したページ
検索