aboutsummaryrefslogtreecommitdiffstats
path: root/util/network/address.h
blob: d9f310ae9d6cb7a9b23cc5628bde9f553d9c9a60 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#pragma once

#include "ip.h"
#include "socket.h"

#include <util/generic/ptr.h>
#include <util/generic/string.h>

namespace NAddr {
    class IRemoteAddr {
    public:
        virtual ~IRemoteAddr() = default;

        virtual const sockaddr* Addr() const = 0;
        virtual socklen_t Len() const = 0;
    };

    using IRemoteAddrPtr = THolder<IRemoteAddr>;
    using IRemoteAddrRef = TAtomicSharedPtr<NAddr::IRemoteAddr>;

    IRemoteAddrPtr GetSockAddr(SOCKET s);
    IRemoteAddrPtr GetPeerAddr(SOCKET s);
    void PrintHost(IOutputStream& out, const IRemoteAddr& addr); 

    TString PrintHost(const IRemoteAddr& addr);
    TString PrintHostAndPort(const IRemoteAddr& addr);

    bool IsLoopback(const IRemoteAddr& addr);
    bool IsSame(const IRemoteAddr& lhs, const IRemoteAddr& rhs);

    socklen_t SockAddrLength(const sockaddr* addr);

    //for accept, recvfrom - see LenPtr()
    class TOpaqueAddr: public IRemoteAddr {
    public:
        inline TOpaqueAddr() noexcept
            : L_(sizeof(S_))
        {
            Zero(S_);
        }

        inline TOpaqueAddr(const IRemoteAddr* addr) noexcept {
            Assign(addr->Addr(), addr->Len());
        }

        inline TOpaqueAddr(const sockaddr* addr) {
            Assign(addr, SockAddrLength(addr));
        }

        const sockaddr* Addr() const override {
            return MutableAddr();
        }

        socklen_t Len() const override {
            return L_;
        }

        inline sockaddr* MutableAddr() const noexcept {
            return (sockaddr*)&S_;
        }

        inline socklen_t* LenPtr() noexcept {
            return &L_;
        }

    private:
        inline void Assign(const sockaddr* addr, socklen_t len) noexcept {
            L_ = len;
            memcpy(MutableAddr(), addr, L_);
        }

    private:
        sockaddr_storage S_;
        socklen_t L_;
    };

    //for TNetworkAddress
    class TAddrInfo: public IRemoteAddr {
    public:
        inline TAddrInfo(const addrinfo* ai) noexcept
            : AI_(ai)
        {
        }

        const sockaddr* Addr() const override {
            return AI_->ai_addr;
        }

        socklen_t Len() const override {
            return (socklen_t)AI_->ai_addrlen;
        }

    private:
        const addrinfo* const AI_;
    };

    //compat, for TIpAddress
    class TIPv4Addr: public IRemoteAddr {
    public:
        inline TIPv4Addr(const TIpAddress& addr) noexcept
            : A_(addr)
        {
        }

        const sockaddr* Addr() const override {
            return A_;
        }

        socklen_t Len() const override {
            return A_;
        }

    private:
        const TIpAddress A_;
    };

    //same, for ipv6 addresses
    class TIPv6Addr: public IRemoteAddr {
    public:
        inline TIPv6Addr(const sockaddr_in6& a) noexcept
            : A_(a)
        {
        }

        const sockaddr* Addr() const override {
            return (sockaddr*)&A_;
        }

        socklen_t Len() const override {
            return sizeof(A_);
        }

    private:
        const sockaddr_in6 A_;
    };
}