6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <netinet/tcp.h>
10 #include "sd-daemon.h"
13 make_server_socket(char *host
, char *port
)
15 int fd
= -1, flags
, r
;
16 struct linger linger
= {0, 0};
17 struct addrinfo
*airoot
, *ai
, hints
;
19 /* See if we got a listen fd from systemd. If so, all socket options etc
20 * are already set, so we check that the fd is a TCP listen socket and
24 return twarn("sd_listen_fds"), -1;
28 twarnx("inherited more than one listen socket;"
29 " 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 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &flags
, sizeof flags
);
77 setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, &flags
, sizeof flags
);
78 setsockopt(fd
, SOL_SOCKET
, SO_LINGER
, &linger
, sizeof linger
);
79 setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &flags
, sizeof flags
);
81 r
= bind(fd
, ai
->ai_addr
, ai
->ai_addrlen
);