11131Smax.romanov@nginx.com 21131Smax.romanov@nginx.com /* 31131Smax.romanov@nginx.com * Copyright (C) NGINX, Inc. 41131Smax.romanov@nginx.com */ 51131Smax.romanov@nginx.com 61131Smax.romanov@nginx.com #include <nxt_main.h> 71131Smax.romanov@nginx.com #include <nxt_websocket.h> 81131Smax.romanov@nginx.com #include <nxt_websocket_header.h> 91131Smax.romanov@nginx.com 101131Smax.romanov@nginx.com 111131Smax.romanov@nginx.com nxt_inline uint16_t 121131Smax.romanov@nginx.com nxt_ntoh16(const uint8_t *b) 131131Smax.romanov@nginx.com { 141131Smax.romanov@nginx.com return ((uint16_t) b[0]) << 8 | ((uint16_t) b[1]); 151131Smax.romanov@nginx.com } 161131Smax.romanov@nginx.com 171131Smax.romanov@nginx.com 181131Smax.romanov@nginx.com nxt_inline void 191131Smax.romanov@nginx.com nxt_hton16(uint8_t *b, uint16_t v) 201131Smax.romanov@nginx.com { 211131Smax.romanov@nginx.com b[0] = (v >> 8); 22*1235Sigor@sysoev.ru b[1] = (v & 0xFFu); 231131Smax.romanov@nginx.com } 241131Smax.romanov@nginx.com 251131Smax.romanov@nginx.com 261131Smax.romanov@nginx.com nxt_inline uint64_t 271131Smax.romanov@nginx.com nxt_ntoh64(const uint8_t *b) 281131Smax.romanov@nginx.com { 291131Smax.romanov@nginx.com return ((uint64_t) b[0]) << 56 301131Smax.romanov@nginx.com | ((uint64_t) b[1]) << 48 311131Smax.romanov@nginx.com | ((uint64_t) b[2]) << 40 321131Smax.romanov@nginx.com | ((uint64_t) b[3]) << 32 331131Smax.romanov@nginx.com | ((uint64_t) b[4]) << 24 341131Smax.romanov@nginx.com | ((uint64_t) b[5]) << 16 351131Smax.romanov@nginx.com | ((uint64_t) b[6]) << 8 361131Smax.romanov@nginx.com | ((uint64_t) b[7]); 371131Smax.romanov@nginx.com } 381131Smax.romanov@nginx.com 391131Smax.romanov@nginx.com 401131Smax.romanov@nginx.com nxt_inline void 411131Smax.romanov@nginx.com nxt_hton64(uint8_t *b, uint64_t v) 421131Smax.romanov@nginx.com { 431131Smax.romanov@nginx.com b[0] = (v >> 56); 441131Smax.romanov@nginx.com b[1] = (v >> 48) & 0xFFu; 451131Smax.romanov@nginx.com b[2] = (v >> 40) & 0xFFu; 461131Smax.romanov@nginx.com b[3] = (v >> 32) & 0xFFu; 471131Smax.romanov@nginx.com b[4] = (v >> 24) & 0xFFu; 481131Smax.romanov@nginx.com b[5] = (v >> 16) & 0xFFu; 491131Smax.romanov@nginx.com b[6] = (v >> 8) & 0xFFu; 501131Smax.romanov@nginx.com b[7] = v & 0xFFu; 511131Smax.romanov@nginx.com } 521131Smax.romanov@nginx.com 531131Smax.romanov@nginx.com 541131Smax.romanov@nginx.com size_t 551131Smax.romanov@nginx.com nxt_websocket_frame_header_size(const void *data) 561131Smax.romanov@nginx.com { 571131Smax.romanov@nginx.com size_t res; 581131Smax.romanov@nginx.com uint64_t p; 591131Smax.romanov@nginx.com const nxt_websocket_header_t *h; 601131Smax.romanov@nginx.com 611131Smax.romanov@nginx.com h = data; 621131Smax.romanov@nginx.com p = h->payload_len; 631131Smax.romanov@nginx.com 641131Smax.romanov@nginx.com res = 2; 651131Smax.romanov@nginx.com 661131Smax.romanov@nginx.com if (p == 126) { 671131Smax.romanov@nginx.com res += 2; 681131Smax.romanov@nginx.com } else if (p == 127) { 691131Smax.romanov@nginx.com res += 8; 701131Smax.romanov@nginx.com } 711131Smax.romanov@nginx.com 721131Smax.romanov@nginx.com if (h->mask) { 731131Smax.romanov@nginx.com res += 4; 741131Smax.romanov@nginx.com } 751131Smax.romanov@nginx.com 761131Smax.romanov@nginx.com return res; 771131Smax.romanov@nginx.com } 781131Smax.romanov@nginx.com 791131Smax.romanov@nginx.com 801131Smax.romanov@nginx.com uint64_t 811131Smax.romanov@nginx.com nxt_websocket_frame_payload_len(const void *data) 821131Smax.romanov@nginx.com { 831131Smax.romanov@nginx.com uint64_t p; 841131Smax.romanov@nginx.com const nxt_websocket_header_t *h; 851131Smax.romanov@nginx.com 861131Smax.romanov@nginx.com h = data; 871131Smax.romanov@nginx.com p = h->payload_len; 881131Smax.romanov@nginx.com 891131Smax.romanov@nginx.com if (p == 126) { 901131Smax.romanov@nginx.com p = nxt_ntoh16(h->payload_len_); 911131Smax.romanov@nginx.com } else if (p == 127) { 921131Smax.romanov@nginx.com p = nxt_ntoh64(h->payload_len_); 931131Smax.romanov@nginx.com } 941131Smax.romanov@nginx.com 951131Smax.romanov@nginx.com return p; 961131Smax.romanov@nginx.com } 971131Smax.romanov@nginx.com 981131Smax.romanov@nginx.com 991131Smax.romanov@nginx.com void * 1001131Smax.romanov@nginx.com nxt_websocket_frame_init(void *data, uint64_t payload_len) 1011131Smax.romanov@nginx.com { 1021131Smax.romanov@nginx.com uint8_t *p; 1031131Smax.romanov@nginx.com nxt_websocket_header_t *h; 1041131Smax.romanov@nginx.com 1051131Smax.romanov@nginx.com h = data; 1061131Smax.romanov@nginx.com p = data; 1071131Smax.romanov@nginx.com 1081131Smax.romanov@nginx.com if (payload_len < 126) { 1091131Smax.romanov@nginx.com h->payload_len = payload_len; 1101131Smax.romanov@nginx.com return p + 2; 1111131Smax.romanov@nginx.com } 1121131Smax.romanov@nginx.com 1131131Smax.romanov@nginx.com if (payload_len < 65536) { 1141131Smax.romanov@nginx.com h->payload_len = 126; 1151131Smax.romanov@nginx.com nxt_hton16(h->payload_len_, payload_len); 1161131Smax.romanov@nginx.com return p + 4; 1171131Smax.romanov@nginx.com } 1181131Smax.romanov@nginx.com 1191131Smax.romanov@nginx.com h->payload_len = 127; 1201131Smax.romanov@nginx.com nxt_hton64(h->payload_len_, payload_len); 1211131Smax.romanov@nginx.com return p + 10; 1221131Smax.romanov@nginx.com } 123