line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#include "inc.h" |
2
|
|
|
|
|
|
|
#include "utils.h" |
3
|
|
|
|
|
|
|
#include "iterator.h" |
4
|
|
|
|
|
|
|
#include |
5
|
|
|
|
|
|
|
#include |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
namespace panda { namespace protocol { namespace websocket { |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
union _check_endianess { unsigned x; unsigned char c; }; |
10
|
18
|
|
|
|
|
|
static const bool am_i_little = (_check_endianess{1}).c; |
11
|
|
|
|
|
|
|
|
12
|
18
|
|
|
|
|
|
string StringPairIterator::global_empty = ""; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
// case-insensitive jenkins_one_at_a_time_hash |
15
|
0
|
|
|
|
|
|
uint32_t string_hash32_ci (const char *key, size_t len) { |
16
|
|
|
|
|
|
|
uint32_t hash, i; |
17
|
0
|
0
|
|
|
|
|
for (hash = i = 0; i < len; ++i) { |
18
|
0
|
|
|
|
|
|
hash += std::tolower(key[i]); |
19
|
0
|
|
|
|
|
|
hash += (hash << 10); |
20
|
0
|
|
|
|
|
|
hash ^= (hash >> 6); |
21
|
|
|
|
|
|
|
} |
22
|
0
|
|
|
|
|
|
hash += (hash << 3); |
23
|
0
|
|
|
|
|
|
hash ^= (hash >> 11); |
24
|
0
|
|
|
|
|
|
hash += (hash << 15); |
25
|
0
|
|
|
|
|
|
return hash; |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
|
28
|
75529
|
|
|
|
|
|
static inline uint32_t rotate_shift (uint32_t x, unsigned shift) { |
29
|
75529
|
100
|
|
|
|
|
if (shift % 32 == 0) return x; |
30
|
56339
|
|
|
|
|
|
return am_i_little ? ((x >> shift) | (x << (sizeof(x)*8 - shift))) : |
31
|
56339
|
50
|
|
|
|
|
((x << shift) | (x >> (sizeof(x)*8 - shift))); |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
75529
|
|
|
|
|
|
void crypt_mask (char* str, size_t len, uint32_t mask, uint64_t bytes_received) { |
35
|
75529
|
|
|
|
|
|
mask = rotate_shift(mask, (bytes_received & 3)*8); |
36
|
75529
|
|
|
|
|
|
const uint64_t mask64 = ((uint64_t)mask << 32) | mask; |
37
|
75529
|
|
|
|
|
|
auto str64 = (uint64_t*)str; |
38
|
75529
|
|
|
|
|
|
auto end64 = str64 + (len / 8); |
39
|
|
|
|
|
|
|
|
40
|
100250
|
100
|
|
|
|
|
while (str64 != end64) *str64++ ^= mask64; |
41
|
|
|
|
|
|
|
|
42
|
75529
|
|
|
|
|
|
auto cstr = (unsigned char*)str64; |
43
|
75529
|
|
|
|
|
|
auto cmask = (const unsigned char*)&mask64; |
44
|
75529
|
|
|
|
|
|
switch (len & 7) { |
45
|
14
|
|
|
|
|
|
case 7: *cstr++ ^= *cmask++; // fallthrough |
46
|
22
|
|
|
|
|
|
case 6: *cstr++ ^= *cmask++; // fallthrough |
47
|
59
|
|
|
|
|
|
case 5: *cstr++ ^= *cmask++; // fallthrough |
48
|
110
|
|
|
|
|
|
case 4: *cstr++ ^= *cmask++; // fallthrough |
49
|
139
|
|
|
|
|
|
case 3: *cstr++ ^= *cmask++; // fallthrough |
50
|
161
|
|
|
|
|
|
case 2: *cstr++ ^= *cmask++; // fallthrough |
51
|
75314
|
|
|
|
|
|
case 1: *cstr++ ^= *cmask++; |
52
|
|
|
|
|
|
|
}; |
53
|
75529
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
252
|
50
|
|
|
|
|
static std::map close_messages = { |
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
56
|
|
|
|
|
|
|
{CloseCode::NOERR , "no error"}, |
57
|
|
|
|
|
|
|
{CloseCode::DONE , "Done"}, |
58
|
|
|
|
|
|
|
{CloseCode::AWAY , "Away"}, |
59
|
|
|
|
|
|
|
{CloseCode::PROTOCOL_ERROR , "WS Protocol Error"}, |
60
|
|
|
|
|
|
|
{CloseCode::INVALID_DATA , "WS Invalid Data"}, |
61
|
|
|
|
|
|
|
{CloseCode::UNKNOWN , "WS Unknown"}, |
62
|
|
|
|
|
|
|
{CloseCode::ABNORMALLY , "Abnormally"}, |
63
|
|
|
|
|
|
|
{CloseCode::INVALID_TEXT , "Invalid Text"}, |
64
|
|
|
|
|
|
|
{CloseCode::BAD_REQUEST , "Bad Request"}, |
65
|
|
|
|
|
|
|
{CloseCode::MAX_SIZE , "Max Size"}, |
66
|
|
|
|
|
|
|
{CloseCode::EXTENSION_NEEDED , "Extension Needed"}, |
67
|
|
|
|
|
|
|
{CloseCode::INTERNAL_ERROR , "Internal Error"}, |
68
|
|
|
|
|
|
|
{CloseCode::TLS , "TLS error"} |
69
|
234
|
|
|
|
|
|
}; |
70
|
|
|
|
|
|
|
|
71
|
0
|
|
|
|
|
|
string close_message(uint16_t code) { |
72
|
0
|
0
|
|
|
|
|
auto iter = close_messages.find(code); |
73
|
0
|
0
|
|
|
|
|
if (iter == close_messages.end()) { |
74
|
0
|
0
|
|
|
|
|
return to_string(code); |
75
|
|
|
|
|
|
|
} else { |
76
|
0
|
0
|
|
|
|
|
return iter->second; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
0
|
|
|
|
|
|
bool register_close_codes(std::initializer_list > pairs) { |
82
|
0
|
0
|
|
|
|
|
for (const auto& p : pairs) { |
83
|
0
|
0
|
|
|
|
|
close_messages.insert({p.first, p.second}); |
84
|
|
|
|
|
|
|
} |
85
|
0
|
|
|
|
|
|
return true; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
0
|
|
|
|
|
|
std::ostream& operator<< (std::ostream& s, const ccfmt& cc) { |
89
|
0
|
0
|
|
|
|
|
s << cc.code << ": " << cc.msg ? cc.msg : close_message(cc.code); |
90
|
0
|
|
|
|
|
|
return s; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
72
|
50
|
|
|
|
|
}}} |
|
|
50
|
|
|
|
|
|