line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#pragma once |
2
|
|
|
|
|
|
|
#include |
3
|
|
|
|
|
|
|
#include |
4
|
|
|
|
|
|
|
#include |
5
|
|
|
|
|
|
|
#ifdef _WIN32 |
6
|
|
|
|
|
|
|
#include |
7
|
|
|
|
|
|
|
#include |
8
|
|
|
|
|
|
|
#else |
9
|
|
|
|
|
|
|
#include |
10
|
|
|
|
|
|
|
#include |
11
|
|
|
|
|
|
|
#include |
12
|
|
|
|
|
|
|
#endif |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
namespace panda { namespace net { |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
using sa_family_t = decltype(std::declval().sa_family); |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
struct SockAddr { |
19
|
|
|
|
|
|
|
struct Inet4; |
20
|
|
|
|
|
|
|
struct Inet6; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
static const size_t IP4_MAX_ADDRSTRLEN = 16; |
23
|
|
|
|
|
|
|
static const size_t IP6_MAX_ADDRSTRLEN = 46; |
24
|
|
|
|
|
|
|
static const size_t BASE_LEN = offsetof(sockaddr, sa_data); |
25
|
|
|
|
|
|
|
|
26
|
38
|
|
|
|
|
|
SockAddr () { sa.sa_family = AF_UNSPEC; } |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
SockAddr (const sockaddr* sa, size_t length); |
29
|
|
|
|
|
|
|
SockAddr (const sockaddr_in* sa) : sa4(*sa) {} |
30
|
|
|
|
|
|
|
SockAddr (const sockaddr_in6* sa) : sa6(*sa) {} |
31
|
|
|
|
|
|
|
|
32
|
36
|
|
|
|
|
|
SockAddr (const SockAddr& oth) { operator=(oth); } |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
SockAddr& operator= (const SockAddr& oth); |
35
|
|
|
|
|
|
|
|
36
|
146
|
|
|
|
|
|
sa_family_t family () const { return sa.sa_family; } |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
bool is_inet4 () const { return family() == AF_INET; } |
39
|
|
|
|
|
|
|
bool is_inet6 () const { return family() == AF_INET6; } |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
const Inet4& as_inet4 () const { return *((const Inet4*)this); } |
42
|
|
|
|
|
|
|
const Inet6& as_inet6 () const { return *((const Inet6*)this); } |
43
|
|
|
|
|
|
|
Inet4& as_inet4 () { return *((Inet4*)this); } |
44
|
|
|
|
|
|
|
Inet6& as_inet6 () { return *((Inet6*)this); } |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
const sockaddr* get () const { return &sa; } |
47
|
|
|
|
|
|
|
sockaddr* get () { return &sa; } |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
bool operator== (const SockAddr& oth) const; |
50
|
|
|
|
|
|
|
bool operator!= (const SockAddr& oth) const { return !operator==(oth); } |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
explicit |
53
|
|
|
|
|
|
|
operator bool () const { return sa.sa_family != AF_UNSPEC; } |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
string ip () const; |
56
|
|
|
|
|
|
|
uint16_t port () const; |
57
|
|
|
|
|
|
|
size_t length () const; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
template |
60
|
|
|
|
|
|
|
void assign_foreign (Function&& fn) { |
61
|
|
|
|
|
|
|
size_t length = sizeof(SockAddr); // max size |
62
|
|
|
|
|
|
|
bool success = fn(&sa, &length); |
63
|
|
|
|
|
|
|
if (success) { |
64
|
|
|
|
|
|
|
// length is the actual size |
65
|
|
|
|
|
|
|
validate(&sa, length); |
66
|
|
|
|
|
|
|
#ifndef _WIN32 |
67
|
|
|
|
|
|
|
if (sa.sa_family == AF_UNIX) fix_unix_path(length); |
68
|
|
|
|
|
|
|
#endif |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
#ifndef _WIN32 |
73
|
|
|
|
|
|
|
static const size_t PATH_OFFSET = offsetof(sockaddr_un, sun_path); |
74
|
|
|
|
|
|
|
struct Unix; |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
SockAddr (const sockaddr_un* sa, size_t length) : SockAddr((const sockaddr*)sa, length) {} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
bool is_unix () const { return family() == AF_UNIX; } |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
Unix& as_unix () const { return *((Unix*)this); } |
81
|
|
|
|
|
|
|
#endif |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
protected: |
84
|
|
|
|
|
|
|
union { |
85
|
|
|
|
|
|
|
sockaddr sa; |
86
|
|
|
|
|
|
|
sockaddr_in sa4; |
87
|
|
|
|
|
|
|
sockaddr_in6 sa6; |
88
|
|
|
|
|
|
|
#ifndef _WIN32 |
89
|
|
|
|
|
|
|
sockaddr_un sau; |
90
|
|
|
|
|
|
|
#endif |
91
|
|
|
|
|
|
|
}; |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
private: |
94
|
|
|
|
|
|
|
void validate (const sockaddr*, size_t len); |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
#ifndef _WIN32 |
97
|
|
|
|
|
|
|
void fix_unix_path (size_t length) noexcept; |
98
|
|
|
|
|
|
|
#endif |
99
|
|
|
|
|
|
|
}; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
std::ostream& operator<< (std::ostream&, const SockAddr&); |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
struct SockAddr::Inet4 : SockAddr { |
104
|
|
|
|
|
|
|
static const in_addr addr_any; |
105
|
|
|
|
|
|
|
static const in_addr addr_loopback; |
106
|
|
|
|
|
|
|
static const in_addr addr_broadcast; |
107
|
|
|
|
|
|
|
static const in_addr addr_none; |
108
|
|
|
|
|
|
|
static const Inet4 sockaddr_any; |
109
|
|
|
|
|
|
|
static const Inet4 sockaddr_loopback; |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
Inet4 (const sockaddr_in* sa) : SockAddr(sa) {} |
112
|
|
|
|
|
|
|
Inet4 (const Inet4& oth) : SockAddr(oth.get()) {} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Inet4 (const string_view& ip, uint16_t port); |
115
|
|
|
|
|
|
|
Inet4 (const in_addr& addr, uint16_t port); |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
const in_addr& addr () const { return sa4.sin_addr; } |
118
|
|
|
|
|
|
|
in_addr& addr () { return sa4.sin_addr; } |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
const sockaddr_in* get () const { return &sa4; } |
121
|
|
|
|
|
|
|
sockaddr_in* get () { return &sa4; } |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
uint16_t port () const { return ntohs(sa4.sin_port); } |
124
|
|
|
|
|
|
|
string ip () const; |
125
|
|
|
|
|
|
|
}; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
struct SockAddr::Inet6 : SockAddr { |
128
|
|
|
|
|
|
|
static const in6_addr addr_any; |
129
|
|
|
|
|
|
|
static const in6_addr addr_loopback; |
130
|
|
|
|
|
|
|
static const Inet6 sockaddr_any; |
131
|
|
|
|
|
|
|
static const Inet6 sockaddr_loopback; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
Inet6 (const sockaddr_in6* sa) : SockAddr(sa) {} |
134
|
|
|
|
|
|
|
Inet6 (const Inet6& oth) : SockAddr(oth.get()) {} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
Inet6 (const string_view& ip, uint16_t port, uint32_t scope_id = 0, uint32_t flowinfo = 0); |
137
|
|
|
|
|
|
|
Inet6 (const in6_addr& addr, uint16_t port, uint32_t scope_id = 0, uint32_t flowinfo = 0); |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
const in6_addr& addr () const { return sa6.sin6_addr; } |
140
|
|
|
|
|
|
|
in6_addr& addr () { return sa6.sin6_addr; } |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
const sockaddr_in6* get () const { return &sa6; } |
143
|
|
|
|
|
|
|
sockaddr_in6* get () { return &sa6; } |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
string ip () const; |
146
|
|
|
|
|
|
|
uint16_t port () const { return ntohs(sa6.sin6_port); } |
147
|
|
|
|
|
|
|
uint32_t scope_id () const { return sa6.sin6_scope_id; } |
148
|
|
|
|
|
|
|
uint32_t flowinfo () const { return ntohl(sa6.sin6_flowinfo); } |
149
|
|
|
|
|
|
|
}; |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
#ifndef _WIN32 |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
struct SockAddr::Unix : SockAddr { |
154
|
|
|
|
|
|
|
Unix (const sockaddr_un* sa, size_t length) : SockAddr(sa, length) {} |
155
|
|
|
|
|
|
|
Unix (const Unix& oth) : SockAddr(oth) {} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
Unix (const string_view& path); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
string_view path () const { return (char*)sau.sun_path; } |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
const sockaddr_un* get () const { return &sau; } |
162
|
|
|
|
|
|
|
sockaddr_un* get () { return &sau; } |
163
|
|
|
|
|
|
|
}; |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
#endif |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
}} |