server: check listen(2) return value
authorDenis Osvald <denis.osvald@sartura.hr>
Mon, 2 Jan 2017 16:33:26 +0000 (17:33 +0100)
committerAndy Green <andy@warmcat.com>
Mon, 2 Jan 2017 17:56:20 +0000 (01:56 +0800)
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>
lib/server.c

index 8f6652ca37c59bbbd22392f416a0a21dcdf2cec9..02b04afb274ccfdf7750acfaf68f3969b43c70e5 100644 (file)
@@ -164,7 +164,14 @@ 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);
+               goto bail;
+       }
        } /* for each thread able to independently listen */
 #else
 #if defined(LWS_WITH_ESP8266)