in src/afs.cc [1789:1868]
bool fill_client_address(SharedSessionData* session,
Port* port,
const char* clientAddress)
{
const char* tag = "fill client address";
// clientAddress: "ipv4:127.0.0.1:40468"
// family: "ipv4"
// host: "127.0.0.1"
// port: "40468"
std::stringstream clientAddressStream{std::string(clientAddress)};
std::string clientFamily("");
std::string clientHost("");
std::string clientPort("");
std::getline(clientAddressStream, clientFamily, ':');
std::getline(clientAddressStream, clientHost, ':');
std::getline(clientAddressStream, clientPort);
if (!(clientFamily == "ipv4" || clientFamily == "ipv6"))
{
set_error_message(
session,
std::string("client family must be ipv4 or ipv6: ") + clientFamily,
tag);
return false;
}
auto clientPortStart = clientPort.c_str();
char* clientPortEnd = nullptr;
auto clientPortNumber = std::strtoul(clientPortStart, &clientPortEnd, 10);
if (clientPortEnd[0] != '\0')
{
set_error_message(
session, std::string("client port is invalid: ") + clientPort, tag);
return false;
}
if (clientPortNumber == 0)
{
set_error_message(session, std::string("client port must not 0"), tag);
return false;
}
if (clientPortNumber > 65535)
{
set_error_message(session,
std::string("client port is too large: ") +
std::to_string(clientPortNumber),
tag);
return false;
}
if (clientFamily == "ipv4")
{
auto raddr = reinterpret_cast<sockaddr_in*>(&(port->raddr.addr));
port->raddr.salen = sizeof(sockaddr_in);
raddr->sin_family = AF_INET;
raddr->sin_port = htons(clientPortNumber);
if (inet_pton(AF_INET, clientHost.c_str(), &(raddr->sin_addr)) == 0)
{
set_error_message(
session,
std::string("client IPv4 address is invalid: ") + clientHost,
tag);
return false;
}
}
else if (clientFamily == "ipv6")
{
auto raddr = reinterpret_cast<sockaddr_in6*>(&(port->raddr.addr));
port->raddr.salen = sizeof(sockaddr_in6);
raddr->sin6_family = AF_INET6;
raddr->sin6_port = htons(clientPortNumber);
raddr->sin6_flowinfo = 0;
if (inet_pton(AF_INET6, clientHost.c_str(), &(raddr->sin6_addr)) == 0)
{
set_error_message(
session,
std::string("client IPv6 address is invalid: ") + clientHost,
tag);
return false;
}
raddr->sin6_scope_id = 0;
}
return true;
}