Loading src/posix/socket.cpp +10 −3 Original line number Diff line number Diff line Loading @@ -106,9 +106,16 @@ void socket::setTimeout(int msec) { } } void socket::copyAddrInfo(ULONG_PTR* dest, ULONG_PTR src, size_t srclen) { // legacy (unused in new POSIX code) std::memcpy((void*)*dest, (void*)src, srclen); void netplus::socket::copyAddrInfo(ULONG_PTR* dest, ULONG_PTR src, size_t){ auto* s = reinterpret_cast<addrinfo*>(src); if (!s || !s->ai_addr || s->ai_addrlen <= 0) return; // store sockaddr in _Addr (sockaddr_storage) std::memset(&_Addr, 0, sizeof(_Addr)); std::memcpy(&_Addr, s->ai_addr, std::min<size_t>(sizeof(_Addr), s->ai_addrlen)); _AddrLen = (socklen_t)s->ai_addrlen; } } // namespace netplus src/posix/tcp.cpp +70 −8 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace netplus { tcp::tcp() : socket() { _Socket = ::socket(0,SOCK_STREAM,IPPROTO_TCP); _Socket = -1; _Type = sockettype::TCP; } Loading Loading @@ -224,14 +224,76 @@ size_t tcp::recvData(buffer& data, int flags) { throw e; } void tcp::connect(std::unique_ptr<socket>& srvsock) { if (::connect(_Socket, reinterpret_cast<sockaddr*>(&srvsock->_Addr), srvsock->_AddrLen) < 0) { NetException e; e[NetException::Error] << "tcp::connect failed: " << strerror(errno); throw e; void netplus::tcp::connect(const std::string& addr, int port, bool nonblock) { NetException exception; addrinfo hints{}; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; addrinfo* result = nullptr; char serv[32]; std::snprintf(serv, sizeof(serv), "%d", port); int gai = ::getaddrinfo(addr.c_str(), serv, &hints, &result); if (gai != 0) { exception[NetException::Error] << "tcp::connect: getaddrinfo failed: " << gai_strerror(gai); throw exception; } for (addrinfo* rp = result; rp; rp = rp->ai_next) { // socket erstellen, falls noch keiner existiert oder family mismatch if (_Socket < 0) { _Socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (_Socket < 0) continue; } if (nonblock) setNonBlock(); // optional: SO_REUSEADDR (bei client meistens egal aber ok) int opt = 1; ::setsockopt(_Socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // 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; ::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; ::freeaddrinfo(result); NetException n; n[NetException::Note] << "tcp::connect: EINPROGRESS"; throw n; // du wartest auf EPOLLOUT } // echter Fehler ::close(_Socket); _Socket = -1; } ::freeaddrinfo(result); exception[NetException::Error] << "tcp::connect: could not connect to " << addr << ":" << port << " (" << strerror(errno) << ")"; throw exception; } void tcp::getAddress(std::string& addr) { Loading src/posix/udp.cpp +54 −9 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace netplus { udp::udp() : socket() { _Socket = _Socket = ::socket(0,SOCK_DGRAM,IPPROTO_UDP); _Socket = -1; _Type = sockettype::UDP; } Loading Loading @@ -209,15 +209,60 @@ size_t udp::recvData(buffer& data, int flags) { throw e; } void udp::connect(std::unique_ptr<socket>& srvsock) { // UDP connect optional if (::connect(_Socket, reinterpret_cast<sockaddr*>(&srvsock->_Addr), srvsock->_AddrLen) < 0) { NetException e; e[NetException::Error] << "udp::connect failed: " << strerror(errno); throw e; void netplus::udp::connect(const std::string& addr, int port,bool ){ NetException exception; addrinfo hints{}; hints.ai_family = AF_UNSPEC; // IPv4 oder IPv6 hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; addrinfo* result = nullptr; char serv[32]; std::snprintf(serv, sizeof(serv), "%d", port); int gai = ::getaddrinfo(addr.c_str(), serv, &hints, &result); if (gai != 0) { exception[NetException::Error] << "udp::connect: getaddrinfo failed: " << gai_strerror(gai); throw exception; } for (addrinfo* rp = result; rp; rp = rp->ai_next) { // ✅ Socket erstellen falls nicht da if (_Socket < 0) { _Socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (_Socket < 0) continue; } // ✅ connect UDP (bindet Default Peer) if (::connect(_Socket, rp->ai_addr, rp->ai_addrlen) == 0) { // ✅ Adresse sauber speichern (deep copy) copyAddrInfo(&_SocketInfo, reinterpret_cast<ULONG_PTR>(rp), sizeof(addrinfo)); _SocketInfoLen = rp->ai_addrlen; ::freeaddrinfo(result); return; } // Fehler -> neuen Socket versuchen ::close(_Socket); _Socket = -1; } ::freeaddrinfo(result); exception[NetException::Error] << "udp::connect: could not connect to " << addr << ":" << port << " (" << strerror(errno) << ")"; throw exception; } void udp::getAddress(std::string& addr) { Loading src/socket.h +23 −22 Original line number Diff line number Diff line Loading @@ -179,7 +179,7 @@ namespace netplus { virtual bool hasPendingWrite() const { return false; } virtual bool getHandshakeDone() { return true; } virtual void connect(std::unique_ptr<socket>& csock) = 0; virtual void connect(const std::string& addr, int port, bool nonblock = false) = 0; virtual void getAddress(std::string& addr) = 0; SOCKET fd(); Loading Loading @@ -244,19 +244,20 @@ namespace netplus { void prime_read(buffer& data); #endif void accept(std::unique_ptr<socket>& csock,bool nonblock); void bind(); void listen(); void setNonBlock(); netplus::tcp& operator=(SOCKET sock); void accept(std::unique_ptr<socket>& csock,bool nonblock) override; void bind() override; void listen() override; void setNonBlock() override; netplus::tcp& operator=(SOCKET sock) override; int getMaxconnections() override; int getMaxconnections(); size_t sendData(buffer& data, int flags = 0) override; size_t recvData(buffer& data, int flags = 0) override; size_t sendData(buffer& data, int flags = 0); size_t recvData(buffer& data, int flags = 0); void connect(const std::string& addr, int port, bool nonblock = false) override; virtual void connect(std::unique_ptr<socket>& srvsock); void getAddress(std::string& addr); void getAddress(std::string& addr) override; private: int _Maxconnections; Loading @@ -273,7 +274,7 @@ namespace netplus { udp(const std::string& addr, int port, int maxconnections,int sockopts); ~udp(); void accept(std::unique_ptr<socket>& csock,bool nonblock); void accept(std::unique_ptr<socket>& csock,bool nonblock) override; #ifdef Windows void accept(LPFN_ACCEPTEX lpfnAcceptEx, std::unique_ptr<socket>& csock, buffer& data); Loading @@ -282,18 +283,18 @@ namespace netplus { void prime_read(buffer& data); #endif void bind(); void listen(); void setNonBlock(); void bind() override; void listen() override; void setNonBlock() override; udp& operator=(SOCKET socket); int getMaxconnections(); udp& operator=(SOCKET socket) override; int getMaxconnections() override; size_t sendData(buffer& data, int flags = 0); size_t recvData(buffer& data, int flags = 0); size_t sendData(buffer& data, int flags = 0) override; size_t recvData(buffer& data, int flags = 0) override; void connect(std::unique_ptr<socket>& srvsock); void getAddress(std::string& addr); void connect(const std::string& addr, int port, bool nonblock = false) override; void getAddress(std::string& addr) override; private: int _Maxconnections; Loading @@ -314,7 +315,7 @@ namespace netplus { void accept(std::unique_ptr<socket>& csock,bool nonblock) override; void handshake_after_accept() override; void connect(std::unique_ptr<socket>& srvsock) override; void connect(const std::string& addr, int port, bool nonblock = false) override; void close() override; size_t sendData(buffer& data, int flags = 0) override; Loading src/ssl.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1767,7 +1767,7 @@ void netplus::ssl::accept(LPFN_ACCEPTEX lpfnAcceptEx, std::unique_ptr<socket>& c } #endif void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) void netplus::ssl::connect(const std::string& addr, int port, bool nonblock) { auto throwSSL = [&](int type, const std::string& msg) { netplus::NetException e; Loading @@ -1780,7 +1780,7 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) // ------------------------------------------------------------ // "this" is the real IO socket (the one the caller uses for send/recv). // srvsock holds the target config (addr/port/opts). tcp::connect(srvsock); tcp::connect(addr,port,nonblock); // ------------------------------------------------------------ // 1) Reset TLS state on THIS object Loading Loading
src/posix/socket.cpp +10 −3 Original line number Diff line number Diff line Loading @@ -106,9 +106,16 @@ void socket::setTimeout(int msec) { } } void socket::copyAddrInfo(ULONG_PTR* dest, ULONG_PTR src, size_t srclen) { // legacy (unused in new POSIX code) std::memcpy((void*)*dest, (void*)src, srclen); void netplus::socket::copyAddrInfo(ULONG_PTR* dest, ULONG_PTR src, size_t){ auto* s = reinterpret_cast<addrinfo*>(src); if (!s || !s->ai_addr || s->ai_addrlen <= 0) return; // store sockaddr in _Addr (sockaddr_storage) std::memset(&_Addr, 0, sizeof(_Addr)); std::memcpy(&_Addr, s->ai_addr, std::min<size_t>(sizeof(_Addr), s->ai_addrlen)); _AddrLen = (socklen_t)s->ai_addrlen; } } // namespace netplus
src/posix/tcp.cpp +70 −8 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace netplus { tcp::tcp() : socket() { _Socket = ::socket(0,SOCK_STREAM,IPPROTO_TCP); _Socket = -1; _Type = sockettype::TCP; } Loading Loading @@ -224,14 +224,76 @@ size_t tcp::recvData(buffer& data, int flags) { throw e; } void tcp::connect(std::unique_ptr<socket>& srvsock) { if (::connect(_Socket, reinterpret_cast<sockaddr*>(&srvsock->_Addr), srvsock->_AddrLen) < 0) { NetException e; e[NetException::Error] << "tcp::connect failed: " << strerror(errno); throw e; void netplus::tcp::connect(const std::string& addr, int port, bool nonblock) { NetException exception; addrinfo hints{}; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; addrinfo* result = nullptr; char serv[32]; std::snprintf(serv, sizeof(serv), "%d", port); int gai = ::getaddrinfo(addr.c_str(), serv, &hints, &result); if (gai != 0) { exception[NetException::Error] << "tcp::connect: getaddrinfo failed: " << gai_strerror(gai); throw exception; } for (addrinfo* rp = result; rp; rp = rp->ai_next) { // socket erstellen, falls noch keiner existiert oder family mismatch if (_Socket < 0) { _Socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (_Socket < 0) continue; } if (nonblock) setNonBlock(); // optional: SO_REUSEADDR (bei client meistens egal aber ok) int opt = 1; ::setsockopt(_Socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // 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; ::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; ::freeaddrinfo(result); NetException n; n[NetException::Note] << "tcp::connect: EINPROGRESS"; throw n; // du wartest auf EPOLLOUT } // echter Fehler ::close(_Socket); _Socket = -1; } ::freeaddrinfo(result); exception[NetException::Error] << "tcp::connect: could not connect to " << addr << ":" << port << " (" << strerror(errno) << ")"; throw exception; } void tcp::getAddress(std::string& addr) { Loading
src/posix/udp.cpp +54 −9 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace netplus { udp::udp() : socket() { _Socket = _Socket = ::socket(0,SOCK_DGRAM,IPPROTO_UDP); _Socket = -1; _Type = sockettype::UDP; } Loading Loading @@ -209,15 +209,60 @@ size_t udp::recvData(buffer& data, int flags) { throw e; } void udp::connect(std::unique_ptr<socket>& srvsock) { // UDP connect optional if (::connect(_Socket, reinterpret_cast<sockaddr*>(&srvsock->_Addr), srvsock->_AddrLen) < 0) { NetException e; e[NetException::Error] << "udp::connect failed: " << strerror(errno); throw e; void netplus::udp::connect(const std::string& addr, int port,bool ){ NetException exception; addrinfo hints{}; hints.ai_family = AF_UNSPEC; // IPv4 oder IPv6 hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; addrinfo* result = nullptr; char serv[32]; std::snprintf(serv, sizeof(serv), "%d", port); int gai = ::getaddrinfo(addr.c_str(), serv, &hints, &result); if (gai != 0) { exception[NetException::Error] << "udp::connect: getaddrinfo failed: " << gai_strerror(gai); throw exception; } for (addrinfo* rp = result; rp; rp = rp->ai_next) { // ✅ Socket erstellen falls nicht da if (_Socket < 0) { _Socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (_Socket < 0) continue; } // ✅ connect UDP (bindet Default Peer) if (::connect(_Socket, rp->ai_addr, rp->ai_addrlen) == 0) { // ✅ Adresse sauber speichern (deep copy) copyAddrInfo(&_SocketInfo, reinterpret_cast<ULONG_PTR>(rp), sizeof(addrinfo)); _SocketInfoLen = rp->ai_addrlen; ::freeaddrinfo(result); return; } // Fehler -> neuen Socket versuchen ::close(_Socket); _Socket = -1; } ::freeaddrinfo(result); exception[NetException::Error] << "udp::connect: could not connect to " << addr << ":" << port << " (" << strerror(errno) << ")"; throw exception; } void udp::getAddress(std::string& addr) { Loading
src/socket.h +23 −22 Original line number Diff line number Diff line Loading @@ -179,7 +179,7 @@ namespace netplus { virtual bool hasPendingWrite() const { return false; } virtual bool getHandshakeDone() { return true; } virtual void connect(std::unique_ptr<socket>& csock) = 0; virtual void connect(const std::string& addr, int port, bool nonblock = false) = 0; virtual void getAddress(std::string& addr) = 0; SOCKET fd(); Loading Loading @@ -244,19 +244,20 @@ namespace netplus { void prime_read(buffer& data); #endif void accept(std::unique_ptr<socket>& csock,bool nonblock); void bind(); void listen(); void setNonBlock(); netplus::tcp& operator=(SOCKET sock); void accept(std::unique_ptr<socket>& csock,bool nonblock) override; void bind() override; void listen() override; void setNonBlock() override; netplus::tcp& operator=(SOCKET sock) override; int getMaxconnections() override; int getMaxconnections(); size_t sendData(buffer& data, int flags = 0) override; size_t recvData(buffer& data, int flags = 0) override; size_t sendData(buffer& data, int flags = 0); size_t recvData(buffer& data, int flags = 0); void connect(const std::string& addr, int port, bool nonblock = false) override; virtual void connect(std::unique_ptr<socket>& srvsock); void getAddress(std::string& addr); void getAddress(std::string& addr) override; private: int _Maxconnections; Loading @@ -273,7 +274,7 @@ namespace netplus { udp(const std::string& addr, int port, int maxconnections,int sockopts); ~udp(); void accept(std::unique_ptr<socket>& csock,bool nonblock); void accept(std::unique_ptr<socket>& csock,bool nonblock) override; #ifdef Windows void accept(LPFN_ACCEPTEX lpfnAcceptEx, std::unique_ptr<socket>& csock, buffer& data); Loading @@ -282,18 +283,18 @@ namespace netplus { void prime_read(buffer& data); #endif void bind(); void listen(); void setNonBlock(); void bind() override; void listen() override; void setNonBlock() override; udp& operator=(SOCKET socket); int getMaxconnections(); udp& operator=(SOCKET socket) override; int getMaxconnections() override; size_t sendData(buffer& data, int flags = 0); size_t recvData(buffer& data, int flags = 0); size_t sendData(buffer& data, int flags = 0) override; size_t recvData(buffer& data, int flags = 0) override; void connect(std::unique_ptr<socket>& srvsock); void getAddress(std::string& addr); void connect(const std::string& addr, int port, bool nonblock = false) override; void getAddress(std::string& addr) override; private: int _Maxconnections; Loading @@ -314,7 +315,7 @@ namespace netplus { void accept(std::unique_ptr<socket>& csock,bool nonblock) override; void handshake_after_accept() override; void connect(std::unique_ptr<socket>& srvsock) override; void connect(const std::string& addr, int port, bool nonblock = false) override; void close() override; size_t sendData(buffer& data, int flags = 0) override; Loading
src/ssl.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1767,7 +1767,7 @@ void netplus::ssl::accept(LPFN_ACCEPTEX lpfnAcceptEx, std::unique_ptr<socket>& c } #endif void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) void netplus::ssl::connect(const std::string& addr, int port, bool nonblock) { auto throwSSL = [&](int type, const std::string& msg) { netplus::NetException e; Loading @@ -1780,7 +1780,7 @@ void netplus::ssl::connect(std::unique_ptr<socket>& srvsock) // ------------------------------------------------------------ // "this" is the real IO socket (the one the caller uses for send/recv). // srvsock holds the target config (addr/port/opts). tcp::connect(srvsock); tcp::connect(addr,port,nonblock); // ------------------------------------------------------------ // 1) Reset TLS state on THIS object Loading