1*1131Smax.romanov@nginx.com 2*1131Smax.romanov@nginx.com /* 3*1131Smax.romanov@nginx.com * Copyright (C) NGINX, Inc. 4*1131Smax.romanov@nginx.com */ 5*1131Smax.romanov@nginx.com 6*1131Smax.romanov@nginx.com #include <nxt_main.h> 7*1131Smax.romanov@nginx.com #include <nxt_websocket.h> 8*1131Smax.romanov@nginx.com #include <nxt_websocket_header.h> 9*1131Smax.romanov@nginx.com 10*1131Smax.romanov@nginx.com 11*1131Smax.romanov@nginx.com nxt_inline uint16_t 12*1131Smax.romanov@nginx.com nxt_ntoh16(const uint8_t *b) 13*1131Smax.romanov@nginx.com { 14*1131Smax.romanov@nginx.com return ((uint16_t) b[0]) << 8 | ((uint16_t) b[1]); 15*1131Smax.romanov@nginx.com } 16*1131Smax.romanov@nginx.com 17*1131Smax.romanov@nginx.com 18*1131Smax.romanov@nginx.com nxt_inline void 19*1131Smax.romanov@nginx.com nxt_hton16(uint8_t *b, uint16_t v) 20*1131Smax.romanov@nginx.com { 21*1131Smax.romanov@nginx.com b[0] = (v >> 8); 22*1131Smax.romanov@nginx.com b[1] = (v & 0xFFu); 23*1131Smax.romanov@nginx.com } 24*1131Smax.romanov@nginx.com 25*1131Smax.romanov@nginx.com 26*1131Smax.romanov@nginx.com nxt_inline uint64_t 27*1131Smax.romanov@nginx.com nxt_ntoh64(const uint8_t *b) 28*1131Smax.romanov@nginx.com { 29*1131Smax.romanov@nginx.com return ((uint64_t) b[0]) << 56 30*1131Smax.romanov@nginx.com | ((uint64_t) b[1]) << 48 31*1131Smax.romanov@nginx.com | ((uint64_t) b[2]) << 40 32*1131Smax.romanov@nginx.com | ((uint64_t) b[3]) << 32 33*1131Smax.romanov@nginx.com | ((uint64_t) b[4]) << 24 34*1131Smax.romanov@nginx.com | ((uint64_t) b[5]) << 16 35*1131Smax.romanov@nginx.com | ((uint64_t) b[6]) << 8 36*1131Smax.romanov@nginx.com | ((uint64_t) b[7]); 37*1131Smax.romanov@nginx.com } 38*1131Smax.romanov@nginx.com 39*1131Smax.romanov@nginx.com 40*1131Smax.romanov@nginx.com nxt_inline void 41*1131Smax.romanov@nginx.com nxt_hton64(uint8_t *b, uint64_t v) 42*1131Smax.romanov@nginx.com { 43*1131Smax.romanov@nginx.com b[0] = (v >> 56); 44*1131Smax.romanov@nginx.com b[1] = (v >> 48) & 0xFFu; 45*1131Smax.romanov@nginx.com b[2] = (v >> 40) & 0xFFu; 46*1131Smax.romanov@nginx.com b[3] = (v >> 32) & 0xFFu; 47*1131Smax.romanov@nginx.com b[4] = (v >> 24) & 0xFFu; 48*1131Smax.romanov@nginx.com b[5] = (v >> 16) & 0xFFu; 49*1131Smax.romanov@nginx.com b[6] = (v >> 8) & 0xFFu; 50*1131Smax.romanov@nginx.com b[7] = v & 0xFFu; 51*1131Smax.romanov@nginx.com } 52*1131Smax.romanov@nginx.com 53*1131Smax.romanov@nginx.com 54*1131Smax.romanov@nginx.com size_t 55*1131Smax.romanov@nginx.com nxt_websocket_frame_header_size(const void *data) 56*1131Smax.romanov@nginx.com { 57*1131Smax.romanov@nginx.com size_t res; 58*1131Smax.romanov@nginx.com uint64_t p; 59*1131Smax.romanov@nginx.com const nxt_websocket_header_t *h; 60*1131Smax.romanov@nginx.com 61*1131Smax.romanov@nginx.com h = data; 62*1131Smax.romanov@nginx.com p = h->payload_len; 63*1131Smax.romanov@nginx.com 64*1131Smax.romanov@nginx.com res = 2; 65*1131Smax.romanov@nginx.com 66*1131Smax.romanov@nginx.com if (p == 126) { 67*1131Smax.romanov@nginx.com res += 2; 68*1131Smax.romanov@nginx.com } else if (p == 127) { 69*1131Smax.romanov@nginx.com res += 8; 70*1131Smax.romanov@nginx.com } 71*1131Smax.romanov@nginx.com 72*1131Smax.romanov@nginx.com if (h->mask) { 73*1131Smax.romanov@nginx.com res += 4; 74*1131Smax.romanov@nginx.com } 75*1131Smax.romanov@nginx.com 76*1131Smax.romanov@nginx.com return res; 77*1131Smax.romanov@nginx.com } 78*1131Smax.romanov@nginx.com 79*1131Smax.romanov@nginx.com 80*1131Smax.romanov@nginx.com uint64_t 81*1131Smax.romanov@nginx.com nxt_websocket_frame_payload_len(const void *data) 82*1131Smax.romanov@nginx.com { 83*1131Smax.romanov@nginx.com uint64_t p; 84*1131Smax.romanov@nginx.com const nxt_websocket_header_t *h; 85*1131Smax.romanov@nginx.com 86*1131Smax.romanov@nginx.com h = data; 87*1131Smax.romanov@nginx.com p = h->payload_len; 88*1131Smax.romanov@nginx.com 89*1131Smax.romanov@nginx.com if (p == 126) { 90*1131Smax.romanov@nginx.com p = nxt_ntoh16(h->payload_len_); 91*1131Smax.romanov@nginx.com } else if (p == 127) { 92*1131Smax.romanov@nginx.com p = nxt_ntoh64(h->payload_len_); 93*1131Smax.romanov@nginx.com } 94*1131Smax.romanov@nginx.com 95*1131Smax.romanov@nginx.com return p; 96*1131Smax.romanov@nginx.com } 97*1131Smax.romanov@nginx.com 98*1131Smax.romanov@nginx.com 99*1131Smax.romanov@nginx.com void * 100*1131Smax.romanov@nginx.com nxt_websocket_frame_init(void *data, uint64_t payload_len) 101*1131Smax.romanov@nginx.com { 102*1131Smax.romanov@nginx.com uint8_t *p; 103*1131Smax.romanov@nginx.com nxt_websocket_header_t *h; 104*1131Smax.romanov@nginx.com 105*1131Smax.romanov@nginx.com h = data; 106*1131Smax.romanov@nginx.com p = data; 107*1131Smax.romanov@nginx.com 108*1131Smax.romanov@nginx.com if (payload_len < 126) { 109*1131Smax.romanov@nginx.com h->payload_len = payload_len; 110*1131Smax.romanov@nginx.com return p + 2; 111*1131Smax.romanov@nginx.com } 112*1131Smax.romanov@nginx.com 113*1131Smax.romanov@nginx.com if (payload_len < 65536) { 114*1131Smax.romanov@nginx.com h->payload_len = 126; 115*1131Smax.romanov@nginx.com nxt_hton16(h->payload_len_, payload_len); 116*1131Smax.romanov@nginx.com return p + 4; 117*1131Smax.romanov@nginx.com } 118*1131Smax.romanov@nginx.com 119*1131Smax.romanov@nginx.com h->payload_len = 127; 120*1131Smax.romanov@nginx.com nxt_hton64(h->payload_len_, payload_len); 121*1131Smax.romanov@nginx.com return p + 10; 122*1131Smax.romanov@nginx.com } 123