1 /* Copyright (C) 2007 Keith Rarick and Philotic Inc.
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <netinet/tcp.h>
26 #include "sd-daemon.h"
29 make_server_socket(char *host
, char *port
)
31 int fd
= -1, flags
, r
;
32 struct linger linger
= {0, 0};
33 struct addrinfo
*airoot
, *ai
, hints
;
35 /* See if we got a listen fd from systemd. If so, all socket options etc
36 * are already set, so we check that the fd is a TCP listen socket and
40 return twarn("sd_listen_fds"), -1;
44 twarnx("inherited more than one listen socket;"
45 " ignoring all but the first");
48 fd
= SD_LISTEN_FDS_START
;
49 r
= sd_is_socket_inet(fd
, 0, SOCK_STREAM
, 1, 0);
52 twarn("sd_is_socket_inet");
56 twarnx("inherited fd is not a TCP listen socket");
62 memset(&hints
, 0, sizeof(hints
));
63 hints
.ai_family
= PF_UNSPEC
;
64 hints
.ai_socktype
= SOCK_STREAM
;
65 hints
.ai_flags
= AI_PASSIVE
;
66 r
= getaddrinfo(host
, port
, &hints
, &airoot
);
68 return twarn("getaddrinfo()"), -1;
70 for(ai
= airoot
; ai
; ai
= ai
->ai_next
) {
71 fd
= socket(ai
->ai_family
, ai
->ai_socktype
, ai
->ai_protocol
);
77 flags
= fcntl(fd
, F_GETFL
, 0);
79 twarn("getting flags");
84 r
= fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
);
86 twarn("setting O_NONBLOCK");
92 setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &flags
, sizeof flags
);
93 setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, &flags
, sizeof flags
);
94 setsockopt(fd
, SOL_SOCKET
, SO_LINGER
, &linger
, sizeof linger
);
95 setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &flags
, sizeof flags
);
97 r
= bind(fd
, ai
->ai_addr
, ai
->ai_addrlen
);
104 r
= listen(fd
, 1024);
114 freeaddrinfo(airoot
);