| 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
|
|
|
|
|
|