File size: 20,090 Bytes
83607bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a8ba146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83607bc
 
 
 
 
 
a8ba146
83607bc
 
 
 
 
 
 
 
a8ba146
 
 
 
 
 
 
83607bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#ifndef __DATA_GRAM__
#define __DATA_GRAM__

#define BOLT_PAYLOAD_HEAD_SIZE 21
#define BOLT_VERSION    1
#define BOLT_RESERVE    0
#define BOLT_PAYLOAD_TYPE_CMD   0
#define BOLT_PAYLOAD_TYPE_ICMP  1
#define BOLT_PAYLOAD_TYPE_TCP  6
#define BOLT_PAYLOAD_TYPE_UDP  17
#define BOLT_PAYLOAD_BIND_LENGTH 73

#define ICMP_REQUEST_TOKEN 0x9f8e7d6c
#define ICMP_RESPONSE_TOKEN 0x4d3c2b1a

enum BOLT_CHANNEL_CMD {
    BOLT_CHANNEL_CMD_BIND_REQUEST    = 1,   //通道绑定请求
    BOLT_CHANNEL_CMD_BIND_RESPONSE   = 2,   //通道绑定回应
    BOLT_CHANNEL_CMD_UNBIND_REQUEST  = 3,   //通道释放
    BOLT_CHANNEL_CMD_INVALID_RESPONSE  = 4,   //通道过期
    BOLT_CHANNEL_CMD_TCP_HANDSHAKE_REQUEST = 0x20,  //TCP握手请求
    BOLT_CHANNEL_CMD_TCP_HANDSHAKE_RESPONSE = 0x21, //TCP握手响应
};

enum BOLT_BIND_RESPONSE_CODE {
    BOLT_BIND_RESPONSE_CODE_FAIL = -2, //本地错误,网络连接问题
    BOLT_BIND_RESPONSE_CODE_UNKONWN = -1, //未知错误
    BOLT_BIND_RESPONSE_CODE_NULL = 0, //正常流程,bolt内部状态码,并不回调到外层

    BOLT_BIND_RESPONSE_CODE_SUCESS = 1, //通道绑定成功
    BOLT_BIND_RESPONSE_CODE_ST_INVALID = 2, //token过期或者错误
    BOLT_BIND_RESPONSE_CODE_RECYCLE = 3, //数据通道被回收
    BOLT_BIND_RESPONSE_CODE_SERVER_INNER_FAIL = 0x1000, //服务器内部错误

    BOLT_CHANNEL_CODE_ST_INVALID = 4,//传输时token过期
};

enum BOLT_UNBIND_RESPONSE_CODE {
    BOLT_UNBIND_RESPONSE_CODE_FAIL = -2, //本地错误,网络连接问题
    BOLT_UNBIND_RESPONSE_CODE_UNKONWN = -1, //未知错误

    BOLT_UNBIND_RESPONSE_CODE_SUCESS = 1, //通道解除绑定成功
    BOLT_UNBIND_RESPONSE_CODE_ALREADY_NOBIND = 2, //通道没有绑定
};

enum BOLT_TCP_HANDSHAKE_RESULT {
    BOLT_TCP_HANDSHAKE_SUCESS        = 0x22, //握手成功
    BOLT_TCP_HANDSHAKE_FAIL_AUTH     = 0x23, //鉴权失败
    BOLT_TCP_HANDSHAKE_FAIL_FORMAT   = 0x24, //包格式错误
    BOLT_TCP_HANDSHAKE_FAIL_TIMEOUT  = 0x25, //连接目标服务器超时
    BOLT_TCP_HANDSHAKE_FAIL_INTERNAL = 0x26, //内部错误
};


struct Bolt_Payload {
    char head[BOLT_PAYLOAD_HEAD_SIZE];
    char data[0];
};

//为了保证内存布局一至,用宏在payload上模拟成员变量
#define GET_BOLT_VERSION(p)		    (*((uint8_t*)((p)->head)) & 0x0F)
#define GET_BOLT_RESERVE(p)		    (*((uint8_t*)((p)->head)) >> 4)
#define GET_BOLT_HEADER_LENGTH(p)	(*((uint8_t*)((p)->head + 1)))
#define GET_BOLT_TOTAL_LENGTH(p)	(*((uint16_t*)((p)->head + 2)))
#define GET_BOLT_PAYLOAD_TYPE(p)	(*((uint8_t*)((p)->head + 4)))
#define GET_BOLT_TARGET_IP(p)	    (*((uint32_t*)((p)->head + 5)))  //网络序
#define GET_BOLT_TARGET_PORT(p)     (*((uint16_t*)((p)->head + 9)))  //网络序
#define GET_BOLT_USER_IP(p)         (*((uint32_t*)((p)->head + 11)))  //网络序
#define GET_BOLT_USER_PORT(p)       (*((uint16_t*)((p)->head + 15)))  //网络序
#define GET_BOLT_TOKEN(p)           (*((uint32_t*)((p)->head + 17)))
#define GET_EXTEND_HEADER_LENGTH(p)	(GET_BOLT_HEADER_LENGTH(p) - BOLT_PAYLOAD_HEAD_SIZE)

#define SET_BOLT_VERSION(p, v)      { *((uint8_t*)((p)->head)) &= 0xF0; *((uint8_t*)((p)->head)) |= v; }
#define SET_BOLT_RESERVE(p, r)      { *((uint8_t*)((p)->head)) &= 0x0F; *((uint8_t*)((p)->head)) |= (r * 16); }
#define SET_BOLT_HEADER_LENGTH(p, l) *((uint8_t*)((p)->head + 1)) = l
#define SET_BOLT_TOTAL_LENGTH(p, l) *((uint16_t*)((p)->head + 2)) = l
#define SET_BOLT_PAYLOAD_TYPE(p, t) *((uint8_t*)((p)->head + 4)) = t
#define SET_BOLT_TARGET_IP(p, i)    *((uint32_t*)((p)->head + 5)) = i
#define SET_BOLT_TARGET_PORT(p, t)  *((uint16_t*)((p)->head + 9)) = t
#define SET_BOLT_USER_IP(p, i)      *((uint32_t*)((p)->head + 11)) = i
#define SET_BOLT_USER_PORT(p, t)    *((uint16_t*)((p)->head + 15)) = t
#define SET_BOLT_TOKEN(p, t)        *((uint32_t*)((p)->head + 17)) = t


#define PACK_TUNNEL_DATA(dest, dest_len, ver, res, type, t_ip, t_port, u_ip, u_port, session_id, extend, extend_len, buf, len) \
    char dest[BOLT_PAYLOAD_HEAD_SIZE + len + extend_len];                                                                   \
    Bolt_Payload * header = (Bolt_Payload*)dest;                                                                            \
    SET_BOLT_VERSION(header, ver);                                                                                          \
    SET_BOLT_RESERVE(header, res);                                                                                          \
	SET_BOLT_PAYLOAD_TYPE(header, type);                                                                                    \
	SET_BOLT_TARGET_IP(header, t_ip);                                                                                       \
	SET_BOLT_TARGET_PORT(header, t_port);                                                                                   \
	SET_BOLT_USER_IP(header, u_ip);                                                                                         \
	SET_BOLT_USER_PORT(header, u_port);                                                                                     \
	SET_BOLT_TOKEN(header, session_id);                                                                                     \
	int dest_len = len + BOLT_PAYLOAD_HEAD_SIZE;                                                                            \
	if((extend_len) > 0) {                                                                                                  \
        memcpy(dest + BOLT_PAYLOAD_HEAD_SIZE, (extend), (extend_len));                                                      \
		memcpy(dest + BOLT_PAYLOAD_HEAD_SIZE + (extend_len), (buf), (len));                                                 \
		dest_len += (extend_len);                                                                                           \
		SET_BOLT_HEADER_LENGTH(header, BOLT_PAYLOAD_HEAD_SIZE + (extend_len));                                              \
        SET_BOLT_TOTAL_LENGTH(header, BOLT_PAYLOAD_HEAD_SIZE + (len) + (extend_len));                                       \
	} else {                                                                                                                \
        memcpy(dest + BOLT_PAYLOAD_HEAD_SIZE , (buf), (len));                                                               \
		SET_BOLT_HEADER_LENGTH(header, BOLT_PAYLOAD_HEAD_SIZE);                                                             \
        SET_BOLT_TOTAL_LENGTH(header, BOLT_PAYLOAD_HEAD_SIZE + (len) + (extend_len));                                       \
    }                                                                                                                       \
  

#define UNPACK_TUNNEL_DATA(dest, dest_len, ver, res, type, t_ip, t_port, u_ip, u_port, session_id, extend, extend_len, buf, len) \
	Bolt_Payload * header = (Bolt_Payload*)buf;                                                                             \
	uint8_t ver = GET_BOLT_VERSION(header);                                                                                 \
	uint8_t res = GET_BOLT_RESERVE(header);                                                                                 \
    uint8_t type = GET_BOLT_PAYLOAD_TYPE(header);                                                                           \
	uint32_t t_ip = GET_BOLT_TARGET_IP(header);                                                                             \
    uint16_t t_port = GET_BOLT_TARGET_PORT(header);                                                                         \
    uint32_t u_ip = GET_BOLT_USER_IP(header);                                                                               \
    uint16_t u_port = GET_BOLT_USER_PORT(header);                                                                           \
    uint32_t session_id = GET_BOLT_TOKEN(header);                                                                           \
    uint16_t extend_len = GET_EXTEND_HEADER_LENGTH(header);                                                                 \
	char* dest = (char*)buf + BOLT_PAYLOAD_HEAD_SIZE;                                                                       \
	int dest_len = len - BOLT_PAYLOAD_HEAD_SIZE;                                                                            \
    char extend[extend_len + 1];                                                                                            \
    memset(extend, 0, extend_len + 1);                                                                                      \
    if(extend_len > 0 && extend_len < (len - BOLT_PAYLOAD_HEAD_SIZE - 1)) {                                                 \
        memcpy(extend, (char*)buf +  BOLT_PAYLOAD_HEAD_SIZE, extend_len);                                                   \
        dest += extend_len;                                                                                                 \
        dest_len -= extend_len;                                                                                             \
     }                                                                                                                      \

#define PACK_BIND_DATA(res, res_len, request_id, signal_id, session_id, data_st)                                            \
    char res[73] = {0};                                                                                                     \
    int res_len = 73;                                                                                                       \
    res[0] = BOLT_CHANNEL_CMD_BIND_REQUEST;                                                                                 \
    memcpy(res + 1, &request_id, 4);                                                                                        \
    memcpy(res + 5, signal_id, 32);                                                                                         \
    memcpy(res + 37, &session_id, 4);                                                                                       \
    memcpy(res + 41, data_st, 32);                                                                                          \

#define UNPACK_BIND_DATA(command, request_id, signal_id, session_id, data_st, data, data_len)                               \
    uint8_t command = *(data);                                                                                              \
    uint32_t request_id = 0;                                                                                                \
    char signal_id[32] = {0};                                                                                               \
    uint32_t session_id = 0;                                                                                                \
    char data_st[32] = {0};                                                                                                 \
    memcpy(&request_id, (char*)data + 1, 4);                                                                                \
    memcpy(&signal_id, (char*)data + 5, 32);                                                                                \
    memcpy(&session_id, (char*)data + 37, 4);                                                                               \
    memcpy(&data_st, (char*)data + 41, 32);                                                                                 \

#define PACK_BIND_RESPONSE_DATA(res, res_len, command, request_id, session_id, response_result)                             \
    char res[13] = {0};                                                                                                     \
    int res_len = 13;                                                                                                       \
    res[0] = command;                                                                                                       \
    memcpy(res + 1, &request_id, 4);                                                                                        \
    memcpy(res + 5, &session_id, 4);                                                                                        \
    memcpy(res + 9, &response_result, 4);                                                                                   \

#define UNPACK_BIND_RESPONSE_DATA(command, request_id, session_id, response_result, bind_resp, bind_resp_len)               \
    uint8_t command = *(bind_resp);                                                                                         \
    uint32_t request_id = 0;                                                                                                \
    uint32_t session_id = 0;                                                                                                \
    uint32_t response_result = 0;                                                                                           \
    memcpy(&request_id, (char*)bind_resp + 1, 4);                                                                           \
    memcpy(&session_id, (char*)bind_resp + 5, 4);                                                                           \
    memcpy(&response_result, (char*)bind_resp + 9, 4);

#define PACK_UNBIND_DATA(res, res_len, session_id, code)                                                                    \
    char res[9] = {0};                                                                                                      \
    int res_len = 9;                                                                                                        \
    res[0] = BOLT_CHANNEL_CMD_UNBIND_REQUEST;                                                                               \
    memcpy(res + 1, &session_id, 4);                                                                                        \
    memcpy(res + 5, &code, 4);                                                                                              \

#define UNPACK_UNBIND_DATA(command, session_id, code, data, data_len)                                                       \
    uint8_t command = *(data);                                                                                              \
    uint32_t session_id = 0;                                                                                                \
    uint32_t code = 0;                                                                                                      \
    memcpy(&session_id, (char*)data + 1, 4);                                                                                \
    memcpy(&code, (char*)data + 5, 4);                                                                                      \

#define PACK_ICMP_REQUEST_DATA(res, res_len, type, code, id, seqno, data, data_len)                                         \
    int res_len = 6 + data_len;                                                                                             \
    char res[res_len];                                                                                                      \
    res[0] = type;                                                                                                          \
    res[1] = code;                                                                                                          \
    memcpy(res + 2, &id, 2);                                                                                                \
    memcpy(res + 4, &seqno, 2);                                                                                             \
    memcpy(res + 6, data, data_len);                                                                                        \

#define UNPACK_ICMP_RESPONSE_DATA(iphdr, type, code, id, seqno, data, data_len, resp, resp_len)                             \
    u8_t iphdr[20] = {0};                                                                                                   \
    memcpy(iphdr, resp, 20);                                                                                                \
    uint8_t type = (*((uint8_t*)(resp + 20)));                                                                              \
    uint8_t code = (*((uint8_t*)(resp + 21)));                                                                              \
    uint16_t id = (*((uint16_t*)(resp + 22)));                                                                              \
    uint16_t seqno = (*((uint16_t*)(resp + 24)));                                                                           \
    int data_len = resp_len - 20 - 6;                                                                                       \
    char *data = (char *)resp + (20 + 6);     
    
    
#define BOLT_SERVER_INFO                                                                                                    \
struct sockaddr_in bolt_server_addr;                                                                                        \
char* signal_id;                                                                                                            \
int request_id;                                                                                                             \
int session_id;                                                                                                             \
int connect_id;                                                                                                             \
char* data_st;                                                                                                              \
bool encrypt;                                                                                                               \

#define BOLT_SERVER_EXTEND                                                                                                  \
bolt_state state;                                                                                                           \
CRYPT_TYPE ept_type;                                                                                                        \
char ept_key;                                                                                                               \

//#pragma pack(push)
//#pragma pack(1)
//	struct _bolt_header {
//		uint8_t ver_; //包含version+reserve
//		uint8_t hdr_len_; //头部长度
//		uint16_t total_len_; //数据总大小
//		uint8_t  type_;
//		uint32_t t_ip; //目标IP 网络序
//		uint16_t t_port_; //目标端口 网络序
//		uint32_t u_ip_;//用户内外IP;
//		uint16_t u_port_; //用户内外端口
//		uint32_t  token_;
//	}BOLTHEADER;
//
// 通道绑定
// struct _bolt_channel_bind_rqeust{
// BOLTHEADER hdr_;
// uint8_t cmd_;   //BOLT_CHANNEL_CMD_BIND_REQUEST
// uint32_t request_id_ ;//
// uint32_t data_session_id_; //通道会话ID(由信令服务分配)
// char data_st_[64];   //通道验证token(由信令服务分配,短有效期,单次使用)
// }
//
// 绑定响应
// struct _bolt_channel_bind_response{
// BOLTHEADER hdr_;
// uint8_t cmd_;  //BOLT_CHANNEL_CMD_BIND_RESPONSE
// uint32_t request_id_;
// uint32_t data_session_id_; //通道会话ID(由信令服务分配)
// uint32_t response_result_; //响应码:
// }
//
// 通道释放
// struct _bolt_channel_unbind{
// BOLTHEADER hdr_;
// uint8_t cmd_;  //BOLT_CHANNEL_CMD_BIND_RESPONSE
// uint32_t data_session_id_; //通道会话ID(由信令服务分配)
// uint32_t code_; //响应码:指示释放的原因;
// }
//
//
// //bolt tcp 握手请求
// struct _bolt_tcp_handshake_request{
// BOLTHEADER hdr_;
// uint8_t cmd; //BOLT_CHANNEL_CMD_TCP_HANDSHAKE_REQUEST
// }
// //bolt tcp 握手回应(连接目标结果之后)
// stuct _bolt_tcp_handshake_response{
// BOLTHEADER hdr_;
// uint8_t cmd; //BOLT_CHANNEL_CMD_TCP_HANDSHAKE_RESPONSE
// uint8_t result; //BOLT_TCP_HANDSHAKE_SUCESS
// }
//#pragma pack(pop)

#endif //end of __DATA_GRAM__