システムコールから辿る
sys_listen()
システムコールで呼ばれる大元の関数
- 引数から作成されたソケットを取得
- backlogの精査
- inet_listen()の呼び出し
sock->ops->listen()とは?
socket構造体にあるproto_ops構造体です。ソースコード
proto_ops構造体はinclude/linux/net.hで宣言されておりipv4でTCP通信の際の実装はnet/ipv4/af_inet.cで行っています。
TCP通信はinet_stream_opsになるので、inet_listen()が呼び出されています。
inet_listen()
- sockをロック
- sockの状態、Typeの精査(CloseとListen以外の状態をはじく、STREAMのみ通す)
- バックログの更新
- sockの状態がListen以外なら
- tcp_fastopenの設定(まだ分からない)
- inet_csk_listen_start()の呼び出し
上記の実装をする事でlisten状態でも、BackLogの更新が可能になる
inet_csk_listen_start()
- reqsk_queue_alloc()でバックログで指定された分だけSYNリクエストキューの割り当て
- ACK回りのメンバをリセット
- sockの状態を「TCP_LISTEN」に変更
- ポートを割り当てることが出来たら
- inet_spotにポートを登録
- dst_entryをリセット
- リスニングソケットハッシュへ登録
- ポートの割り当てができなかったら、
- sockの状態を「TCP_CLOSE」に変更
- 1番で割り当てた、queueを削除
参考文献
https://www.codetd.com/ja/article/11908254#3.2%20inet_csk_listen_start%28%29
https://elixir.bootlin.com/linux/latest/source/net/ipv4/af_inet.c#L192
https://elixir.bootlin.com/linux/latest/source/net/ipv4/inet_connection_sock.c#L1038
https://elixir.bootlin.com/linux/latest/source/net/socket.c#L1716
https://elixir.bootlin.com/linux/latest/source/include/linux/net.h#L114
https://elixir.bootlin.com/linux/latest/source/include/linux/net.h#L137
https://elixir.bootlin.com/linux/latest/source/net/ipv4/af_inet.c#L1020