31#define SHUT_RDWR SD_BOTH
32#define SHUT_WR SD_SEND
33#define LASTERROR WSAGetLastError()
34#define ERRNO_INTR WSAEINTR
36typedef IN_ADDR in_addr_t;
42#include <sys/socket.h>
43#include <sys/select.h>
44#include <netinet/in.h>
47#define closesocket(a) close(a)
48#define LASTERROR errno
49#define ERRNO_INTR EINTR
54using namespace NSROOT;
56static int __addressFamily(SOCKET_AF_t saf)
74 sockaddr_storage data;
77 SocketAddress() { Clear(AF_UNSPEC); }
78 SocketAddress(
int family) { Clear(family); }
79 inline sockaddr* sa() {
return (sockaddr*)&data; }
80 inline int sa_family() {
return data.ss_family; }
81 void Clear(
int family)
83 memset(&data, 0,
sizeof(data));
84 data.ss_family = family;
85 sa_len = (family == AF_INET ?
sizeof(sockaddr_in) :
sizeof(sockaddr_in6));
96static char my_hostname[SOCKET_HOSTNAME_MAXSIZE];
100, m_socket(INVALID_SOCKET_VALUE)
101, m_rcvbuf(SOCKET_RCVBUF_MINSIZE)
103, m_attempt(SOCKET_READ_ATTEMPT)
106, m_buflen(SOCKET_BUFFER_SIZE)
111TcpSocket::~TcpSocket()
119static int __connectAddr(
struct addrinfo *addr, net_socket_t *s,
int rcvbuf)
124 if ((my_hostname[0] ==
'\0') && (gethostname(my_hostname,
sizeof(my_hostname)) < 0))
127 DBG(DBG_ERROR,
"%s: gethostname failed (%d)\n", __FUNCTION__, err);
131 *s = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
132 if (*s == INVALID_SOCKET_VALUE)
135 DBG(DBG_ERROR,
"%s: invalid socket (%d)\n", __FUNCTION__, err);
140 int opt_rcvbuf = (rcvbuf < SOCKET_RCVBUF_MINSIZE ? SOCKET_RCVBUF_MINSIZE : rcvbuf);
141 if (setsockopt(*s, SOL_SOCKET, SO_RCVBUF, (
char*)&opt_rcvbuf,
sizeof(opt_rcvbuf)))
142 DBG(DBG_WARN,
"%s: could not set SO_RCVBUF from socket (%d)\n", __FUNCTION__, LASTERROR);
147 int opt_timeo = SOCKET_TIMEOUT_SEC * 1000;
149 struct timeval opt_timeo;
150 opt_timeo.tv_sec = SOCKET_TIMEOUT_SEC;
151 opt_timeo.tv_usec = 0;
153 if (setsockopt(*s, SOL_SOCKET, SO_SNDTIMEO, (
char*)&opt_timeo,
sizeof(opt_timeo)))
154 DBG(DBG_WARN,
"%s: could not set SO_SNDTIMEO from socket (%d)\n", __FUNCTION__, LASTERROR);
160 if (setsockopt(*s, SOL_SOCKET, SO_NOSIGPIPE, (
char*)&opt_set,
sizeof(
int)))
161 DBG(DBG_WARN,
"%s: could not set SO_NOSIGPIPE from socket (%d)\n", __FUNCTION__, LASTERROR);
170 ioctlsocket(*s, FIONBIO, &nonblock);
173 int flags = fcntl(*s, F_GETFL, 0);
174 if (flags == -1) flags = 0;
175 fcntl(*s, F_SETFL, flags | O_NONBLOCK);
178 if (connect(*s, addr->ai_addr, addr->ai_addrlen) == 0)
183 ioctlsocket(*s, FIONBIO, &nonblock);
185 fcntl(*s, F_SETFL, flags);
187 DBG(DBG_PROTO,
"%s: connected to socket(%p)\n", __FUNCTION__, s);
193 if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS)
195 DBG(DBG_ERROR,
"%s: failed to connect (%d)\n", __FUNCTION__, err);
197 *s = INVALID_SOCKET_VALUE;
201 if (err != EINPROGRESS)
203 DBG(DBG_ERROR,
"%s: failed to connect (%d)\n", __FUNCTION__, err);
205 *s = INVALID_SOCKET_VALUE;
215 tv.tv_sec = SOCKET_TIMEOUT_SEC;
218 int r = select((*s) + 1,
nullptr, &fds,
nullptr, &tv);
223 socklen_t so_len =
sizeof(so_error);
224 if (getsockopt(*s, SOL_SOCKET, SO_ERROR, (
char*)&so_error, &so_len) == 0)
228 DBG(DBG_ERROR,
"%s: failed to connect (SO_ERROR=%d)\n", __FUNCTION__, so_error);
230 *s = INVALID_SOCKET_VALUE;
237 ioctlsocket(*s, FIONBIO, &nonblock);
239 fcntl(*s, F_SETFL, flags);
241 DBG(DBG_PROTO,
"%s: connected to socket(%p)\n", __FUNCTION__, s);
250 DBG(DBG_ERROR,
"%s: failed to connect (%d)\n", __FUNCTION__, err);
252 *s = INVALID_SOCKET_VALUE;
258 struct addrinfo hints;
259 struct addrinfo *result, *addr;
266 if (rcvbuf > SOCKET_RCVBUF_MINSIZE)
269 memset(&hints, 0,
sizeof (hints));
270 hints.ai_family = AF_UNSPEC;
271 hints.ai_socktype = SOCK_STREAM;
272 hints.ai_protocol = IPPROTO_TCP;
273 snprintf(service,
sizeof(service),
"%u", port);
275 err = getaddrinfo(server, service, &hints, &result);
281 DBG(DBG_ERROR,
"%s: the specified host is unknown\n", __FUNCTION__);
284 DBG(DBG_ERROR,
"%s: a non-recoverable failure in name resolution occurred\n", __FUNCTION__);
287 DBG(DBG_ERROR,
"%s: a memory allocation failure occurred\n", __FUNCTION__);
290 DBG(DBG_ERROR,
"%s: a temporary error occurred on an authoritative name server\n", __FUNCTION__);
293 DBG(DBG_ERROR,
"%s: unknown error %d\n", __FUNCTION__, err);
300 for (addr = result; addr; addr = addr->ai_next)
302 err = __connectAddr(addr, &m_socket, m_rcvbuf);
306 freeaddrinfo(result);
308 return (err ?
false :
true);
316#if defined(__WINDOWS__) || defined(SO_NOSIGPIPE)
317 size_t s = send(m_socket, msg, size, 0);
323#elif defined(MSG_NOSIGNAL)
324 size_t s = send(m_socket, msg, size, MSG_NOSIGNAL);
331 sigset_t sig_block, sig_restore, sig_pending;
332 sigemptyset(&sig_block);
333 sigaddset(&sig_block, SIGPIPE);
339 if (pthread_sigmask(SIG_BLOCK, &sig_block, &sig_restore) != 0)
344 int sigpipe_pending = -1;
345 if (sigpending(&sig_pending) != -1)
346 sigpipe_pending = sigismember(&sig_pending, SIGPIPE);
347 if (sigpipe_pending == -1)
349 pthread_sigmask(SIG_SETMASK, &sig_restore,
nullptr);
353 size_t s = send(m_socket, msg, size, 0);
364 if (m_errno == EPIPE && sigpipe_pending == 0)
370 while ((sig = sigtimedwait(&sig_block, 0, &ts)) == -1 && LASTERROR == EINTR);
372 pthread_sigmask(SIG_SETMASK, &sig_restore,
nullptr);
375 pthread_sigmask(SIG_SETMASK, &sig_restore,
nullptr);
391 char *p = (
char*)buf;
396 if (m_bufptr < m_buffer + m_rcvlen)
398 rcvlen = m_rcvlen - (m_bufptr - m_buffer);
401 memcpy(p, m_bufptr, rcvlen);
409 else if ((m_buffer =
new char[m_buflen]) ==
nullptr)
412 DBG(DBG_ERROR,
"%s: cannot allocate %u bytes for buffer\n", __FUNCTION__, (
unsigned)m_buflen);
421 int r = 0, hangcount = 0;
427 FD_SET(m_socket, &fds);
428 r = select(m_socket + 1, &fds,
nullptr,
nullptr, &tv);
434 if ((r = recv(m_socket, m_buffer, m_buflen, 0)) > 0)
440 memcpy(p, m_buffer, s);
441 m_bufptr = m_buffer + s;
450 if ((r = recv(m_socket, p, n, 0)) > 0)
460 DBG(DBG_INFO,
"%s: socket(%p) timed out (%d)\n", __FUNCTION__, &m_socket, hangcount);
462 if (++hangcount >= m_attempt)
468 if (m_errno != ERRNO_INTR)
485 if (m_bufptr < m_buffer + m_rcvlen)
487 size_t rcvlen = m_rcvlen - (m_bufptr - m_buffer);
490 memcpy(buf, m_bufptr, rcvlen);
497 if ((r = recv(m_socket, (
char*)buf, n, 0)) > 0)
507 if (shutdown(m_socket, SHUT_RDWR) == 0)
517 FD_SET(m_socket, &fds);
518 if (select(m_socket + 1, &fds,
nullptr,
nullptr, &tv) > 0 &&
519 recv(m_socket, buf,
sizeof(buf), 0) > 0)
530 closesocket(m_socket);
531 m_socket = INVALID_SOCKET_VALUE;
538 return (m_socket == INVALID_SOCKET_VALUE ?
false :
true);
549 FD_SET(m_socket, &fds);
550 r = select(m_socket + 1, &fds,
nullptr,
nullptr, timeout);
561 char rhost[INET6_ADDRSTRLEN];
562 memset(rhost, 0, INET6_ADDRSTRLEN);
567 char addr[
sizeof(sockaddr_in6)];
568 socklen_t addr_len =
sizeof(addr);
570 if (getpeername(m_socket, (sockaddr*)&addr, &addr_len) == 0)
571 getnameinfo((sockaddr*)&addr, addr_len, rhost,
sizeof(rhost),
nullptr, 0, NI_NUMERICHOST);
580 char host[INET6_ADDRSTRLEN];
581 memset(host, 0, INET6_ADDRSTRLEN);
586 char addr[
sizeof(sockaddr_in6)];
587 socklen_t addr_len =
sizeof(addr);
589 if (getsockname(m_socket, (sockaddr*)&addr, &addr_len) == 0)
590 getnameinfo((sockaddr*)&addr, addr_len, host,
sizeof(host),
nullptr, 0, NI_NUMERICHOST);
607TcpServerSocket::TcpServerSocket()
608: m_socket(INVALID_SOCKET_VALUE)
610, m_requestQueueSize(0)
615TcpServerSocket::~TcpServerSocket()
630 m_addr->Clear(__addressFamily(af));
631 m_socket = socket(m_addr->sa_family(), SOCK_STREAM, 0);
635 DBG(DBG_ERROR,
"%s: invalid socket (%d)\n", __FUNCTION__, m_errno);
644 if (setsockopt(m_socket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (
char*)&opt_set,
sizeof(
int)))
647 DBG(DBG_ERROR,
"%s: could not set SO_EXCLUSIVEADDRUSE from socket (%d)\n", __FUNCTION__, m_errno);
654 if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (
char*)&opt_set,
sizeof(
int)))
657 DBG(DBG_ERROR,
"%s: could not set SO_REUSEADDR from socket (%d)\n", __FUNCTION__, m_errno);
667 return (m_socket == INVALID_SOCKET_VALUE ?
false :
true);
676 m_addr->Clear(m_addr->sa_family());
677 switch (m_addr->sa_family())
681 sockaddr_in* sa = (sockaddr_in*)m_addr->sa();
682 sa->sin_addr.s_addr = htonl(INADDR_ANY);
683 sa->sin_port = htons(port);
684 r = bind(m_socket, m_addr->sa(), m_addr->sa_len);
689 sockaddr_in6* sa = (sockaddr_in6*)m_addr->sa();
690 sa->sin6_addr = in6addr_any;
691 sa->sin6_port = htons(port);
692 r = bind(m_socket, m_addr->sa(), m_addr->sa_len);
700 DBG(DBG_ERROR,
"%s: could not bind to address (%d)\n", __FUNCTION__, m_errno);
711 if (listen(m_socket, queueSize))
714 DBG(DBG_ERROR,
"%s: listen failed (%d)\n", __FUNCTION__, m_errno);
717 m_requestQueueSize = queueSize;
725 struct timeval tv = { timeout, 0 };
729 FD_SET(m_socket, &fds);
730 r = select(m_socket + 1, &fds,
nullptr,
nullptr, &tv);
733 return ACCEPT_TIMEOUT;
738 if (m_errno == ERRNO_INTR)
739 return ACCEPT_TIMEOUT;
744 m_addr->sa_len =
sizeof(m_addr->data);
745 socket.m_socket = accept(m_socket, m_addr->sa(), &m_addr->sa_len);
752 return ACCEPT_FAILURE;
758 if (setsockopt(socket.m_socket, SOL_SOCKET, SO_NOSIGPIPE, (
char*)&opt_set,
sizeof(
int)))
759 DBG(DBG_WARN,
"%s: could not set SO_NOSIGPIPE from socket (%d)\n", __FUNCTION__, LASTERROR);
763 if (setsockopt(socket.m_socket, SOL_SOCKET, SO_KEEPALIVE, (
char*)&opt_set,
sizeof(
int)))
765 DBG(DBG_ERROR,
"%s: could not set SO_KEEPALIVE from socket (%d)\n", __FUNCTION__, LASTERROR);
766 return ACCEPT_FAILURE;
771 int opt_timeo = SOCKET_TIMEOUT_SEC * 1000;
773 struct timeval opt_timeo;
774 opt_timeo.tv_sec = SOCKET_TIMEOUT_SEC;
775 opt_timeo.tv_usec = 0;
777 if (setsockopt(socket.m_socket, SOL_SOCKET, SO_SNDTIMEO, (
char*)&opt_timeo,
sizeof(opt_timeo)))
778 DBG(DBG_WARN,
"%s: could not set SO_SNDTIMEO from socket (%d)\n", __FUNCTION__, LASTERROR);
781 return ACCEPT_SUCCESS;
786 char rhost[INET6_ADDRSTRLEN];
787 memset(rhost, 0, INET6_ADDRSTRLEN);
788 getnameinfo(m_addr->sa(), m_addr->sa_len, rhost,
sizeof(rhost),
nullptr, 0, NI_NUMERICHOST);
796 closesocket(m_socket);
797 m_socket = INVALID_SOCKET_VALUE;
806UdpSocket::UdpSocket()
807: m_socket(INVALID_SOCKET_VALUE)
811, m_buflen(SOCKET_BUFFER_SIZE)
818UdpSocket::UdpSocket(
size_t bufferSize)
819: m_socket(INVALID_SOCKET_VALUE)
823, m_buflen(bufferSize)
830UdpSocket::~UdpSocket()
834 closesocket(m_socket);
835 m_socket = INVALID_SOCKET_VALUE;
850 m_buffer = m_bufptr =
nullptr;
861 if (
IsValid() && m_addr->sa_family() != __addressFamily(af))
863 closesocket(m_socket);
864 m_socket = INVALID_SOCKET_VALUE;
866 if (m_socket == INVALID_SOCKET_VALUE)
868 m_addr->Clear(__addressFamily(af));
869 m_from->Clear(AF_UNSPEC);
870 if ((m_socket = socket(m_addr->sa_family(), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET_VALUE)
873 DBG(DBG_ERROR,
"%s: create socket failed (%d)\n", __FUNCTION__, m_errno);
876 if (broadcast && af == SOCKET_AF_INET4)
880 if (setsockopt(m_socket, SOL_SOCKET, SO_BROADCAST, (
char*)&_broadcast,
sizeof(_broadcast)))
883 DBG(DBG_ERROR,
"%s: could not set SO_BROADCAST from socket (%d)\n", __FUNCTION__, m_errno);
896 DBG(DBG_ERROR,
"%s: invalid socket\n", __FUNCTION__);
900 unsigned char _addr[
sizeof(
struct in6_addr)];
901 if (inet_pton(m_addr->sa_family(), target, &_addr) == 0)
904 DBG(DBG_ERROR,
"%s: invalid address (%s)\n", __FUNCTION__, target);
908 m_addr->Clear(m_addr->sa_family());
909 switch(m_addr->sa_family())
913 sockaddr_in* sa = (sockaddr_in*)m_addr->sa();
914 memcpy(&(sa->sin_addr.s_addr), _addr,
sizeof(in_addr_t));
915 sa->sin_port = htons(port);
920 sockaddr_in6* sa = (sockaddr_in6*)m_addr->sa();
921 memcpy(&(sa->sin6_addr), _addr,
sizeof(
struct in6_addr));
922 sa->sin6_port = htons(port);
927 DBG(DBG_ERROR,
"%s: address familly unknown (%d)\n", __FUNCTION__, m_addr->sa_family());
939 switch(m_addr->sa_family())
944 unsigned char _ttl = (
unsigned char) multicastTTL;
945 if (setsockopt(m_socket, IPPROTO_IP, IP_MULTICAST_TTL, (
char*)&_ttl,
sizeof(_ttl)))
948 DBG(DBG_ERROR,
"%s: could not set IP_MULTICAST_TTL from socket (%d)\n", __FUNCTION__, m_errno);
956 if (setsockopt(m_socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (
char*)&multicastTTL,
sizeof(multicastTTL)))
959 DBG(DBG_ERROR,
"%s: could not set IPV6_MULTICAST_HOPS from socket (%d)\n", __FUNCTION__, m_errno);
966 DBG(DBG_ERROR,
"%s: address familly unknown (%d)\n", __FUNCTION__, m_addr->sa_family());
977 size_t s = sendto(m_socket, buf, size, 0, m_addr->sa(), m_addr->sa_len);
1000 if (m_bufptr < m_buffer + m_rcvlen)
1002 len = m_rcvlen - (m_bufptr - m_buffer);
1005 memcpy(buf, m_bufptr, len);
1010 else if ((m_buffer =
new char[m_buflen]) ==
nullptr)
1013 DBG(DBG_ERROR,
"%s: cannot allocate %u bytes for buffer\n", __FUNCTION__, (
unsigned)m_buflen);
1017 m_bufptr = m_buffer;
1026 FD_SET(m_socket, &fds);
1027 r = select(m_socket + 1, &fds,
nullptr,
nullptr, &tv);
1030 if ((r = recvfrom(m_socket, m_buffer, m_buflen, 0, m_from->sa(), &m_from->sa_len)) > 0)
1033 if (m_rcvlen == m_buflen)
1034 DBG(DBG_WARN,
"%s: datagram have been truncated (%d)\n", __FUNCTION__, r);
1037 memcpy(buf, m_buffer, len);
1043 m_errno = ETIMEDOUT;
1044 DBG(DBG_DEBUG,
"%s: socket(%p) timed out\n", __FUNCTION__, &m_socket);
1048 m_errno = LASTERROR;
1049 DBG(DBG_ERROR,
"%s: socket(%p) read error (%d)\n", __FUNCTION__, &m_socket, m_errno);
1059 return (m_socket == INVALID_SOCKET_VALUE ?
false :
true);
1064 char host[INET6_ADDRSTRLEN];
1065 memset(host, 0, INET6_ADDRSTRLEN);
1066 getnameinfo(m_from->sa(), m_from->sa_len, host,
sizeof(host),
nullptr, 0, NI_NUMERICHOST);
1075UdpServerSocket::UdpServerSocket()
1076: m_socket(INVALID_SOCKET_VALUE)
1080, m_buflen(SOCKET_BUFFER_SIZE)
1085 m_timeout.tv_sec = SOCKET_TIMEOUT_SEC;
1086 m_timeout.tv_usec = SOCKET_TIMEOUT_USEC;
1090UdpServerSocket::UdpServerSocket(
size_t bufferSize)
1091: m_socket(INVALID_SOCKET_VALUE)
1095, m_buflen(bufferSize)
1100 m_timeout.tv_sec = SOCKET_TIMEOUT_SEC;
1101 m_timeout.tv_usec = SOCKET_TIMEOUT_USEC;
1104UdpServerSocket::~UdpServerSocket()
1108 closesocket(m_socket);
1109 m_socket = INVALID_SOCKET_VALUE;
1124 m_buffer = m_bufptr =
nullptr;
1133 m_addr->Clear(__addressFamily(af));
1134 m_socket = socket(m_addr->sa_family(), SOCK_DGRAM, 0);
1137 m_errno = LASTERROR;
1138 DBG(DBG_ERROR,
"%s: invalid socket (%d)\n", __FUNCTION__, m_errno);
1143 if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (
char*)&opt,
sizeof(opt)))
1145 m_errno = LASTERROR;
1146 DBG(DBG_ERROR,
"%s: could not set reuseaddr from socket (%d)\n", __FUNCTION__, m_errno);
1154 return (m_socket == INVALID_SOCKET_VALUE ?
false :
true);
1162 m_addr->Clear(m_addr->sa_family());
1163 switch (m_addr->sa_family())
1167 sockaddr_in* sa = (sockaddr_in*)m_addr->sa();
1168 sa->sin_addr.s_addr = htonl(INADDR_ANY);
1169 sa->sin_port = htons(port);
1174 sockaddr_in6* sa = (sockaddr_in6*)m_addr->sa();
1175 sa->sin6_addr = in6addr_any;
1176 sa->sin6_port = htons(port);
1181 DBG(DBG_ERROR,
"%s: address familly unknown (%d)\n", __FUNCTION__, m_addr->sa_family());
1187 int opt = (reuse ? 0 : 1);
1188 if (setsockopt(m_socket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (
char*)&opt,
sizeof(opt)))
1190 m_errno = LASTERROR;
1191 DBG(DBG_ERROR,
"%s: could not set exclusiveaddruse from socket (%d)\n", __FUNCTION__, m_errno);
1194#elif defined(SO_REUSEPORT)
1195 int opt = (reuse ? 1 : 0);
1196 if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEPORT, (
char*)&opt,
sizeof(opt)))
1198 m_errno = LASTERROR;
1199 DBG(DBG_ERROR,
"%s: could not set reuseport from socket (%d)\n", __FUNCTION__, m_errno);
1203 int opt = (reuse ? 1 : 0);
1204 if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (
char*)&opt,
sizeof(opt)))
1206 m_errno = LASTERROR;
1207 DBG(DBG_ERROR,
"%s: could not set reuseaddr from socket (%d)\n", __FUNCTION__, m_errno);
1212 if (bind(m_socket, m_addr->sa(), m_addr->sa_len) != 0)
1214 m_errno = LASTERROR;
1215 DBG(DBG_ERROR,
"%s: could not bind to address (%d)\n", __FUNCTION__, m_errno);
1227 unsigned char _addr[
sizeof(
struct in6_addr)];
1228 if (inet_pton(m_addr->sa_family(), addr, &_addr) == 0)
1230 m_errno = LASTERROR;
1231 DBG(DBG_ERROR,
"%s: invalid address (%s)\n", __FUNCTION__, addr);
1235 m_addr->Clear(m_addr->sa_family());
1236 switch(m_addr->sa_family())
1240 sockaddr_in* sa = (sockaddr_in*)m_addr->sa();
1241 memcpy(&(sa->sin_addr.s_addr), _addr,
sizeof(in_addr_t));
1242 sa->sin_port = htons(port);
1247 sockaddr_in6* sa = (sockaddr_in6*)m_addr->sa();
1248 memcpy(&(sa->sin6_addr), _addr,
sizeof(
struct in6_addr));
1249 sa->sin6_port = htons(port);
1254 DBG(DBG_ERROR,
"%s: address familly unknown (%d)\n", __FUNCTION__, m_addr->sa_family());
1260 int opt = (reuse ? 0 : 1);
1261 if (setsockopt(m_socket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (
char*)&opt,
sizeof(opt)))
1263 m_errno = LASTERROR;
1264 DBG(DBG_ERROR,
"%s: could not set exclusiveaddruse from socket (%d)\n", __FUNCTION__, m_errno);
1267#elif defined(SO_REUSEPORT)
1268 int opt = (reuse ? 1 : 0);
1269 if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEPORT, (
char*)&opt,
sizeof(opt)))
1271 m_errno = LASTERROR;
1272 DBG(DBG_ERROR,
"%s: could not set reuseport from socket (%d)\n", __FUNCTION__, m_errno);
1276 int opt = (reuse ? 1 : 0);
1277 if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (
char*)&opt,
sizeof(opt)))
1279 m_errno = LASTERROR;
1280 DBG(DBG_ERROR,
"%s: could not set reuseaddr from socket (%d)\n", __FUNCTION__, m_errno);
1285 if (bind(m_socket, m_addr->sa(), m_addr->sa_len) != 0)
1287 m_errno = LASTERROR;
1288 DBG(DBG_ERROR,
"%s: could not bind to address (%d)\n", __FUNCTION__, m_errno);
1300 switch(m_addr->sa_family())
1305 unsigned char _ttl = (
unsigned char) multicastTTL;
1306 if (setsockopt(m_socket, IPPROTO_IP, IP_MULTICAST_TTL, (
char*)&_ttl,
sizeof(_ttl)))
1308 m_errno = LASTERROR;
1309 DBG(DBG_ERROR,
"%s: could not set IP_MULTICAST_TTL from socket (%d)\n", __FUNCTION__, m_errno);
1317 if (setsockopt(m_socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (
char*)&multicastTTL,
sizeof(multicastTTL)))
1319 m_errno = LASTERROR;
1320 DBG(DBG_ERROR,
"%s: could not set IPV6_MULTICAST_HOPS from socket (%d)\n", __FUNCTION__, m_errno);
1327 DBG(DBG_ERROR,
"%s: address familly unknown (%d)\n", __FUNCTION__, m_addr->sa_family());
1339 switch(m_addr->sa_family())
1343 struct ip_mreq mreq;
1344 if (inet_pton(AF_INET, group, &mreq.imr_multiaddr) == 0)
1346 m_errno = LASTERROR;
1347 DBG(DBG_ERROR,
"%s: invalid address (%d)\n", __FUNCTION__, m_errno);
1350 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
1351 if (setsockopt(m_socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP,
reinterpret_cast<const char*
>(&mreq),
sizeof(mreq)))
1353 m_errno = LASTERROR;
1354 DBG(DBG_ERROR,
"%s: could not set multicast membership from socket (%d)\n", __FUNCTION__, m_errno);
1361 struct ipv6_mreq mreq;
1362 if (inet_pton(AF_INET6, group, &mreq.ipv6mr_multiaddr) == 0)
1364 m_errno = LASTERROR;
1365 DBG(DBG_ERROR,
"%s: invalid address (%d)\n", __FUNCTION__, m_errno);
1368 mreq.ipv6mr_interface = 0;
1369 if (setsockopt(m_socket, IPPROTO_IPV6, join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP,
reinterpret_cast<const char*
>(&mreq),
sizeof(mreq)))
1371 m_errno = LASTERROR;
1372 DBG(DBG_ERROR,
"%s: could not set multicast membership from socket (%d)\n", __FUNCTION__, m_errno);
1379 DBG(DBG_ERROR,
"%s: address familly unknown (%d)\n", __FUNCTION__, m_addr->sa_family());
1392 if (!m_buffer && (m_buffer =
new char[m_buflen]) ==
nullptr)
1395 DBG(DBG_ERROR,
"%s: cannot allocate %u bytes for buffer\n", __FUNCTION__, (
unsigned)m_buflen);
1399 m_bufptr = m_buffer;
1406 FD_SET(m_socket, &fds);
1407 r = select(m_socket + 1, &fds,
nullptr,
nullptr, &m_timeout);
1410 if ((r = recvfrom(m_socket, m_buffer, m_buflen, 0, m_from->sa(), &m_from->sa_len)) > 0)
1413 if (m_rcvlen == m_buflen)
1414 DBG(DBG_WARN,
"%s: datagram have been truncated (%d)\n", __FUNCTION__, r);
1419 m_errno = ETIMEDOUT;
1420 DBG(DBG_DEBUG,
"%s: socket(%p) timed out\n", __FUNCTION__, &m_socket);
1424 m_errno = LASTERROR;
1425 DBG(DBG_ERROR,
"%s: socket(%p) read error (%d)\n", __FUNCTION__, &m_socket, m_errno);
1435 char host[INET6_ADDRSTRLEN];
1436 memset(host, 0, INET6_ADDRSTRLEN);
1437 getnameinfo(m_from->sa(), m_from->sa_len, host,
sizeof(host),
nullptr, 0, NI_NUMERICHOST);
1448 if (m_buffer && m_bufptr < m_buffer + m_rcvlen)
1450 len = m_rcvlen - (m_bufptr - m_buffer);
1453 memcpy(buf, m_bufptr, len);
bool Create(SOCKET_AF_t af)
std::string GetRemoteAddrInfo()
AcceptStatus AcceptConnection(TcpSocket &socket, int timeout)
bool ListenConnection(int queueSize=SOCKET_LISTEN_QUEUE_SIZE)
virtual void Disconnect()
static const char * GetMyHostName()
std::string GetRemoteAddrInfo()
std::string GetHostAddrInfo()
virtual size_t ReceiveData(void *buf, size_t n)
void SetReadAttempt(int n)
virtual bool SendData(const char *buf, size_t size)
virtual bool IsValid() const
virtual bool Connect(const char *server, unsigned port, int rcvbuf)
int Listen(timeval *timeout)
virtual size_t BlockingRead(void *buf, size_t n)
bool Bind(unsigned port, bool reuse=false)
bool SetMulticastTTL(int multicastTTL)
size_t ReadData(void *buf, size_t n)
bool Create(SOCKET_AF_t af)
bool SetMulticastMembership(const char *group, bool join)
std::string GetRemoteAddrInfo() const
std::string GetRemoteAddrInfo() const
size_t ReceiveData(void *buf, size_t n)
bool SetMulticastTTL(int multicastTTL)
bool Open(SOCKET_AF_t af, const char *target, unsigned port)
bool SetAddress(const char *target, unsigned port)
bool SendData(const char *buf, size_t size)