2014年1月28日火曜日

somaxconnの上限値は65535

Linuxのネットワークパラメータの一つに、net.core.somaxconnというのがあります。これはlisten(2)の第二引数backlogの上限値となっています。このsomaxconnは一見intに見えますが、実はunsigned shortの範囲の数値しか受け付けません。それを超える数値を入れると黙って切り捨てられます。つまり

  • -1→65535
  • 0→0
  • 65535→65535
  • 65536→0
  • 65537→1

と同じような動作を内部的にします。なので、この値は絶対に0~65535の範囲を超えてはいけません。以下、詳しい説明です。

おことわり: この仕様はLinux 3.11以降変更されており、範囲外の数値を設定できないようになっています。ここに書いてある内容が再現するのは、Linux 3.10以前の古いカーネルのみです。

まずsysctlの定義ですが

net/core/sysctl_net_core.c

static struct ctl_table netns_core_table[] = {
 {
  .procname = "somaxconn",
  .data  = &init_net.core.sysctl_somaxconn,
  .maxlen  = sizeof(int),
  .mode  = 0644,
  .proc_handler = proc_dointvec
 },

include/net/netns/core.h

struct netns_core {
        /* core sysctls */
        struct ctl_table_header *sysctl_hdr;

        int     sysctl_somaxconn;

        struct prot_inuse __percpu *inuse;
};

以上のようにしっかりと"int"と書かれています。

さて、この値がどう使われているかというと、listen(2)でbacklogの最大値として利用された後inet_listenに引き渡されます。

net/ipv4/af_inet.c

int inet_listen(struct socket *sock, int backlog)
{
        struct sock *sk = sock->sk;
        unsigned char old_state;
        int err;
(途中省略)
        sk->sk_max_ack_backlog = backlog;
        err = 0;

out:
        release_sock(sk);
        return err;
}

という感じで、socket.sk_max_ack_backlogに渡されています。この値の宣言を見ると

include/net/sock.h

struct sock {
(途中省略)
        unsigned short          sk_ack_backlog;
        unsigned short          sk_max_ack_backlog;

unsigned shortとなっています。intをunsigned shortにそのまま代入してますね。なので、一番上に書いたようにオーバーフローします。黙ってオーバーフローします。net.core.somaxconnの値は正しくセットされるのが余計にたちが悪いですね。

ところでbacklog=0ってなんでしょうか?全くacceptできないように思えますが、実はキューの長さは

include/net/sock.h

static inline bool sk_acceptq_is_full(const struct sock *sk)
{
        return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}

という感じで不等号で比較されているので、最低一つはaccept待ちのソケットが使用できます。

これはTCPのコードですが、unix domain socketでも似たような事象が起こります。

あと何年かすれば役に立たなくなる感じの知識ではありますが、今のところsomaxconnは16bitです。

1 件のコメント:

  1. Circle table icon of 3 varieties color, black and white, define. Roulette table multi colored flat icons on 우리카지노 round backgrounds. Included white, gentle and dark icon variations for hover and active standing effects, and bonus shades. 3d isometric flat vector conceptual illustration of online gambling platform.

    返信削除