7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <netinet/tcp.h>
11 #include "sd-daemon.h"
14 make_server_socket(char *host
, char *port
)
16 int fd
= -1, flags
, r
;
17 struct linger linger
= {0, 0};
18 struct addrinfo
*airoot
, *ai
, hints
;
20 /* See if we got a listen fd from systemd. If so, all socket options etc
21 * are already set, so we check that the fd is a TCP listen socket and
25 return twarn("sd_listen_fds"), -1;
29 twarnx("inherited more than one listen socket;"
30 " ignoring all but the first");
33 fd
= SD_LISTEN_FDS_START
;
34 r
= sd_is_socket_inet(fd
, 0, SOCK_STREAM
, 1, 0);
37 twarn("sd_is_socket_inet");
41 twarnx("inherited fd is not a TCP listen socket");
47 memset(&hints
, 0, sizeof(hints
));
48 hints
.ai_family
= PF_UNSPEC
;
49 hints
.ai_socktype
= SOCK_STREAM
;
50 hints
.ai_flags
= AI_PASSIVE
;
51 r
= getaddrinfo(host
, port
, &hints
, &airoot
);
53 return twarn("getaddrinfo()"), -1;
55 for(ai
= airoot
; ai
; ai
= ai
->ai_next
) {
56 fd
= socket(ai
->ai_family
, ai
->ai_socktype
, ai
->ai_protocol
);
62 flags
= fcntl(fd
, F_GETFL
, 0);
64 twarn("getting flags");
69 r
= fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
);
71 twarn("setting O_NONBLOCK");
77 r
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &flags
, sizeof flags
);
79 twarn("setting SO_REUSEADDR on fd %d", fd
);
83 r
= setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, &flags
, sizeof flags
);
85 twarn("setting SO_KEEPALIVE on fd %d", fd
);
89 r
= setsockopt(fd
, SOL_SOCKET
, SO_LINGER
, &linger
, sizeof linger
);
91 twarn("setting SO_LINGER on fd %d", fd
);
95 r
= setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &flags
, sizeof flags
);
97 twarn("setting TCP_NODELAY on fd %d", fd
);
103 char hbuf
[NI_MAXHOST
], pbuf
[NI_MAXSERV
], *h
= host
, *p
= port
;
104 r
= getnameinfo(ai
->ai_addr
, ai
->ai_addrlen
,
107 NI_NUMERICHOST
|NI_NUMERICSERV
);
112 if (ai
->ai_family
== AF_INET6
) {
113 printf("bind %d [%s]:%s\n", fd
, h
, p
);
115 printf("bind %d %s:%s\n", fd
, h
, p
);
118 r
= bind(fd
, ai
->ai_addr
, ai
->ai_addrlen
);
125 r
= listen(fd
, 1024);
135 freeaddrinfo(airoot
);