[Libwebsockets] [libwebsockets] #105: Pending SSL data not read

Trac trac at libwebsockets.org
Mon Mar 16 23:23:06 CET 2015


#105: Pending SSL data not read
------------------------------------+-----------------------------------
  Reporter:  mokumei                |      Owner:
      Type:  defect                 |     Status:  new
  Priority:  major                  |  Milestone:
 Component:  libwebsockets library  |    Version:
Resolution:                         |   Keywords:  OpenSSL, pending data
------------------------------------+-----------------------------------

Comment (by mokumei):

 Thanks!
 I needed to change the code to the following (see below).
 It fixes the "pending" problem, but there is still another issue. Will
 file another ticket for that.

 LWS_VISIBLE int
 lws_plat_service(struct libwebsocket_context *context, int timeout_ms)
 {
         int n;
         int i;
         DWORD ev;
         WSANETWORKEVENTS networkevents;
         struct libwebsocket_pollfd *pfd;
         struct libwebsocket  *wsi, *wsi_next;
         int forcePollin = 0;

         /* stay dead once we are dead */

         if (context == NULL)
                 return 1;

         context->service_tid = context->protocols[0].callback(context,
 NULL,
                                      LWS_CALLBACK_GET_THREAD_ID, NULL,
 NULL, 0);

         for (i = 0; i < context->fds_count; ++i) {
                 pfd = &context->fds[i];
                 if (pfd->fd == context->listen_service_fd)
                         continue;

                 if (pfd->events & LWS_POLLOUT) {
                         if
 (wsi_from_fd(context,pfd->fd)->sock_send_blocking)
                                 continue;
                         pfd->revents = LWS_POLLOUT;
                         n = libwebsocket_service_fd(context, pfd);
                         if (n < 0)
                                 return n;
                 }
         }

 #ifdef LWS_OPENSSL_SUPPORT
         /* if we know we have non-network pending data, do not wait in
 poll */
         if (lws_ssl_anybody_has_buffered_read(context))
                 timeout_ms = 0;
 #endif

         ev = WSAWaitForMultipleEvents(context->fds_count + 1,
                                      context->events, FALSE, timeout_ms,
 FALSE);
         context->service_tid = 0;

 #ifdef LWS_OPENSSL_SUPPORT
     if (!lws_ssl_anybody_has_buffered_read(context) && ev ==
 WSA_WAIT_TIMEOUT) {
                 forcePollin = 1;
 #else
         if (ev == WSA_WAIT_TIMEOUT) /* poll timeout */ {
 #endif
                 libwebsocket_service_fd(context, NULL);
                 lwsl_debug("WSAWaitForMultipleEvents() => timeout\n");
                 return 0;
         }

         if (ev == WSA_WAIT_EVENT_0) {
                 WSAResetEvent(context->events[0]);
                 return 0;
         }

         if (!forcePollin && (ev < WSA_WAIT_EVENT_0 || ev >
 WSA_WAIT_EVENT_0 + context->fds_count))
                 return -1;

         pfd = &context->fds[ev - WSA_WAIT_EVENT_0 - 1];

         if (WSAEnumNetworkEvents(pfd->fd,
                         context->events[ev - WSA_WAIT_EVENT_0],
                                               &networkevents) ==
 SOCKET_ERROR) {
                 lwsl_err("WSAEnumNetworkEvents() failed with error %d\n",
 LWS_ERRNO);
                 return -1;
         }


 #ifdef LWS_OPENSSL_SUPPORT
     /*
         * For all guys with buffered SSL read data already saved up, if
 they
         * are not flowcontrolled, fake their POLLIN status so they'll get
         * service to use up the buffered incoming data, even though their
         * network socket may have nothing
         */

     wsi = context->pending_read_list;
     while (wsi) {
         wsi_next = wsi->pending_read_list_next;
         context->fds[wsi->sock].revents |= LWS_POLLIN;
         /*
             * he's going to get serviced now, take him off the
             * list of guys with buffered SSL.  If he still has some
             * at the end of the service, he'll get put back on the
             * list then.
         */
         lws_ssl_remove_wsi_from_buffered_list(context, wsi);
         wsi = wsi_next;
     }
 #endif


         pfd->revents = networkevents.lNetworkEvents;

         lwsl_debug("WSAWaitForMultipleEvents() fired. network events: %d
 POLLIN = %d\n", pfd->revents, pfd->revents & LWS_POLLIN);

         if (pfd->revents & LWS_POLLOUT)
                 wsi_from_fd(context,pfd->fd)->sock_send_blocking = FALSE;

         return libwebsocket_service_fd(context, pfd);
 }

--
Ticket URL: <http://libwebsockets.org/trac/libwebsockets/ticket/105#comment:2>
libwebsockets <http://libwebsockets.org>
libwebsockets C library



More information about the Libwebsockets mailing list