diff --git a/src/forwarder.hpp b/src/forwarder.hpp index 295b5133d172d4fcf4f3c09deea8538b9381077a..6a0de5b62f3fe0b4d50630625c67468a782d67f0 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 9fd0e74b8dabcad7147a7f5819563c4ce875f7e0..d6ca82fc9a7cd9abe4fbad3452050acbe77c62ae 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 e21938c7f4b11631644e23d3501407d4bb6efb06..ab591a7d568fd91bd071c31c2b15791783f65304 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 {