trac 18 deal with service connection timing out
While looking at http://libwebsockets.org/trac/ticket/18
noticed the flow for timeout in service_fd will do bad things
if the fd we came to service has timed out. It gets freed and
then "serviced'.
Reported-by: Joakim Soderberg <joakim.soderberg@gmail.com>
Signed-off-by: Andy Green <andy.green@linaro.org>
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index 0291acb..8756de7 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -760,7 +760,7 @@
-void
+int
libwebsocket_service_timeout_check(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned int sec)
{
@@ -780,7 +780,7 @@
#endif
if (!wsi->pending_timeout)
- return;
+ return 0;
/*
* if we went beyond the allowed time, kill the
@@ -791,7 +791,10 @@
lwsl_info("TIMEDOUT WAITING\n");
libwebsocket_close_and_free_session(context,
wsi, LWS_CLOSE_STATUS_NOSTATUS);
+ return 1;
}
+
+ return 0;
}
/**
@@ -817,6 +820,8 @@
int m;
int listen_socket_fds_index = 0;
struct timeval tv;
+ int timed_out = 0;
+ int our_fd = 0;
#ifndef LWS_NO_EXTENSIONS
int more = 1;
@@ -847,16 +852,28 @@
/* global timeout check once per second */
+ if (pollfd)
+ our_fd = pollfd->fd;
+
for (n = 0; n < context->fds_count; n++) {
- struct libwebsocket *new_wsi =
- context->lws_lookup[context->fds[n].fd];
- if (!new_wsi)
+ m = context->fds[n].fd;
+ wsi = context->lws_lookup[m];
+ if (!wsi)
continue;
- libwebsocket_service_timeout_check(context,
- new_wsi, tv.tv_sec);
+
+ if (libwebsocket_service_timeout_check(context, wsi,
+ tv.tv_sec))
+ /* he did time out... */
+ if (m == our_fd)
+ /* it was the guy we came to service! */
+ timed_out = 1;
}
}
+ /* the socket we came to service timed out, nothing to do */
+ if (timed_out)
+ return 0;
+
/* just here for timeout management? */
if (pollfd == NULL)