Allow port specified inside str for SocketAddress
This commit is contained in:
parent
61109f4aad
commit
40b0a6371e
@ -62,27 +62,91 @@ SocketAddress::SocketAddress(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4,
|
|||||||
} // SocketAddress(uint8_t,...)
|
} // SocketAddress(uint8_t,...)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** String initialization (Can be IPv4, IPv6 or domain). */
|
/** String initialization (Can be IPv4, IPv6 or domain).
|
||||||
void SocketAddress::init(const std::string& str, uint16_t port_number)
|
* \param str The address (can have a port with :)
|
||||||
|
* \param port_number The port number, default is 0 or overwritten if
|
||||||
|
* specified in str
|
||||||
|
* \param family AF_UNSPEC, AF_INET or AF_INET6 for example
|
||||||
|
*/
|
||||||
|
void SocketAddress::init(const std::string& str, uint16_t port_number,
|
||||||
|
short family)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
if (str.empty())
|
||||||
|
{
|
||||||
|
Log::error("SocketAddress", "Empty address is specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string addr_str;
|
||||||
|
std::string port_str;
|
||||||
|
|
||||||
|
bool only_1_colon = false;
|
||||||
|
size_t colon_pos = std::string::npos;
|
||||||
|
// Check if only 1 colon, if so then it's either domain:port or IPv4:port
|
||||||
|
for (size_t i = 0; i < str.size(); i++)
|
||||||
|
{
|
||||||
|
if (str[i] == ':')
|
||||||
|
{
|
||||||
|
if (colon_pos == std::string::npos)
|
||||||
|
{
|
||||||
|
colon_pos = i;
|
||||||
|
only_1_colon = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
only_1_colon = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (only_1_colon)
|
||||||
|
{
|
||||||
|
addr_str = std::string(str, 0, colon_pos);
|
||||||
|
if (colon_pos + 1 < str.size())
|
||||||
|
port_str = std::string(str, colon_pos + 1, str.size());
|
||||||
|
else
|
||||||
|
port_str = StringUtils::toString(port_number);
|
||||||
|
}
|
||||||
|
else if (str[0] == '[')
|
||||||
|
{
|
||||||
|
// Handle [IPv6 address]:port format
|
||||||
|
size_t pos = str.find(']');
|
||||||
|
if (pos == std::string::npos || pos - 1 == 0)
|
||||||
|
{
|
||||||
|
Log::error("SocketAddress", "Invalid IPv6 address is specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addr_str = std::string(str, 1, pos - 1);
|
||||||
|
if (pos + 2 < str.size() && str[pos + 1] == ':')
|
||||||
|
port_str = std::string(str, pos + 2, str.size());
|
||||||
|
else
|
||||||
|
port_str = StringUtils::toString(port_number);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr_str = str;
|
||||||
|
port_str = StringUtils::toString(port_number);
|
||||||
|
}
|
||||||
|
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
struct addrinfo* res = NULL;
|
struct addrinfo* res = NULL;
|
||||||
std::string port_str = StringUtils::toString(port_number);
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof hints);
|
memset(&hints, 0, sizeof hints);
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
int status = getaddrinfo_compat(str.c_str(), port_str.c_str(), &hints,
|
int status = getaddrinfo_compat(addr_str.c_str(), port_str.c_str(), &hints,
|
||||||
&res);
|
&res);
|
||||||
if (status != 0 || res == NULL)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
Log::error("TransportAddress", "Error in getaddrinfo for "
|
Log::error("SocketAddress", "Error in getaddrinfo for "
|
||||||
" TransportAddress (str constructor) %s: %s",
|
" SocketAddress (str constructor) %s: %s",
|
||||||
str.c_str(), gai_strerror(status));
|
str.c_str(), gai_strerror(status));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (res == NULL)
|
||||||
|
{
|
||||||
|
Log::error("SocketAddress", "No address is resolved.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (struct addrinfo* addr = res; addr != NULL; addr = addr->ai_next)
|
for (struct addrinfo* addr = res; addr != NULL; addr = addr->ai_next)
|
||||||
{
|
{
|
||||||
@ -573,4 +637,13 @@ void SocketAddress::unitTesting()
|
|||||||
|
|
||||||
SocketAddress v6_11("fec0::");
|
SocketAddress v6_11("fec0::");
|
||||||
assert(!v6_11.isLAN());
|
assert(!v6_11.isLAN());
|
||||||
|
|
||||||
|
SocketAddress ipv4_port("0.0.0.1:1");
|
||||||
|
assert(ipv4_port.getIP() == 1);
|
||||||
|
assert(ipv4_port.getPort() == 1);
|
||||||
|
|
||||||
|
SocketAddress ipv6_port("[::2]:1");
|
||||||
|
assert(ipv6_port.toString(false) == "::2");
|
||||||
|
assert(ipv6_port.getPort() == 1);
|
||||||
|
|
||||||
} // unitTesting
|
} // unitTesting
|
||||||
|
@ -69,7 +69,8 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
bool operator!=(const SocketAddress& other) const;
|
bool operator!=(const SocketAddress& other) const;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void init(const std::string& str, uint16_t port_number = 0);
|
void init(const std::string& str, uint16_t port_number = 0,
|
||||||
|
short family = AF_UNSPEC);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
bool isLAN() const;
|
bool isLAN() const;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user