pmd: autobahn fixes
[platform/upstream/libwebsockets.git] / lib / extension-permessage-deflate.c
1 /*
2  * ./lib/extension-permessage-deflate.c
3  *
4  *  Copyright (C) 2016 Andy Green <andy@warmcat.com>
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation:
9  *  version 2.1 of the License.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *  MA  02110-1301  USA
20  */
21
22 #include "private-libwebsockets.h"
23 #include "extension-permessage-deflate.h"
24 #include <stdio.h>
25 #include <string.h>
26 #include <assert.h>
27
28 #define LWS_ZLIB_MEMLEVEL 8
29
30 const struct lws_ext_options lws_ext_pm_deflate_options[] = {
31         /* public RFC7692 settings */
32         { "server_no_context_takeover", EXTARG_NONE },
33         { "client_no_context_takeover", EXTARG_NONE },
34         { "server_max_window_bits",     EXTARG_OPT_DEC },
35         { "client_max_window_bits",     EXTARG_OPT_DEC },
36         /* ones only user code can set */
37         { "rx_buf_size",                EXTARG_DEC },
38         { "tx_buf_size",                EXTARG_DEC },
39         { "compression_level",          EXTARG_DEC },
40         { "mem_level",                  EXTARG_DEC },
41         { NULL, 0 }, /* sentinel */
42 };
43
44 static void
45 lws_extension_pmdeflate_restrict_args(struct lws *wsi,
46                                       struct lws_ext_pm_deflate_priv *priv)
47 {
48         int n, extra;
49
50         /* cap the RX buf at the nearest power of 2 to protocol rx buf */
51
52         n = wsi->context->pt_serv_buf_size;
53         if (wsi->protocol->rx_buffer_size)
54                 n =  wsi->protocol->rx_buffer_size;
55
56         extra = 7;
57         while (n >= 1 << (extra + 1))
58                 extra++;
59
60         if (extra < priv->args[PMD_RX_BUF_PWR2]) {
61                 priv->args[PMD_RX_BUF_PWR2] = extra;
62                 lwsl_err(" Capping pmd rx to %d\n", 1 << extra);
63         }
64 }
65
66 LWS_VISIBLE int
67 lws_extension_callback_pm_deflate(struct lws_context *context,
68                                   const struct lws_extension *ext,
69                                   struct lws *wsi,
70                                   enum lws_extension_callback_reasons reason,
71                                   void *user, void *in, size_t len)
72 {
73         struct lws_ext_pm_deflate_priv *priv =
74                                      (struct lws_ext_pm_deflate_priv *)user;
75         struct lws_tokens *eff_buf = (struct lws_tokens *)in;
76         static unsigned char trail[] = { 0, 0, 0xff, 0xff };
77         int n, ret = 0, was_fin = 0, extra;
78         struct lws_ext_option_arg *oa;
79
80         switch (reason) {
81         case LWS_EXT_CB_NAMED_OPTION_SET:
82                 oa = in;
83                 if (!oa->option_name)
84                         break;
85                 for (n = 0; n < ARRAY_SIZE(lws_ext_pm_deflate_options); n++)
86                         if (!strcmp(lws_ext_pm_deflate_options[n].name, oa->option_name))
87                                 break;
88
89                 if (n == ARRAY_SIZE(lws_ext_pm_deflate_options))
90                         break;
91                 oa->option_index = n;
92
93                 /* fallthru */
94
95         case LWS_EXT_CB_OPTION_SET:
96                 oa = in;
97                 lwsl_notice("%s: option set: idx %d, %s, len %d\n", __func__,
98                           oa->option_index, oa->start, oa->len);
99                 if (oa->start)
100                         priv->args[oa->option_index] = atoi(oa->start);
101                 else
102                         priv->args[oa->option_index] = 1;
103
104                 if (priv->args[PMD_CLIENT_MAX_WINDOW_BITS] == 8)
105                         priv->args[PMD_CLIENT_MAX_WINDOW_BITS] = 9;
106
107                 lws_extension_pmdeflate_restrict_args(wsi, priv);
108                 break;
109
110         case LWS_EXT_CB_OPTION_CONFIRM:
111                 if (priv->args[PMD_SERVER_MAX_WINDOW_BITS] < 8 ||
112                     priv->args[PMD_SERVER_MAX_WINDOW_BITS] > 15 ||
113                     priv->args[PMD_CLIENT_MAX_WINDOW_BITS] < 8 ||
114                     priv->args[PMD_CLIENT_MAX_WINDOW_BITS] > 15)
115                         return -1;
116                 break;
117
118         case LWS_EXT_CB_CLIENT_CONSTRUCT:
119         case LWS_EXT_CB_CONSTRUCT:
120
121                 n = context->pt_serv_buf_size;
122                 if (wsi->protocol->rx_buffer_size)
123                         n =  wsi->protocol->rx_buffer_size;
124
125                 if (n < 128) {
126                         lwsl_err(" permessage-deflate requires the protocol (%s) to have an RX buffer >= 128\n",
127                                         wsi->protocol->name);
128                         return -1;
129                 }
130
131                 /* fill in **user */
132                 priv = lws_zalloc(sizeof(*priv));
133                 *((void **)user) = priv;
134                 lwsl_ext("%s: LWS_EXT_CB_*CONSTRUCT\n", __func__);
135                 memset(priv, 0, sizeof(*priv));
136
137                 /* fill in pointer to options list */
138                 if (in)
139                         *((const struct lws_ext_options **)in) =
140                                         lws_ext_pm_deflate_options;
141
142                 /* fallthru */
143
144         case LWS_EXT_CB_OPTION_DEFAULT:
145
146                 /* set the public, RFC7692 defaults... */
147
148                 priv->args[PMD_SERVER_NO_CONTEXT_TAKEOVER] = 0,
149                 priv->args[PMD_CLIENT_NO_CONTEXT_TAKEOVER] = 0;
150                 priv->args[PMD_SERVER_MAX_WINDOW_BITS] = 15;
151                 priv->args[PMD_CLIENT_MAX_WINDOW_BITS] = 15;
152
153                 /* ...and the ones the user code can override */
154
155                 priv->args[PMD_RX_BUF_PWR2] = 10; /* ie, 1024 */
156                 priv->args[PMD_TX_BUF_PWR2] = 10; /* ie, 1024 */
157                 priv->args[PMD_COMP_LEVEL] = 1;
158                 priv->args[PMD_MEM_LEVEL] = 8;
159
160                 lws_extension_pmdeflate_restrict_args(wsi, priv);
161                 break;
162
163         case LWS_EXT_CB_DESTROY:
164                 lwsl_ext("%s: LWS_EXT_CB_DESTROY\n", __func__);
165                 lws_free(priv->buf_rx_inflated);
166                 lws_free(priv->buf_tx_deflated);
167                 if (priv->rx_init)
168                         (void)inflateEnd(&priv->rx);
169                 if (priv->tx_init)
170                         (void)deflateEnd(&priv->tx);
171                 lws_free(priv);
172                 return ret;
173
174         case LWS_EXT_CB_PAYLOAD_RX:
175                 lwsl_ext(" %s: LWS_EXT_CB_PAYLOAD_RX: in %d, existing in %d\n",
176                          __func__, eff_buf->token_len, priv->rx.avail_in);
177                 if (!(wsi->u.ws.rsv_first_msg & 0x40))
178                         return 0;
179
180 #if 0
181                 for (n = 0; n < eff_buf->token_len; n++) {
182                         printf("%02X ", (unsigned char)eff_buf->token[n]);
183                         if ((n & 15) == 15)
184                                 printf("\n");
185                 }
186                 printf("\n");
187 #endif
188                 if (!priv->rx_init)
189                         if (inflateInit2(&priv->rx, -priv->args[PMD_SERVER_MAX_WINDOW_BITS]) != Z_OK) {
190                                 lwsl_err("%s: iniflateInit failed\n", __func__);
191                                 return -1;
192                         }
193                 priv->rx_init = 1;
194                 if (!priv->buf_rx_inflated)
195                         priv->buf_rx_inflated = lws_malloc(LWS_PRE + 7 + 5 +
196                                             (1 << priv->args[PMD_RX_BUF_PWR2]));
197                 if (!priv->buf_rx_inflated) {
198                         lwsl_err("%s: OOM\n", __func__);
199                         return -1;
200                 }
201
202                 /*
203                  * We have to leave the input stream alone if we didn't
204                  * finish with it yet.  The input stream is held in the wsi
205                  * rx buffer by the caller, so this assumption is safe while
206                  * we block new rx while draining the existing rx
207                  */
208                 if (!priv->rx.avail_in && eff_buf->token && eff_buf->token_len) {
209                         priv->rx.next_in = (unsigned char *)eff_buf->token;
210                         priv->rx.avail_in = eff_buf->token_len;
211                 }
212                 priv->rx.next_out = priv->buf_rx_inflated + LWS_PRE;
213                 eff_buf->token = (char *)priv->rx.next_out;
214                 priv->rx.avail_out = 1 << priv->args[PMD_RX_BUF_PWR2];
215
216                 if (priv->rx_held_valid) {
217                         lwsl_ext("-- RX piling on held byte --\n");
218                         *(priv->rx.next_out++) = priv->rx_held;
219                         priv->rx.avail_out--;
220                         priv->rx_held_valid = 0;
221                 }
222
223                 /* if...
224                  *
225                  *  - he has no remaining input content for this message, and
226                  *  - and this is the final fragment, and
227                  *  - we used everything that could be drained on the input side
228                  *
229                  * ...then put back the 00 00 FF FF the sender stripped as our
230                  * input to zlib
231                  */
232                 if (!priv->rx.avail_in && wsi->u.ws.final &&
233                     !wsi->u.ws.rx_packet_length) {
234                         lwsl_ext("RX APPEND_TRAILER-DO\n");
235                         was_fin = 1;
236                         priv->rx.next_in = trail;
237                         priv->rx.avail_in = sizeof(trail);
238                 }
239
240                 n = inflate(&priv->rx, Z_NO_FLUSH);
241                 lwsl_ext("inflate ret %d, avi %d, avo %d, wsifinal %d\n", n,
242                          priv->rx.avail_in, priv->rx.avail_out, wsi->u.ws.final);
243                 switch (n) {
244                 case Z_NEED_DICT:
245                 case Z_STREAM_ERROR:
246                 case Z_DATA_ERROR:
247                 case Z_MEM_ERROR:
248                         lwsl_info("zlib error inflate %d: %s\n",
249                                   n, priv->rx.msg);
250                         return -1;
251                 }
252                 /*
253                  * If we did not already send in the 00 00 FF FF, and he's
254                  * out of input, he did not EXACTLY fill the output buffer
255                  * (which is ambiguous and we will force it to go around
256                  * again by withholding a byte), and he's otherwise working on
257                  * being a FIN fragment, then do the FIN message processing
258                  * of faking up the 00 00 FF FF that the sender stripped.
259                  */
260                 if (!priv->rx.avail_in && wsi->u.ws.final &&
261                     !wsi->u.ws.rx_packet_length && !was_fin &&
262                     priv->rx.avail_out /* ambiguous as to if it is the end */
263                 ) {
264                         lwsl_ext("RX APPEND_TRAILER-DO\n");
265                         was_fin = 1;
266                         priv->rx.next_in = trail;
267                         priv->rx.avail_in = sizeof(trail);
268                         n = inflate(&priv->rx, Z_SYNC_FLUSH);
269                         lwsl_ext("RX trailer inf returned %d, avi %d, avo %d\n", n,
270                                  priv->rx.avail_in, priv->rx.avail_out);
271                         switch (n) {
272                         case Z_NEED_DICT:
273                         case Z_STREAM_ERROR:
274                         case Z_DATA_ERROR:
275                         case Z_MEM_ERROR:
276                                 lwsl_info("zlib error inflate %d: %s\n",
277                                           n, priv->rx.msg);
278                                 return -1;
279                         }
280                 }
281                 /*
282                  * we must announce in our returncode now if there is more
283                  * output to be expected from inflate, so we can decide to
284                  * set the FIN bit on this bufferload or not.  However zlib
285                  * is ambiguous when we exactly filled the inflate buffer.  It
286                  * does not give us a clue as to whether we should understand
287                  * that to mean he ended on a buffer boundary, or if there is
288                  * more in the pipeline.
289                  *
290                  * So to work around that safely, if it used all output space
291                  * exactly, we ALWAYS say there is more coming and we withhold
292                  * the last byte of the buffer to guarantee that is true.
293                  *
294                  * That still leaves us at least one byte to finish with a FIN
295                  * on, even if actually nothing more is coming from the next
296                  * inflate action itself.
297                  */
298                 if (!priv->rx.avail_out) { /* he used all available out buf */
299                         lwsl_ext("-- rx grabbing held --\n");
300                         /* snip the last byte and hold it for next time */
301                         priv->rx_held = *(--priv->rx.next_out);
302                         priv->rx_held_valid = 1;
303                 }
304
305                 eff_buf->token_len = (char *)priv->rx.next_out - eff_buf->token;
306                 priv->count_rx_between_fin += eff_buf->token_len;
307
308                 lwsl_ext("  %s: RX leaving with new effbuff len %d, "
309                          "ret %d, rx.avail_in=%d, TOTAL RX since FIN %lu\n",
310                          __func__, eff_buf->token_len, priv->rx_held_valid,
311                          priv->rx.avail_in,
312                          (unsigned long)priv->count_rx_between_fin);
313
314                 if (was_fin) {
315                         priv->count_rx_between_fin = 0;
316                         if (priv->args[PMD_SERVER_NO_CONTEXT_TAKEOVER]) {
317                                 (void)inflateEnd(&priv->rx);
318                                 priv->rx_init = 0;
319                         }
320                 }
321 #if 0
322                 for (n = 0; n < eff_buf->token_len; n++)
323                         putchar(eff_buf->token[n]);
324                 puts("\n");
325 #endif
326
327                 return priv->rx_held_valid;
328
329         case LWS_EXT_CB_PAYLOAD_TX:
330
331                 if (!priv->tx_init) {
332                         n = deflateInit2(&priv->tx, priv->args[PMD_COMP_LEVEL],
333                                          Z_DEFLATED,
334                                          -priv->args[PMD_SERVER_MAX_WINDOW_BITS +
335                                                      (wsi->vhost->listen_port <= 0)],
336                                          priv->args[PMD_MEM_LEVEL],
337                                          Z_DEFAULT_STRATEGY);
338                         if (n != Z_OK) {
339                                 lwsl_ext("inflateInit2 failed %d\n", n);
340                                 return 1;
341                         }
342                 }
343                 priv->tx_init = 1;
344                 if (!priv->buf_tx_deflated)
345                         priv->buf_tx_deflated = lws_malloc(LWS_PRE + 7 + 5 +
346                                             (1 << priv->args[PMD_TX_BUF_PWR2]));
347                 if (!priv->buf_tx_deflated) {
348                         lwsl_err("%s: OOM\n", __func__);
349                         return -1;
350                 }
351
352                 if (eff_buf->token) {
353                         lwsl_ext("%s: TX: eff_buf length %d\n", __func__,
354                                  eff_buf->token_len);
355                         priv->tx.next_in = (unsigned char *)eff_buf->token;
356                         priv->tx.avail_in = eff_buf->token_len;
357                 }
358
359 #if 0
360                 for (n = 0; n < eff_buf->token_len; n++) {
361                         printf("%02X ", (unsigned char)eff_buf->token[n]);
362                         if ((n & 15) == 15)
363                                 printf("\n");
364                 }
365                 printf("\n");
366 #endif
367
368                 priv->tx.next_out = priv->buf_tx_deflated + LWS_PRE + 5;
369                 eff_buf->token = (char *)priv->tx.next_out;
370                 priv->tx.avail_out = 1 << priv->args[PMD_TX_BUF_PWR2];
371
372                 n = deflate(&priv->tx, Z_SYNC_FLUSH);
373                 if (n == Z_STREAM_ERROR) {
374                         lwsl_ext("%s: Z_STREAM_ERROR\n", __func__);
375                         return -1;
376                 }
377
378                 if (priv->tx_held_valid) {
379                         priv->tx_held_valid = 0;
380                         if (priv->tx.avail_out == 1 << priv->args[PMD_TX_BUF_PWR2])
381                                 /*
382                                  * we can get a situation he took something in
383                                  * but did not generate anything out, at the end
384                                  * of a message (eg, next thing he sends is 80
385                                  * 00, a zero length FIN, like Authobahn can
386                                  * send).
387                                  * If we have come back as a FIN, we must not
388                                  * place the pending trailer 00 00 FF FF, just
389                                  * the 1 byte of live data
390                                  */
391                                 *(--eff_buf->token) = priv->tx_held[0];
392                         else {
393                                 /* he generated data, prepend whole pending */
394                                 eff_buf->token -= 5;
395                                 for (n = 0; n < 5; n++)
396                                         eff_buf->token[n] = priv->tx_held[n];
397
398                         }
399                 }
400                 priv->compressed_out = 1;
401                 eff_buf->token_len = (int)(priv->tx.next_out -
402                                            (unsigned char *)eff_buf->token);
403
404                 /*
405                  * we must announce in our returncode now if there is more
406                  * output to be expected from inflate, so we can decide to
407                  * set the FIN bit on this bufferload or not.  However zlib
408                  * is ambiguous when we exactly filled the inflate buffer.  It
409                  * does not give us a clue as to whether we should understand
410                  * that to mean he ended on a buffer boundary, or if there is
411                  * more in the pipeline.
412                  *
413                  * Worse, the guy providing the stuff we are sending may not
414                  * know until after that this was, actually, the last chunk,
415                  * that can happen even if we did not fill the output buf, ie
416                  * he may send after this a zero-length FIN fragment.
417                  *
418                  * This is super difficult because we must snip the last 4
419                  * bytes in the case this is the last compressed output of the
420                  * message.  The only way to deal with it is defer sending the
421                  * last 5 bytes of each frame until the next one, when we will
422                  * be in a position to understand if that has a FIN or not.
423                  */
424
425                 extra = !!(len & LWS_WRITE_NO_FIN) || !priv->tx.avail_out;
426
427                 if (eff_buf->token_len >= 4 + extra) {
428                         lwsl_ext("tx held %d\n", 4 + extra);
429                         priv->tx_held_valid = extra;
430                         for (n = 3 + extra; n >= 0; n--)
431                                 priv->tx_held[n] = *(--priv->tx.next_out);
432                         eff_buf->token_len -= 4 + extra;
433                 }
434                 lwsl_ext("  TX rewritten with new effbuff len %d, ret %d\n",
435                          eff_buf->token_len, !priv->tx.avail_out);
436
437                 return !priv->tx.avail_out; /* 1 == have more tx pending */
438
439         case LWS_EXT_CB_PACKET_TX_PRESEND:
440                 if (!priv->compressed_out)
441                         break;
442                 priv->compressed_out = 0;
443
444                 if ((*(eff_buf->token) & 0x80) &&
445                     priv->args[PMD_CLIENT_NO_CONTEXT_TAKEOVER]) {
446                         lwsl_debug("PMD_CLIENT_NO_CONTEXT_TAKEOVER\n");
447                         (void)deflateEnd(&priv->tx);
448                         priv->tx_init = 0;
449                 }
450
451                 n = *(eff_buf->token) & 15;
452                 /* set RSV1, but not on CONTINUATION */
453                 if (n == LWSWSOPC_TEXT_FRAME || n == LWSWSOPC_BINARY_FRAME)
454                         *eff_buf->token |= 0x40;
455 #if 0
456                 for (n = 0; n < eff_buf->token_len; n++) {
457                         printf("%02X ", (unsigned char)eff_buf->token[n]);
458                         if ((n & 15) == 15)
459                                 puts("\n");
460                 }
461                 puts("\n");
462 #endif
463                 lwsl_ext("%s: tx opcode 0x%02X\n", __func__,
464                          (unsigned char)*eff_buf->token);
465                 break;
466
467         default:
468                 break;
469         }
470
471         return 0;
472 }
473