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");
32 fd
= SD_LISTEN_FDS_START
;
33 r
= sd_is_socket_inet(fd
, 0, SOCK_STREAM
, 1, 0);
36 twarn("sd_is_socket_inet");
40 twarnx("inherited fd is not a TCP listen socket");
46 memset(&hints
, 0, sizeof(hints
));
47 hints
.ai_family
= PF_UNSPEC
;
48 hints
.ai_socktype
= SOCK_STREAM
;
49 hints
.ai_flags
= AI_PASSIVE
;
50 r
= getaddrinfo(host
, port
, &hints
, &airoot
);
52 return twarn("getaddrinfo()"), -1;
54 for(ai
= airoot
; ai
; ai
= ai
->ai_next
) {
55 fd
= socket(ai
->ai_family
, ai
->ai_socktype
, ai
->ai_protocol
);
61 flags
= fcntl(fd
, F_GETFL
, 0);
63 twarn("getting flags");
68 r
= fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
);
70 twarn("setting O_NONBLOCK");
76 r
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &flags
, sizeof flags
);
78 twarn("setting SO_REUSEADDR on fd %d", fd
);
82 r
= setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, &flags
, sizeof flags
);
84 twarn("setting SO_KEEPALIVE on fd %d", fd
);
88 r
= setsockopt(fd
, SOL_SOCKET
, SO_LINGER
, &linger
, sizeof linger
);
90 twarn("setting SO_LINGER on fd %d", fd
);
94 r
= setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &flags
, sizeof flags
);
96 twarn("setting TCP_NODELAY on fd %d", fd
);
102 char hbuf
[NI_MAXHOST
], pbuf
[NI_MAXSERV
], *h
= host
, *p
= port
;
103 r
= getnameinfo(ai
->ai_addr
, ai
->ai_addrlen
,
106 NI_NUMERICHOST
|NI_NUMERICSERV
);
111 if (ai
->ai_family
== AF_INET6
) {
112 printf("bind %d [%s]:%s\n", fd
, h
, p
);
114 printf("bind %d %s:%s\n", fd
, h
, p
);
117 r
= bind(fd
, ai
->ai_addr
, ai
->ai_addrlen
);
124 r
= listen(fd
, 1024);
134 freeaddrinfo(airoot
);