Loading src/CMakeLists.txt +4 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ list(APPEND netplussrc crypto/rc4.cpp crypto/rsa.cpp crypto/x509.cpp crypto/ecc_u256.cpp crypto/ecc_p256.cpp ) if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") Loading Loading @@ -53,6 +55,8 @@ set(headers crypto/rc4.h crypto/rsa.h crypto/x509.h crypto/ecc_u256.h crypto/ecc_p256.h ) add_library(netplus SHARED ${netplussrc} ${headers}) Loading src/posix/socket.cpp +14 −4 Original line number Diff line number Diff line Loading @@ -69,10 +69,14 @@ void netplus::socket::close() { } void socket::setFlag(int flag, int value) { int sockopts = ::fcntl(_Socket, F_GETFL, 0); int sockopts; do { sockopts = ::fcntl(_Socket, F_GETFL, 0); } while (sockopts < 0 && errno == EINTR); if (sockopts < 0) { NetException e; e[NetException::Error] << "fcntl(F_GETFL) failed"; e[NetException::Error] << "fcntl(F_GETFL) failed: " << strerror(errno); throw e; } Loading @@ -81,13 +85,19 @@ void socket::setFlag(int flag, int value) { else sockopts &= ~flag; if (::fcntl(_Socket, F_SETFL, sockopts) < 0) { int r; do { r = ::fcntl(_Socket, F_SETFL, sockopts); } while (r < 0 && errno == EINTR); if (r < 0) { NetException e; e[NetException::Error] << "fcntl(F_SETFL) failed"; e[NetException::Error] << "fcntl(F_SETFL) failed: " << strerror(errno); throw e; } } void socket::setTimeout(int msec) { timeval timeout{}; timeout.tv_sec = msec / 1000; Loading src/posix/tcp.cpp +56 −22 Original line number Diff line number Diff line Loading @@ -159,6 +159,10 @@ void tcp::setNonBlock() { setFlag(O_NONBLOCK, 1); } void tcp::setBlock() { setFlag(O_NONBLOCK, 0); } int tcp::getMaxconnections() { return _Maxconnections; } Loading Loading @@ -210,8 +214,12 @@ size_t tcp::recvData(buffer& data, int flags) { data.size = (size_t)r; return (size_t)r; } if (r == 0) return 0; if (r == 0) { NetException e; e[NetException::Error] << "tcp::recvData peer closed (EOF)"; throw e; } if (errno == EAGAIN || errno == EWOULDBLOCK) { NetException e; Loading Loading @@ -247,55 +255,81 @@ void netplus::tcp::connect(const std::string& addr, int port, bool nonblock) for (addrinfo* rp = result; rp; rp = rp->ai_next) { // socket erstellen, falls noch keiner existiert oder family mismatch // ------------------------------------------------------- // 1) ensure socket exists and matches family // ------------------------------------------------------- if (_Socket >= 0) { // if family mismatch, close and recreate sockaddr_storage tmp{}; socklen_t tmpLen = sizeof(tmp); if (::getsockname(_Socket, (sockaddr*)&tmp, &tmpLen) == 0) { if (tmp.ss_family != rp->ai_family) { ::close(_Socket); _Socket = -1; } } } if (_Socket < 0) { _Socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (_Socket < 0) continue; } if (nonblock) // ------------------------------------------------------- // 2) set nonblock BEFORE connect() if requested // ------------------------------------------------------- if (nonblock) { try { setNonBlock(); } catch (...) { ::close(_Socket); _Socket = -1; continue; } } // optional: SO_REUSEADDR (bei client meistens egal aber ok) int opt = 1; ::setsockopt(_Socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // connect // ------------------------------------------------------- // 3) connect() // ------------------------------------------------------- if (::connect(_Socket, rp->ai_addr, rp->ai_addrlen) == 0) { // ✅ sofort verbunden copyAddrInfo(&_SocketInfo, reinterpret_cast<ULONG_PTR>(rp), sizeof(addrinfo)); _SocketInfoLen = rp->ai_addrlen; // ✅ connected immediately setAddrFromAI(rp); ::freeaddrinfo(result); return; } // nonblocking connect -> EINPROGRESS ist ok if (nonblock && errno == EINPROGRESS) { copyAddrInfo(&_SocketInfo, reinterpret_cast<ULONG_PTR>(rp), sizeof(addrinfo)); _SocketInfoLen = rp->ai_addrlen; // ------------------------------------------------------- // 4) nonblocking in progress // ------------------------------------------------------- if (nonblock && (errno == EINPROGRESS || errno == EWOULDBLOCK)) { setAddrFromAI(rp); ::freeaddrinfo(result); NetException n; n[NetException::Note] << "tcp::connect: EINPROGRESS"; throw n; // du wartest auf EPOLLOUT throw n; // caller waits EPOLLOUT/select } // echter Fehler // ------------------------------------------------------- // 5) fatal error -> try next addrinfo // ------------------------------------------------------- ::close(_Socket); _Socket = -1; } ::freeaddrinfo(result); exception[NetException::Error] << "tcp::connect: could not connect to " exception[NetException::Error] << "tcp::connect: could not connect to " << addr << ":" << port << " (" << strerror(errno) << ")"; throw exception; } void tcp::getAddress(std::string& addr) { char buf[INET6_ADDRSTRLEN]{}; Loading src/posix/udp.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,10 @@ void udp::setNonBlock() { setFlag(O_NONBLOCK, 1); } void udp::setBlock() { setFlag(O_NONBLOCK, 0); } int udp::getMaxconnections() { return _Maxconnections; } Loading src/socket.h +23 −4 Original line number Diff line number Diff line Loading @@ -158,6 +158,7 @@ namespace netplus { virtual void accept(std::unique_ptr<socket>& csock,bool nonblock) = 0; virtual void handshake_after_accept(){}; virtual void handshake_after_connect(){}; #ifdef Windows virtual void accept(LPFN_ACCEPTEX lpfnAcceptEx, std::unique_ptr<socket>& csock, buffer& data) = 0; Loading @@ -170,6 +171,7 @@ namespace netplus { virtual void bind() = 0; virtual void listen() = 0; virtual void setNonBlock() = 0; virtual void setBlock()=0; virtual int getMaxconnections() = 0; Loading Loading @@ -248,6 +250,7 @@ namespace netplus { void bind() override; void listen() override; void setNonBlock() override; void setBlock() override; netplus::tcp& operator=(SOCKET sock) override; int getMaxconnections() override; Loading Loading @@ -286,6 +289,7 @@ namespace netplus { void bind() override; void listen() override; void setNonBlock() override; void setBlock() override; udp& operator=(SOCKET socket) override; int getMaxconnections() override; Loading Loading @@ -315,6 +319,7 @@ namespace netplus { void accept(std::unique_ptr<socket>& csock,bool nonblock) override; void handshake_after_accept() override; void handshake_after_connect() override; void connect(const std::string& addr, int port, bool nonblock = false) override; void close() override; Loading Loading @@ -345,7 +350,6 @@ namespace netplus { void flush_out() override; std::vector<uint8_t> readTlsRecordAsync(); std::vector<uint8_t> readHandshakeMessageAsync(); void resetTLS(); Loading Loading @@ -414,7 +418,7 @@ namespace netplus { netplus::x509cert _peer_cert; std::shared_ptr<netplus::x509cert> _cert; netplus::rsa _rsa; std::string _hostname; bool _secure_reneg = true; uint16_t _chosenSuite = 0x002F; bool _ccs_received = false; Loading Loading @@ -453,16 +457,30 @@ namespace netplus { bool _client_offered_tls13 = false; void _queueClientHello(); enum class HsState { // server READ_CLIENT_HELLO, SEND_SERVER_FLIGHT, WAIT_CKE, WAIT_CCS, WAIT_FIN, SEND_CCS_FIN, // client CLI_FLUSH_CH, CLI_WAIT_SERVER_HELLO, CLI_WAIT_CERT, CLI_WAIT_SHD, CLI_SEND_CKE, CLI_SEND_CCS_FIN, CLI_WAIT_SCCS, CLI_WAIT_SFIN, DONE, FAIL, IDLE, READ_CLIENT_HELLO IDLE }; HsState _hs_state = HsState::READ_CLIENT_HELLO; Loading @@ -471,6 +489,7 @@ namespace netplus { std::vector<uint8_t> _handshake_transcript; bool _handshakeDone; bool _is_server = true; friend class poll; friend class event; Loading Loading
src/CMakeLists.txt +4 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ list(APPEND netplussrc crypto/rc4.cpp crypto/rsa.cpp crypto/x509.cpp crypto/ecc_u256.cpp crypto/ecc_p256.cpp ) if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") Loading Loading @@ -53,6 +55,8 @@ set(headers crypto/rc4.h crypto/rsa.h crypto/x509.h crypto/ecc_u256.h crypto/ecc_p256.h ) add_library(netplus SHARED ${netplussrc} ${headers}) Loading
src/posix/socket.cpp +14 −4 Original line number Diff line number Diff line Loading @@ -69,10 +69,14 @@ void netplus::socket::close() { } void socket::setFlag(int flag, int value) { int sockopts = ::fcntl(_Socket, F_GETFL, 0); int sockopts; do { sockopts = ::fcntl(_Socket, F_GETFL, 0); } while (sockopts < 0 && errno == EINTR); if (sockopts < 0) { NetException e; e[NetException::Error] << "fcntl(F_GETFL) failed"; e[NetException::Error] << "fcntl(F_GETFL) failed: " << strerror(errno); throw e; } Loading @@ -81,13 +85,19 @@ void socket::setFlag(int flag, int value) { else sockopts &= ~flag; if (::fcntl(_Socket, F_SETFL, sockopts) < 0) { int r; do { r = ::fcntl(_Socket, F_SETFL, sockopts); } while (r < 0 && errno == EINTR); if (r < 0) { NetException e; e[NetException::Error] << "fcntl(F_SETFL) failed"; e[NetException::Error] << "fcntl(F_SETFL) failed: " << strerror(errno); throw e; } } void socket::setTimeout(int msec) { timeval timeout{}; timeout.tv_sec = msec / 1000; Loading
src/posix/tcp.cpp +56 −22 Original line number Diff line number Diff line Loading @@ -159,6 +159,10 @@ void tcp::setNonBlock() { setFlag(O_NONBLOCK, 1); } void tcp::setBlock() { setFlag(O_NONBLOCK, 0); } int tcp::getMaxconnections() { return _Maxconnections; } Loading Loading @@ -210,8 +214,12 @@ size_t tcp::recvData(buffer& data, int flags) { data.size = (size_t)r; return (size_t)r; } if (r == 0) return 0; if (r == 0) { NetException e; e[NetException::Error] << "tcp::recvData peer closed (EOF)"; throw e; } if (errno == EAGAIN || errno == EWOULDBLOCK) { NetException e; Loading Loading @@ -247,55 +255,81 @@ void netplus::tcp::connect(const std::string& addr, int port, bool nonblock) for (addrinfo* rp = result; rp; rp = rp->ai_next) { // socket erstellen, falls noch keiner existiert oder family mismatch // ------------------------------------------------------- // 1) ensure socket exists and matches family // ------------------------------------------------------- if (_Socket >= 0) { // if family mismatch, close and recreate sockaddr_storage tmp{}; socklen_t tmpLen = sizeof(tmp); if (::getsockname(_Socket, (sockaddr*)&tmp, &tmpLen) == 0) { if (tmp.ss_family != rp->ai_family) { ::close(_Socket); _Socket = -1; } } } if (_Socket < 0) { _Socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (_Socket < 0) continue; } if (nonblock) // ------------------------------------------------------- // 2) set nonblock BEFORE connect() if requested // ------------------------------------------------------- if (nonblock) { try { setNonBlock(); } catch (...) { ::close(_Socket); _Socket = -1; continue; } } // optional: SO_REUSEADDR (bei client meistens egal aber ok) int opt = 1; ::setsockopt(_Socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // connect // ------------------------------------------------------- // 3) connect() // ------------------------------------------------------- if (::connect(_Socket, rp->ai_addr, rp->ai_addrlen) == 0) { // ✅ sofort verbunden copyAddrInfo(&_SocketInfo, reinterpret_cast<ULONG_PTR>(rp), sizeof(addrinfo)); _SocketInfoLen = rp->ai_addrlen; // ✅ connected immediately setAddrFromAI(rp); ::freeaddrinfo(result); return; } // nonblocking connect -> EINPROGRESS ist ok if (nonblock && errno == EINPROGRESS) { copyAddrInfo(&_SocketInfo, reinterpret_cast<ULONG_PTR>(rp), sizeof(addrinfo)); _SocketInfoLen = rp->ai_addrlen; // ------------------------------------------------------- // 4) nonblocking in progress // ------------------------------------------------------- if (nonblock && (errno == EINPROGRESS || errno == EWOULDBLOCK)) { setAddrFromAI(rp); ::freeaddrinfo(result); NetException n; n[NetException::Note] << "tcp::connect: EINPROGRESS"; throw n; // du wartest auf EPOLLOUT throw n; // caller waits EPOLLOUT/select } // echter Fehler // ------------------------------------------------------- // 5) fatal error -> try next addrinfo // ------------------------------------------------------- ::close(_Socket); _Socket = -1; } ::freeaddrinfo(result); exception[NetException::Error] << "tcp::connect: could not connect to " exception[NetException::Error] << "tcp::connect: could not connect to " << addr << ":" << port << " (" << strerror(errno) << ")"; throw exception; } void tcp::getAddress(std::string& addr) { char buf[INET6_ADDRSTRLEN]{}; Loading
src/posix/udp.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,10 @@ void udp::setNonBlock() { setFlag(O_NONBLOCK, 1); } void udp::setBlock() { setFlag(O_NONBLOCK, 0); } int udp::getMaxconnections() { return _Maxconnections; } Loading
src/socket.h +23 −4 Original line number Diff line number Diff line Loading @@ -158,6 +158,7 @@ namespace netplus { virtual void accept(std::unique_ptr<socket>& csock,bool nonblock) = 0; virtual void handshake_after_accept(){}; virtual void handshake_after_connect(){}; #ifdef Windows virtual void accept(LPFN_ACCEPTEX lpfnAcceptEx, std::unique_ptr<socket>& csock, buffer& data) = 0; Loading @@ -170,6 +171,7 @@ namespace netplus { virtual void bind() = 0; virtual void listen() = 0; virtual void setNonBlock() = 0; virtual void setBlock()=0; virtual int getMaxconnections() = 0; Loading Loading @@ -248,6 +250,7 @@ namespace netplus { void bind() override; void listen() override; void setNonBlock() override; void setBlock() override; netplus::tcp& operator=(SOCKET sock) override; int getMaxconnections() override; Loading Loading @@ -286,6 +289,7 @@ namespace netplus { void bind() override; void listen() override; void setNonBlock() override; void setBlock() override; udp& operator=(SOCKET socket) override; int getMaxconnections() override; Loading Loading @@ -315,6 +319,7 @@ namespace netplus { void accept(std::unique_ptr<socket>& csock,bool nonblock) override; void handshake_after_accept() override; void handshake_after_connect() override; void connect(const std::string& addr, int port, bool nonblock = false) override; void close() override; Loading Loading @@ -345,7 +350,6 @@ namespace netplus { void flush_out() override; std::vector<uint8_t> readTlsRecordAsync(); std::vector<uint8_t> readHandshakeMessageAsync(); void resetTLS(); Loading Loading @@ -414,7 +418,7 @@ namespace netplus { netplus::x509cert _peer_cert; std::shared_ptr<netplus::x509cert> _cert; netplus::rsa _rsa; std::string _hostname; bool _secure_reneg = true; uint16_t _chosenSuite = 0x002F; bool _ccs_received = false; Loading Loading @@ -453,16 +457,30 @@ namespace netplus { bool _client_offered_tls13 = false; void _queueClientHello(); enum class HsState { // server READ_CLIENT_HELLO, SEND_SERVER_FLIGHT, WAIT_CKE, WAIT_CCS, WAIT_FIN, SEND_CCS_FIN, // client CLI_FLUSH_CH, CLI_WAIT_SERVER_HELLO, CLI_WAIT_CERT, CLI_WAIT_SHD, CLI_SEND_CKE, CLI_SEND_CCS_FIN, CLI_WAIT_SCCS, CLI_WAIT_SFIN, DONE, FAIL, IDLE, READ_CLIENT_HELLO IDLE }; HsState _hs_state = HsState::READ_CLIENT_HELLO; Loading @@ -471,6 +489,7 @@ namespace netplus { std::vector<uint8_t> _handshake_transcript; bool _handshakeDone; bool _is_server = true; friend class poll; friend class event; Loading