1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
#include <stdio.h>
#include <string.h>
#include <endian.h>
#include "../websocksy.h"
typedef struct /*_framing_config*/ {
uint32_t offset;
int32_t fixed;
uint8_t endian;
} dynamic32_config_t;
static int64_t framing_dynamic32(uint8_t* data, size_t length, size_t last_read, ws_operation* opcode, void** framing_data, const char* config){
size_t u;
uint32_t* size_p, size = 0;
//get the current config if set
dynamic32_config_t* conncfg = (*framing_data) ? ((dynamic32_config_t*) (*framing_data)) : NULL;
//configure framing for this connection
if(data && !conncfg){
conncfg = calloc(1, sizeof(dynamic32_config_t));
if(!conncfg){
fprintf(stderr, "Failed to allocate memory\n");
return -1;
}
//parse config string
for(u = 0; config[u];){
if(!strncmp(config + u, "offset=", 7)){
conncfg->offset = strtoul(config + u + 7, NULL, 0);
}
else if(!strncmp(config + u, "static=", 7)){
conncfg->fixed = strtoul(config + u + 7, NULL, 0);
}
else if(!strncmp(config + u, "endian=", 7)){
conncfg->endian = 0;
if(!strncmp(config + u + 7, "big", 3)){
conncfg->endian = 1;
}
}
//skip to next item
for(; config[u] && config[u] != ','; u++){
}
}
//store configuration
*framing_data = conncfg;
}
//clean up configuration
else if(!data && conncfg){
free(*framing_data);
*framing_data = NULL;
}
if(length >= conncfg->offset + 4){
//read size field
size_p = (uint32_t*) (data + conncfg->offset);
size = le32toh(*size_p);
if(conncfg->endian){
size = be32toh(*size_p);
}
if(length >= conncfg->offset + 4 + conncfg->fixed + size){
return conncfg->offset + 4 + conncfg->fixed + size;
}
}
return 0;
}
static void __attribute__((constructor)) init(){
core_register_framing("dynamic32", framing_dynamic32);
}
|