- Today
- Total
Byeo
listen system call 1 (__sys_listen) 본문
BSD socket API에서 server쪽은 bind를 실행한 뒤, listen을 시작합니다.
Application이 listen을 시작하면 이제 받을 수 있게 됩니다. 이 때, listen은 client가 요청한 연결들을 보관하는 함수라고 볼 수 있을 것 같은데요. 그 보관 가능한 최대 개수가 listen system call의 2번째 인자인 'backlog'라고 보면 될 것 같습니다. 이 큐를 소모하는 주체(consumer)는 일반적으로 listen 다음에서 불리는 accept() system call입니다.
backlog와 관련된 내용은 별도의 포스트에서 다뤄보겠습니다.
이 번에는 BSD socket API중에서 listen를 분석해보려고 합니다.
이전 포스트 (bind system call)
https://byeo.tistory.com/entry/bind-system-call-1
bind system call 1 (__sys_bind)
BSD socket API에서 socket을 생성한 뒤에는 server-side 측에서 bind를 실행합니다. bind는 나의 ip:port를 socket과 연결하는 역할을 수행하죠. 이 번에는 BSD socket API중에서 bind를 분석해보려고 합니다. 이전
byeo.tistory.com
1. sys_listen()
// net/socket.c/SYSCALL_DEFINE2() :1734
SYSCALL_DEFINE2(listen, int, fd, int, backlog)
{
return __sys_listen(fd, backlog);
}
자주 본 구조이므로 넘기겠습니다.
2. __sys_listen
// net/socket.c/__sys_listen() :1707
/*
* Perform a listen. Basically, we allow the protocol to do anything
* necessary for a listen, and if that works, we mark the socket as
* ready for listening.
*/
int __sys_listen(int fd, int backlog)
{
struct socket *sock;
int err, fput_needed;
int somaxconn;
sock = sockfd_lookup_light(fd, &err, &fput_needed);
if (sock) {
somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
if ((unsigned int)backlog > somaxconn)
backlog = somaxconn;
err = security_socket_listen(sock, backlog);
if (!err)
err = sock->ops->listen(sock, backlog);
fput_light(sock->file, fput_needed);
}
return err;
}
2-1) sockfd_lookup_light
file descriptor를 인자로 받아서 struct socket* sock을 얻어오는 함수입니다. https://byeo.tistory.com/entry/bind-system-call-1 의 2) sockfd_lookup_light 와 중복되므로 넘기겠습니다.
2-2) backlog 최대값
backlog의 값은 namespace에서 지정된 somaxconn값을 넘길 수 없습니다.
somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
if ((unsigned int)backlog > somaxconn)
backlog = somaxconn;
qemu 내에서 살펴보니 위와 같이 설정되어 있네요. 다음과 같은 자료구조에서 관리합니다.
// include/net/netns/core.h:8
struct netns_core {
/* core sysctls */
struct ctl_table_header *sysctl_hdr;
int sysctl_somaxconn;
#ifdef CONFIG_PROC_FS
int __percpu *sock_inuse;
struct prot_inuse __percpu *prot_inuse;
#endif
};
2-3) sock->ops->listen(sock, backlog)
listen 함수의 구조가 어째 bind랑 많이 비슷하죠? sock->ops는 &inet_stream_ops였고, 이는 inet_listen을 호출합니다.
현재까지 흐름도
'프로그래밍 (Programming) > 네트워크 스택' 카테고리의 다른 글
listen system call 3 (inet_hash) (0) | 2024.05.12 |
---|---|
listen system call 2 (inet_listen) (0) | 2024.05.11 |
bind system call 3 (__inet_bind - 2) (0) | 2024.05.01 |
bind system call 2 (__inet_bind) (0) | 2024.04.28 |
bind system call 1 (__sys_bind) (0) | 2024.04.27 |