document the new binlog stats
[beanstalkd.git] / net.c
blob460a278b2aefd8d37b6cf1f7b3ff6d6e287bb6f4
1 #include <netdb.h>
2 #include <unistd.h>
3 #include <fcntl.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <netinet/tcp.h>
9 #include "dat.h"
10 #include "sd-daemon.h"
12 int
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
21 * return. */
22 r = sd_listen_fds(1);
23 if (r < 0) {
24 return twarn("sd_listen_fds"), -1;
26 if (r > 0) {
27 if (r > 1) {
28 twarnx("inherited more than one listen socket;"
29 " ignoring all but the first");
30 r = 1;
32 fd = SD_LISTEN_FDS_START;
33 r = sd_is_socket_inet(fd, 0, SOCK_STREAM, 1, 0);
34 if (r < 0) {
35 errno = -r;
36 twarn("sd_is_socket_inet");
37 return -1;
39 if (!r) {
40 twarnx("inherited fd is not a TCP listen socket");
41 return -1;
43 return fd;
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);
51 if (r == -1)
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);
56 if (fd == -1) {
57 twarn("socket()");
58 continue;
61 flags = fcntl(fd, F_GETFL, 0);
62 if (flags < 0) {
63 twarn("getting flags");
64 close(fd);
65 continue;
68 r = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
69 if (r == -1) {
70 twarn("setting O_NONBLOCK");
71 close(fd);
72 continue;
75 flags = 1;
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);
82 if (r == -1) {
83 twarn("bind()");
84 close(fd);
85 continue;
88 r = listen(fd, 1024);
89 if (r == -1) {
90 twarn("listen()");
91 close(fd);
92 continue;
95 break;
98 freeaddrinfo(airoot);
100 if(ai == NULL)
101 fd = -1;
103 return fd;