Commit 7c62c6ad authored by jan.koester's avatar jan.koester
Browse files

urgent

parent d8a30e40
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -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
+70 −8
Original line number Diff line number Diff line
@@ -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;
}

@@ -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) {
+54 −9
Original line number Diff line number Diff line
@@ -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;
}

@@ -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) {
+23 −22
Original line number Diff line number Diff line
@@ -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();
@@ -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;
@@ -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);
@@ -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;
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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