iodine 0.7.17 → 0.7.18

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of iodine might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 909a4b34102fd6e636eab59eccf82deaf315bcc50131ee9f4d476f249df2fe2a
4
- data.tar.gz: dded0a5249df8dcd0854198ea6df03661e40b69ddcba35d0bd693c1a6acf6cb2
3
+ metadata.gz: 664ebf25c0cad461467cdb2af2b789d3a0897721566c015bff60b68768a7e3ad
4
+ data.tar.gz: cc31d5af68fd2a59dc8fa927af51c2228082f05ca7b69c2c4b31e1d208f88337
5
5
  SHA512:
6
- metadata.gz: 9cdaf95feee9f8de5daedf472a3bd5318931c1aa1b5a5ccc95178e62053ba6e97e021f856ec863e586f22d0b760dee1a66a6204c1cd71267545f164cd9ce378f
7
- data.tar.gz: 24d6b5d326fd11cb69beeb215bfc80b4f062d269d3734bc78710654c5444d370346793da2f18c6dba955f53f9754063206399d9de1aef5d76d04299a8ee29aeb
6
+ metadata.gz: ae79cb205f288cb84b14d92f7b987f7e350f747c560e3a6e23cb3c1f1d43864234e75dd7f8b71f179f3cecfc8841c0f1da53a41995502c2c8c8c6945c248cc86
7
+ data.tar.gz: 705d7b0d312e1c3b7953cf503878a2c91a006cef1c7bf9612f83f8f3d97494208bdc8c2ef1a6a857839586525dcd3cbaa4e64758c597a5fd1d929a364f2b9b3c
@@ -6,6 +6,10 @@ Please notice that this change log contains changes for upcoming releases as wel
6
6
 
7
7
  ## Changes:
8
8
 
9
+ #### Change log v.0.7.18
10
+
11
+ **Fix** (`pubsub`) fixed pub/sub for longer WebSocket messages. Issue where network byte ordering wasn't always respected and integer bit size was wrong for larger payloads. Credit to Marouane Elmidaoui (@moxgeek) for exposing the issue.
12
+
9
13
  #### Change log v.0.7.17
10
14
 
11
15
  **Security**: (`fio`) improved security against hash flooding attacks.
@@ -221,82 +221,40 @@ void websocket_xmask(void *msg, uint64_t len, uint32_t mask) {
221
221
  Message wrapping
222
222
  ***************************************************************************** */
223
223
 
224
- // clang-format off
225
- #if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
226
- # if defined(__has_include)
227
- # if __has_include(<endian.h>)
228
- # include <endian.h>
229
- # elif __has_include(<sys/endian.h>)
230
- # include <sys/endian.h>
231
- # endif
232
- # endif
233
- # if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) && \
234
- __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
235
- # define __BIG_ENDIAN__
236
- # endif
237
- #endif
238
- // clang-format on
239
-
240
- #ifdef __BIG_ENDIAN__
241
- /** stub byte swap 64 bit integer from pointer */
242
- static inline uint64_t netpiswap64(uint8_t *i) {
243
- uint64_t ret = 0;
244
- uint8_t *const pret = (uint8_t *)&ret;
245
- pret[7] = i[7];
246
- pret[6] = i[6];
247
- pret[5] = i[5];
248
- pret[4] = i[4];
249
- pret[3] = i[3];
250
- pret[2] = i[2];
251
- pret[1] = i[1];
252
- pret[0] = i[0];
253
- return ret;
254
- }
255
- /** stub byte swap 16 bit integer from pointer */
256
- static inline uint16_t netpiswap16(uint8_t *i) {
257
- uint16_t ret = 0;
258
- uint8_t *const pret = (uint8_t *)&ret;
259
- pret[1] = i[1];
260
- pret[0] = i[0];
261
- return ret;
262
- }
263
- #define netiswap64(i) (i)
264
- #define netiswap16(i) (i)
265
-
266
- #else
267
- // TODO: check for __builtin_bswap64
268
- /** byte swap 64 bit integer */
269
- #define netiswap64(i) \
270
- ((((i)&0xFFULL) << 56) | (((i)&0xFF00ULL) << 40) | \
271
- (((i)&0xFF0000ULL) << 24) | (((i)&0xFF000000ULL) << 8) | \
272
- (((i)&0xFF00000000ULL) >> 8) | (((i)&0xFF0000000000ULL) >> 24) | \
273
- (((i)&0xFF000000000000ULL) >> 40) | (((i)&0xFF00000000000000ULL) >> 56))
274
- /** byte swap 16 bit integer */
275
- #define netiswap16(i) ((((i)&0x00ff) << 8) | (((i)&0xff00) >> 8))
276
- /** byte swap 64 bit integer from pointer */
277
- static inline uint64_t netpiswap64(uint8_t *i) {
278
- uint64_t ret = 0;
279
- uint8_t *const pret = (uint8_t *)&ret;
280
- pret[0] = i[7];
281
- pret[1] = i[6];
282
- pret[2] = i[5];
283
- pret[3] = i[4];
284
- pret[4] = i[3];
285
- pret[5] = i[2];
286
- pret[6] = i[1];
287
- pret[7] = i[0];
288
- return ret;
289
- }
290
- /** byte swap 16 bit integer from pointer */
291
- static inline uint16_t netpiswap16(uint8_t *i) {
292
- uint16_t ret = 0;
293
- uint8_t *const pret = (uint8_t *)&ret;
294
- pret[0] = i[1];
295
- pret[1] = i[0];
296
- return ret;
297
- }
298
-
299
- #endif
224
+ /** Converts an unaligned network ordered byte stream to a 16 bit number. */
225
+ #define websocket_str2u16(c) \
226
+ ((uint16_t)(((uint16_t)(((uint8_t *)(c))[0]) << 8) | \
227
+ (uint16_t)(((uint8_t *)(c))[1])))
228
+
229
+ /** Converts an unaligned network ordered byte stream to a 64 bit number. */
230
+ #define websocket_str2u64(c) \
231
+ ((uint64_t)((((uint64_t)((uint8_t *)(c))[0]) << 56) | \
232
+ (((uint64_t)((uint8_t *)(c))[1]) << 48) | \
233
+ (((uint64_t)((uint8_t *)(c))[2]) << 40) | \
234
+ (((uint64_t)((uint8_t *)(c))[3]) << 32) | \
235
+ (((uint64_t)((uint8_t *)(c))[4]) << 24) | \
236
+ (((uint64_t)((uint8_t *)(c))[5]) << 16) | \
237
+ (((uint64_t)((uint8_t *)(c))[6]) << 8) | (((uint8_t *)(c))[7])))
238
+
239
+ /** Writes a local 16 bit number to an unaligned buffer in network order. */
240
+ #define websocket_u2str16(buffer, i) \
241
+ do { \
242
+ ((uint8_t *)(buffer))[0] = ((uint16_t)(i) >> 8) & 0xFF; \
243
+ ((uint8_t *)(buffer))[1] = ((uint16_t)(i)) & 0xFF; \
244
+ } while (0);
245
+
246
+ /** Writes a local 64 bit number to an unaligned buffer in network order. */
247
+ #define websocket_u2str64(buffer, i) \
248
+ do { \
249
+ ((uint8_t *)(buffer))[0] = ((uint64_t)(i) >> 56) & 0xFF; \
250
+ ((uint8_t *)(buffer))[1] = ((uint64_t)(i) >> 48) & 0xFF; \
251
+ ((uint8_t *)(buffer))[2] = ((uint64_t)(i) >> 40) & 0xFF; \
252
+ ((uint8_t *)(buffer))[3] = ((uint64_t)(i) >> 32) & 0xFF; \
253
+ ((uint8_t *)(buffer))[4] = ((uint64_t)(i) >> 24) & 0xFF; \
254
+ ((uint8_t *)(buffer))[5] = ((uint64_t)(i) >> 16) & 0xFF; \
255
+ ((uint8_t *)(buffer))[6] = ((uint64_t)(i) >> 8) & 0xFF; \
256
+ ((uint8_t *)(buffer))[7] = ((uint64_t)(i)) & 0xFF; \
257
+ } while (0);
300
258
 
301
259
  /** returns the length of the buffer required to wrap a message `len` long */
302
260
  static inline uint64_t websocket_wrapped_len(uint64_t len) {
@@ -346,23 +304,13 @@ static uint64_t websocket_server_wrap(void *target, void *msg, uint64_t len,
346
304
  } else if (len < (1UL << 16)) {
347
305
  /* head is 4 bytes */
348
306
  ((uint8_t *)target)[1] = 126;
349
- const uint16_t net_len = netiswap16(len);
350
- ((uint8_t *)target)[2] = ((uint8_t *)(&net_len))[0];
351
- ((uint8_t *)target)[3] = ((uint8_t *)(&net_len))[1];
307
+ websocket_u2str16(((uint8_t *)target + 2), len);
352
308
  memcpy((uint8_t *)target + 4, msg, len);
353
309
  return len + 4;
354
310
  }
355
311
  /* Really Long Message */
356
312
  ((uint8_t *)target)[1] = 127;
357
- const uint64_t net_len = netiswap16(len);
358
- ((uint8_t *)target)[2] = ((uint8_t *)(&net_len))[0];
359
- ((uint8_t *)target)[3] = ((uint8_t *)(&net_len))[1];
360
- ((uint8_t *)target)[4] = ((uint8_t *)(&net_len))[2];
361
- ((uint8_t *)target)[5] = ((uint8_t *)(&net_len))[3];
362
- ((uint8_t *)target)[6] = ((uint8_t *)(&net_len))[4];
363
- ((uint8_t *)target)[7] = ((uint8_t *)(&net_len))[5];
364
- ((uint8_t *)target)[8] = ((uint8_t *)(&net_len))[6];
365
- ((uint8_t *)target)[9] = ((uint8_t *)(&net_len))[7];
313
+ websocket_u2str64(((uint8_t *)target + 2), len);
366
314
  memcpy((uint8_t *)target + 10, msg, len);
367
315
  return len + 10;
368
316
  }
@@ -402,9 +350,7 @@ static uint64_t websocket_client_wrap(void *target, void *msg, uint64_t len,
402
350
  } else if (len < (1UL << 16)) {
403
351
  /* head is 4 bytes */
404
352
  ((uint8_t *)target)[1] = 126 | 128;
405
- const uint16_t net_len = netiswap16(len);
406
- ((uint8_t *)target)[2] = ((uint8_t *)(&net_len))[0];
407
- ((uint8_t *)target)[3] = ((uint8_t *)(&net_len))[1];
353
+ websocket_u2str16(((uint8_t *)target + 2), len);
408
354
  ((uint8_t *)target)[4] = ((uint8_t *)(&mask))[0];
409
355
  ((uint8_t *)target)[5] = ((uint8_t *)(&mask))[1];
410
356
  ((uint8_t *)target)[6] = ((uint8_t *)(&mask))[2];
@@ -415,15 +361,7 @@ static uint64_t websocket_client_wrap(void *target, void *msg, uint64_t len,
415
361
  }
416
362
  /* Really Long Message */
417
363
  ((uint8_t *)target)[1] = 255;
418
- const uint64_t net_len = netiswap16(len);
419
- ((uint8_t *)target)[2] = ((uint8_t *)(&net_len))[0];
420
- ((uint8_t *)target)[3] = ((uint8_t *)(&net_len))[1];
421
- ((uint8_t *)target)[4] = ((uint8_t *)(&net_len))[2];
422
- ((uint8_t *)target)[5] = ((uint8_t *)(&net_len))[3];
423
- ((uint8_t *)target)[6] = ((uint8_t *)(&net_len))[4];
424
- ((uint8_t *)target)[7] = ((uint8_t *)(&net_len))[5];
425
- ((uint8_t *)target)[8] = ((uint8_t *)(&net_len))[6];
426
- ((uint8_t *)target)[9] = ((uint8_t *)(&net_len))[7];
364
+ websocket_u2str64(((uint8_t *)target + 2), len);
427
365
  ((uint8_t *)target)[10] = ((uint8_t *)(&mask))[0];
428
366
  ((uint8_t *)target)[11] = ((uint8_t *)(&mask))[1];
429
367
  ((uint8_t *)target)[12] = ((uint8_t *)(&mask))[2];
@@ -460,14 +398,15 @@ websocket_buffer_peek(void *buffer, uint64_t len) {
460
398
  if (len < 4)
461
399
  return (struct websocket_packet_info_s){0, (uint8_t)(4 + mask_l), mask_f};
462
400
  return (struct websocket_packet_info_s){
463
- (uint64_t)netpiswap16(((uint8_t *)buffer) + 2), (uint8_t)(4 + mask_l),
464
- mask_f};
401
+ (uint64_t)websocket_str2u16(((uint8_t *)buffer + 2)),
402
+ (uint8_t)(4 + mask_l), mask_f};
465
403
  case 127:
466
404
  if (len < 10)
467
405
  return (struct websocket_packet_info_s){0, (uint8_t)(10 + mask_l),
468
406
  mask_f};
469
407
  return (struct websocket_packet_info_s){
470
- netpiswap64(((uint8_t *)buffer) + 2), (uint8_t)(10 + mask_l), mask_f};
408
+ websocket_str2u64(((uint8_t *)buffer + 2)), (uint8_t)(10 + mask_l),
409
+ mask_f};
471
410
  default:
472
411
  return (struct websocket_packet_info_s){len_indicator,
473
412
  (uint8_t)(2 + mask_l), mask_f};
@@ -542,29 +542,34 @@ static inline void websocket_on_pubsub_message_direct_internal(fio_msg_s *msg,
542
542
  }
543
543
  FIOBJ message = FIOBJ_INVALID;
544
544
  FIOBJ pre_wrapped = FIOBJ_INVALID;
545
- switch (txt) {
546
- case 0:
547
- pre_wrapped =
548
- (FIOBJ)fio_message_metadata(msg, WEBSOCKET_OPTIMIZE_PUBSUB_BINARY);
549
- break;
550
- case 1:
551
- pre_wrapped =
552
- (FIOBJ)fio_message_metadata(msg, WEBSOCKET_OPTIMIZE_PUBSUB_TEXT);
553
- break;
554
- case 2:
555
- pre_wrapped = (FIOBJ)fio_message_metadata(msg, WEBSOCKET_OPTIMIZE_PUBSUB);
556
- break;
557
- default:
558
- break;
559
- }
560
- if (pre_wrapped) {
561
- fiobj_send_free((intptr_t)msg->udata1, fiobj_dup(pre_wrapped));
562
- goto finish;
545
+ if (!((ws_s *)pr)->is_client) {
546
+ /* pre-wrapping is only for client data */
547
+ switch (txt) {
548
+ case 0:
549
+ pre_wrapped =
550
+ (FIOBJ)fio_message_metadata(msg, WEBSOCKET_OPTIMIZE_PUBSUB_BINARY);
551
+ break;
552
+ case 1:
553
+ pre_wrapped =
554
+ (FIOBJ)fio_message_metadata(msg, WEBSOCKET_OPTIMIZE_PUBSUB_TEXT);
555
+ break;
556
+ case 2:
557
+ pre_wrapped = (FIOBJ)fio_message_metadata(msg, WEBSOCKET_OPTIMIZE_PUBSUB);
558
+ break;
559
+ default:
560
+ break;
561
+ }
562
+ if (pre_wrapped) {
563
+ // FIO_LOG_DEBUG(
564
+ // "pub/sub WebSocket optimization route for pre-wrapped message.");
565
+ fiobj_send_free((intptr_t)msg->udata1, fiobj_dup(pre_wrapped));
566
+ goto finish;
567
+ }
563
568
  }
564
569
  if (txt == 2) {
565
570
  /* unknown text state */
566
571
  fio_str_s tmp =
567
- FIO_STR_INIT_EXISTING(msg->msg.data, msg->msg.len, 0); // don't free
572
+ FIO_STR_INIT_STATIC2(msg->msg.data, msg->msg.len); // don't free
568
573
  txt = (tmp.len >= (2 << 14) ? 0 : fio_str_utf8_valid(&tmp));
569
574
  }
570
575
  websocket_write((ws_s *)pr, msg->msg, txt & 1);
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = '0.7.17'.freeze
2
+ VERSION = '0.7.18'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iodine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.17
4
+ version: 0.7.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-17 00:00:00.000000000 Z
11
+ date: 2019-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -220,7 +220,7 @@ licenses:
220
220
  - MIT
221
221
  metadata:
222
222
  allowed_push_host: https://rubygems.org
223
- post_install_message: 'Thank you for installing Iodine 0.7.17.
223
+ post_install_message: 'Thank you for installing Iodine 0.7.18.
224
224
 
225
225
  '
226
226
  rdoc_options: []