Spaces:
Paused
Paused
xukc
commited on
Commit
Β·
bb16f10
1
Parent(s):
1bff97b
[opt]udp
Browse files- .vscode/launch.json +1 -1
- include/tcp_client_map.h +0 -1
- include/timer_thread.h +43 -0
- include/udp_client.h +10 -0
- include/{hv_utils.h β utils.h} +1 -0
- src/main.cpp +5 -1
- src/tcp_client.cpp +1 -1
- src/udp_client.cpp +42 -1
- src/udp_inbound.cpp +1 -1
- src/{hv_utils.cpp β utils.cpp} +13 -1
.vscode/launch.json
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
"type": "cppdbg",
|
7 |
"request": "launch",
|
8 |
"program": "${workspaceFolder}/proxyServer",
|
9 |
-
"args": ["
|
10 |
"stopAtEntry": false,
|
11 |
"cwd": "${workspaceFolder}",
|
12 |
"environment": [],
|
|
|
6 |
"type": "cppdbg",
|
7 |
"request": "launch",
|
8 |
"program": "${workspaceFolder}/proxyServer",
|
9 |
+
"args": ["1", "8082"],
|
10 |
"stopAtEntry": false,
|
11 |
"cwd": "${workspaceFolder}",
|
12 |
"environment": [],
|
include/tcp_client_map.h
CHANGED
@@ -5,7 +5,6 @@
|
|
5 |
#include <map>
|
6 |
#include <shared_mutex>
|
7 |
#include <mutex>
|
8 |
-
#include <memory>
|
9 |
|
10 |
template <typename Key, typename Value>
|
11 |
class TcpClientMap {
|
|
|
5 |
#include <map>
|
6 |
#include <shared_mutex>
|
7 |
#include <mutex>
|
|
|
8 |
|
9 |
template <typename Key, typename Value>
|
10 |
class TcpClientMap {
|
include/timer_thread.h
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#ifndef PROXYSERVER_TIMER_THREAD_H
|
2 |
+
#define PROXYSERVER_TIMER_THREAD_H
|
3 |
+
|
4 |
+
#include "hv/EventLoopThread.h"
|
5 |
+
|
6 |
+
class TimerThread : public hv::EventLoopThread {
|
7 |
+
public:
|
8 |
+
std::atomic<hv::TimerID> nextTimerID;
|
9 |
+
TimerThread() : EventLoopThread() {
|
10 |
+
nextTimerID = 0;
|
11 |
+
start();
|
12 |
+
}
|
13 |
+
|
14 |
+
virtual ~TimerThread() {
|
15 |
+
stop();
|
16 |
+
join();
|
17 |
+
}
|
18 |
+
|
19 |
+
public:
|
20 |
+
// setTimer, setTimeout, killTimer, resetTimer thread-safe
|
21 |
+
hv::TimerID setTimer(int timeout_ms, hv::TimerCallback cb, uint32_t repeat = INFINITE) {
|
22 |
+
hv::TimerID timerID = ++nextTimerID;
|
23 |
+
loop()->setTimerInLoop(timeout_ms, cb, repeat, timerID);
|
24 |
+
return timerID;
|
25 |
+
}
|
26 |
+
// alias javascript setTimeout, setInterval
|
27 |
+
hv::TimerID setTimeout(int timeout_ms, hv::TimerCallback cb) {
|
28 |
+
return setTimer(timeout_ms, cb, 1);
|
29 |
+
}
|
30 |
+
hv::TimerID setInterval(int interval_ms, hv::TimerCallback cb) {
|
31 |
+
return setTimer(interval_ms, cb, INFINITE);
|
32 |
+
}
|
33 |
+
|
34 |
+
void killTimer(hv::TimerID timerID) {
|
35 |
+
loop()->killTimer(timerID);
|
36 |
+
}
|
37 |
+
|
38 |
+
void resetTimer(hv::TimerID timerID, int timeout_ms = 0) {
|
39 |
+
loop()->resetTimer(timerID, timeout_ms);
|
40 |
+
}
|
41 |
+
};
|
42 |
+
|
43 |
+
#endif // PROXYSERVER_TIMER_THREAD_H
|
include/udp_client.h
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
|
4 |
#include "hv/hloop.h"
|
5 |
#include "hv/UdpClient.h"
|
|
|
6 |
#include "bolt/crypt.h"
|
7 |
#include "udp_client_map.h"
|
8 |
#include <string>
|
@@ -19,6 +20,8 @@ public:
|
|
19 |
char ept_key;
|
20 |
};
|
21 |
|
|
|
|
|
22 |
class UdpClientProxy
|
23 |
{
|
24 |
public:
|
@@ -26,6 +29,9 @@ public:
|
|
26 |
hv::UdpClient *getClient() { return &cli; }
|
27 |
bool init();
|
28 |
void close();
|
|
|
|
|
|
|
29 |
|
30 |
private:
|
31 |
void onRecv(const hv::SocketChannelPtr &channel, hv::Buffer *buf);
|
@@ -36,7 +42,9 @@ public:
|
|
36 |
|
37 |
private:
|
38 |
hv::UdpClient cli;
|
|
|
39 |
uint32_t session_id;
|
|
|
40 |
};
|
41 |
|
42 |
class UdpServerBoltProxy
|
@@ -50,6 +58,8 @@ public:
|
|
50 |
|
51 |
int sendData(struct sockaddr_in t_addr, struct sockaddr_in u_addr, void *data, int data_len);
|
52 |
|
|
|
|
|
53 |
void recycle();
|
54 |
|
55 |
private:
|
|
|
3 |
|
4 |
#include "hv/hloop.h"
|
5 |
#include "hv/UdpClient.h"
|
6 |
+
#include "timer_thread.h"
|
7 |
#include "bolt/crypt.h"
|
8 |
#include "udp_client_map.h"
|
9 |
#include <string>
|
|
|
20 |
char ept_key;
|
21 |
};
|
22 |
|
23 |
+
#define TIMEOUT_TIMEUNIT 10 * 1000
|
24 |
+
#define DNS_TIMEOUT 5 * 1000
|
25 |
class UdpClientProxy
|
26 |
{
|
27 |
public:
|
|
|
29 |
hv::UdpClient *getClient() { return &cli; }
|
30 |
bool init();
|
31 |
void close();
|
32 |
+
bool isDns() {
|
33 |
+
return ntohs(t_addr.sin_port) == 53;
|
34 |
+
};
|
35 |
|
36 |
private:
|
37 |
void onRecv(const hv::SocketChannelPtr &channel, hv::Buffer *buf);
|
|
|
42 |
|
43 |
private:
|
44 |
hv::UdpClient cli;
|
45 |
+
TimerThread timer;
|
46 |
uint32_t session_id;
|
47 |
+
long long ts;
|
48 |
};
|
49 |
|
50 |
class UdpServerBoltProxy
|
|
|
58 |
|
59 |
int sendData(struct sockaddr_in t_addr, struct sockaddr_in u_addr, void *data, int data_len);
|
60 |
|
61 |
+
void closeClient(struct sockaddr_in &t_addr, struct sockaddr_in &u_addr);
|
62 |
+
|
63 |
void recycle();
|
64 |
|
65 |
private:
|
include/{hv_utils.h β utils.h}
RENAMED
@@ -10,5 +10,6 @@ hloop_t* get_next_loop();
|
|
10 |
|
11 |
char generateRandomKey();
|
12 |
|
|
|
13 |
|
14 |
#endif //PROXYSERVER_HV_UTILS_H
|
|
|
10 |
|
11 |
char generateRandomKey();
|
12 |
|
13 |
+
long long currentTimeMillis();
|
14 |
|
15 |
#endif //PROXYSERVER_HV_UTILS_H
|
src/main.cpp
CHANGED
@@ -129,7 +129,7 @@
|
|
129 |
|
130 |
#include "hv/hloop.h"
|
131 |
#include "hv/hthread.h"
|
132 |
-
#include "
|
133 |
#include "tcp_inbound.h"
|
134 |
#include "udp_inbound.h"
|
135 |
|
@@ -174,7 +174,9 @@ static HTHREAD_RETTYPE tcpaccept_thread(void* userdata) {
|
|
174 |
if (listenio == NULL) {
|
175 |
exit(1);
|
176 |
}
|
|
|
177 |
hloop_run(loop);
|
|
|
178 |
return 0;
|
179 |
}
|
180 |
|
@@ -184,12 +186,14 @@ static HTHREAD_RETTYPE udpbind_thread(void* userdata) {
|
|
184 |
if (bindio == NULL) {
|
185 |
exit(1);
|
186 |
}
|
|
|
187 |
spdlog::info("ProxyServer start: udp->{}", port);
|
188 |
hio_setcb_read(bindio, udp_on_recvfrom);
|
189 |
hio_setcb_write(bindio, udp_on_writed);
|
190 |
hio_setcb_close(bindio, udp_on_close);
|
191 |
hio_read(bindio);
|
192 |
hloop_run(loop);
|
|
|
193 |
return 0;
|
194 |
}
|
195 |
|
|
|
129 |
|
130 |
#include "hv/hloop.h"
|
131 |
#include "hv/hthread.h"
|
132 |
+
#include "utils.h"
|
133 |
#include "tcp_inbound.h"
|
134 |
#include "udp_inbound.h"
|
135 |
|
|
|
174 |
if (listenio == NULL) {
|
175 |
exit(1);
|
176 |
}
|
177 |
+
int listeniofd = hio_fd(listenio);
|
178 |
hloop_run(loop);
|
179 |
+
close(listeniofd);
|
180 |
return 0;
|
181 |
}
|
182 |
|
|
|
186 |
if (bindio == NULL) {
|
187 |
exit(1);
|
188 |
}
|
189 |
+
int bindfd = hio_fd(bindio);
|
190 |
spdlog::info("ProxyServer start: udp->{}", port);
|
191 |
hio_setcb_read(bindio, udp_on_recvfrom);
|
192 |
hio_setcb_write(bindio, udp_on_writed);
|
193 |
hio_setcb_close(bindio, udp_on_close);
|
194 |
hio_read(bindio);
|
195 |
hloop_run(loop);
|
196 |
+
close(bindfd);
|
197 |
return 0;
|
198 |
}
|
199 |
|
src/tcp_client.cpp
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
#include "tcp_client.h"
|
2 |
#include "bolt/datagram.h"
|
3 |
#include "tcp_client_map.h"
|
4 |
-
#include "
|
5 |
#include "spdlog/spdlog.h"
|
6 |
#include <string>
|
7 |
#include <time.h>
|
|
|
1 |
#include "tcp_client.h"
|
2 |
#include "bolt/datagram.h"
|
3 |
#include "tcp_client_map.h"
|
4 |
+
#include "utils.h"
|
5 |
#include "spdlog/spdlog.h"
|
6 |
#include <string>
|
7 |
#include <time.h>
|
src/udp_client.cpp
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
#include "udp_client.h"
|
2 |
#include "conn_map.h"
|
|
|
3 |
#include "hv/UdpClient.h"
|
4 |
#include "bolt/datagram.h"
|
5 |
#include "spdlog/spdlog.h"
|
@@ -41,10 +42,27 @@ bool UdpServerBoltProxy::analyzeData(struct sockaddr_in t_addr, struct sockaddr_
|
|
41 |
|
42 |
int UdpServerBoltProxy::sendData(struct sockaddr_in t_addr, struct sockaddr_in u_addr, void *data, int data_len)
|
43 |
{
|
|
|
|
|
|
|
|
|
|
|
44 |
PACK_TUNNEL_DATA(boltdata, boltdata_len, BOLT_VERSION, BOLT_RESERVE, BOLT_PAYLOAD_TYPE_UDP, t_addr.sin_addr.s_addr, t_addr.sin_port, u_addr.sin_addr.s_addr, u_addr.sin_port, config.session_id, 0, 0, data, data_len)
|
45 |
hio_write(io, boltdata, boltdata_len);
|
46 |
}
|
47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
void UdpServerBoltProxy::recycle()
|
49 |
{
|
50 |
for (auto it = _map.begin(); it != _map.end(); ++it)
|
@@ -73,14 +91,36 @@ bool UdpClientProxy::init()
|
|
73 |
hio_setcb_close(cli.channel.get()->io(), [](hio_t *io) {
|
74 |
|
75 |
});
|
76 |
-
|
77 |
cli.start();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
return true;
|
79 |
}
|
80 |
|
81 |
void UdpClientProxy::close()
|
82 |
{
|
83 |
cli.closesocket();
|
|
|
84 |
}
|
85 |
|
86 |
void UdpClientProxy::onRecv(const hv::SocketChannelPtr &channel, hv::Buffer *buf)
|
@@ -91,6 +131,7 @@ void UdpClientProxy::onRecv(const hv::SocketChannelPtr &channel, hv::Buffer *buf
|
|
91 |
{
|
92 |
return;
|
93 |
}
|
|
|
94 |
serverProxy->sendData(t_addr, u_addr, buf->data(), buf->size());
|
95 |
}
|
96 |
|
|
|
1 |
#include "udp_client.h"
|
2 |
#include "conn_map.h"
|
3 |
+
#include "utils.h"
|
4 |
#include "hv/UdpClient.h"
|
5 |
#include "bolt/datagram.h"
|
6 |
#include "spdlog/spdlog.h"
|
|
|
42 |
|
43 |
int UdpServerBoltProxy::sendData(struct sockaddr_in t_addr, struct sockaddr_in u_addr, void *data, int data_len)
|
44 |
{
|
45 |
+
|
46 |
+
if (getConfig().ept_type == CRYPT_TYPE::XOR)
|
47 |
+
{
|
48 |
+
xor_::crypt((char *)data, data_len, getConfig().ept_key);
|
49 |
+
}
|
50 |
PACK_TUNNEL_DATA(boltdata, boltdata_len, BOLT_VERSION, BOLT_RESERVE, BOLT_PAYLOAD_TYPE_UDP, t_addr.sin_addr.s_addr, t_addr.sin_port, u_addr.sin_addr.s_addr, u_addr.sin_port, config.session_id, 0, 0, data, data_len)
|
51 |
hio_write(io, boltdata, boltdata_len);
|
52 |
}
|
53 |
|
54 |
+
void UdpServerBoltProxy::closeClient(struct sockaddr_in &t_addr, struct sockaddr_in &u_addr)
|
55 |
+
{
|
56 |
+
auto key = get_key(t_addr, u_addr);
|
57 |
+
auto client = _map.get(key);
|
58 |
+
if (client)
|
59 |
+
{
|
60 |
+
client->close();
|
61 |
+
_map.remove(key);
|
62 |
+
}
|
63 |
+
|
64 |
+
}
|
65 |
+
|
66 |
void UdpServerBoltProxy::recycle()
|
67 |
{
|
68 |
for (auto it = _map.begin(); it != _map.end(); ++it)
|
|
|
91 |
hio_setcb_close(cli.channel.get()->io(), [](hio_t *io) {
|
92 |
|
93 |
});
|
|
|
94 |
cli.start();
|
95 |
+
|
96 |
+
timer.setInterval(TIMEOUT_TIMEUNIT, [this](hv::TimerID timerID) {
|
97 |
+
long timeout = isDns() ? DNS_TIMEOUT : TIMEOUT_TIMEUNIT;
|
98 |
+
long time = currentTimeMillis() - ts;
|
99 |
+
if (time > 0 && time < timeout)
|
100 |
+
{
|
101 |
+
long remaining = (timeout-time);
|
102 |
+
if(remaining < TIMEOUT_TIMEUNIT) {
|
103 |
+
} else {
|
104 |
+
|
105 |
+
}
|
106 |
+
} else {
|
107 |
+
auto serverProxy = UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().get(session_id);
|
108 |
+
if (!serverProxy)
|
109 |
+
{
|
110 |
+
close();
|
111 |
+
return;
|
112 |
+
}
|
113 |
+
serverProxy->closeClient(t_addr, u_addr);
|
114 |
+
}
|
115 |
+
|
116 |
+
});
|
117 |
return true;
|
118 |
}
|
119 |
|
120 |
void UdpClientProxy::close()
|
121 |
{
|
122 |
cli.closesocket();
|
123 |
+
timer.stop();
|
124 |
}
|
125 |
|
126 |
void UdpClientProxy::onRecv(const hv::SocketChannelPtr &channel, hv::Buffer *buf)
|
|
|
131 |
{
|
132 |
return;
|
133 |
}
|
134 |
+
ts = currentTimeMillis();
|
135 |
serverProxy->sendData(t_addr, u_addr, buf->data(), buf->size());
|
136 |
}
|
137 |
|
src/udp_inbound.cpp
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
#include "udp_inbound.h"
|
2 |
#include "udp_client.h"
|
3 |
#include "conn_map.h"
|
4 |
-
#include "
|
5 |
#include "bolt/datagram.h"
|
6 |
#include "bolt/crypt.h"
|
7 |
|
|
|
1 |
#include "udp_inbound.h"
|
2 |
#include "udp_client.h"
|
3 |
#include "conn_map.h"
|
4 |
+
#include "utils.h"
|
5 |
#include "bolt/datagram.h"
|
6 |
#include "bolt/crypt.h"
|
7 |
|
src/{hv_utils.cpp β utils.cpp}
RENAMED
@@ -1,4 +1,5 @@
|
|
1 |
-
#include "
|
|
|
2 |
|
3 |
int thread_num = 4;
|
4 |
hloop_t** worker_loops = NULL;
|
@@ -28,4 +29,15 @@ char generateRandomKey()
|
|
28 |
|
29 |
// ηζ 'A' ε° 'Z' δΉι΄ηιζΊε符
|
30 |
return (char)('A' + rand() % 26);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
|
|
1 |
+
#include "utils.h"
|
2 |
+
#include <sys/time.h>
|
3 |
|
4 |
int thread_num = 4;
|
5 |
hloop_t** worker_loops = NULL;
|
|
|
29 |
|
30 |
// ηζ 'A' ε° 'Z' δΉι΄ηιζΊε符
|
31 |
return (char)('A' + rand() % 26);
|
32 |
+
}
|
33 |
+
|
34 |
+
long long currentTimeMillis() {
|
35 |
+
struct timeval now;
|
36 |
+
gettimeofday(&now, NULL);
|
37 |
+
|
38 |
+
// return time(NULL);
|
39 |
+
|
40 |
+
// struct timespec now;
|
41 |
+
// clock_gettime(CLOCK_MONOTONIC, &now);
|
42 |
+
return now.tv_sec * 1000 + now.tv_usec / 1000;
|
43 |
}
|