"src/test/git@code.fbi.h-da.de:istiiahma/spring-boot.git" did not exist on "849b257e4c0111a6719e379ecc1541a83cab2818"
Newer
Older
#include "sockaddr.hpp"
#include <cstring>
#include <stdexcept>
#include <arpa/inet.h>
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
SockAddr::SockAddr()
: SockAddr{IpAddr::V4("0.0.0.0"), 0}
{ }
SockAddr::SockAddr(IpAddr _address, uint16_t _port)
: address{_address}, port{_port}
{
setRawSockaddr(address, port);
}
SockAddr::SockAddr(const std::string &_address, uint16_t _port)
: SockAddr(IpAddr(_address), _port)
{ }
SockAddr::SockAddr(const std::string &_address_port)
{
std::string str_addr;
std::string str_port;
// Try to find the positions of the brackets and colons
size_t pos_bracket1 = _address_port.find("[");
size_t pos_bracket2 = _address_port.find("]:");
size_t pos_colon = _address_port.find(":");
// If no colon was found at all, the port is definitely missing
if (pos_colon == std::string::npos)
{
throw std::runtime_error("SockAddr ip:port string is missing \":port\"");
}
// If the string starts with "[" and also contains "]:", it must be Ipv6
if (pos_bracket1 == 0 && pos_bracket2 != std::string::npos)
{
str_addr = _address_port.substr(1, pos_bracket2-1);
str_port = _address_port.substr(pos_bracket2+2);
address = IpAddr::V6(str_addr);
}
// If the string contains "." it must be Ipv4
else if (_address_port.find(".") != std::string::npos)
{
str_addr = _address_port.substr(0, pos_colon);
str_port = _address_port.substr(pos_colon+1);
address = IpAddr::V4(str_addr);
}
// If it is neither Ipv4 nor Ipv6, it is invalid
else
{
throw std::runtime_error("Conversion from String to SockAddr failed");
}
// Convert the port string to int
int port_int = std::stoi(str_port);
// If the port is not in the range of uint16_t, it is invalid
if (port_int < 0 || port_int > 0xffff || str_port.empty())
throw std::runtime_error("Invalid port number");
port = port_int;
// Transfer the information onto the raw sockaddr
setRawSockaddr(address, port);
}
SockAddr::SockAddr(sockaddr *_raw_sockaddr, IpAddr::Type _type)
{
if (_type == IpAddr::Type::V4)
{
// Type-pun the sockaddr to Ipv4 sockaddr_in
raw_sockaddr.v4 = *((sockaddr_in*)_raw_sockaddr);
// Get the port in host byte order
port = ntohs(raw_sockaddr.v4.sin_port);
// Set the address type
address.type = _type;
// Copy the raw address data
address.raw_addr.v4 = raw_sockaddr.v4.sin_addr;
// Buffer to hold the string representation of the Ipv4 address
char str_addr[INET_ADDRSTRLEN];
// Convert the raw address to string
inet_ntop(AF_INET, &raw_sockaddr.v4.sin_addr, str_addr, INET_ADDRSTRLEN);
// Set the string in address
address.str_addr = str_addr;
}
else if (_type == IpAddr::Type::V6)
{
// Same as if the type was Ipv4, but with a 6 instead
raw_sockaddr.v6 = *((sockaddr_in6*)_raw_sockaddr);
port = ntohs(raw_sockaddr.v6.sin6_port);
address.type = _type;
address.raw_addr.v6 = raw_sockaddr.v6.sin6_addr;
char str_addr[INET6_ADDRSTRLEN] = {0};
inet_ntop(AF_INET6, &raw_sockaddr.v6.sin6_addr, str_addr, INET6_ADDRSTRLEN);
address.str_addr = str_addr;
}
else
{
throw std::runtime_error("Can't build SockAddr from IpAddr::Type::Undef");
}
}
void SockAddr::setRawSockaddr(IpAddr _address, uint16_t _port)
{
memset(&raw_sockaddr, 0, sizeof(raw_sockaddr));
// Set the information in the raw sockaddr
if (_address.isIpv4())
{
// Set address family to Ipv4
raw_sockaddr.v4.sin_family = AF_INET;
// Set the port (in network byte order)
raw_sockaddr.v4.sin_port = htons(_port);
// Copy the raw ip address from IpAddr
raw_sockaddr.v4.sin_addr = _address.raw_addr.v4;
}
else if (_address.isIpv6())
{
// Set address family to Ipv6
raw_sockaddr.v6.sin6_family = AF_INET6;
// Set the port (in network byte order)
raw_sockaddr.v6.sin6_port = htons(_port);
// Copy the raw ip address from IpAddr
raw_sockaddr.v6.sin6_addr = _address.raw_addr.v6;
}
else
{
throw std::runtime_error("Can't create SockAddr from IpAddr::Type::Undef");
}
}
const IpAddr & SockAddr::getIpAddress() const
{
return address;
}
const std::string & SockAddr::getIpAddressString() const
{
return address.getAddressString();
}
const uint16_t SockAddr::getPort() const
{
return port;
}