72 #pragma comment(lib, "ws2_32.lib")
78 #include <sys/types.h>
79 #include <sys/socket.h>
82 #include <arpa/inet.h>
83 #define SOCKET int32_t
84 #define SOCKET_ERROR -1
85 #define INVALID_SOCKET ((int32_t)-1)
94 #if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__)
95 #define USE_GETIFADDRS 1
102 #define MSG_NOSIGNAL 0
108 #define PEEKBUFSIZE 32768
150 switch (remote->ss_family)
154 src = &(((
struct sockaddr_in*)remote)->sin_addr);
158 src = &(((
struct sockaddr_in6*)remote)->sin6_addr);
159 length = INET6_ADDRSTRLEN;
163 if (inet_ntop(remote->ss_family, src, address->m_data, (
size_t)(ptrdiff_t)
length) == NULL)
173 if (thisPtr && thisPtr->
d)
189 if (functionResult == 0)
192 err = WSAGetLastError();
195 case WSA_INVALID_HANDLE:
196 case WSA_INVALID_PARAMETER:
200 case WSA_NOT_ENOUGH_MEMORY:
203 case WSA_OPERATION_ABORTED:
216 case WSA_IO_INCOMPLETE:
226 case WSAEDESTADDRREQ:
229 case WSAEPROTONOSUPPORT:
230 case WSAESOCKTNOSUPPORT:
232 case WSAEPFNOSUPPORT:
233 case WSAEAFNOSUPPORT:
234 case WSAEADDRNOTAVAIL:
238 case WSAECONNABORTED:
244 case WSAETOOMANYREFS:
245 case WSAECONNREFUSED:
247 case WSAENAMETOOLONG:
249 case WSAEHOSTUNREACH:
257 case WSAVERNOTSUPPORTED:
258 case WSANOTINITIALISED:
262 case WSAEINVALIDPROCTABLE:
263 case WSAEINVALIDPROVIDER:
264 case WSAEPROVIDERFAILEDINIT:
265 case WSASYSCALLFAILURE:
266 case WSASERVICE_NOT_FOUND:
267 case WSATYPE_NOT_FOUND:
269 case WSA_E_CANCELLED:
271 case WSAHOST_NOT_FOUND:
336 memset(thisPtr->
d, 0,
sizeof(*thisPtr->
d));
340 (void)WSAStartup(MAKEWORD(2, 0), &thisPtr->
d->m_sockData);
354 thisPtr->
d->
m_sd = socket(
355 (ip ==
NLP_IPV4) ? PF_INET : PF_INET6,
356 (protocol ==
IP_UDP) ? SOCK_DGRAM : SOCK_STREAM,
357 (protocol ==
IP_UDP) ? IPPROTO_UDP : IPPROTO_TCP);
372 thisPtr->
d->
m_sd = nativeSocket;
376 memcpy(&thisPtr->
d->
m_remoteAddr, theirInfo, (
size_t)(ptrdiff_t) infolen);
424 return thisPtr->
d->
m_sd;
490 struct timeval timeout;
495 FD_SET(thisPtr->
d->
m_sd, &readfd);
496 FD_SET(thisPtr->
d->
m_sd, &writefd);
497 FD_SET(thisPtr->
d->
m_sd, &errorfd);
504 timeout.tv_sec = mstimeout / 1000;
505 timeout.tv_usec = (mstimeout % 1000) * 1000;
507 rv = select(FD_SETSIZE, (canRead ? &readfd : NULL),
508 (canWrite ? &writefd : NULL),
509 &errorfd, mstimeout >= 0 ? &timeout : NULL);
520 if (FD_ISSET(thisPtr->
d->
m_sd, &errorfd))
528 *canRead = FD_ISSET(thisPtr->
d->
m_sd, &readfd);
530 *canWrite = FD_ISSET(thisPtr->
d->
m_sd, &writefd);
578 struct sockaddr_storage sender;
579 socklen_t l =
sizeof(sender);
589 rv = recvfrom(thisPtr->
d->
m_sd, dest, (
int)size, 0, (
struct sockaddr*)&sender, &l);
595 *port = ntohs(((
struct sockaddr_in*)&sender)->sin_port);
628 struct sockaddr_storage sender;
629 socklen_t l =
sizeof(sender);
651 *port = ntohs(((
struct sockaddr_in*)&sender)->sin_port);
682 int numbersFound = 0;
684 if (!hostname || !hostname->m_data)
687 for (c = hostname->m_data; *c !=
'\0'; c++)
697 else if (isdigit(*c))
703 if (numbersFound == 3)
715 if (!hostname || !hostname->m_data)
723 const char prefix[] =
"::ffff:";
746 struct sockaddr* info, socklen_t* addrlen)
748 struct addrinfo* lookupInfo, *p;
751 struct addrinfo hints;
753 memset(&hints, 0,
sizeof(hints));
758 hints.ai_family = AF_INET6;
761 hints.ai_family = AF_INET;
764 hints.ai_family = AF_UNSPEC;
768 hints.ai_flags = hints_flags;
770 sprintf(gaport,
"%u", (
unsigned int) port);
780 ret = getaddrinfo(host.m_data, gaport, &hints, &lookupInfo);
785 ret = getaddrinfo(NULL, gaport, &hints, &lookupInfo);
814 for (p = lookupInfo; p != NULL; p = p->ai_next)
816 s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
820 ret = tester(thisPtr,
s, p);
826 if ((socklen_t)p->ai_addrlen < *addrlen)
827 *addrlen = (socklen_t)p->ai_addrlen;
828 memcpy(info, p->ai_addr, (
size_t)(ptrdiff_t) *addrlen);
834 freeaddrinfo(lookupInfo);
842 return connect(currentSocket, info->ai_addr, (
int) info->ai_addrlen);
863 struct sockaddr_storage storage;
864 struct sockaddr* addr = NULL;
865 socklen_t addrlen = 0;
877 addr = (
struct sockaddr*)&storage;
878 addrlen =
sizeof(storage);
897 int broadcast = enable ? 1 : 0;
898 int res = setsockopt(thisPtr->
d->
m_sd, SOL_SOCKET, SO_BROADCAST, (
char*)&broadcast,
sizeof(broadcast));
908 #ifdef USE_GETIFADDRS
909 static uint32_t SockAddrToUint32(
struct sockaddr* a)
911 return ((a) && (a->sa_family == AF_INET)) ? ntohl(((
struct sockaddr_in*)a)->sin_addr.s_addr) : 0;
926 struct sockaddr_in addr;
940 addr.sin_family = AF_INET;
941 addr.sin_port = htons(port);
942 addr.sin_addr.s_addr = INADDR_BROADCAST;
948 MIB_IPADDRTABLE* ipTable = NULL;
951 for (
int i = 0; i < 5; i++)
953 DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, FALSE);
954 if (ipRet == ERROR_INSUFFICIENT_BUFFER)
957 ipTable = (MIB_IPADDRTABLE*) malloc(bufLen);
959 else if (ipRet == NO_ERROR)
972 IP_ADAPTER_INFO* pAdapterInfo = NULL;
975 for (
int i = 0; i < 5; i++)
977 DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
978 if (apRet == ERROR_BUFFER_OVERFLOW)
981 pAdapterInfo = (IP_ADAPTER_INFO*) malloc(bufLen);
983 else if (apRet == ERROR_SUCCESS)
994 for (DWORD i = 0; i < ipTable->dwNumEntries; i++)
996 const MIB_IPADDRROW* row = &ipTable->table[i];
997 uint32_t ad = ntohl(row->dwAddr) | ~ntohl(row->dwMask);
999 sprintf(bcastAddr,
"%u.%u.%u.%u", (ad >> 24) & 0xFF, (ad >> 16) & 0xFF, (ad >> 8) & 0xFF, ad & 0xFF);
1000 inet_pton(AF_INET, bcastAddr, &addr.sin_addr);
1001 sent = sendto(thisPtr->
d->
m_sd,
data, (
int)size,
MSG_NOSIGNAL, (
struct sockaddr
const*) &addr,
sizeof(addr));
1015 #elif defined(USE_GETIFADDRS)
1017 struct ifaddrs* ifap;
1018 if (getifaddrs(&ifap) == 0)
1020 struct ifaddrs* p = ifap;
1026 char bcastAddrStr[32];
1027 sprintf(bcastAddrStr,
"%u.%u.%u.%u", (bcastAddr >> 24) & 0xFF, (bcastAddr >> 16) & 0xFF, (bcastAddr >> 8) & 0xFF, bcastAddr & 0xFF);
1028 inet_pton(AF_INET, bcastAddrStr, &addr.sin_addr);
1029 sent = (int)sendto(thisPtr->
d->
m_sd,
data, size,
MSG_NOSIGNAL, (
struct sockaddr
const*) &addr,
sizeof(addr));
1044 sent = sendto(thisPtr->
d->
m_sd,
data, (
int)size,
MSG_NOSIGNAL, (
struct sockaddr
const*) &addr,
sizeof(addr));
1087 struct sockaddr_storage theirInfo;
1088 socklen_t infoLength =
sizeof(
struct sockaddr_storage);
1108 sd = accept(thisPtr->
d->
m_sd, (
struct sockaddr*)&theirInfo, &infoLength);
1158 const char* valPtr = (
const char*)valuePtr;
1160 const void* valPtr = valuePtr;
1166 nativeOption = SO_REUSEADDR;
1169 #if !defined(_WIN32) && !defined(__ANDROID__)
1171 nativeOption = SO_REUSEPORT;
1179 res = setsockopt(thisPtr->
d->
m_sd, SOL_SOCKET, nativeOption, valPtr, valueSize);
1193 const char* yes = (
const char*)&yesval;
1195 const void* yes = &yesval;
1198 (void)currentSocket;
1200 res = setsockopt(thisPtr->
d->
m_sd, SOL_SOCKET, SO_REUSEADDR, yes,
sizeof(yesval));
1207 res = bind(thisPtr->
d->
m_sd, info->ai_addr, (
int)info->ai_addrlen);
1223 struct sockaddr_storage
s;
1229 memset(&
s, 0,
sizeof(
s));
1233 struct sockaddr_in* sin = (
struct sockaddr_in*)&
s;
1234 sin->sin_family = AF_INET;
1235 sin->sin_port = htons(port);
1236 sin->sin_addr.s_addr = INADDR_ANY;
1237 addrlen =
sizeof(*sin);
1241 struct sockaddr_in6* sin6 = (
struct sockaddr_in6*)&
s;
1242 sin6->sin6_family = AF_INET6;
1243 sin6->sin6_port = htons(port);
1244 sin6->sin6_addr = in6addr_any;
1245 addrlen =
sizeof(*sin6);
1248 rv = bind(thisPtr->
d->
m_sd, (
struct sockaddr*)&
s, addrlen);
1261 int r = listen(thisPtr->
d->
m_sd, maxPending);
1272 (void)currentSocket;
1274 ret = connect(thisPtr->
d->
m_sd, info->ai_addr, (
int)info->ai_addrlen);
1279 memcpy(&thisPtr->
d->
m_remoteAddr, info->ai_addr, info->ai_addrlen);