Spaces:
Paused
Paused
xukc
commited on
Commit
·
1bff97b
1
Parent(s):
8122175
[feat]support udp
Browse files- .vscode/launch.json +2 -2
- .vscode/tasks.json +1 -4
- Dockerfile +2 -2
- include/conn_map.h +42 -11
- include/hv_utils.h +2 -0
- include/tcp_client_map.h +4 -3
- include/udp_client.h +61 -0
- include/udp_client_map.h +12 -0
- include/udp_inbound.h +9 -0
- src/hv_utils.cpp +9 -0
- src/main.cpp +38 -10
- src/tcp_client.cpp +6 -10
- src/tcp_inbound.cpp +5 -4
- src/udp_client.cpp +100 -0
- src/udp_inbound.cpp +85 -0
.vscode/launch.json
CHANGED
|
@@ -5,8 +5,8 @@
|
|
| 5 |
"name": "Debug",
|
| 6 |
"type": "cppdbg",
|
| 7 |
"request": "launch",
|
| 8 |
-
"program": "${workspaceFolder}/
|
| 9 |
-
"args": [],
|
| 10 |
"stopAtEntry": false,
|
| 11 |
"cwd": "${workspaceFolder}",
|
| 12 |
"environment": [],
|
|
|
|
| 5 |
"name": "Debug",
|
| 6 |
"type": "cppdbg",
|
| 7 |
"request": "launch",
|
| 8 |
+
"program": "${workspaceFolder}/proxyServer",
|
| 9 |
+
"args": ["0", "8080"],
|
| 10 |
"stopAtEntry": false,
|
| 11 |
"cwd": "${workspaceFolder}",
|
| 12 |
"environment": [],
|
.vscode/tasks.json
CHANGED
|
@@ -9,12 +9,9 @@
|
|
| 9 |
"-std=c++14",
|
| 10 |
"-g",
|
| 11 |
"-o",
|
| 12 |
-
"
|
| 13 |
"-I",
|
| 14 |
"include",
|
| 15 |
-
// "-I",
|
| 16 |
-
// "include/bolt",
|
| 17 |
-
// "*.cpp",
|
| 18 |
"src/*.cpp",
|
| 19 |
"-lhv",
|
| 20 |
"-lspdlog"
|
|
|
|
| 9 |
"-std=c++14",
|
| 10 |
"-g",
|
| 11 |
"-o",
|
| 12 |
+
"proxyServer",
|
| 13 |
"-I",
|
| 14 |
"include",
|
|
|
|
|
|
|
|
|
|
| 15 |
"src/*.cpp",
|
| 16 |
"-lhv",
|
| 17 |
"-lspdlog"
|
Dockerfile
CHANGED
|
@@ -50,7 +50,7 @@ WORKDIR /app
|
|
| 50 |
COPY . .
|
| 51 |
|
| 52 |
# Compile the C++ program
|
| 53 |
-
RUN g++ -std=c++14 -g -o
|
| 54 |
|
| 55 |
RUN apt-get install -y tzdata
|
| 56 |
|
|
@@ -61,4 +61,4 @@ RUN dpkg-reconfigure --frontend noninteractive tzdata
|
|
| 61 |
|
| 62 |
EXPOSE 8080
|
| 63 |
# Run my_program when the container launches
|
| 64 |
-
CMD ["./
|
|
|
|
| 50 |
COPY . .
|
| 51 |
|
| 52 |
# Compile the C++ program
|
| 53 |
+
RUN g++ -std=c++14 -g -o proxyServer src/*.cpp -I include -lhv -lspdlog
|
| 54 |
|
| 55 |
RUN apt-get install -y tzdata
|
| 56 |
|
|
|
|
| 61 |
|
| 62 |
EXPOSE 8080
|
| 63 |
# Run my_program when the container launches
|
| 64 |
+
CMD ["./proxyServer 0 8080"]
|
include/conn_map.h
CHANGED
|
@@ -7,18 +7,12 @@
|
|
| 7 |
#include <mutex>
|
| 8 |
#include <memory>
|
| 9 |
|
|
|
|
| 10 |
template <typename Key, typename Value>
|
| 11 |
-
class
|
| 12 |
public:
|
| 13 |
-
static ConnMap& getInstance() {
|
| 14 |
-
static ConnMap instance; // 在首次使用时创建
|
| 15 |
-
return instance;
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
ConnMap(ConnMap const&) = delete;
|
| 19 |
-
void operator=(ConnMap const&) = delete;
|
| 20 |
|
| 21 |
-
void add(const Key& key, std::unique_ptr<Value> value) {
|
| 22 |
std::unique_lock<std::shared_timed_mutex> lock(mutex_);
|
| 23 |
map_[key] = std::move(value);
|
| 24 |
}
|
|
@@ -41,11 +35,48 @@ public:
|
|
| 41 |
std::unique_lock<std::shared_timed_mutex> lock(mutex_);
|
| 42 |
map_.clear();
|
| 43 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
-
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
| 47 |
mutable std::shared_timed_mutex mutex_;
|
| 48 |
std::map<Key, std::unique_ptr<Value>> map_;
|
| 49 |
};
|
| 50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
#endif //PROXYSERVER_CONN_MAP_H
|
|
|
|
| 7 |
#include <mutex>
|
| 8 |
#include <memory>
|
| 9 |
|
| 10 |
+
|
| 11 |
template <typename Key, typename Value>
|
| 12 |
+
class SafeMap {
|
| 13 |
public:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
+
void add(const Key& key, std::unique_ptr<Value> &value) {
|
| 16 |
std::unique_lock<std::shared_timed_mutex> lock(mutex_);
|
| 17 |
map_[key] = std::move(value);
|
| 18 |
}
|
|
|
|
| 35 |
std::unique_lock<std::shared_timed_mutex> lock(mutex_);
|
| 36 |
map_.clear();
|
| 37 |
}
|
| 38 |
+
|
| 39 |
+
typename std::map<Key, std::unique_ptr<Value>>::iterator begin() {
|
| 40 |
+
return map_.begin();
|
| 41 |
+
}
|
| 42 |
|
| 43 |
+
typename std::map<Key, std::unique_ptr<Value>>::iterator end() {
|
| 44 |
+
return map_.end();
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
protected:
|
| 48 |
mutable std::shared_timed_mutex mutex_;
|
| 49 |
std::map<Key, std::unique_ptr<Value>> map_;
|
| 50 |
};
|
| 51 |
|
| 52 |
+
template <typename Key, typename Value>
|
| 53 |
+
class TcpConnMap : public SafeMap<Key, Value> {
|
| 54 |
+
public:
|
| 55 |
+
static TcpConnMap& getInstance() {
|
| 56 |
+
static TcpConnMap instance; // 在首次使用时创建
|
| 57 |
+
return instance;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
TcpConnMap(TcpConnMap const&) = delete;
|
| 61 |
+
void operator=(TcpConnMap const&) = delete;
|
| 62 |
+
|
| 63 |
+
private:
|
| 64 |
+
TcpConnMap() = default;
|
| 65 |
+
};
|
| 66 |
+
|
| 67 |
+
template <typename Key, typename Value>
|
| 68 |
+
class UdpConnMap : public SafeMap<Key, Value> {
|
| 69 |
+
public:
|
| 70 |
+
static UdpConnMap& getInstance() {
|
| 71 |
+
static UdpConnMap instance; // 在首次使用时创建
|
| 72 |
+
return instance;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
UdpConnMap(UdpConnMap const&) = delete;
|
| 76 |
+
void operator=(UdpConnMap const&) = delete;
|
| 77 |
+
|
| 78 |
+
private:
|
| 79 |
+
UdpConnMap() = default;
|
| 80 |
+
};
|
| 81 |
+
|
| 82 |
#endif //PROXYSERVER_CONN_MAP_H
|
include/hv_utils.h
CHANGED
|
@@ -8,5 +8,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
|
|
|
|
| 8 |
|
| 9 |
hloop_t* get_next_loop();
|
| 10 |
|
| 11 |
+
char generateRandomKey();
|
| 12 |
+
|
| 13 |
|
| 14 |
#endif //PROXYSERVER_HV_UTILS_H
|
include/tcp_client_map.h
CHANGED
|
@@ -1,10 +1,11 @@
|
|
| 1 |
-
#ifndef
|
| 2 |
-
#define
|
| 3 |
|
| 4 |
#include <iostream>
|
| 5 |
#include <map>
|
| 6 |
#include <shared_mutex>
|
| 7 |
#include <mutex>
|
|
|
|
| 8 |
|
| 9 |
template <typename Key, typename Value>
|
| 10 |
class TcpClientMap {
|
|
@@ -47,4 +48,4 @@ private:
|
|
| 47 |
std::map<Key, Value> map_;
|
| 48 |
};
|
| 49 |
|
| 50 |
-
#endif //
|
|
|
|
| 1 |
+
#ifndef PROXYSERVER_TCP_CLIENT_MAP_H
|
| 2 |
+
#define PROXYSERVER_TCP_CLIENT_MAP_H
|
| 3 |
|
| 4 |
#include <iostream>
|
| 5 |
#include <map>
|
| 6 |
#include <shared_mutex>
|
| 7 |
#include <mutex>
|
| 8 |
+
#include <memory>
|
| 9 |
|
| 10 |
template <typename Key, typename Value>
|
| 11 |
class TcpClientMap {
|
|
|
|
| 48 |
std::map<Key, Value> map_;
|
| 49 |
};
|
| 50 |
|
| 51 |
+
#endif //PROXYSERVER_TCP_CLIENT_MAP_H
|
include/udp_client.h
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef PROXYSERVER_UDP_CLIENT_H
|
| 2 |
+
#define PROXYSERVER_UDP_CLIENT_H
|
| 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>
|
| 9 |
+
|
| 10 |
+
class UdpBoltConfig
|
| 11 |
+
{
|
| 12 |
+
public:
|
| 13 |
+
uint32_t request_id;
|
| 14 |
+
uint32_t session_id;
|
| 15 |
+
std::string signal_id;
|
| 16 |
+
std::string data_st;
|
| 17 |
+
bool encrypt = false;
|
| 18 |
+
CRYPT_TYPE ept_type;
|
| 19 |
+
char ept_key;
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
class UdpClientProxy
|
| 23 |
+
{
|
| 24 |
+
public:
|
| 25 |
+
UdpClientProxy(struct sockaddr_in t_addr, struct sockaddr_in u_addr, uint32_t session_id) : t_addr(t_addr), u_addr(u_addr), session_id(session_id) {}
|
| 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);
|
| 32 |
+
void onWrited(const hv::SocketChannelPtr &channel, hv::Buffer *buf);
|
| 33 |
+
|
| 34 |
+
public:
|
| 35 |
+
struct sockaddr_in t_addr, u_addr;
|
| 36 |
+
|
| 37 |
+
private:
|
| 38 |
+
hv::UdpClient cli;
|
| 39 |
+
uint32_t session_id;
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
+
class UdpServerBoltProxy
|
| 43 |
+
{
|
| 44 |
+
public:
|
| 45 |
+
UdpServerBoltProxy(hio_t *_io) : io(_io) {}
|
| 46 |
+
|
| 47 |
+
UdpBoltConfig &getConfig() { return config; }
|
| 48 |
+
|
| 49 |
+
bool analyzeData(struct sockaddr_in t_addr, struct sockaddr_in u_addr, uint32_t session_id, char *data, int data_len, char *extend, int extend_len);
|
| 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:
|
| 56 |
+
UdpBoltConfig config;
|
| 57 |
+
hio_t *io;
|
| 58 |
+
UdpClientMap<std::string, UdpClientProxy> _map;
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
#endif // PROXYSERVER_UDP_CLIENT_H
|
include/udp_client_map.h
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef PROXYSERVER_UDP_CLIENT_MAP_H
|
| 2 |
+
#define PROXYSERVER_UDP_CLIENT_MAP_H
|
| 3 |
+
|
| 4 |
+
#include "conn_map.h"
|
| 5 |
+
|
| 6 |
+
template <typename Key, typename Value>
|
| 7 |
+
class UdpClientMap : public SafeMap<Key, Value> {
|
| 8 |
+
public:
|
| 9 |
+
|
| 10 |
+
};
|
| 11 |
+
|
| 12 |
+
#endif //PROXYSERVER_UDP_CLIENT_MAP_H
|
include/udp_inbound.h
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef PROXYSERVER_UDP_INBOUND_H
|
| 2 |
+
#define PROXYSERVER_UDP_INBOUND_H
|
| 3 |
+
|
| 4 |
+
#include "hv/hloop.h"
|
| 5 |
+
void udp_on_recvfrom(hio_t* io, void* buf, int readbytes);
|
| 6 |
+
void udp_on_writed(hio_t* io, const void* buf, int writebytes);
|
| 7 |
+
void udp_on_close(hio_t* io);
|
| 8 |
+
|
| 9 |
+
#endif //PROXYSERVER_UDP_INBOUND_H
|
src/hv_utils.cpp
CHANGED
|
@@ -19,4 +19,13 @@ hloop_t* get_next_loop() {
|
|
| 19 |
s_cur_index = 0;
|
| 20 |
}
|
| 21 |
return worker_loops[s_cur_index++];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
}
|
|
|
|
| 19 |
s_cur_index = 0;
|
| 20 |
}
|
| 21 |
return worker_loops[s_cur_index++];
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
char generateRandomKey()
|
| 25 |
+
{
|
| 26 |
+
// 使用时间作为随机数种子,确保每次运行生成的随机数都不同
|
| 27 |
+
srand((unsigned int)time(NULL));
|
| 28 |
+
|
| 29 |
+
// 生成 'A' 到 'Z' 之间的随机字符
|
| 30 |
+
return (char)('A' + rand() % 26);
|
| 31 |
}
|
src/main.cpp
CHANGED
|
@@ -131,6 +131,7 @@
|
|
| 131 |
#include "hv/hthread.h"
|
| 132 |
#include "hv_utils.h"
|
| 133 |
#include "tcp_inbound.h"
|
|
|
|
| 134 |
|
| 135 |
#include "spdlog/spdlog.h"
|
| 136 |
#include "spdlog/async.h"
|
|
@@ -139,7 +140,7 @@
|
|
| 139 |
static const char* host = "0.0.0.0";
|
| 140 |
static int port = 8080;
|
| 141 |
static int thread_num = 4;
|
| 142 |
-
static hloop_t*
|
| 143 |
|
| 144 |
static void new_conn_event(hevent_t* ev) {
|
| 145 |
hloop_t* loop = ev->loop;
|
|
@@ -167,7 +168,7 @@ static HTHREAD_RETTYPE worker_thread(void* userdata) {
|
|
| 167 |
return 0;
|
| 168 |
}
|
| 169 |
|
| 170 |
-
static HTHREAD_RETTYPE
|
| 171 |
hloop_t* loop = (hloop_t*)userdata;
|
| 172 |
hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept);
|
| 173 |
if (listenio == NULL) {
|
|
@@ -177,12 +178,27 @@ static HTHREAD_RETTYPE accept_thread(void* userdata) {
|
|
| 177 |
return 0;
|
| 178 |
}
|
| 179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
int main(int argc, char** argv) {
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
int cores = std::thread::hardware_concurrency();
|
| 187 |
if (cores > 0) {
|
| 188 |
thread_num = cores;
|
|
@@ -198,12 +214,24 @@ int main(int argc, char** argv) {
|
|
| 198 |
spdlog::set_default_logger(std::make_shared<spdlog::async_logger>(
|
| 199 |
"ProxyServer", console_sink, spdlog::thread_pool(), spdlog::async_overflow_policy::block));
|
| 200 |
|
| 201 |
-
init_loop(thread_num, worker_thread);
|
| 202 |
|
| 203 |
spdlog::info("ProxyServer start: threadNum:{:d}", thread_num);
|
| 204 |
|
| 205 |
-
|
| 206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
|
| 208 |
return 0;
|
| 209 |
}
|
|
|
|
| 131 |
#include "hv/hthread.h"
|
| 132 |
#include "hv_utils.h"
|
| 133 |
#include "tcp_inbound.h"
|
| 134 |
+
#include "udp_inbound.h"
|
| 135 |
|
| 136 |
#include "spdlog/spdlog.h"
|
| 137 |
#include "spdlog/async.h"
|
|
|
|
| 140 |
static const char* host = "0.0.0.0";
|
| 141 |
static int port = 8080;
|
| 142 |
static int thread_num = 4;
|
| 143 |
+
static hloop_t *tcpaccept_loop = NULL, *udpbind_loop = NULL;
|
| 144 |
|
| 145 |
static void new_conn_event(hevent_t* ev) {
|
| 146 |
hloop_t* loop = ev->loop;
|
|
|
|
| 168 |
return 0;
|
| 169 |
}
|
| 170 |
|
| 171 |
+
static HTHREAD_RETTYPE tcpaccept_thread(void* userdata) {
|
| 172 |
hloop_t* loop = (hloop_t*)userdata;
|
| 173 |
hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept);
|
| 174 |
if (listenio == NULL) {
|
|
|
|
| 178 |
return 0;
|
| 179 |
}
|
| 180 |
|
| 181 |
+
static HTHREAD_RETTYPE udpbind_thread(void* userdata) {
|
| 182 |
+
hloop_t* loop = (hloop_t*)userdata;
|
| 183 |
+
hio_t* bindio = hloop_create_udp_server(loop, host, port);
|
| 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 |
+
|
| 196 |
int main(int argc, char** argv) {
|
| 197 |
+
int type = 0;
|
| 198 |
+
if (argc == 3) {
|
| 199 |
+
type = atoi(argv[1]);
|
| 200 |
+
port = atoi(argv[2]);
|
| 201 |
+
}
|
| 202 |
int cores = std::thread::hardware_concurrency();
|
| 203 |
if (cores > 0) {
|
| 204 |
thread_num = cores;
|
|
|
|
| 214 |
spdlog::set_default_logger(std::make_shared<spdlog::async_logger>(
|
| 215 |
"ProxyServer", console_sink, spdlog::thread_pool(), spdlog::async_overflow_policy::block));
|
| 216 |
|
|
|
|
| 217 |
|
| 218 |
spdlog::info("ProxyServer start: threadNum:{:d}", thread_num);
|
| 219 |
|
| 220 |
+
if (type == 1)
|
| 221 |
+
{
|
| 222 |
+
//Udp
|
| 223 |
+
spdlog::info("ProxyServer start: udp->{}", port);
|
| 224 |
+
udpbind_loop = hloop_new(HLOOP_FLAG_AUTO_FREE);
|
| 225 |
+
udpbind_thread(udpbind_loop);
|
| 226 |
+
}
|
| 227 |
+
else {
|
| 228 |
+
//Tcp
|
| 229 |
+
init_loop(thread_num, worker_thread);
|
| 230 |
+
spdlog::info("ProxyServer start: tcp->{}", port);
|
| 231 |
+
tcpaccept_loop = hloop_new(HLOOP_FLAG_AUTO_FREE);
|
| 232 |
+
tcpaccept_thread(tcpaccept_loop);
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
|
| 236 |
return 0;
|
| 237 |
}
|
src/tcp_client.cpp
CHANGED
|
@@ -1,19 +1,11 @@
|
|
| 1 |
#include "tcp_client.h"
|
| 2 |
#include "bolt/datagram.h"
|
| 3 |
#include "tcp_client_map.h"
|
|
|
|
| 4 |
#include "spdlog/spdlog.h"
|
| 5 |
#include <string>
|
| 6 |
#include <time.h>
|
| 7 |
|
| 8 |
-
char generateRandomKey()
|
| 9 |
-
{
|
| 10 |
-
// 使用时间作为随机数种子,确保每次运行生成的随机数都不同
|
| 11 |
-
srand((unsigned int)time(NULL));
|
| 12 |
-
|
| 13 |
-
// 生成 'A' 到 'Z' 之间的随机字符
|
| 14 |
-
return (char)('A' + rand() % 26);
|
| 15 |
-
}
|
| 16 |
-
|
| 17 |
void TcpClientBolt::onConnection(const hv::SocketChannelPtr &channel)
|
| 18 |
{
|
| 19 |
char buff[2];
|
|
@@ -49,7 +41,11 @@ void TcpClientBolt::onRecv(const hv::SocketChannelPtr &channel, hv::Buffer *buf)
|
|
| 49 |
|
| 50 |
void TcpClientBolt::onWrited(const hv::SocketChannelPtr &channel, hv::Buffer *buf)
|
| 51 |
{
|
| 52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
}
|
| 54 |
|
| 55 |
void TcpClientBolt::onDisConnection(const hv::SocketChannelPtr &channel)
|
|
|
|
| 1 |
#include "tcp_client.h"
|
| 2 |
#include "bolt/datagram.h"
|
| 3 |
#include "tcp_client_map.h"
|
| 4 |
+
#include "hv_utils.h"
|
| 5 |
#include "spdlog/spdlog.h"
|
| 6 |
#include <string>
|
| 7 |
#include <time.h>
|
| 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
void TcpClientBolt::onConnection(const hv::SocketChannelPtr &channel)
|
| 10 |
{
|
| 11 |
char buff[2];
|
|
|
|
| 41 |
|
| 42 |
void TcpClientBolt::onWrited(const hv::SocketChannelPtr &channel, hv::Buffer *buf)
|
| 43 |
{
|
| 44 |
+
if (channel.get()->isWriteComplete())
|
| 45 |
+
{
|
| 46 |
+
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
}
|
| 50 |
|
| 51 |
void TcpClientBolt::onDisConnection(const hv::SocketChannelPtr &channel)
|
src/tcp_inbound.cpp
CHANGED
|
@@ -9,16 +9,16 @@
|
|
| 9 |
static void tcp_on_close(hio_t* io) {
|
| 10 |
spdlog::info("tcp_on_close fd={} error={}\n", hio_fd(io), hio_error(io));
|
| 11 |
|
| 12 |
-
auto cli =
|
| 13 |
if(cli) {
|
| 14 |
-
|
| 15 |
cli->close();
|
| 16 |
}
|
| 17 |
}
|
| 18 |
|
| 19 |
static void tcp_on_recv(hio_t* io, void* buf, int readbytes) {
|
| 20 |
spdlog::info("tcp_on_recv fd={} buf({})={}\n", hio_fd(io), readbytes, (const char*)buf);
|
| 21 |
-
auto cli =
|
| 22 |
if(cli) {
|
| 23 |
if (cli->hasHandshake())
|
| 24 |
{
|
|
@@ -41,7 +41,8 @@ void tcp_on_accept(hio_t* io, hevent_t* ev) {
|
|
| 41 |
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
|
| 42 |
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
|
| 43 |
|
| 44 |
-
|
|
|
|
| 45 |
|
| 46 |
hio_setcb_close(io, tcp_on_close);
|
| 47 |
hio_setcb_read(io, tcp_on_recv);
|
|
|
|
| 9 |
static void tcp_on_close(hio_t* io) {
|
| 10 |
spdlog::info("tcp_on_close fd={} error={}\n", hio_fd(io), hio_error(io));
|
| 11 |
|
| 12 |
+
auto cli = TcpConnMap<hio_t*, TcpClientBolt>::getInstance().get(io);
|
| 13 |
if(cli) {
|
| 14 |
+
TcpConnMap<hio_t*, TcpClientBolt>::getInstance().remove(io);
|
| 15 |
cli->close();
|
| 16 |
}
|
| 17 |
}
|
| 18 |
|
| 19 |
static void tcp_on_recv(hio_t* io, void* buf, int readbytes) {
|
| 20 |
spdlog::info("tcp_on_recv fd={} buf({})={}\n", hio_fd(io), readbytes, (const char*)buf);
|
| 21 |
+
auto cli = TcpConnMap<hio_t*, TcpClientBolt>::getInstance().get(io);
|
| 22 |
if(cli) {
|
| 23 |
if (cli->hasHandshake())
|
| 24 |
{
|
|
|
|
| 41 |
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
|
| 42 |
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
|
| 43 |
|
| 44 |
+
auto client = std::make_unique<TcpClientBolt>(io);
|
| 45 |
+
TcpConnMap<hio_t*, TcpClientBolt>::getInstance().add(io, client);
|
| 46 |
|
| 47 |
hio_setcb_close(io, tcp_on_close);
|
| 48 |
hio_setcb_read(io, tcp_on_recv);
|
src/udp_client.cpp
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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"
|
| 6 |
+
#include <sstream>
|
| 7 |
+
|
| 8 |
+
std::string get_key(struct sockaddr_in t_addr, struct sockaddr_in u_addr)
|
| 9 |
+
{
|
| 10 |
+
std::ostringstream string_stream;
|
| 11 |
+
string_stream << t_addr.sin_addr.s_addr << t_addr.sin_port;
|
| 12 |
+
string_stream << u_addr.sin_addr.s_addr << u_addr.sin_port;
|
| 13 |
+
return string_stream.str();
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
bool UdpServerBoltProxy::analyzeData(struct sockaddr_in t_addr, struct sockaddr_in u_addr,
|
| 17 |
+
uint32_t session_id, char *dest, int dest_len, char *extend, int extend_len)
|
| 18 |
+
{
|
| 19 |
+
auto key = get_key(t_addr, u_addr);
|
| 20 |
+
auto client = _map.get(key);
|
| 21 |
+
if (!client)
|
| 22 |
+
{
|
| 23 |
+
std::unique_ptr<UdpClientProxy> new_client = std::make_unique<UdpClientProxy>(t_addr, u_addr, session_id);
|
| 24 |
+
if (!new_client->init())
|
| 25 |
+
{
|
| 26 |
+
return false;
|
| 27 |
+
}
|
| 28 |
+
_map.add(key, new_client);
|
| 29 |
+
client = new_client.get();
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
if (getConfig().ept_type == CRYPT_TYPE::XOR)
|
| 33 |
+
{
|
| 34 |
+
xor_::crypt((char *)dest, dest_len, getConfig().ept_key);
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
client->getClient()->sendto(dest, dest_len);
|
| 38 |
+
|
| 39 |
+
return true;
|
| 40 |
+
}
|
| 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)
|
| 51 |
+
{
|
| 52 |
+
it->second->close();
|
| 53 |
+
}
|
| 54 |
+
_map.clear();
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
bool UdpClientProxy::init()
|
| 58 |
+
{
|
| 59 |
+
|
| 60 |
+
int sockfd = cli.createsocket(t_addr.sin_port, inet_ntoa(t_addr.sin_addr));
|
| 61 |
+
if (sockfd < 0)
|
| 62 |
+
{
|
| 63 |
+
return false;
|
| 64 |
+
}
|
| 65 |
+
cli.onWriteComplete = [this](const hv::SocketChannelPtr &channel, hv::Buffer *buf)
|
| 66 |
+
{
|
| 67 |
+
onWrited(channel, buf);
|
| 68 |
+
};
|
| 69 |
+
cli.onMessage = [this](const hv::SocketChannelPtr &channel, hv::Buffer *buf)
|
| 70 |
+
{
|
| 71 |
+
onRecv(channel, buf);
|
| 72 |
+
};
|
| 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)
|
| 87 |
+
{
|
| 88 |
+
spdlog::info("<<< size:{} : data: {}", (int)buf->size(), (char *)buf->data());
|
| 89 |
+
auto serverProxy = UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().get(session_id);
|
| 90 |
+
if (!serverProxy)
|
| 91 |
+
{
|
| 92 |
+
return;
|
| 93 |
+
}
|
| 94 |
+
serverProxy->sendData(t_addr, u_addr, buf->data(), buf->size());
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
void UdpClientProxy::onWrited(const hv::SocketChannelPtr &channel, hv::Buffer *buf)
|
| 98 |
+
{
|
| 99 |
+
spdlog::info(">>> size:{} : data: {}", (int)buf->size(), (char *)buf->data());
|
| 100 |
+
}
|
src/udp_inbound.cpp
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "udp_inbound.h"
|
| 2 |
+
#include "udp_client.h"
|
| 3 |
+
#include "conn_map.h"
|
| 4 |
+
#include "hv_utils.h"
|
| 5 |
+
#include "bolt/datagram.h"
|
| 6 |
+
#include "bolt/crypt.h"
|
| 7 |
+
|
| 8 |
+
void udp_on_recvfrom(hio_t *io, void *buf, int readbytes)
|
| 9 |
+
{
|
| 10 |
+
|
| 11 |
+
if (readbytes > 0)
|
| 12 |
+
{
|
| 13 |
+
UNPACK_TUNNEL_DATA(dest, dest_len, ver, res, type, t_ip, t_port, u_ip, u_port, session_id, extend, extend_len, buf, readbytes)
|
| 14 |
+
if (ver == BOLT_VERSION && res == BOLT_RESERVE)
|
| 15 |
+
{
|
| 16 |
+
if (type == BOLT_PAYLOAD_TYPE_CMD)
|
| 17 |
+
{
|
| 18 |
+
if (dest_len == 73 && dest[0] == BOLT_CHANNEL_CMD_BIND_REQUEST)
|
| 19 |
+
{
|
| 20 |
+
UNPACK_BIND_DATA(command, request_id, signal_id, session_id, data_st, dest, dest_len)
|
| 21 |
+
UdpServerBoltProxy *serverProxy = new UdpServerBoltProxy(io);
|
| 22 |
+
serverProxy->getConfig().request_id = request_id;
|
| 23 |
+
serverProxy->getConfig().session_id = session_id;
|
| 24 |
+
serverProxy->getConfig().data_st = data_st;
|
| 25 |
+
serverProxy->getConfig().signal_id = signal_id;
|
| 26 |
+
if (extend_len >= 5)
|
| 27 |
+
{
|
| 28 |
+
if (strcmp(extend, "ept=1") == 0)
|
| 29 |
+
{
|
| 30 |
+
serverProxy->getConfig().encrypt = true;
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
serverProxy->getConfig().ept_type = serverProxy->getConfig().encrypt ? CRYPT_TYPE::XOR : CRYPT_TYPE::NONE;
|
| 34 |
+
serverProxy->getConfig().ept_key = serverProxy->getConfig().encrypt ? generateRandomKey() : 0;
|
| 35 |
+
|
| 36 |
+
GENERATE_DECRYPT_KEY(extend_response, extend_response_len, serverProxy->getConfig().ept_type, serverProxy->getConfig().ept_key)
|
| 37 |
+
|
| 38 |
+
char result[1] = {BOLT_BIND_RESPONSE_CODE_SUCESS};
|
| 39 |
+
|
| 40 |
+
PACK_BIND_RESPONSE_DATA(bind_response, bind_response_len, BOLT_CHANNEL_CMD_BIND_RESPONSE, request_id, session_id, result)
|
| 41 |
+
|
| 42 |
+
PACK_TUNNEL_DATA(response, response_len, BOLT_VERSION, BOLT_RESERVE, BOLT_PAYLOAD_TYPE_CMD, 0, 0, 0, 0, session_id, extend_response, extend_response_len, bind_response, bind_response_len)
|
| 43 |
+
hio_write(io, response, response_len);
|
| 44 |
+
|
| 45 |
+
auto proxy = std::unique_ptr<UdpServerBoltProxy>(serverProxy);
|
| 46 |
+
UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().add(session_id, proxy);
|
| 47 |
+
}
|
| 48 |
+
else if (dest_len == 9 && dest[0] == BOLT_CHANNEL_CMD_UNBIND_REQUEST)
|
| 49 |
+
{
|
| 50 |
+
UNPACK_UNBIND_DATA(command, session_id, code, dest, dest_len)
|
| 51 |
+
|
| 52 |
+
auto serverProxy = UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().get(session_id);
|
| 53 |
+
serverProxy->recycle();
|
| 54 |
+
UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().remove(session_id);
|
| 55 |
+
}
|
| 56 |
+
else
|
| 57 |
+
{
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
else if (type == BOLT_PAYLOAD_TYPE_UDP)
|
| 61 |
+
{
|
| 62 |
+
|
| 63 |
+
auto serverProxy = UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().get(session_id);
|
| 64 |
+
struct sockaddr_in t_addr = {0}, u_addr = {0};
|
| 65 |
+
t_addr.sin_addr.s_addr = t_ip;
|
| 66 |
+
t_addr.sin_port = t_port;
|
| 67 |
+
u_addr.sin_addr.s_addr = u_ip;
|
| 68 |
+
u_addr.sin_port = u_port;
|
| 69 |
+
if (serverProxy && serverProxy->analyzeData(t_addr, u_addr, session_id, dest, dest_len, extend, extend_len))
|
| 70 |
+
{
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
void udp_on_writed(hio_t *io, const void *buf, int writebytes)
|
| 78 |
+
{
|
| 79 |
+
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
void udp_on_close(hio_t *io)
|
| 83 |
+
{
|
| 84 |
+
|
| 85 |
+
}
|