]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
websocket / pjsip: Increase maximum packet size.
authorJoshua C. Colp <jcolp@sangoma.com>
Wed, 22 Jul 2020 17:57:44 +0000 (14:57 -0300)
committerJoshua Colp <jcolp@sangoma.com>
Thu, 23 Jul 2020 12:30:25 +0000 (07:30 -0500)
When dealing with a lot of video streams on WebRTC
the resulting SDPs can grow to be quite large. This
effectively doubles the maximum size to allow more
streams to exist.

The res_http_websocket module has also been changed
to use a buffer on the session for reading in packets
to ensure that the stack space usage is not excessive.

Change-Id: I31d4351d70c8e2c11564807a7528b984f3fbdd01

res/res_http_websocket.c
res/res_pjsip_pubsub.c
third-party/pjproject/patches/config_site.h

index d6cd359946cf3c5fa2482c711e8c63b530ce1b8c..6f3e5a5661fa2f40f0c8544b5c6e2759a5ce7df2 100644 (file)
 #define MAXIMUM_RECONSTRUCTION_CEILING 8192
 #else
 /*! \brief Size of the pre-determined buffer for WebSocket frames */
-#define MAXIMUM_FRAME_SIZE 32768
+#define MAXIMUM_FRAME_SIZE 65535
 
 /*! \brief Default reconstruction size for multi-frame payload reconstruction. If exceeded the next frame will start a
  *         payload.
  */
-#define DEFAULT_RECONSTRUCTION_CEILING 32768
+#define DEFAULT_RECONSTRUCTION_CEILING MAXIMUM_FRAME_SIZE
 
 /*! \brief Maximum reconstruction size for multi-frame payload reconstruction. */
-#define MAXIMUM_RECONSTRUCTION_CEILING 32768
+#define MAXIMUM_RECONSTRUCTION_CEILING MAXIMUM_FRAME_SIZE
 #endif
 
 /*! \brief Maximum size of a websocket frame header
@@ -100,6 +100,7 @@ struct ast_websocket {
        struct websocket_client *client;    /*!< Client object when connected as a client websocket */
        char session_id[AST_UUID_STR_LEN];  /*!< The identifier for the websocket session */
        uint16_t close_status_code;         /*!< Status code sent in a CLOSE frame upon shutdown */
+       char buf[MAXIMUM_FRAME_SIZE];       /*!< Fixed buffer for reading data into */
 };
 
 /*! \brief Hashing function for protocols */
@@ -600,7 +601,6 @@ static inline int ws_safe_read(struct ast_websocket *session, char *buf, size_t
 
 int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, char **payload, uint64_t *payload_len, enum ast_websocket_opcode *opcode, int *fragmented)
 {
-       char buf[MAXIMUM_FRAME_SIZE] = "";
        int fin = 0;
        int mask_present = 0;
        char *mask = NULL, *new_payload = NULL;
@@ -610,25 +610,25 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
        *payload_len = 0;
        *fragmented = 0;
 
-       if (ws_safe_read(session, &buf[0], MIN_WS_HDR_SZ, opcode)) {
+       if (ws_safe_read(session, &session->buf[0], MIN_WS_HDR_SZ, opcode)) {
                return -1;
        }
        frame_size += MIN_WS_HDR_SZ;
 
        /* ok, now we have the first 2 bytes, so we know some flags, opcode and payload length (or whether payload length extension will be required) */
-       *opcode = buf[0] & 0xf;
-       *payload_len = buf[1] & 0x7f;
+       *opcode = session->buf[0] & 0xf;
+       *payload_len = session->buf[1] & 0x7f;
        if (*opcode == AST_WEBSOCKET_OPCODE_TEXT || *opcode == AST_WEBSOCKET_OPCODE_BINARY || *opcode == AST_WEBSOCKET_OPCODE_CONTINUATION ||
            *opcode == AST_WEBSOCKET_OPCODE_PING || *opcode == AST_WEBSOCKET_OPCODE_PONG  || *opcode == AST_WEBSOCKET_OPCODE_CLOSE) {
-               fin = (buf[0] >> 7) & 1;
-               mask_present = (buf[1] >> 7) & 1;
+               fin = (session->buf[0] >> 7) & 1;
+               mask_present = (session->buf[1] >> 7) & 1;
 
                /* Based on the mask flag and payload length, determine how much more we need to read before start parsing the rest of the header */
                options_len += mask_present ? 4 : 0;
                options_len += (*payload_len == 126) ? 2 : (*payload_len == 127) ? 8 : 0;
                if (options_len) {
                        /* read the rest of the header options */
-                       if (ws_safe_read(session, &buf[frame_size], options_len, opcode)) {
+                       if (ws_safe_read(session, &session->buf[frame_size], options_len, opcode)) {
                                return -1;
                        }
                        frame_size += options_len;
@@ -636,19 +636,19 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
 
                if (*payload_len == 126) {
                        /* Grab the 2-byte payload length  */
-                       *payload_len = ntohs(get_unaligned_uint16(&buf[2]));
-                       mask = &buf[4];
+                       *payload_len = ntohs(get_unaligned_uint16(&session->buf[2]));
+                       mask = &session->buf[4];
                } else if (*payload_len == 127) {
                        /* Grab the 8-byte payload length  */
-                       *payload_len = ntohl(get_unaligned_uint64(&buf[2]));
-                       mask = &buf[10];
+                       *payload_len = ntohll(get_unaligned_uint64(&session->buf[2]));
+                       mask = &session->buf[10];
                } else {
                        /* Just set the mask after the small 2-byte header */
-                       mask = &buf[2];
+                       mask = &session->buf[2];
                }
 
                /* Now read the rest of the payload */
-               *payload = &buf[frame_size]; /* payload will start here, at the end of the options, if any */
+               *payload = &session->buf[frame_size]; /* payload will start here, at the end of the options, if any */
                frame_size = frame_size + (*payload_len); /* final frame size is header + optional headers + payload data */
                if (frame_size > MAXIMUM_FRAME_SIZE) {
                        ast_log(LOG_WARNING, "Cannot fit huge websocket frame of %zu bytes\n", frame_size);
index be1eb39db2b6e81f9ee8aceb3ea7c076581253f1..1142bbd41d5ba54e688d706259f5681b66c5d34f 100644 (file)
                                        that a server has to process.</para>
                                        <note>
                                                <para>Current limitations limit the size of SIP NOTIFY requests that Asterisk sends
-                                               to 64000 bytes. If your resource list notifications are larger than this maximum, you
-                                               will need to make adjustments.</para>
+                                               to double that of the PJSIP maximum packet length. If your resource list notifications
+                                               are larger than this maximum, you will need to make adjustments.</para>
                                        </note>
                                </description>
                                <configOption name="type">
@@ -1950,15 +1950,7 @@ struct ast_taskprocessor *ast_sip_subscription_get_serializer(struct ast_sip_sub
  * we instead take the strategy of pre-allocating the buffer, testing for ourselves
  * if the message will fit, and resizing the buffer as required.
  *
- * RFC 3261 says that a SIP UDP request can be up to 65535 bytes long. We're capping
- * it at 64000 for a couple of reasons:
- * 1) Allocating more than 64K at a time is hard to justify
- * 2) If the message goes through proxies, those proxies will want to add Via and
- *    Record-Route headers, making the message even larger. Giving some space for
- *    those headers is a nice thing to do.
- *
- * RFC 3261 does not place an upper limit on the size of TCP requests, but we are
- * going to impose the same 64K limit as a memory savings.
+ * The limit we impose is double that of the maximum packet length.
  *
  * \param tdata The tdata onto which to allocate a buffer
  * \retval 0 Success
@@ -1970,7 +1962,7 @@ static int allocate_tdata_buffer(pjsip_tx_data *tdata)
        int size = -1;
        char *buf;
 
-       for (buf_size = PJSIP_MAX_PKT_LEN; size == -1 && buf_size < 64000; buf_size *= 2) {
+       for (buf_size = PJSIP_MAX_PKT_LEN; size == -1 && buf_size < (PJSIP_MAX_PKT_LEN * 2); buf_size *= 2) {
                buf = pj_pool_alloc(tdata->pool, buf_size);
                size = pjsip_msg_print(tdata->msg, buf, buf_size);
        }
index aea7d0d38e7eeb6e285bae2c7aef7068671a36cb..5884108f68dbd5c411454badf7f55e28c144a819 100644 (file)
@@ -65,7 +65,7 @@
   Enabling it will result in SEGFAULTS when URIs containing escape sequences are encountered.
 */
 #undef PJSIP_UNESCAPE_IN_PLACE
-#define PJSIP_MAX_PKT_LEN                      32000
+#define PJSIP_MAX_PKT_LEN                      65535
 
 #undef PJ_TODO
 #define PJ_TODO(x)