|
|
|
@ -8,16 +8,34 @@ |
|
|
|
|
#include <bakanet.h> |
|
|
|
|
#include <cerrno> |
|
|
|
|
#include <cstdarg> |
|
|
|
|
#include <cstddef> |
|
|
|
|
#include <cstdio> |
|
|
|
|
#include <functional> |
|
|
|
|
#include <sys/epoll.h> |
|
|
|
|
#include <thread> |
|
|
|
|
#include <tuple> |
|
|
|
|
#include <vector> |
|
|
|
|
|
|
|
|
|
#include "config.h" |
|
|
|
|
#include <string> |
|
|
|
|
|
|
|
|
|
#define CREATE_MAPPING(var, ...) std::vector<std::pair<std::string, std::string>> var = { __VA_ARGS__ } |
|
|
|
|
#define MAKE_RANGE(var, ...) range ( var, __VA_ARGS__) |
|
|
|
|
#define BIND(listener, target) { listener, target } |
|
|
|
|
|
|
|
|
|
#define MAX_EVENTS 10 |
|
|
|
|
#define MAX_CONNECTOR_WORKERS 8 |
|
|
|
|
#define MAX_LISTENER_CONNECTION 50 |
|
|
|
|
#define MAX_PACKET_SIZE 64000 |
|
|
|
|
|
|
|
|
|
using namespace Bk; |
|
|
|
|
using namespace Bk::Net; |
|
|
|
|
|
|
|
|
|
void range(std::vector<std::pair<std::string, std::string>>& binds, std::string listener, std::string target, int min, int max)
|
|
|
|
|
{
|
|
|
|
|
for(int i = min; i <= max; i++)
|
|
|
|
|
binds.push_back({ listener + ":" + std::to_string(i), target + ":" + std::to_string(i) });
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int setnonblocking(int sock) |
|
|
|
|
{ |
|
|
|
|
int result; |
|
|
|
@ -39,10 +57,10 @@ int setnonblocking(int sock) |
|
|
|
|
struct Binder
|
|
|
|
|
{ |
|
|
|
|
Scope<Socket> src;
|
|
|
|
|
u16 listener = 0; |
|
|
|
|
u16 target = 0; |
|
|
|
|
std::tuple<std::string, u16> listener; |
|
|
|
|
std::tuple<std::string, u16> target; |
|
|
|
|
|
|
|
|
|
Binder(Socket* src, u16 listener, u16 target) |
|
|
|
|
Binder(Socket* src, std::tuple<std::string, u16> listener, std::tuple<std::string, u16> target) |
|
|
|
|
:src(src), listener(listener), target(target) { } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -141,7 +159,7 @@ class Connector |
|
|
|
|
ePoll.on(PollEvent::Closed, [this](int fd) |
|
|
|
|
{ |
|
|
|
|
int i = findBridge(fd); |
|
|
|
|
BK_INFO("Deleting bridge N° {0} - Remaining bridges {1}", i, bridges.size() -1); |
|
|
|
|
BK_INFO("Deleted bridge N° {0} - Remaining bridges {1}\n", i, bridges.size() -1); |
|
|
|
|
if(i > -1) bridges.erase(bridges.begin() + i); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
@ -204,6 +222,7 @@ class Connector |
|
|
|
|
ePoll.add(bridge.downstream->get_raw_socket(), 2, PollEvent::Readable, PollEvent::Closed); |
|
|
|
|
bridges.push_back(std::move(bridge)); |
|
|
|
|
} |
|
|
|
|
BK_INFO("Added bridge - Total bridges {0}\n", bridges.size() - 1); |
|
|
|
|
condition.notify_one(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -219,26 +238,44 @@ class Connector |
|
|
|
|
std::vector<Bridge> bridges; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class Initiator
|
|
|
|
|
std::tuple<std::string, u32> parseConnection(std::string conn) |
|
|
|
|
{ |
|
|
|
|
size_t pos = conn.find_first_of(":"); |
|
|
|
|
if(pos != std::string::npos) { |
|
|
|
|
auto ip = conn.substr(0, pos); |
|
|
|
|
auto port = std::stoi(conn.substr(pos + 1, conn.length())); |
|
|
|
|
return std::tuple(ip, port); |
|
|
|
|
} else if (conn.length()) return std::tuple("", std::stoi(conn.substr(0, conn.length()))); |
|
|
|
|
return std::tuple("", 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class TcpProxy
|
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
Initiator(const std::map<Bk::u16, Bk::u16>& portBinds) |
|
|
|
|
TcpProxy(const std::vector<std::pair<std::string, std::string>>& proxyBinds) |
|
|
|
|
{ |
|
|
|
|
IpAddress src; |
|
|
|
|
binds.reserve(portBinds.size()); |
|
|
|
|
|
|
|
|
|
BK_INFO("Starting binds (count: {0})", portBinds.size()); |
|
|
|
|
binds.reserve(proxyBinds.size()); |
|
|
|
|
BK_INFO("Starting binds (count: {0})", proxyBinds.size()); |
|
|
|
|
int i = 0; |
|
|
|
|
for (auto& portBind : portBinds) |
|
|
|
|
for (auto& proxyBind : proxyBinds) |
|
|
|
|
{ |
|
|
|
|
BK_INFO("{2}. Buiding binder on port {0}:{1}", portBind.first, portBind.second, i + 1); |
|
|
|
|
std::tuple<std::string, u16> listener = parseConnection(proxyBind.first); |
|
|
|
|
std::tuple<std::string, u16> target = parseConnection(proxyBind.second); |
|
|
|
|
BK_INFO("{0}. Buiding binder [{1}:{2}] -> [{3}:{4}]",
|
|
|
|
|
i + 1,
|
|
|
|
|
std::get<0>(listener),
|
|
|
|
|
std::get<1>(listener),
|
|
|
|
|
std::get<0>(target),
|
|
|
|
|
std::get<1>(target) |
|
|
|
|
); |
|
|
|
|
binds.insert(binds.begin() + i, Binder( |
|
|
|
|
Socket::create(src, portBind.first, IpProtocol::TCP),
|
|
|
|
|
portBind.first,
|
|
|
|
|
portBind.second) |
|
|
|
|
Socket::create(std::get<0>(listener), std::get<1>(listener), IpProtocol::TCP),
|
|
|
|
|
listener,
|
|
|
|
|
target |
|
|
|
|
) |
|
|
|
|
); |
|
|
|
|
BK_ASSERT(binds[i].src->init()); |
|
|
|
|
BK_ASSERT(binds[i].src->start(10)); |
|
|
|
|
BK_ASSERT(binds[i].src->start(MAX_LISTENER_CONNECTION)); |
|
|
|
|
ePoll.add(binds[i].src->get_raw_socket(), 1, PollEvent::Accept); |
|
|
|
|
i++; |
|
|
|
|
} |
|
|
|
@ -247,15 +284,16 @@ class Initiator |
|
|
|
|
{ |
|
|
|
|
auto& bind = binds[findBinder(fd)]; |
|
|
|
|
Socket* conn = bind.src->ack(); |
|
|
|
|
Socket* target = Socket::create(IpAddress(TARGET), bind.target, IpProtocol::TCP); |
|
|
|
|
Socket* target = Socket::create(IpAddress(std::get<0>(bind.target)), std::get<1>(bind.target), IpProtocol::TCP); |
|
|
|
|
BK_INFO("New connection"); |
|
|
|
|
BK_INFO("Connection info :"); |
|
|
|
|
BK_INFO("PORT BIND [{0}:{1}]", bind.listener, bind.target); |
|
|
|
|
BK_INFO("TARGET [{0} ({1})]", target->get_ip(), target->get_raw_socket() > 0 ? "Alive" : "Dead"); |
|
|
|
|
BK_INFO("CLIENT [{0} ({1})] ", conn->get_ip(), conn->get_raw_socket() > 0 ? "Alive" : "Dead"); |
|
|
|
|
BK_INFO("PORT BIND [{0}:{1}]", std::get<1>(bind.listener), std::get<1>(bind.target)); |
|
|
|
|
BK_INFO("TARGET [{0}]", target->get_ip()); |
|
|
|
|
BK_INFO("LISTENER [{0}]", bind.src->get_ip()); |
|
|
|
|
BK_INFO("CLIENT [{0}]", conn->get_ip()); |
|
|
|
|
setnonblocking(conn->get_raw_socket()); |
|
|
|
|
if(connectorPtr >= connectors.size()) connectorPtr = 0; |
|
|
|
|
BK_INFO("Forwarding to connector N°{0}", connectorPtr); |
|
|
|
|
BK_INFO("Forwarding to connector N°{0}\n", connectorPtr); |
|
|
|
|
connectors[connectorPtr].add(Bridge(target, conn)); |
|
|
|
|
connectorPtr++; |
|
|
|
|
}); |
|
|
|
@ -281,6 +319,7 @@ class Initiator |
|
|
|
|
BK_INFO("Starting connector N°{0}", connectorPtr); |
|
|
|
|
connector.start(); |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
while (running) { |
|
|
|
|
ePoll.wait(); |
|
|
|
|
}
|
|
|
|
@ -290,21 +329,33 @@ class Initiator |
|
|
|
|
bool running = false; |
|
|
|
|
std::vector<Binder> binds; |
|
|
|
|
EventPoll ePoll; |
|
|
|
|
std::array<Connector, MAX_CONNECTIOR_WORKERS> connectors; |
|
|
|
|
std::array<Connector, MAX_CONNECTOR_WORKERS> connectors; |
|
|
|
|
int connectorPtr = 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
int main() |
|
|
|
|
{
|
|
|
|
|
Log::Init("Bakanet"); |
|
|
|
|
// BK_INFO("Epoll events types");
|
|
|
|
|
// BK_INFO("EPOLLIN {0} {0:b}", (u32)EPOLLIN);
|
|
|
|
|
// BK_INFO("EPOLLOUT {0} {0:b}", (u32)EPOLLOUT);
|
|
|
|
|
// BK_INFO("EPOLLET {0} {0:b}", (u32)EPOLLET);
|
|
|
|
|
// BK_INFO("EPOLLHUP {0} {0:b}", (u32)EPOLLHUP);
|
|
|
|
|
// BK_INFO("EPOLLERR {0} {0:b}", (u32)EPOLLERR);
|
|
|
|
|
// BK_INFO("EPOLLRDHUP {0} {0:b}", (u32)EPOLLRDHUP);
|
|
|
|
|
Initiator initiator(portBinds); |
|
|
|
|
BK_INFO("Epoll events types"); |
|
|
|
|
BK_INFO("EPOLLIN {0} {0:b}", (u32)EPOLLIN); |
|
|
|
|
BK_INFO("EPOLLOUT {0} {0:b}", (u32)EPOLLOUT); |
|
|
|
|
BK_INFO("EPOLLET {0} {0:b}", (u32)EPOLLET); |
|
|
|
|
BK_INFO("EPOLLHUP {0} {0:b}", (u32)EPOLLHUP); |
|
|
|
|
BK_INFO("EPOLLERR {0} {0:b}", (u32)EPOLLERR); |
|
|
|
|
BK_INFO("EPOLLRDHUP {0} {0:b}", (u32)EPOLLRDHUP); |
|
|
|
|
printf("\n"); |
|
|
|
|
|
|
|
|
|
CREATE_MAPPING(proxyBinds,
|
|
|
|
|
BIND("192.168.1.128:25000", "192.168.1.128:25001"), |
|
|
|
|
BIND("192.168.1.128:25001", "192.168.1.128:25002"), |
|
|
|
|
BIND("192.168.1.128:25002", "192.168.1.128:25003"), |
|
|
|
|
BIND("192.168.1.128:25003", "192.168.1.128:25004"), |
|
|
|
|
BIND("192.168.1.128:25004", "192.168.1.128:25005"), |
|
|
|
|
BIND("192.168.1.128:25005", "192.168.1.128:25006"), |
|
|
|
|
BIND("192.168.1.128:25006", "192.168.1.128:25007"), |
|
|
|
|
BIND("192.168.1.128:25007", "192.168.1.159:22") |
|
|
|
|
); |
|
|
|
|
TcpProxy initiator(proxyBinds); |
|
|
|
|
initiator.start(); |
|
|
|
|
return 0; |
|
|
|
|
} |