Commit f58b8c37 authored by jan.koester's avatar jan.koester
Browse files

test

parent a3e2a85c
Loading
Loading
Loading
Loading
+284 −232

File changed.

Preview size limit exceeded, changes collapsed.

+30 −30
Original line number Diff line number Diff line
@@ -35,51 +35,51 @@
namespace netplus {

    struct ASN1Node {
        uint8_t tag{};
        std::vector<uint8_t> data;
        uint8_t tag = 0;
        const uint8_t* data = nullptr;
        size_t len = 0;
        std::vector<ASN1Node> children;
    };

        ASN1Node() = default;
        ASN1Node(const ASN1Node&) = default;
        ASN1Node& operator=(const ASN1Node&) = default;
        ASN1Node(ASN1Node&&) noexcept = default;
        ASN1Node& operator=(ASN1Node&&) noexcept = default;
        ~ASN1Node() = default;
    struct X509State {
        std::vector<uint8_t> der;
        ASN1Node root;
    };

    class x509cert {
    private:
        std::shared_ptr<X509State> state;

    public:
        x509cert();
        x509cert(const x509cert &cert);
        x509cert(const x509cert&) = default;
        x509cert& operator=(const x509cert&) = default;

        x509cert(x509cert&&) noexcept = default;
        x509cert& operator=(x509cert&&) noexcept = default;

        x509cert& operator=(const x509cert &cert);
        const std::vector<uint8_t>& derData() const { return state->der; }
        std::vector<uint8_t>& derData() { return state->der; }

        // Load binary DER data
        bool loadFromBuffer(std::vector<uint8_t>&& buffer);
        bool loadFromBuffer(const std::vector<uint8_t>& buffer);
        bool loadFromFile(const std::string& filePath);
        bool checkValidity();
        bool loadFromFile(const std::string& path);

        std::string getSubjectCN();
        bool checkValidity();
        bool extractPublicKey(netplus::rsa& outRsa);
        std::vector<uint8_t> pemCertToDer(const std::string& pem);
        std::string getSubjectCN();
        std::vector<std::string> getSubjectAltNames();

        std::string decodeOID(const uint8_t* data, size_t len);
        time_t parseASN1Time(const uint8_t* data, size_t len, uint8_t tag);
        std::vector<uint8_t> pemCertToDer(const std::string& pem);
        void bytesToBigInt(const std::vector<uint8_t>& bytes, netplus::rsa::bigInt& out);
    private:

        struct CertificateValidity {
            std::tm notBefore;
            std::tm notAfter;
        };

        std::vector<uint8_t> derData;

        // Internal ASN.1 parsing helpers
        ASN1Node root;
        size_t parseInternal(const uint8_t* data, size_t size, ASN1Node& outNode);
        time_t parseASN1Time(const std::vector<uint8_t>& data, uint8_t tag) ;
        std::string decodeOID(const std::vector<uint8_t>& data);
        std::string bytesToHex(const std::vector<uint8_t>& bytes);
        void bytesToBigInt(const std::vector<uint8_t>& bytes, netplus::rsa::bigInt& out);

        // Helper um bequem root zu bekommen
        ASN1Node& root() { return state->root; }
        const ASN1Node& root() const { return state->root; }
        friend class ssl;
    };

};
+4 −8
Original line number Diff line number Diff line
@@ -305,17 +305,12 @@ namespace netplus {
                        rcv = c->csock->recvData(buf, 0);
                    } catch (NetException& e) {
                        if (e.getErrorType() == NetException::Note) {
                            // nothing to read right now
                            rcv = 0;
                        } else {
                            throw;
                            return;
                        }
                        throw;
                    }

                    if (rcv == 0) {
                        // If peer closed => recvData must return 0.
                        // Note case already handled.
                        // In TLS, alert/EOF => close.
                        rearm.disarm();
                        CloseEventHandler(fd, tid, args);
                        return;
@@ -325,6 +320,7 @@ namespace netplus {
                    evconnection->RequestEvent(*c, tid, args);
                }


                // -------------------------------------------------
                // 3) EPOLLOUT: flush + send one chunk
                // -------------------------------------------------
+70 −16
Original line number Diff line number Diff line
@@ -58,16 +58,32 @@ netplus::socket::socket(){
}

netplus::socket::~socket() {
    if(_SocketInfo){
            free(((struct addrinfo*)_SocketInfo)->ai_addr);
            free((void*)_SocketInfo);
    auto* ai = reinterpret_cast<addrinfo*>(_SocketInfo);
    if (!ai) return;

    if (ai->ai_addr) {
        std::free(ai->ai_addr);
        ai->ai_addr = nullptr;
    }
    if (ai->ai_canonname) {
        std::free(ai->ai_canonname);
        ai->ai_canonname = nullptr;
    }
    ai->ai_addrlen = 0;
    ai->ai_next = nullptr;

    std::free(reinterpret_cast<void*>(_SocketInfo));   // ✅ WICHTIG
    _SocketInfo = 0;
}

void netplus::socket::close() {
    if (_Socket < 0) return;

    ::shutdown(_Socket, SHUT_RDWR);
    ::close(_Socket);
}

    _Socket = -1;
}

void netplus::socket::setFlag(int flag,int value){
    int sockopts=fcntl(_Socket, F_GETFL, 0);
@@ -108,18 +124,56 @@ void netplus::socket::setTimeout(int usec){
}

void netplus::socket::copyAddrInfo(ULONG_PTR* dest, ULONG_PTR src, size_t srclen) {
    auto* s = reinterpret_cast<addrinfo*>(src);
    auto* d = reinterpret_cast<addrinfo*>(*dest);

    memcpy((void*)*dest, (void*)src,srclen);
    if (!s || !d) return;

    ((struct addrinfo*)*dest)->ai_addr = (struct sockaddr*)malloc(((struct addrinfo*)src)->ai_addrlen);
    // ✅ free old deep fields (avoid leak)
    if (d->ai_addr) {
        std::free(d->ai_addr);
        d->ai_addr = nullptr;
    }
    if (d->ai_canonname) {
        std::free(d->ai_canonname);
        d->ai_canonname = nullptr;
    }

    // Ensure srclen
    if (srclen < sizeof(addrinfo)) srclen = sizeof(addrinfo);

    // Copy only POD header fields
    std::memset(d, 0, srclen);
    d->ai_family   = s->ai_family;
    d->ai_socktype = s->ai_socktype;
    d->ai_protocol = s->ai_protocol;
    d->ai_flags    = s->ai_flags;
    d->ai_next     = nullptr;

    // Canonname optional
    if (s->ai_canonname) {
        size_t n = std::strlen(s->ai_canonname);
        d->ai_canonname = static_cast<char*>(std::malloc(n + 1));
        if (d->ai_canonname) {
            std::memcpy(d->ai_canonname, s->ai_canonname, n);
            d->ai_canonname[n] = '\0';
        }
    }

    memset(((struct addrinfo*)*dest)->ai_addr,0,((struct addrinfo*)src)->ai_addrlen);
    // Deep copy sockaddr
    d->ai_addrlen = s->ai_addrlen;

    memcpy((void*)((struct addrinfo*)*dest)->ai_addr,
        (void*)((struct addrinfo*)src)->ai_addr,
        ((struct addrinfo*)(struct addrinfo*)*dest)->ai_addrlen
    );
    ((struct addrinfo*)*dest)->ai_addrlen = ((struct addrinfo*)src)->ai_addrlen;
    if (s->ai_addr && s->ai_addrlen > 0) {
        d->ai_addr = static_cast<sockaddr*>(std::malloc(s->ai_addrlen));
        if (!d->ai_addr) {
            d->ai_addrlen = 0;
            return;
        }
        std::memcpy(d->ai_addr, s->ai_addr, s->ai_addrlen);
    } else {
        d->ai_addr = nullptr;
        d->ai_addrlen = 0;
    }
}


+47 −25
Original line number Diff line number Diff line
@@ -69,52 +69,74 @@ netplus::tcp::tcp(const std::string &uxsocket,int maxconnections,int sockopts) :
    _Type=sockettype::TCP;
}

netplus::tcp::tcp(const std::string &addr, int port,int maxconnections,int sockopts) : socket() {
netplus::tcp::tcp(const std::string& addr, int port, int maxconnections, int sockopts)
: socket() {

    NetException exception;
    _Maxconnections = maxconnections;
    if(sockopts == -1)
        sockopts=SO_REUSEADDR;



    struct addrinfo hints,*result,*rp;
    if (sockopts == -1)
        sockopts = SO_REUSEADDR | SO_REUSEPORT;

    memset(&hints, 0, sizeof(hints));
    addrinfo hints{};
    hints.ai_family   = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags    = AI_PASSIVE;
    hints.ai_protocol = 0;
    hints.ai_canonname = NULL;
    hints.ai_addr = NULL;
    hints.ai_next = NULL;

    int tsock;
    addrinfo* result = nullptr;

    char serv[512];
    snprintf(serv,512,"%d",port);
    char serv[32];
    std::snprintf(serv, sizeof(serv), "%d", port);

    if ((tsock=::getaddrinfo(addr.c_str(), serv,&hints,&result)) < 0) {
        exception[NetException::Critical] << "Socket Invalid address/ Address not supported";
    int gai = ::getaddrinfo(addr.empty() ? nullptr : addr.c_str(), serv, &hints, &result);
    if (gai != 0) {
        exception[NetException::Critical]
            << "Socket Invalid address/ Address not supported: " << gai_strerror(gai);
        throw exception;
    }

    addrinfo* rp = nullptr;

    for (rp = result; rp != nullptr; rp = rp->ai_next) {
        _Socket = ::socket(rp->ai_family, rp->ai_socktype,
                           rp->ai_protocol);
        _Socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        if (_Socket == -1)
            continue;
        copyAddrInfo(&_SocketInfo,(ULONG_PTR)rp,sizeof(hints));

        // ✅ copy addrinfo deep (dest must be allocated in base class!)
        copyAddrInfo(reinterpret_cast<ULONG_PTR*>(&_SocketInfo),
                     reinterpret_cast<ULONG_PTR>(rp),
                     sizeof(addrinfo));

        // ✅ use correct addrlen (NOT sizeof(hints))
        _SocketInfoLen = reinterpret_cast<addrinfo*>(_SocketInfo)->ai_addrlen;

        break;
    }

    _SocketInfoLen = sizeof(hints);
    ::freeaddrinfo(result);

    if (_Socket == -1) {
        exception[NetException::Critical] << "Failed to create socket for given address/port";
        throw exception;
    }

    int optval = 1;
    setsockopt(_Socket, SOL_SOCKET, sockopts,&optval,sizeof(optval));

    // ✅ set each option separately (sockopts may be bitmask)
    if (sockopts & SO_REUSEADDR) {
        ::setsockopt(_Socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    }
#ifdef SO_REUSEPORT
    if (sockopts & SO_REUSEPORT) {
        ::setsockopt(_Socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
    }
#endif

    _Type = sockettype::TCP;
}



netplus::tcp::~tcp(){
    if (_Socket!=-1)
        ::close(_Socket);
Loading