SOL_SNDBUF set to protocol rx size
authorAndy Green <andy.green@linaro.org>
Sat, 23 Mar 2013 01:53:17 +0000 (09:53 +0800)
committerAndy Green <andy.green@linaro.org>
Sat, 23 Mar 2013 01:53:17 +0000 (09:53 +0800)
This tells the OS to reserve a TX buffer at least the size of the biggest RX frame
expected, for both server and client connections.

In Linux, the OS reserves 2 x the requested amount.

This is aimed at reducing the partial large atomic frame send problem to the point
it's only coming at large atomic frames the OS balks at reserving the size for.

If you have a lot of data to send, it is better to split it into multiple writes,
and use the FIN / CONTINUATION websocket stuff to manage it.

See the "fraggle" test app for example code of how to do that.

Signed-off-by: Andy Green <andy.green@linaro.org>
lib/client.c
lib/handshake.c

index 963c659..836203c 100644 (file)
@@ -379,6 +379,7 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
        const char *c;
 #endif
        int n;
+       int close_reason = LWS_CLOSE_STATUS_PROTOCOL_ERR;
 
        /*
         * well, what the server sent looked reasonable for syntax.
@@ -641,10 +642,15 @@ check_accept:
        wsi->u.ws.rx_user_buffer = malloc(n);
        if (!wsi->u.ws.rx_user_buffer) {
                lwsl_err("Out of Mem allocating rx buffer %d\n", n);
-               goto bail3;
+               goto bail2;
        }
        lwsl_info("Allocating client RX buffer %d\n", n);
 
+       if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF,  &n, sizeof n)) {
+               lwsl_warn("Failed to set SNDBUF to %d", n);
+               goto bail3;
+       }
+
        lwsl_debug("handshake OK for protocol %s\n", wsi->protocol->name);
 
        /* call him back to inform him he is up */
@@ -675,6 +681,9 @@ check_accept:
        return 0;
 
 bail3:
+       free(wsi->u.ws.rx_user_buffer);
+       wsi->u.ws.rx_user_buffer = NULL;
+       close_reason = LWS_CLOSE_STATUS_NOSTATUS;
 
 bail2:
        if (wsi->protocol)
@@ -689,8 +698,7 @@ bail2:
        if (wsi->u.hdr.ah)
                free(wsi->u.hdr.ah);
 
-       libwebsocket_close_and_free_session(context, wsi,
-                                                LWS_CLOSE_STATUS_PROTOCOL_ERR);
+       libwebsocket_close_and_free_session(context, wsi, close_reason);
 
        return 1;
 }
index 4e9bd70..3fa30f1 100644 (file)
@@ -258,6 +258,11 @@ libwebsocket_read(struct libwebsocket_context *context,
                }
                lwsl_info("Allocating RX buffer %d\n", n);
 
+               if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF,  &n, sizeof n)) {
+                       lwsl_warn("Failed to set SNDBUF to %d", n);
+                       goto bail;
+               }
+
                lwsl_parser("accepted v%02d connection\n",
                                                       wsi->ietf_spec_revision);
 #endif