From d7f9371a9142fa5d2392ae46b61654b5cf1bb22e Mon Sep 17 00:00:00 2001 From: Bensong Liu <bensl@microsoft.com> Date: Wed, 29 Jul 2020 14:29:41 +0800 Subject: [PATCH] more practicial framework now --- src/forwarder.hpp | 10 +--------- src/protocols/plain.hpp | 31 ++++++++++++++++++++++++++++--- src/utils.hpp | 27 +++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/forwarder.hpp b/src/forwarder.hpp index 295b513..6a0de5b 100644 --- a/src/forwarder.hpp +++ b/src/forwarder.hpp @@ -1,7 +1,6 @@ #ifndef UDP_FORWARDER_DYN_FORWARDER_HPP_ #define UDP_FORWARDER_DYN_FORWARDER_HPP_ -#include <unordered_map> #include <rlib/sys/sio.hpp> #include "utils.hpp" @@ -10,14 +9,7 @@ using std::string; -struct ConnectionMapping { - std::unordered_map<string, fd_t> client2server; - std::unordered_multimap<fd_t, string> server2client; - static string clientInfoAsKey(string ip, uint16_t port) { - // Also works for ipv6. We just want to eliminate duplication, rather than make it easy to read. - return ip + '@' + port; - } -}; + class Forwarder { public: diff --git a/src/protocols/plain.hpp b/src/protocols/plain.hpp index 9fd0e74..d6ca82f 100644 --- a/src/protocols/plain.hpp +++ b/src/protocols/plain.hpp @@ -34,11 +34,36 @@ namespace Protocols { epoll_event events[MAX_EVENTS]; char buffer[DGRAM_BUFFER_SIZE]; // WARN: If you want to modify this program to work for both TCP and UDP, PLEASE use rlib::sockIO::recv instead of fixed buffer. - + + auto onEvent = [&](auto activeFd) { + if (activeFd == ipcPipeInboundEnd) { + // Outbound gave me a message to forward! Send it. + auto targetClientId = rlib::sockIO::recv_msg(activeFd); + auto msg = rlib::sockIO::recv_msg(activeFd); + + auto [clientAddr, clientPort] = ConnectionMapping::parseClientId(targetClientId); + + + } + else if (activeFd == listenFd) { + SockAddr clientAddr; + auto ret = recvfrom(activeFd, buffer, sizeof(buffer), 0, &clientAddr.addr, &clientAddr.len); + if (ret == -1) throw std::runtime_error("recvfrom failed. "); + + + } + + }; + rlog.info("PlainListener listening InboundPort [{}]:{} ...", listenAddr, listenPort); while (true) { - // ... - // epoll + auto nfds = epoll_wait(epollFd, events, MAX_EVENTS, -1); + if (nfds == -1) + throw std::runtime_error("epoll_wait failed."); + + for (auto cter = 0; cter < nfds; ++cter) { + onEvent(events[cter].data.fd); + } } } diff --git a/src/utils.hpp b/src/utils.hpp index e21938c..ab591a7 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -4,6 +4,7 @@ #include <rlib/sys/os.hpp> #include <rlib/sys/sio.hpp> #include <thread> +#include <unordered_map> #include "common.hpp" #if RLIB_OS_ID == OS_LINUX @@ -12,6 +13,32 @@ #include <wepoll.h> #endif +struct SockAddr { + union { + sockaddr_storage addr_storage; + sockaddr addr; + sockaddr_in in4; + sockaddr_in6 in6; + }; + int len; +}; + +struct ConnectionMapping { + std::unordered_map<string, fd_t> client2server; + std::unordered_multimap<fd_t, string> server2client; + static string makeClientId(const SockAddr &osStrust) const { + // ClientId is a binary string. + string result(sizeof(osStruct), '\0'); + std::memcpy(result.data(), &osStruct, sizeof(osStrust)); + return result; + } + static void parseClientId(const string &clientId, SockAddr &output) const { + static_assert(sizeof(output) == sizeof(SockAddr), "error: programming error detected."); + if (clientId.size() != sizeof(output)) + throw std::invalid_argument("parseClientId, invalid input binary string length."); + std::memcpy(&output, clientId.data(), sizeof(output)); + } +}; inline void epoll_add_fd(fd_t epollFd, fd_t fd) { epoll_event event { -- GitLab