Skip to content

Commit b9bd2b1

Browse files
committed
Cleanup how listening sockets are created/passed down from systemd
1 parent 7985267 commit b9bd2b1

File tree

1 file changed

+42
-46
lines changed

1 file changed

+42
-46
lines changed

src/lib/lwan-socket.c

+42-46
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,6 @@ sa_family_t lwan_socket_parse_address(char *listener, char **node, char **port)
170170
return parse_listener_ipv4(listener, node, port);
171171
}
172172

173-
static sa_family_t parse_listener(char *listener, char **node, char **port)
174-
{
175-
if (streq(listener, "systemd")) {
176-
lwan_status_critical(
177-
"Listener configured to use systemd socket activation, "
178-
"but started outside systemd.");
179-
return AF_MAX;
180-
}
181-
182-
return lwan_socket_parse_address(listener, node, port);
183-
}
184-
185173
static int listen_addrinfo(int fd,
186174
const struct addrinfo *addr,
187175
bool print_listening_msg,
@@ -232,9 +220,7 @@ static int bind_and_listen_addrinfos(const struct addrinfo *addrs,
232220

233221
/* Try each address until we bind one successfully. */
234222
for (addr = addrs; addr; addr = addr->ai_next) {
235-
int fd = socket(addr->ai_family,
236-
addr->ai_socktype,
237-
addr->ai_protocol);
223+
int fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
238224
if (fd < 0)
239225
continue;
240226

@@ -254,14 +240,38 @@ static int bind_and_listen_addrinfos(const struct addrinfo *addrs,
254240
lwan_status_critical("Could not bind socket");
255241
}
256242

243+
static int set_socket_options(const struct lwan *l, int fd)
244+
{
245+
SET_SOCKET_OPTION(SOL_SOCKET, SO_LINGER,
246+
(&(struct linger){.l_onoff = 1, .l_linger = 1}));
247+
248+
#ifdef __linux__
249+
250+
#ifndef TCP_FASTOPEN
251+
#define TCP_FASTOPEN 23
252+
#endif
253+
254+
SET_SOCKET_OPTION_MAY_FAIL(SOL_SOCKET, SO_REUSEADDR, (int[]){1});
255+
SET_SOCKET_OPTION_MAY_FAIL(SOL_TCP, TCP_FASTOPEN, (int[]){5});
256+
SET_SOCKET_OPTION_MAY_FAIL(SOL_TCP, TCP_QUICKACK, (int[]){0});
257+
SET_SOCKET_OPTION_MAY_FAIL(SOL_TCP, TCP_DEFER_ACCEPT,
258+
(int[]){(int)l->config.keep_alive_timeout});
259+
260+
if (is_reno_supported())
261+
setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, "reno", 4);
262+
#endif
263+
264+
return fd;
265+
}
266+
257267
static int setup_socket_normally(const struct lwan *l,
258268
bool print_listening_msg,
259269
bool is_https,
260270
const char *listener_from_config)
261271
{
262272
char *node, *port;
263273
char *listener = strdupa(listener_from_config);
264-
sa_family_t family = parse_listener(listener, &node, &port);
274+
sa_family_t family = lwan_socket_parse_address(listener, &node, &port);
265275

266276
if (family == AF_MAX) {
267277
lwan_status_critical("Could not parse listener: %s",
@@ -279,31 +289,7 @@ static int setup_socket_normally(const struct lwan *l,
279289

280290
int fd = bind_and_listen_addrinfos(addrs, print_listening_msg, is_https);
281291
freeaddrinfo(addrs);
282-
return fd;
283-
}
284-
285-
static int set_socket_options(const struct lwan *l, int fd)
286-
{
287-
SET_SOCKET_OPTION(SOL_SOCKET, SO_LINGER,
288-
(&(struct linger){.l_onoff = 1, .l_linger = 1}));
289-
290-
#ifdef __linux__
291-
292-
#ifndef TCP_FASTOPEN
293-
#define TCP_FASTOPEN 23
294-
#endif
295-
296-
SET_SOCKET_OPTION_MAY_FAIL(SOL_SOCKET, SO_REUSEADDR, (int[]){1});
297-
SET_SOCKET_OPTION_MAY_FAIL(SOL_TCP, TCP_FASTOPEN, (int[]){5});
298-
SET_SOCKET_OPTION_MAY_FAIL(SOL_TCP, TCP_QUICKACK, (int[]){0});
299-
SET_SOCKET_OPTION_MAY_FAIL(SOL_TCP, TCP_DEFER_ACCEPT,
300-
(int[]){(int)l->config.keep_alive_timeout});
301-
302-
if (is_reno_supported())
303-
setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, "reno", 4);
304-
#endif
305-
306-
return fd;
292+
return set_socket_options(l, fd);
307293
}
308294

309295
static int from_systemd_socket(const struct lwan *l, int fd)
@@ -320,22 +306,28 @@ int lwan_create_listen_socket(const struct lwan *l,
320306
bool print_listening_msg,
321307
bool is_https)
322308
{
323-
const char *listener = is_https ? l->config.tls_listener
324-
: l->config.listener;
309+
const char *listener =
310+
is_https ? l->config.tls_listener : l->config.listener;
325311

326312
if (!strncmp(listener, "systemd:", sizeof("systemd:") - 1)) {
327313
char **names = NULL;
328314
int n = sd_listen_fds_with_names(false, &names);
329315
int fd = -1;
330316

317+
listener += sizeof("systemd:") - 1;
318+
331319
if (n < 0) {
332320
errno = -n;
333321
lwan_status_perror(
334322
"Could not parse socket activation data from systemd");
335323
return n;
336324
}
337325

338-
listener += sizeof("systemd:") - 1;
326+
if (n == 0) {
327+
lwan_status_critical("Not invoked from systemd "
328+
"(expecting socket name %s)",
329+
listener);
330+
}
339331

340332
for (int i = 0; i < n; i++) {
341333
if (!strcmp(names[i], listener)) {
@@ -363,6 +355,11 @@ int lwan_create_listen_socket(const struct lwan *l,
363355
return n;
364356
}
365357

358+
if (n == 0) {
359+
lwan_status_critical(
360+
"Not invoked from systemd (expecting 1 socket)");
361+
}
362+
366363
if (n != 1) {
367364
lwan_status_critical(
368365
"%d listeners passed from systemd. Must specify listeners with "
@@ -373,8 +370,7 @@ int lwan_create_listen_socket(const struct lwan *l,
373370
return from_systemd_socket(l, SD_LISTEN_FDS_START);
374371
}
375372

376-
int fd = setup_socket_normally(l, print_listening_msg, is_https, listener);
377-
return set_socket_options(l, fd);
373+
return setup_socket_normally(l, print_listening_msg, is_https, listener);
378374
}
379375

380376
#undef SET_SOCKET_OPTION

0 commit comments

Comments
 (0)