15 #include <sys/socket.h>
16 #include <arpa/inet.h>
22 #include <system_error>
39 std::string parseAddress(
const int family,
const struct sockaddr_in*
const sin) {
40 const size_t bufferLen = std::max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN);
41 char buffer[bufferLen];
44 const char* actualAddressString = inet_ntop(family, &(sin->sin_addr.s_addr), buffer, bufferLen);
45 if(
nullptr == actualAddressString) {
46 throw std::invalid_argument(
"Address not valid");
49 return actualAddressString;
58 std::string parseAddress(
const struct addrinfo& result) {
59 const struct sockaddr_in*
const sin = (sockaddr_in*) result.ai_addr;
60 return parseAddress(result.ai_family, sin);
77 typedef std::shared_ptr<InetAddressPimpl>
Ptr;
84 InetAddressPimpl(
const sockaddr_in& theLowLevelAddress,
const std::string& theActualAddress)
109 const std::string actualAddress;
117 SocketType socketType,
const std::string& serviceName,
const std::string& address,
118 std::vector<InetAddress::Ptr>& created,
unsigned int max
121 struct addrinfo hints;
122 memset(&hints, 0,
sizeof(hints));
123 hints.ai_family = PF_UNSPEC;
127 struct addrinfo *results =
nullptr;
128 const int error = getaddrinfo(address.c_str(), serviceName.c_str(), &hints, &results);
131 throw std::system_error(error, std::system_category(), gai_strerror(error));
134 if(
nullptr == results) {
136 throw std::invalid_argument(
"Invalid address and/or service");
141 unsigned int count = 0;
142 for(
struct addrinfo* result = results;
nullptr != result && (max <= 0 || count < max); result = result->ai_next, ++count) {
146 throw std::invalid_argument(
"Invalid address family for address");
148 const std::string actualAddress = parseAddress(*result);
152 *
reinterpret_cast<const struct sockaddr_in* const
>(result->ai_addr), actualAddress));
157 freeaddrinfo(results);
164 std::vector<InetAddress::Ptr> found;
165 create(socketType, serviceName, address, found, 1);
173 const std::string& theServiceName,
const std::string& theRequestedAddress,
174 std::shared_ptr<InetAddressPimpl> pimpl
176 :
Address(theSocketDomain, theSocketType, theProtocol),
177 serviceName(theServiceName),
178 requestedAddress(theRequestedAddress),
181 if(
nullptr == pimpl) {
182 throw new std::invalid_argument(
"Invalid address");
187 return requestedAddress;
191 return pimpl->getActualAddress();
199 return pimpl->getPort();
207 const int fromLowLevelAddressFamily = fromLowLevelAddress->getSockAddr().sa_family;
209 if(AF_INET != fromLowLevelAddressFamily && AF_INET6 != fromLowLevelAddressFamily) {
210 throw std::invalid_argument(
"LowLevelAddress is of wrong type for InetAddress to create");
213 const struct sockaddr_in*
const sin =
214 reinterpret_cast<const struct sockaddr_in* const
>(&fromLowLevelAddress->getSockAddr());
216 const std::string theActualAddress = parseAddress(fromLowLevelAddressFamily, sin);
Base class for all addresses.
std::shared_ptr< Address > Ptr
SocketDomain getSocketDomain() const
SocketType getSocketType() const
Internet Address Class supporting IPv4 and IPv6 and creatable from hostnames and service names.
const unsigned int getPort() const
const std::string & getActualAddress() const
const std::string & getServiceName() const
const std::string & getRequestedAddress() const
std::shared_ptr< InetAddress > Ptr
virtual std::shared_ptr< LowLevelAddress > makeTempLowLevelAddress() const
static int create(SocketType socketType, const std::string &serviceName, const std::string &address, std::vector< InetAddress::Ptr > &created, unsigned int max=0)
virtual LowLevelAddress & getLowLevelAddress() const
The private implementation of InetAddress.
InetAddressPimpl(const sockaddr_in &theLowLevelAddress, const std::string &theActualAddress)
const unsigned int getPort() const
std::shared_ptr< InetAddressPimpl > Ptr
const std::string & getActualAddress() const
Interface for the low-level address implementation.
std::shared_ptr< LowLevelAddress > Ptr
LowLevelAddress template for the various cast-to-sockaddr implementaitons.
Namespace of the BsdSockets library.
LowLevelAddressType< struct sockaddr_in > InetLowLevelAddress
int socketTypeToLowLevel(SocketType type)
SocketDomain lowLevelToSocketDomain(int lowLevel)