1#include "InternetSocket.h"
2#include "SockAddress.h"
3#include "TempFailure.h"
16 explicit NonBlockingGuard(
int fd) : m_fd(fd)
18 m_flags = ::fcntl( m_fd, F_GETFL, 0);
20 throw SocketException(
"Unable to get file status (fcntl)");
21 if( ::fcntl( m_fd, F_SETFL, m_flags | O_NONBLOCK) < 0)
22 throw SocketException(
"Unable to set non-blocking mode (fcntl)");
27 const int savedErrno = errno;
28 ::fcntl( m_fd, F_SETFL, m_flags);
32 NonBlockingGuard(
const NonBlockingGuard&) =
delete;
33 NonBlockingGuard& operator=(
const NonBlockingGuard&) =
delete;
40AddressFamily socketAddressFamily(
int fd)
43 if( ::getsockname( fd, addr.data(), addr.lengthPtr()) < 0)
46 switch (addr.family())
48 case AF_INET:
return AddressFamily::IPv4;
49 case AF_INET6:
return AddressFamily::IPv6;
58: SimpleSocket(
SockAddress::nativeFamily(family), type, protocol)
63: SimpleSocket( sockfd)
64, m_family( socketAddressFamily(sockfd))
69 const int value = enable;
70 if( ::setsockopt( m_socket, SOL_SOCKET, SO_REUSEADDR, &value,
sizeof(value)) < 0)
76 SockAddress addr( m_family, foreignAddress, foreignPort);
78 if(
::connect( m_socket, addr.data(), addr.length()) < 0)
81 m_peerDisconnected =
false;
89 NonBlockingGuard nonBlocking( m_socket);
91 const auto throwError = []() {
96 int ret =
::connect( m_socket, addr.data(), addr.length());
98 m_peerDisconnected =
false;
103 if( errno != EINPROGRESS && errno != EWOULDBLOCK && errno != EINTR)
109 poll.events = POLLOUT;
111 ret = TEMP_FAILURE_RETRY (::poll( &poll, 1, timeout));
112 if( ret < 0) throwError();
120 socklen_t errLen =
sizeof(sockError);
121 ret = ::getsockopt( m_socket, SOL_SOCKET, SO_ERROR, &sockError, &errLen);
122 if( ret < 0) throwError();
123 if( sockError != 0) {
128 m_peerDisconnected =
false;
136 if(
::bind( m_socket, addr.data(), addr.length()) < 0)
142 SockAddress addr( m_family, localAddress, localPort);
144 if(
::bind( m_socket, addr.data(), addr.length()) < 0)
152 if( ::getsockname( m_socket, addr.data(), addr.lengthPtr()) < 0)
155 return addr.address();
162 if( ::getsockname( m_socket, addr.data(), addr.lengthPtr()) < 0)
172 if( ::getpeername( m_socket, addr.data(), addr.lengthPtr()) < 0)
173 throw SocketException(
"Fetch of foreign address failed (getpeername)");
175 return addr.address();
182 if( ::getpeername( m_socket, addr.data(), addr.lengthPtr()) < 0)
void bind(unsigned short localPort=0)
unsigned short getLocalPort() const
unsigned short getForeignPort() const
InternetSocket(int sockfd)
create socket from a SocketHandle returned by an accept() call
int timedConnect(std::string_view foreignAddress, unsigned short foreignPort, int timeout)
establish a connection with the given foreign address and port
void setReuseAddress(bool enable)
Enable or disable local address reuse.
void connect(std::string_view foreignAddress, unsigned short foreignPort)
establish a connection with the given foreign address and port
std::string getLocalAddress() const
std::string getForeignAddress() const
Signals a problem with the execution of a socket call.