xukc commited on
Commit
83607bc
·
1 Parent(s): a4d0c68

[feat]proxy framework

Browse files
.vscode/c_cpp_properties.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "configurations": [
3
+ {
4
+ "name": "Mac",
5
+ "includePath": [
6
+ "${workspaceFolder}/**"
7
+ ],
8
+ "defines": [],
9
+ "macFrameworkPath": [
10
+ "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
11
+ ],
12
+ "compilerPath": "/usr/bin/clang",
13
+ "cStandard": "c17",
14
+ "cppStandard": "c++17",
15
+ "intelliSenseMode": "macos-clang-arm64"
16
+ }
17
+ ],
18
+ "version": 4
19
+ }
.vscode/launch.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Debug",
6
+ "type": "cppdbg",
7
+ "request": "launch",
8
+ "program": "${workspaceFolder}/test",
9
+ "args": [],
10
+ "stopAtEntry": false,
11
+ "cwd": "${workspaceFolder}",
12
+ "environment": [],
13
+ "externalConsole": false,
14
+ "MIMode": "lldb",
15
+ "preLaunchTask": "build",
16
+ "setupCommands": [
17
+ {
18
+ "description": "Enable pretty-printing for lldb",
19
+ "text": "enable",
20
+ "ignoreFailures": true
21
+ }
22
+ ]
23
+ }
24
+ ]
25
+ }
.vscode/settings.json ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "files.associations": {
3
+ "*.cc": "cpp",
4
+ "__bit_reference": "cpp",
5
+ "__bits": "cpp",
6
+ "__config": "cpp",
7
+ "__debug": "cpp",
8
+ "__errc": "cpp",
9
+ "__hash_table": "cpp",
10
+ "__locale": "cpp",
11
+ "__mutex_base": "cpp",
12
+ "__node_handle": "cpp",
13
+ "__nullptr": "cpp",
14
+ "__split_buffer": "cpp",
15
+ "__string": "cpp",
16
+ "__threading_support": "cpp",
17
+ "__tree": "cpp",
18
+ "__tuple": "cpp",
19
+ "array": "cpp",
20
+ "atomic": "cpp",
21
+ "bitset": "cpp",
22
+ "cctype": "cpp",
23
+ "chrono": "cpp",
24
+ "clocale": "cpp",
25
+ "cmath": "cpp",
26
+ "compare": "cpp",
27
+ "complex": "cpp",
28
+ "concepts": "cpp",
29
+ "cstdarg": "cpp",
30
+ "cstddef": "cpp",
31
+ "cstdint": "cpp",
32
+ "cstdio": "cpp",
33
+ "cstdlib": "cpp",
34
+ "cstring": "cpp",
35
+ "ctime": "cpp",
36
+ "cwchar": "cpp",
37
+ "cwctype": "cpp",
38
+ "deque": "cpp",
39
+ "exception": "cpp",
40
+ "forward_list": "cpp",
41
+ "initializer_list": "cpp",
42
+ "ios": "cpp",
43
+ "iosfwd": "cpp",
44
+ "iostream": "cpp",
45
+ "istream": "cpp",
46
+ "limits": "cpp",
47
+ "list": "cpp",
48
+ "locale": "cpp",
49
+ "map": "cpp",
50
+ "memory": "cpp",
51
+ "mutex": "cpp",
52
+ "new": "cpp",
53
+ "numeric": "cpp",
54
+ "optional": "cpp",
55
+ "ostream": "cpp",
56
+ "queue": "cpp",
57
+ "ratio": "cpp",
58
+ "sstream": "cpp",
59
+ "stdexcept": "cpp",
60
+ "streambuf": "cpp",
61
+ "string": "cpp",
62
+ "string_view": "cpp",
63
+ "system_error": "cpp",
64
+ "tuple": "cpp",
65
+ "type_traits": "cpp",
66
+ "typeinfo": "cpp",
67
+ "unordered_map": "cpp",
68
+ "valarray": "cpp",
69
+ "variant": "cpp",
70
+ "vector": "cpp",
71
+ "algorithm": "cpp",
72
+ "shared_mutex": "cpp",
73
+ "__memory": "cpp"
74
+ }
75
+ }
.vscode/tasks.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "2.0.0",
3
+ "tasks": [
4
+ {
5
+ "label": "build",
6
+ "type": "shell",
7
+ "command": "g++",
8
+ "args": [
9
+ "-std=c++14",
10
+ "-g",
11
+ "-o",
12
+ "test",
13
+ "-I",
14
+ "include",
15
+ "hv_utils.cpp",
16
+ "tcp_inbound.cpp",
17
+ "main.cpp",
18
+ "-lhv"
19
+ ],
20
+ "group": {
21
+ "kind": "build",
22
+ "isDefault": true
23
+ }
24
+ }
25
+ ]
26
+ }
Dockerfile ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Ubuntu runtime as a parent image
2
+ FROM ubuntu:latest
3
+
4
+ # Set the working directory to /app
5
+ WORKDIR /app
6
+
7
+ # Copy the source code into the container
8
+ COPY . .
9
+
10
+ # Install necessary dependencies
11
+ RUN apt-get update && apt-get install -y g++ libhv-dev
12
+
13
+ # Compile the C++ program
14
+ RUN g++ -std=c++14 -g -o proxyServer hv_utils.cpp tcp_inbound.cpp main.cpp -I include -lhv
15
+
16
+ EXPOSE 8080
17
+ # Run my_program when the container launches
18
+ CMD ["./proxyServer"]
README.md CHANGED
@@ -5,6 +5,7 @@ colorFrom: red
5
  colorTo: red
6
  sdk: docker
7
  pinned: false
 
8
  ---
9
 
10
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
5
  colorTo: red
6
  sdk: docker
7
  pinned: false
8
+ app_port: 8080
9
  ---
10
 
11
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
hv_utils.cpp ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include "include/hv_utils.h"
2
+
3
+ int thread_num = 4;
4
+ hloop_t** worker_loops = NULL;
5
+
6
+ void init_loop(int _thread_num, hthread_routine worker_thread) {
7
+ thread_num = _thread_num;
8
+
9
+ worker_loops = (hloop_t**)malloc(sizeof(hloop_t*) * thread_num);
10
+ for (int i = 0; i < thread_num; ++i) {
11
+ worker_loops[i] = hloop_new(HLOOP_FLAG_AUTO_FREE);
12
+ hthread_create(worker_thread, worker_loops[i]);
13
+ }
14
+ }
15
+
16
+ hloop_t* get_next_loop() {
17
+ static int s_cur_index = 0;
18
+ if (s_cur_index == thread_num) {
19
+ s_cur_index = 0;
20
+ }
21
+ return worker_loops[s_cur_index++];
22
+ }
include/accumulator.h ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+
4
+ class Accumulator {
5
+ public:
6
+ void addData(const char* data, size_t size) {
7
+ // 将新的数据块追加到累加器
8
+ dataBlocks.insert(dataBlocks.end(), data, data + size);
9
+ }
10
+
11
+ size_t getDataSize() const {
12
+ return dataBlocks.size();
13
+ }
14
+
15
+ const char* getData() const {
16
+ return dataBlocks.data();
17
+ }
18
+
19
+ void clear() {
20
+ dataBlocks.clear();
21
+ }
22
+
23
+ private:
24
+ std::vector<char> dataBlocks;
25
+ };
include/bolt/crypt.h ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // Created by dvc890 on 8/23/21.
3
+ //
4
+
5
+ #ifndef PING_ENGINE_ANDROID_BOLT_CRYPT_H
6
+ #define PING_ENGINE_ANDROID_BOLT_CRYPT_H
7
+
8
+ enum CRYPT_TYPE {
9
+ NONE = 0,
10
+ XOR = '1'
11
+ };
12
+
13
+ namespace xor_ {
14
+ static void crypt(char* data, int data_len, char key){
15
+ for (int i = 0; i < data_len; i++){
16
+ data[i] = data[i] ^ key;
17
+ }
18
+ }
19
+
20
+ static void crypt2(const char* indata, int data_len, char key, char* outdata) {
21
+ for (int i = 0; i < data_len; i++){
22
+ outdata[i] = indata[i] ^ key;
23
+ }
24
+ }
25
+ }
26
+
27
+
28
+ #define GENERATE_ENCRYPT_EXTEN(extend, extend_len, encrypt) \
29
+ char extend[6] = {0}; \
30
+ int extend_len = 0; \
31
+ if(encrypt) { \
32
+ extend_len = sprintf(extend, "ept=1"); \
33
+ } \
34
+
35
+ #define EXTRACTION_DECRYPT_KEY(ept_type, ept_key, extend, extend_len) \
36
+ CRYPT_TYPE ept_type = NONE; \
37
+ char ept_key; \
38
+ if(extend_len > 0) { \
39
+ if(char* type_ptr = strstr(extend, "ept_type")) { \
40
+ ept_type = (CRYPT_TYPE)(type_ptr[9]); \
41
+ } \
42
+ switch (ept_type) { \
43
+ case XOR: { \
44
+ if(char* key_ptr = strstr(extend, "ept_key")) { \
45
+ ept_key = key_ptr[8]; \
46
+ } \
47
+ break; \
48
+ } \
49
+ default: \
50
+ break; \
51
+ } \
52
+ } \
53
+
54
+ #endif //PING_ENGINE_ANDROID_BOLT_CRYPT_H
include/bolt/datagram.h ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #ifndef __DATA_GRAM__
2
+ #define __DATA_GRAM__
3
+
4
+ #define BOLT_PAYLOAD_HEAD_SIZE 21
5
+ #define BOLT_VERSION 1
6
+ #define BOLT_RESERVE 0
7
+ #define BOLT_PAYLOAD_TYPE_CMD 0
8
+ #define BOLT_PAYLOAD_TYPE_ICMP 1
9
+ #define BOLT_PAYLOAD_TYPE_TCP 6
10
+ #define BOLT_PAYLOAD_TYPE_UDP 17
11
+ #define BOLT_PAYLOAD_BIND_LENGTH 73
12
+
13
+ #define ICMP_REQUEST_TOKEN 0x9f8e7d6c
14
+ #define ICMP_RESPONSE_TOKEN 0x4d3c2b1a
15
+
16
+ enum BOLT_CHANNEL_CMD {
17
+ BOLT_CHANNEL_CMD_BIND_REQUEST = 1, //通道绑定请求
18
+ BOLT_CHANNEL_CMD_BIND_RESPONSE = 2, //通道绑定回应
19
+ BOLT_CHANNEL_CMD_UNBIND_REQUEST = 3, //通道释放
20
+ BOLT_CHANNEL_CMD_INVALID_RESPONSE = 4, //通道过期
21
+ BOLT_CHANNEL_CMD_TCP_HANDSHAKE_REQUEST = 0x20, //TCP握手请求
22
+ BOLT_CHANNEL_CMD_TCP_HANDSHAKE_RESPONSE = 0x21, //TCP握手响应
23
+ };
24
+
25
+ enum BOLT_BIND_RESPONSE_CODE {
26
+ BOLT_BIND_RESPONSE_CODE_FAIL = -2, //本地错误,网络连接问题
27
+ BOLT_BIND_RESPONSE_CODE_UNKONWN = -1, //未知错误
28
+ BOLT_BIND_RESPONSE_CODE_NULL = 0, //正常流程,bolt内部状态码,并不回调到外层
29
+
30
+ BOLT_BIND_RESPONSE_CODE_SUCESS = 1, //通道绑定成功
31
+ BOLT_BIND_RESPONSE_CODE_ST_INVALID = 2, //token过期或者错误
32
+ BOLT_BIND_RESPONSE_CODE_RECYCLE = 3, //数据通道被回收
33
+ BOLT_BIND_RESPONSE_CODE_SERVER_INNER_FAIL = 0x1000, //服务器内部错误
34
+
35
+ BOLT_CHANNEL_CODE_ST_INVALID = 4,//传输时token过期
36
+ };
37
+
38
+ enum BOLT_UNBIND_RESPONSE_CODE {
39
+ BOLT_UNBIND_RESPONSE_CODE_FAIL = -2, //本地错误,网络连接问题
40
+ BOLT_UNBIND_RESPONSE_CODE_UNKONWN = -1, //未知错误
41
+
42
+ BOLT_UNBIND_RESPONSE_CODE_SUCESS = 1, //通道解除绑定成功
43
+ BOLT_UNBIND_RESPONSE_CODE_ALREADY_NOBIND = 2, //通道没有绑定
44
+ };
45
+
46
+ enum BOLT_TCP_HANDSHAKE_RESULT {
47
+ BOLT_TCP_HANDSHAKE_SUCESS = 0x22, //握手成功
48
+ BOLT_TCP_HANDSHAKE_FAIL_AUTH = 0x23, //鉴权失败
49
+ BOLT_TCP_HANDSHAKE_FAIL_FORMAT = 0x24, //包格式错误
50
+ BOLT_TCP_HANDSHAKE_FAIL_TIMEOUT = 0x25, //连接目标服务器超时
51
+ BOLT_TCP_HANDSHAKE_FAIL_INTERNAL = 0x26, //内部错误
52
+ };
53
+
54
+
55
+ struct Bolt_Payload {
56
+ char head[BOLT_PAYLOAD_HEAD_SIZE];
57
+ char data[0];
58
+ };
59
+
60
+ //为了保证内存布局一至,用宏在payload上模拟成员变量
61
+ #define GET_BOLT_VERSION(p) (*((uint8_t*)((p)->head)) & 0x0F)
62
+ #define GET_BOLT_RESERVE(p) (*((uint8_t*)((p)->head)) >> 4)
63
+ #define GET_BOLT_HEADER_LENGTH(p) (*((uint8_t*)((p)->head + 1)))
64
+ #define GET_BOLT_TOTAL_LENGTH(p) (*((uint16_t*)((p)->head + 2)))
65
+ #define GET_BOLT_PAYLOAD_TYPE(p) (*((uint8_t*)((p)->head + 4)))
66
+ #define GET_BOLT_TARGET_IP(p) (*((uint32_t*)((p)->head + 5))) //网络序
67
+ #define GET_BOLT_TARGET_PORT(p) (*((uint16_t*)((p)->head + 9))) //网络序
68
+ #define GET_BOLT_USER_IP(p) (*((uint32_t*)((p)->head + 11))) //网络序
69
+ #define GET_BOLT_USER_PORT(p) (*((uint16_t*)((p)->head + 15))) //网络序
70
+ #define GET_BOLT_TOKEN(p) (*((uint32_t*)((p)->head + 17)))
71
+ #define GET_EXTEND_HEADER_LENGTH(p) (GET_BOLT_HEADER_LENGTH(p) - BOLT_PAYLOAD_HEAD_SIZE)
72
+
73
+ #define SET_BOLT_VERSION(p, v) { *((uint8_t*)((p)->head)) &= 0xF0; *((uint8_t*)((p)->head)) |= v; }
74
+ #define SET_BOLT_RESERVE(p, r) { *((uint8_t*)((p)->head)) &= 0x0F; *((uint8_t*)((p)->head)) |= (r * 16); }
75
+ #define SET_BOLT_HEADER_LENGTH(p, l) *((uint8_t*)((p)->head + 1)) = l
76
+ #define SET_BOLT_TOTAL_LENGTH(p, l) *((uint16_t*)((p)->head + 2)) = l
77
+ #define SET_BOLT_PAYLOAD_TYPE(p, t) *((uint8_t*)((p)->head + 4)) = t
78
+ #define SET_BOLT_TARGET_IP(p, i) *((uint32_t*)((p)->head + 5)) = i
79
+ #define SET_BOLT_TARGET_PORT(p, t) *((uint16_t*)((p)->head + 9)) = t
80
+ #define SET_BOLT_USER_IP(p, i) *((uint32_t*)((p)->head + 11)) = i
81
+ #define SET_BOLT_USER_PORT(p, t) *((uint16_t*)((p)->head + 15)) = t
82
+ #define SET_BOLT_TOKEN(p, t) *((uint32_t*)((p)->head + 17)) = t
83
+
84
+
85
+ #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) \
86
+ char dest[BOLT_PAYLOAD_HEAD_SIZE + len + extend_len]; \
87
+ Bolt_Payload * header = (Bolt_Payload*)dest; \
88
+ SET_BOLT_VERSION(header, ver); \
89
+ SET_BOLT_RESERVE(header, res); \
90
+ SET_BOLT_PAYLOAD_TYPE(header, type); \
91
+ SET_BOLT_TARGET_IP(header, t_ip); \
92
+ SET_BOLT_TARGET_PORT(header, t_port); \
93
+ SET_BOLT_USER_IP(header, u_ip); \
94
+ SET_BOLT_USER_PORT(header, u_port); \
95
+ SET_BOLT_TOKEN(header, session_id); \
96
+ int dest_len = len + BOLT_PAYLOAD_HEAD_SIZE; \
97
+ if((extend_len) > 0) { \
98
+ memcpy(dest + BOLT_PAYLOAD_HEAD_SIZE, (extend), (extend_len)); \
99
+ memcpy(dest + BOLT_PAYLOAD_HEAD_SIZE + (extend_len), (buf), (len)); \
100
+ dest_len += (extend_len); \
101
+ SET_BOLT_HEADER_LENGTH(header, BOLT_PAYLOAD_HEAD_SIZE + (extend_len)); \
102
+ SET_BOLT_TOTAL_LENGTH(header, BOLT_PAYLOAD_HEAD_SIZE + (len) + (extend_len)); \
103
+ } else { \
104
+ memcpy(dest + BOLT_PAYLOAD_HEAD_SIZE , (buf), (len)); \
105
+ SET_BOLT_HEADER_LENGTH(header, BOLT_PAYLOAD_HEAD_SIZE); \
106
+ SET_BOLT_TOTAL_LENGTH(header, BOLT_PAYLOAD_HEAD_SIZE + (len) + (extend_len)); \
107
+ } \
108
+
109
+
110
+ #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) \
111
+ Bolt_Payload * header = (Bolt_Payload*)buf; \
112
+ uint8_t ver = GET_BOLT_VERSION(header); \
113
+ uint8_t res = GET_BOLT_RESERVE(header); \
114
+ uint8_t type = GET_BOLT_PAYLOAD_TYPE(header); \
115
+ uint32_t t_ip = GET_BOLT_TARGET_IP(header); \
116
+ uint16_t t_port = GET_BOLT_TARGET_PORT(header); \
117
+ uint32_t u_ip = GET_BOLT_USER_IP(header); \
118
+ uint16_t u_port = GET_BOLT_USER_PORT(header); \
119
+ uint32_t session_id = GET_BOLT_TOKEN(header); \
120
+ uint16_t extend_len = GET_EXTEND_HEADER_LENGTH(header); \
121
+ char* dest = (char*)buf + BOLT_PAYLOAD_HEAD_SIZE; \
122
+ int dest_len = len - BOLT_PAYLOAD_HEAD_SIZE; \
123
+ char extend[extend_len + 1]; \
124
+ memset(extend, 0, extend_len + 1); \
125
+ if(extend_len > 0 && extend_len < (len - BOLT_PAYLOAD_HEAD_SIZE - 1)) { \
126
+ memcpy(extend, (char*)buf + BOLT_PAYLOAD_HEAD_SIZE, extend_len); \
127
+ dest += extend_len; \
128
+ dest_len -= extend_len; \
129
+ } \
130
+
131
+ #define PACK_BIND_DATA(res, res_len, request_id, signal_id, session_id, data_st) \
132
+ char res[73] = {0}; \
133
+ int res_len = 73; \
134
+ res[0] = BOLT_CHANNEL_CMD_BIND_REQUEST; \
135
+ memcpy(res + 1, &request_id, 4); \
136
+ memcpy(res + 5, signal_id, 32); \
137
+ memcpy(res + 37, &session_id, 4); \
138
+ memcpy(res + 41, data_st, 32); \
139
+
140
+ #define UNPACK_BIND_DATA(command, request_id, session_id, response_result, bind_resp, bind_resp_len) \
141
+ uint8_t command = *(bind_resp); \
142
+ uint32_t request_id = 0; \
143
+ uint32_t session_id = 0; \
144
+ uint32_t response_result = 0; \
145
+ memcpy(&request_id, (char*)bind_resp + 1, 4); \
146
+ memcpy(&session_id, (char*)bind_resp + 5, 4); \
147
+ memcpy(&response_result, (char*)bind_resp + 9, 4); \
148
+
149
+ #define PACK_UNBIND_DATA(res, res_len, session_id, code) \
150
+ char res[9] = {0}; \
151
+ int res_len = 9; \
152
+ res[0] = BOLT_CHANNEL_CMD_UNBIND_REQUEST; \
153
+ memcpy(res + 1, &session_id, 4); \
154
+ memcpy(res + 5, &code, 4); \
155
+
156
+ #define PACK_ICMP_REQUEST_DATA(res, res_len, type, code, id, seqno, data, data_len) \
157
+ int res_len = 6 + data_len; \
158
+ char res[res_len]; \
159
+ res[0] = type; \
160
+ res[1] = code; \
161
+ memcpy(res + 2, &id, 2); \
162
+ memcpy(res + 4, &seqno, 2); \
163
+ memcpy(res + 6, data, data_len); \
164
+
165
+ #define UNPACK_ICMP_RESPONSE_DATA(iphdr, type, code, id, seqno, data, data_len, resp, resp_len) \
166
+ u8_t iphdr[20] = {0}; \
167
+ memcpy(iphdr, resp, 20); \
168
+ uint8_t type = (*((uint8_t*)(resp + 20))); \
169
+ uint8_t code = (*((uint8_t*)(resp + 21))); \
170
+ uint16_t id = (*((uint16_t*)(resp + 22))); \
171
+ uint16_t seqno = (*((uint16_t*)(resp + 24))); \
172
+ int data_len = resp_len - 20 - 6; \
173
+ char *data = (char *)resp + (20 + 6);
174
+
175
+
176
+ #define BOLT_SERVER_INFO \
177
+ struct sockaddr_in bolt_server_addr; \
178
+ char* signal_id; \
179
+ int request_id; \
180
+ int session_id; \
181
+ int connect_id; \
182
+ char* data_st; \
183
+ bool encrypt; \
184
+
185
+ #define BOLT_SERVER_EXTEND \
186
+ bolt_state state; \
187
+ CRYPT_TYPE ept_type; \
188
+ char ept_key; \
189
+
190
+ //#pragma pack(push)
191
+ //#pragma pack(1)
192
+ // struct _bolt_header {
193
+ // uint8_t ver_; //包含version+reserve
194
+ // uint8_t hdr_len_; //头部长度
195
+ // uint16_t total_len_; //数据总大小
196
+ // uint8_t type_;
197
+ // uint32_t t_ip; //目标IP 网络序
198
+ // uint16_t t_port_; //目标端口 网络序
199
+ // uint32_t u_ip_;//用户内外IP;
200
+ // uint16_t u_port_; //用户内外端口
201
+ // uint32_t token_;
202
+ // }BOLTHEADER;
203
+ //
204
+ // 通道绑定
205
+ // struct _bolt_channel_bind_rqeust{
206
+ // BOLTHEADER hdr_;
207
+ // uint8_t cmd_; //BOLT_CHANNEL_CMD_BIND_REQUEST
208
+ // uint32_t request_id_ ;//
209
+ // uint32_t data_session_id_; //通道会话ID(由信令服务分配)
210
+ // char data_st_[64]; //通道验证token(由信令服务分配,短有效期,单次使用)
211
+ // }
212
+ //
213
+ // 绑定响应
214
+ // struct _bolt_channel_bind_response{
215
+ // BOLTHEADER hdr_;
216
+ // uint8_t cmd_; //BOLT_CHANNEL_CMD_BIND_RESPONSE
217
+ // uint32_t request_id_;
218
+ // uint32_t data_session_id_; //通道会话ID(由信令服务分配)
219
+ // uint32_t response_result_; //响应码:
220
+ // }
221
+ //
222
+ // 通道释放
223
+ // struct _bolt_channel_unbind{
224
+ // BOLTHEADER hdr_;
225
+ // uint8_t cmd_; //BOLT_CHANNEL_CMD_BIND_RESPONSE
226
+ // uint32_t data_session_id_; //通道会话ID(由信令服务分配)
227
+ // uint32_t code_; //响应码:指示释放的原因;
228
+ // }
229
+ //
230
+ //
231
+ // //bolt tcp 握手请求
232
+ // struct _bolt_tcp_handshake_request{
233
+ // BOLTHEADER hdr_;
234
+ // uint8_t cmd; //BOLT_CHANNEL_CMD_TCP_HANDSHAKE_REQUEST
235
+ // }
236
+ // //bolt tcp 握手回应(连接目标结果之后)
237
+ // stuct _bolt_tcp_handshake_response{
238
+ // BOLTHEADER hdr_;
239
+ // uint8_t cmd; //BOLT_CHANNEL_CMD_TCP_HANDSHAKE_RESPONSE
240
+ // uint8_t result; //BOLT_TCP_HANDSHAKE_SUCESS
241
+ // }
242
+ //#pragma pack(pop)
243
+
244
+ #endif //end of __DATA_GRAM__
include/conn_map.h ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #ifndef PROXYSERVER_CONN_MAP_H
2
+ #define PROXYSERVER_CONN_MAP_H
3
+
4
+ #include <iostream>
5
+ #include <map>
6
+ #include <shared_mutex>
7
+
8
+ template <typename Key, typename Value>
9
+ class ConnMap {
10
+ public:
11
+ static ConnMap& getInstance() {
12
+ static ConnMap instance; // 在首次使用时创建
13
+ return instance;
14
+ }
15
+
16
+ ConnMap(ConnMap const&) = delete;
17
+ void operator=(ConnMap const&) = delete;
18
+
19
+ void add(const Key& key, const Value& value) {
20
+ std::unique_lock<std::shared_timed_mutex> lock(mutex_);
21
+ map_[key] = value;
22
+ }
23
+
24
+ Value* get(const Key& key) const {
25
+ std::shared_lock<std::shared_timed_mutex> lock(mutex_);
26
+ auto it = map_.find(key);
27
+ if (it != map_.end()) {
28
+ return (Value*)(&(it->second));
29
+ }
30
+ return nullptr;
31
+ }
32
+
33
+ void remove(const Key& key) {
34
+ std::unique_lock<std::shared_timed_mutex> lock(mutex_);
35
+ map_.erase(key);
36
+ }
37
+
38
+ void clear() {
39
+ std::unique_lock<std::shared_timed_mutex> lock(mutex_);
40
+ map_.clear();
41
+ }
42
+
43
+ private:
44
+ ConnMap() = default;
45
+ mutable std::shared_timed_mutex mutex_;
46
+ std::map<Key, Value> map_;
47
+ };
48
+
49
+ #endif //PROXYSERVER_CONN_MAP_H
include/hv_utils.h ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #ifndef PROXYSERVER_HV_UTILS_H
2
+ #define PROXYSERVER_HV_UTILS_H
3
+
4
+ #include "hv/hloop.h"
5
+ #include "hv/hthread.h"
6
+
7
+ void init_loop(int _thread_num, hthread_routine worker_thread);
8
+
9
+ hloop_t* get_next_loop();
10
+
11
+
12
+ #endif //PROXYSERVER_HV_UTILS_H
include/tcp_inbound.h ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ #ifndef PROXYSERVER_TCP_INBOUND_H
2
+ #define PROXYSERVER_TCP_INBOUND_H
3
+
4
+ #include "hv/hloop.h"
5
+ void tcp_on_accept(hio_t* io, hevent_t* ev);
6
+
7
+ #endif //PROXYSERVER_TCP_INBOUND_H
main.cpp ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // #include "hv/HttpServer.h"
2
+ // using namespace hv;
3
+
4
+ // int main() {
5
+ // HttpService router;
6
+ // router.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
7
+ // print("/ping");
8
+ // return resp->String("pong");
9
+ // });
10
+
11
+ // router.GET("/data", [](HttpRequest* req, HttpResponse* resp) {
12
+ // print("/data");
13
+ // static char data[] = "0123456789";
14
+ // return resp->Data(data, 10);
15
+ // });
16
+
17
+ // router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) {
18
+ // print("/paths");
19
+ // return resp->Json(router.Paths());
20
+ // });
21
+
22
+ // router.GET("/get", [](HttpRequest* req, HttpResponse* resp) {
23
+ // print("/get");
24
+ // resp->json["origin"] = req->client_addr.ip;
25
+ // resp->json["url"] = req->url;
26
+ // resp->json["args"] = req->query_params;
27
+ // resp->json["headers"] = req->headers;
28
+ // hv::Json myArray = hv::Json::array();
29
+ // myArray.push_back("apple");
30
+ // myArray.push_back("banana");
31
+ // myArray.push_back("orange");
32
+ // resp->json["fruits"] = myArray;
33
+ // resp->json["test"]["a"] = "json_serializer";
34
+ // return 200;
35
+ // });
36
+
37
+ // router.POST("/echo", [](const HttpContextPtr& ctx) {
38
+ // print(ctx->body());
39
+ // return ctx->send(ctx->body(), ctx->type());
40
+ // });
41
+
42
+ // HttpServer server(&router);
43
+ // server.setPort(8080);
44
+ // server.setThreadNum(4);
45
+ // server.run();
46
+ // return 0;
47
+ // }
48
+
49
+ // #include "hv/TcpServer.h"
50
+ // using namespace hv;
51
+
52
+ // int main() {
53
+ // int port = 1234;
54
+ // TcpServer srv;
55
+ // int listenfd = srv.createsocket(port);
56
+ // if (listenfd < 0) {
57
+ // return -1;
58
+ // }
59
+ // printf("server listen on port %d, listenfd=%d ...\n", port, listenfd);
60
+ // srv.onConnection = [](const SocketChannelPtr& channel) {
61
+ // std::string peeraddr = channel->peeraddr();
62
+ // if (channel->isConnected()) {
63
+ // printf("%s connected! connfd=%d\n", peeraddr.c_str(), channel->fd());
64
+ // } else {
65
+ // printf("%s disconnected! connfd=%d\n", peeraddr.c_str(), channel->fd());
66
+ // }
67
+ // };
68
+ // srv.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) {
69
+ // // echo
70
+ // channel->write(buf);
71
+ // };
72
+ // srv.setThreadNum(4);
73
+ // srv.start();
74
+
75
+ // // press Enter to stop
76
+ // while (getchar() != '\n');
77
+ // return 0;
78
+ // }
79
+
80
+ // #include <iostream>
81
+ // #include "hv/TcpClient.h"
82
+ // using namespace hv;
83
+
84
+ // int main() {
85
+ // int port = 1234;
86
+ // TcpClient cli;
87
+ // int connfd = cli.createsocket(port);
88
+ // if (connfd < 0) {
89
+ // return -1;
90
+ // }
91
+ // cli.onConnection = [](const SocketChannelPtr& channel) {
92
+ // std::string peeraddr = channel->peeraddr();
93
+ // if (channel->isConnected()) {
94
+ // printf("connected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd());
95
+ // } else {
96
+ // printf("disconnected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd());
97
+ // }
98
+ // };
99
+ // cli.onMessage = [](const SocketChannelPtr& channel, Buffer* buf) {
100
+ // printf("< %.*s\n", (int)buf->size(), (char*)buf->data());
101
+ // };
102
+ // cli.start();
103
+
104
+ // std::string str;
105
+ // while (std::getline(std::cin, str)) {
106
+ // if (str == "close") {
107
+ // cli.closesocket();
108
+ // } else if (str == "start") {
109
+ // cli.start();
110
+ // } else if (str == "stop") {
111
+ // cli.stop();
112
+ // break;
113
+ // } else {
114
+ // if (!cli.isConnected()) break;
115
+ // cli.send(str);
116
+ // }
117
+ // }
118
+ // return 0;
119
+ // }
120
+
121
+ /*
122
+ *
123
+ * @build make examples
124
+ * @server bin/one-acceptor-multi-workers 1234
125
+ * @client bin/nc 127.0.0.1 1234
126
+ * nc 127.0.0.1 1234
127
+ * telnet 127.0.0.1 1234
128
+ */
129
+
130
+ #include "hv/hloop.h"
131
+ #include "hv/hthread.h"
132
+ #include "include/hv_utils.h"
133
+ #include "include/tcp_inbound.h"
134
+
135
+ static const char* host = "0.0.0.0";
136
+ static int port = 8080;
137
+ static int thread_num = 4;
138
+ static hloop_t* accept_loop = NULL;
139
+
140
+ static void new_conn_event(hevent_t* ev) {
141
+ hloop_t* loop = ev->loop;
142
+ hio_t* io = (hio_t*)hevent_userdata(ev);
143
+ hio_attach(loop, io);
144
+
145
+ tcp_on_accept(io, ev);
146
+ }
147
+
148
+ static void on_accept(hio_t* io) {
149
+ hio_detach(io);
150
+
151
+ hloop_t* worker_loop = get_next_loop();
152
+ hevent_t ev;
153
+ memset(&ev, 0, sizeof(ev));
154
+ ev.loop = worker_loop;
155
+ ev.cb = new_conn_event;
156
+ ev.userdata = io;
157
+ hloop_post_event(worker_loop, &ev);
158
+ }
159
+
160
+ static HTHREAD_RETTYPE worker_thread(void* userdata) {
161
+ hloop_t* loop = (hloop_t*)userdata;
162
+ hloop_run(loop);
163
+ return 0;
164
+ }
165
+
166
+ static HTHREAD_RETTYPE accept_thread(void* userdata) {
167
+ hloop_t* loop = (hloop_t*)userdata;
168
+ hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept);
169
+ if (listenio == NULL) {
170
+ exit(1);
171
+ }
172
+ hloop_run(loop);
173
+ return 0;
174
+ }
175
+
176
+ int main(int argc, char** argv) {
177
+ // if (argc < 2) {
178
+ // printf("Usage: cmd port\n");
179
+ // return -10;
180
+ // }
181
+ // port = atoi(argv[1]);
182
+
183
+ init_loop(thread_num, worker_thread);
184
+
185
+ accept_loop = hloop_new(HLOOP_FLAG_AUTO_FREE);
186
+ accept_thread(accept_loop);
187
+
188
+ return 0;
189
+ }
tcp_inbound.cpp ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include "include/tcp_inbound.h"
2
+ #include "include/conn_map.h"
3
+ #include "include/accumulator.h"
4
+ #include "hv/hsocket.h"
5
+ #include "hv/hthread.h"
6
+ #include "hv/TcpClient.h"
7
+ #include <string>
8
+
9
+ class TcpClientShell {
10
+ public:
11
+ bool init(hio_t* _io) {
12
+ io = _io;
13
+ int connfd = cli.createsocket(hio_peeraddr(io));
14
+ if (connfd < 0) {
15
+ return -1;
16
+ }
17
+ cli.onConnection = [this](const hv::SocketChannelPtr& channel) {
18
+ std::string peeraddr = channel->peeraddr();
19
+ if (channel->isConnected()) {
20
+ printf("connected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd());
21
+ if (wait_send_buf.getDataSize() > 0)
22
+ {
23
+ cli.send(wait_send_buf.getData(), wait_send_buf.getDataSize());
24
+ }
25
+ } else {
26
+ printf("disconnected to %s! connfd=%d\n", peeraddr.c_str(), channel->fd());
27
+ hio_close(io);
28
+ }
29
+ };
30
+
31
+ cli.onMessage = [this](const hv::SocketChannelPtr& channel, hv::Buffer* buf) {
32
+ hio_write(io, buf->data(), buf->size());
33
+ printf("< %.*s\n", (int)buf->size(), (char*)buf->data());
34
+ };
35
+
36
+ cli.onWriteComplete = [this](const hv::SocketChannelPtr& channel, hv::Buffer* buf) {
37
+
38
+ };
39
+ cli.start();
40
+ }
41
+
42
+ int send(const char* data, int size) {
43
+ if (cli.isConnected())
44
+ {
45
+ return cli.send(data, size);
46
+ } else {
47
+ wait_send_buf.addData(data, size);
48
+ return size;
49
+ }
50
+ }
51
+
52
+ void close() {
53
+ cli.closesocket();
54
+ }
55
+
56
+ private:
57
+ hv::TcpClient cli;
58
+ hio_t* io;
59
+ Accumulator wait_send_buf;
60
+ };
61
+
62
+ static void tcp_on_close(hio_t* io) {
63
+ printf("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
64
+ ConnMap<hio_t*, TcpClientShell>::getInstance().remove(io);
65
+ }
66
+
67
+ static void tcp_on_recv(hio_t* io, void* buf, int readbytes) {
68
+ // echo
69
+ hio_write(io, buf, readbytes);
70
+ auto cli = ConnMap<hio_t*, TcpClientShell>::getInstance().get(io);
71
+ if(cli) {
72
+ cli->send((const char*) buf, readbytes);
73
+ }
74
+ }
75
+
76
+ void tcp_on_accept(hio_t* io, hevent_t* ev) {
77
+ hloop_t* loop = ev->loop;
78
+
79
+ char localaddrstr[SOCKADDR_STRLEN] = {0};
80
+ char peeraddrstr[SOCKADDR_STRLEN] = {0};
81
+ printf("tid=%ld connfd=%d [%s] <= [%s]\n",
82
+ (long)hv_gettid(),
83
+ (int)hio_fd(io),
84
+ SOCKADDR_STR(hio_localaddr(io), localaddrstr),
85
+ SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
86
+
87
+ hio_setcb_close(io, tcp_on_close);
88
+ hio_setcb_read(io, tcp_on_recv);
89
+ hio_read(io);
90
+ }