Spaces:
Paused
Paused
xukc
commited on
Commit
·
83607bc
1
Parent(s):
a4d0c68
[feat]proxy framework
Browse files- .vscode/c_cpp_properties.json +19 -0
- .vscode/launch.json +25 -0
- .vscode/settings.json +75 -0
- .vscode/tasks.json +26 -0
- Dockerfile +18 -0
- README.md +1 -0
- hv_utils.cpp +22 -0
- include/accumulator.h +25 -0
- include/bolt/crypt.h +54 -0
- include/bolt/datagram.h +244 -0
- include/conn_map.h +49 -0
- include/hv_utils.h +12 -0
- include/tcp_inbound.h +7 -0
- main.cpp +189 -0
- tcp_inbound.cpp +90 -0
.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 |
+
}
|