server: check listen(2) return value

The `listen` call can fail with EADDRINUSE after bind() succeeds, for
example because another process called listen on that port in the
meantime, or under some circumstances with IPv6-mapped-IPv4. This was
causing EINVAL on accept, with an infinite loop in case of libuv.

A reproducible example was to run nc -l -p 5555 ( OpenBSD netcat (Debian
patchlevel 1)) before starting test-server

Signed-off-by: Denis Osvald <denis.osvald@sartura.hr>
This commit is contained in:
Denis Osvald 2017-01-03 02:06:37 +08:00 committed by Andy Green
parent 15b35bcc63
commit 10eacf2873

View file

@ -132,7 +132,15 @@ lws_context_init_server(struct lws_context_creation_info *info,
vhost->lserv_wsi = wsi;
#if LWS_POSIX
listen(wsi->sock, LWS_SOMAXCONN);
n = listen(wsi->sock, LWS_SOMAXCONN);
if (n < 0) {
lwsl_err("listen failed with error %d\n", LWS_ERRNO);
vhost->lserv_wsi = NULL;
vhost->context->count_wsi_allocated--;
remove_wsi_socket_from_fds(wsi);
vhost->context->pt[m].wsi_listening = NULL;
goto bail;
}
} /* for each thread able to independently listen */
#else
mbed3_tcp_stream_bind(wsi->sock, info->port, wsi);