11 #include <drift/dslcore.h>
12 #include <drift/sockets3.h>
13 #include <drift/Threading.h>
14 #include <drift/GenLib.h>
29 x->socks.insert(sock);
32 return (x->socks.find(sock) != x->socks.end());
35 auto it = x->socks.find(sock);
36 if (it != x->socks.end()) {
41 out->socks = in->socks;
54 hMutex =
new DSL_Mutex();
58 avail_flags |= DS3_FLAG_ZIP;
59 enabled_flags |= DS3_FLAG_ZIP;
61 memset(bError,0,
sizeof(bError));
70 DSL_Sockets3_Base::~DSL_Sockets3_Base() {
72 for (knownSocketList::const_iterator i = sockets.begin(); i != sockets.end(); i++) {
73 if (!silent) { printf(
"WARNING: DSL_SOCKET 0x%p (%s:%d) was not closed before DSL_Sockets3 was deleted!\n", *i, (*i)->remote_ip, (*i)->remote_port); }
84 #define WspiapiGetAddrInfo getaddrinfo
85 #define WspiapiFreeAddrInfo freeaddrinfo
88 addrinfo * DSL_Sockets3_Base::pResolve(
DSL_SOCKET * sock,
const char * host,
int port) {
93 sprintf(buf,
"%d", port);
96 struct addrinfo hints, *ret;
98 memset(&hints, 0,
sizeof(hints));
99 hints.ai_family = sock->family;
100 hints.ai_socktype = sock->type;
101 hints.ai_protocol = sock->proto;
102 int error = WspiapiGetAddrInfo(host, buf, &hints, &ret);
111 void DSL_Sockets3_Base::pFreeAddrInfo(addrinfo * ai) {
112 WspiapiFreeAddrInfo(ai);
115 bool DSL_Sockets3_Base::pUpdateAddrInfo(
DSL_SOCKET * sock) {
116 sockaddr_storage addr;
117 socklen_t addrLen =
sizeof(addr);
119 sock->remote_ip[0]=0;
126 char port[DS3_MAX_SERVLEN]={0};
127 if (getpeername(sock->sock, (sockaddr *)&addr, &addrLen) == 0) {
128 if (getnameinfo((sockaddr *)&addr, addrLen, sock->remote_ip,
sizeof(sock->remote_ip), port,
sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV) == 0) {
129 sock->remote_port = atoi(port);
138 if (getsockname(sock->sock, (sockaddr *)&addr, &addrLen) == 0) {
139 if (getnameinfo((sockaddr *)&addr, addrLen, sock->local_ip,
sizeof(sock->local_ip), port,
sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV) == 0) {
140 sock->local_port = atoi(port);
147 bool DSL_Sockets3_Base::IsKnownSocket(
DSL_SOCKET * sock) {
148 AutoMutexPtr(hMutex);
150 knownSocketList::const_iterator i = sockets.find(sock);
151 if (i != sockets.end()) {
158 DSL_SOCKET * DSL_Sockets3_Base::pAllocSocket() {
162 DSL_SOCKET * DSL_Sockets3_Base::Create(
int family,
int type,
int proto, uint32 flags) {
165 ret->family = family;
168 ret->sock = socket(family,type,proto);
170 if (ret->sock == INVALID_SOCKET) {
172 if (ret->sock == -1) {
179 if (flags & DS3_FLAG_ZIP) {
181 ret->flags |= DS3_FLAG_ZIP;
183 strcpy(bError,
"DSL has not been compiled with zlib support");
197 if ((enabled_flags & flag) == flag) {
204 if ((avail_flags & flag) == flag) {
211 sockaddr_storage addr;
212 memset(&addr, 0,
sizeof(addr));
213 socklen_t addrlen =
sizeof(addr);
214 return Accept(s, (sockaddr *)&addr, &addrlen, flags);
217 DSL_SOCKET * DSL_Sockets3_Base::Accept(
DSL_SOCKET * s, sockaddr *addr, socklen_t *addrlen, uint32 flags) {
219 memset(addr, 0, *addrlen);
220 ret->sock = accept(s->sock,addr,addrlen);
222 if (ret->sock == INVALID_SOCKET) {
224 if (ret->sock == -1) {
235 pUpdateAddrInfo(ret);
237 if (flags & DS3_FLAG_SSL) {
241 if (ssl->SwitchToSSL_Server(ret)) {
242 ret->flags |= DS3_FLAG_SSL;
248 strcpy(bError,
"SSL has not been enabled!");
255 strcpy(bError,
"DSL has not been compiled with SSL support");
261 if (flags & DS3_FLAG_ZIP) {
263 ret->flags |= DS3_FLAG_ZIP;
266 strcpy(bError,
"DSL has not been compiled with zlib support");
276 char buf[NI_MAXHOST], sport[NI_MAXSERV];
279 if (sock->family == AF_UNIX) {
280 struct sockaddr_un addr;
281 memset(&addr, 0,
sizeof(addr));
282 addr.sun_family = sock->family;
284 *addr.sun_path =
'\0';
285 strlcpy(addr.sun_path + 1, host + 1,
sizeof(addr.sun_path) - 1);
288 if (access(host, F_OK) == 0) {
292 int ret = bind(sock->sock, (
struct sockaddr*)&addr,
sizeof(addr));
295 if (getnameinfo((
struct sockaddr*)&addr,
sizeof(addr), buf,
sizeof(buf), sport,
sizeof(sport), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
296 printf(
"DSL_Sockets3_Base::BindToAddr() -> Bound to %s:%s\n", buf, sport);
308 addrinfo * ai = pResolve(sock, host, port);
310 addrinfo * Scan = ai;
311 while (!bret && Scan) {
312 if (Scan->ai_family == sock->family || sock->family == AF_UNSPEC) {
313 if (port > 0 && Scan->ai_family == AF_INET) {
314 ((sockaddr_in *)Scan->ai_addr)->sin_port = htons(port);
316 if (port > 0 && Scan->ai_family == AF_INET6) {
317 ((sockaddr_in6 *)Scan->ai_addr)->sin6_port = htons(port);
320 int ret = bind(sock->sock, Scan->ai_addr, Scan->ai_addrlen);
323 if (getnameinfo(Scan->ai_addr, Scan->ai_addrlen, buf,
sizeof(buf), sport,
sizeof(sport), NI_NUMERICHOST|NI_NUMERICSERV) == 0) {
324 printf(
"DSL_Sockets3_Base::BindToAddr() -> Bound to %s:%s\n", buf, sport);
331 if (getnameinfo(Scan->ai_addr, Scan->ai_addrlen, buf,
sizeof(buf), sport,
sizeof(sport), NI_NUMERICHOST|NI_NUMERICSERV) == 0) {
332 printf(
"DSL_Sockets3_Base::BindToAddr() -> Error binding %s:%s\n", buf, sport);
337 Scan = Scan->ai_next;
342 pUpdateError(sock, 999,
"Could not resolve any addresses matching address family.");
348 if (sock->family == AF_UNIX) {
349 pUpdateError(sock, 999,
"Bind() does not support Unix Domain Sockets.");
355 #if !defined(NO_IPV6)
356 if (sock->family == AF_INET6) {
358 memset(&addr, 0,
sizeof(addr));
359 addr.sin6_family = AF_INET6;
360 addr.sin6_port = htons(port);
361 ret = bind(sock->sock,(
const sockaddr *)&addr,
sizeof(sockaddr_in6));
365 memset(&addr, 0,
sizeof(addr));
366 addr.sin_addr.s_addr = INADDR_ANY;
367 addr.sin_family = AF_INET;
368 addr.sin_port = htons(port);
369 memset(addr.sin_zero, 0,
sizeof(addr.sin_zero));
370 ret = bind(sock->sock,(
const sockaddr *)&addr,
sizeof(sockaddr_in));
371 #if !defined(NO_IPV6)
375 return (ret == 0) ?
true:
false;
378 bool DSL_Sockets3_Base::Listen(
DSL_SOCKET * sock,
int backlog) {
379 int ret = listen(sock->sock,backlog);
387 int DSL_Sockets3_Base::Close(
DSL_SOCKET * sock) {
388 if (sock == NULL) {
return -1; }
391 knownSocketList::iterator x = sockets.find(sock);
392 if (x != sockets.end()) {
397 SOCKET s = sock->sock;
399 if (sock->flags & DS3_FLAG_SSL) {
402 ssl->pCloseSSL(sock);
411 return closesocket(s);
419 sock.family = PF_UNSPEC;
420 addrinfo * ai = pResolve(&sock, host, port);
429 bool DSL_Sockets3_Base::Connect(
DSL_SOCKET * sock, sockaddr * addr,
size_t addrlen) {
430 if (connect(sock->sock,addr,addrlen) != 0) {
432 pUpdateAddrInfo(sock);
435 pUpdateAddrInfo(sock);
439 bool DSL_Sockets3_Base::Connect(
DSL_SOCKET * sock,
const char * host,
int port) {
440 if (sock->family == AF_UNIX) {
441 struct sockaddr_un addr;
442 memset(&addr, 0,
sizeof(addr));
443 addr.sun_family = sock->family;
445 *addr.sun_path =
'\0';
446 strlcpy(addr.sun_path + 1, host + 1,
sizeof(addr.sun_path) - 1);
450 int ret = connect(sock->sock, (
struct sockaddr*)&addr,
sizeof(addr));
459 addrinfo * ai = pResolve(sock, host, port);
462 addrinfo * Scan = ai;
463 while (Scan && !(ret = Connect(sock,Scan->ai_addr,Scan->ai_addrlen)) && !sock->nonblocking) {
464 Scan = Scan->ai_next;
466 if (!ret) { pUpdateError(sock); }
476 if (sock->family == AF_UNIX) {
477 pUpdateError(sock, 999,
"ConnectWithTimeout() does not support Unix Domain Sockets.");
481 addrinfo * ai = pResolve(sock, host, port);
487 bool nb = sock->nonblocking;
489 SetNonBlocking(sock,
true);
494 addrinfo * Scan = ai;
497 while (Scan && tries--) {
498 Connect(sock, Scan->ai_addr, Scan->ai_addrlen);
500 printf(
"DSL_Sockets3_Base::ConnectWithTimeout(%s:%d): Trying %s ...\n", host, port, sock->remote_ip);
502 memset(&timeo,0,
sizeof(timeo));
503 timeo.tv_sec = (timeout / 1000);
504 timeo.tv_usec = timeout - (timeo.tv_sec * 1000);
505 timeo.tv_usec *= 1000;
507 if (pUpdateAddrInfo(sock)) {
512 Scan = Scan->ai_next;
517 SetNonBlocking(sock,
false);
523 int DSL_Sockets3_Base::Send(
DSL_SOCKET * sock,
const char * data_in,
int datalen,
bool doloop) {
524 char * data = (
char *)data_in;
525 if (datalen == -1) { datalen = strlen(data); }
528 if (sock->flags & DS3_FLAG_ZIP) {
529 unsigned long dlen = compressBound(datalen)+9;
530 char * data2 = (
char *)dsl_malloc(dlen);
531 if (compress2((Bytef *)data2+9, &dlen, (Bytef *)data, datalen, 5) == Z_OK && dlen < datalen) {
533 memcpy(data2+1, &dlen, 4);
534 memcpy(data2+5, &datalen, 4);
538 memcpy(data2+1, &datalen, 4);
539 memcpy(data2+5, data, datalen);
546 if (datalen == 0) {
return 0; }
550 int o = pSend(sock,data+n,left);
555 if (sock->flags & DS3_FLAG_ZIP) {
563 if (sock->flags & DS3_FLAG_ZIP) {
573 }
while (left > 0 && doloop);
576 if (sock->flags & DS3_FLAG_ZIP) {
583 int DSL_Sockets3_Base::pSend(
DSL_SOCKET * sock,
const char * data, uint32 datalen) {
584 return send(sock->sock, data, datalen, 0);
588 char * data = (
char *)data_in;
589 if (sock->flags & DS3_FLAG_SSL) {
590 sprintf(bError,
"SendTo doesn't work with SSL");
595 if (datalen == -1) { datalen = strlen(data); }
598 if (sock->flags & DS3_FLAG_ZIP) {
599 unsigned long dlen = compressBound(datalen)+9;
600 char * data2 = (
char *)dsl_malloc(dlen);
601 if (compress2((Bytef *)data2+9, &dlen, (Bytef *)data, datalen, 5) == Z_OK && dlen < datalen) {
603 memcpy(data2+1, &dlen, 4);
604 memcpy(data2+5, &datalen, 4);
608 memcpy(data2+1, &datalen, 4);
609 memcpy(data2+5, data, datalen);
616 addrinfo * ai = pResolve(sock, host, port);
618 int ret = sendto(sock->sock,data,datalen,0,ai->ai_addr,ai->ai_addrlen);
619 if (ret <= 0) { pUpdateError(sock); }
620 pUpdateAddrInfo(sock);
622 if (sock->flags & DS3_FLAG_ZIP) {
630 if (sock->flags & DS3_FLAG_ZIP) {
638 if (sock->flags & DS3_FLAG_SSL) {
639 sprintf(bError,
"RecvFrom doesn't work with SSL");
644 sockaddr * addr = (sockaddr *)dsl_malloc(ADDRLEN);
645 memset(addr, 0, ADDRLEN);
647 int addrLen = ADDRLEN;
649 socklen_t addrLen = ADDRLEN;
651 int n = recvfrom(sock->sock,buf,bufsize,0, (sockaddr *)addr, &addrLen);
652 if (n <= 0) { pUpdateError(sock); }
654 if (addr->sa_family == AF_INET) {
655 sockaddr_in * p = (sockaddr_in *)addr;
656 inet_ntop(addr->sa_family, &p->sin_addr, sock->remote_ip,
sizeof(sock->remote_ip));
657 sock->remote_port = ntohs(p->sin_port);
658 }
else if (addr->sa_family == AF_INET6) {
659 sockaddr_in6 * p = (sockaddr_in6 *)addr;
660 inet_ntop(addr->sa_family, &p->sin6_addr, sock->remote_ip,
sizeof(sock->remote_ip));
661 sock->remote_port = ntohs(p->sin6_port);
663 sprintf(bError,
"Unknown address family!");
670 memset(host, 0, hostSize);
671 strncpy(host, sock->remote_ip, hostSize-1);
674 *port = sock->remote_port;
681 int DSL_Sockets3_Base::pRecv(
DSL_SOCKET * sock,
char * buf, uint32 bufsize) {
682 int n = recv(sock->sock,buf,bufsize,0);
683 if (n <= 0) { pUpdateError(sock); }
684 if (n < 0) { n = -1; }
688 int DSL_Sockets3_Base::pPeek(
DSL_SOCKET * sock,
char * buf, uint32 bufsize) {
689 int n = recv(sock->sock,buf,bufsize,MSG_PEEK);
690 if (n <= 0) { pUpdateError(sock); }
691 if (n < 0) { n = -1; }
695 int DSL_Sockets3_Base::Recv(
DSL_SOCKET * sock,
char * buf, uint32 bufsize) {
698 if (sock->flags & DS3_FLAG_ZIP) {
701 strcpy(bError,
"Buffer too small");
705 n = pRecv(sock, buf, 1);
714 uint32 * sizec = (uint32 *)p;
716 uint32 * sizeu = (uint32 *)p;
717 if (*sizeu > bufsize) {
719 strcpy(bError,
"Buffer too small");
722 uint32 left = *sizec;
723 uLongf size = *sizeu;
725 char * tmp = (
char *)dsl_malloc(left);
727 n = pRecv(sock, tmp+ind, left);
734 if (uncompress((Bytef *)buf, (uLongf *)&size, (Bytef *)tmp, ind) == Z_OK) {
740 strcpy(bError,
"Error uncompressing data stream");
744 }
else if (buf[0] ==
'U') {
746 uint32 * size = (uint32 *)buf;
747 if (*size > bufsize) {
749 strcpy(bError,
"Buffer too small");
755 n = pRecv(sock, buf+ind, left);
766 strcpy(bError,
"ERROR: Stream does not appear to be zipped!");
771 return pRecv(sock,buf,bufsize);
774 int DSL_Sockets3_Base::Peek(
DSL_SOCKET * sock,
char * buf, uint32 bufsize) {
775 return pPeek(sock,buf,bufsize);
779 if (sock->flags & DS3_FLAG_SSL) {
780 sprintf(bError,
"PeekFrom doesn't work with SSL");
785 sockaddr * addr = (sockaddr *)dsl_malloc(ADDRLEN);
786 memset(addr, 0, ADDRLEN);
788 int addrLen = ADDRLEN;
790 socklen_t addrLen = ADDRLEN;
792 int n = recvfrom(sock->sock,buf,bufsize, MSG_PEEK, (sockaddr *)addr, &addrLen);
793 if (n <= 0) { pUpdateError(sock); }
795 pUpdateAddrInfo(sock);
797 memset(host, 0, hostSize);
798 strncpy(host, sock->remote_ip, hostSize-1);
801 *port = sock->remote_port;
808 int DSL_Sockets3_Base::RecvLine(
DSL_SOCKET * sock,
char * buf,
int bufsize) {
809 int n = Peek(sock,buf,bufsize - 1);
810 if (n < 0) {
return RL3_ERROR; }
811 if (n == 0) {
return RL3_CLOSED; }
814 char *p = strchr(buf,
'\n');
818 memset(buf, 0, bufsize);
820 while (buf[strlen(buf) - 1] ==
'\n') { buf[strlen(buf) - 1] = 0; }
821 while (buf[strlen(buf) - 1] ==
'\r') { buf[strlen(buf) - 1] = 0; }
823 }
else if (n == (bufsize-1)) {
824 return RL3_LINETOOLONG;
831 int n =
PeekFrom(sock, host, hostSize, port, buf,bufsize - 1);
832 if (n <= 0) { pUpdateError(sock); }
833 if (n < 0) {
return RL3_ERROR; }
834 if (n == 0) {
return RL3_CLOSED; }
837 char *p = strchr(buf,
'\n');
840 memset(buf, 0, bufsize);
841 RecvFrom(sock, host, hostSize, port, buf,n);
842 while (buf[strlen(buf) - 1] ==
'\n') { buf[strlen(buf) - 1] = 0; }
843 while (buf[strlen(buf) - 1] ==
'\r') { buf[strlen(buf) - 1] = 0; }
852 timeo.tv_sec = millisec / 1000;
853 millisec -= (timeo.tv_sec * 1000);
854 timeo.tv_usec = (millisec * 1000);
858 int DSL_Sockets3_Base::pSelect_Read(
DSL_SOCKET * sock, timeval * timeo) {
861 FD_SET(sock->sock, &fd);
862 int ret = select(sock->sock + 1, &fd, NULL, NULL, timeo);
863 if (ret < 0) { pUpdateError(sock); }
868 return pSelect_Read(sock, timeo);
879 DFD_COPY(list_r, &tmp);
880 for (
auto x = list_r->socks.begin(); x != list_r->socks.end(); x++) {
881 if ((*x)->sock > high) {
884 FD_SET((*x)->sock, &fd);
890 DFD_COPY(list_w, &tmp2);
891 for (
auto x = list_w->socks.begin(); x != list_w->socks.end(); x++) {
892 if ((*x)->sock > high) {
895 FD_SET((*x)->sock, &fd2);
900 int ret = select(high+1, list_r ? &fd : NULL, list_w ? &fd2 : NULL, NULL, timeo);
901 if (ret < 0) { pUpdateError(NULL); }
904 for (
auto x = tmp.socks.begin(); x != tmp.socks.end(); x++) {
905 if (FD_ISSET((*x)->sock, &fd)) {
912 for (
auto x = tmp2.socks.begin(); x != tmp2.socks.end(); x++) {
913 if (FD_ISSET((*x)->sock, &fd2)) {
924 timeo.tv_sec = millisec / 1000;
925 millisec -= (timeo.tv_sec * 1000);
926 timeo.tv_usec = (millisec * 1000);
937 tmp.socks = list_r->socks;
938 for (
auto x = list_r->socks.begin(); x != list_r->socks.end(); x++) {
939 if ((*x)->sock > high) {
942 FD_SET((*x)->sock, &fd);
947 int ret = select(high+1, list_r ? &fd : NULL, NULL, NULL, timeo);
948 if (ret < 0) { pUpdateError(NULL); }
951 for (
auto x = tmp.socks.begin(); x != tmp.socks.end(); x++) {
952 if (FD_ISSET((*x)->sock, &fd)) {
963 timeo.tv_sec = millisec / 1000;
964 millisec -= (timeo.tv_sec * 1000);
965 timeo.tv_usec = (millisec * 1000);
972 FD_SET(sock->sock, &fd);
973 int ret = select(sock->sock+1,NULL,&fd,NULL,timeo);
974 if (ret < 0) { pUpdateError(sock); }
980 timeo.tv_sec = millisec / 1000;
981 millisec -= (timeo.tv_sec * 1000);
982 timeo.tv_usec = (millisec * 1000);
987 int DSL_Sockets3_Base::SetLinger(
DSL_SOCKET * sock,
bool linger,
unsigned short timeo) {
988 struct linger lin = { linger ? 1:0, linger ? timeo:0 };
989 int ret = setsockopt(sock->sock, SOL_SOCKET, SO_LINGER, (
char *)&lin,
sizeof(lin));
994 int DSL_Sockets3_Base::SetReuseAddr(
DSL_SOCKET * sock,
bool reuse_addr) {
995 int ra = reuse_addr ? 1:0;
996 int ret = setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (
char *)&ra,
sizeof(ra));
1001 int DSL_Sockets3_Base::SetNoDelay(
DSL_SOCKET * sock,
bool no_delay) {
1003 int nodelay = no_delay ? 1:0;
1004 int ret = setsockopt(sock->sock, IPPROTO_TCP, TCP_NODELAY, (
char *)&nodelay,
sizeof(
int));
1008 pUpdateError(sock, 999,
"Feature not supported on this platform");
1013 int DSL_Sockets3_Base::SetKeepAlive(
DSL_SOCKET * sock,
bool ka) {
1014 int keepalive = ka ? 1:0;
1015 int ret = setsockopt(sock->sock,SOL_SOCKET,SO_KEEPALIVE,(
char *)&keepalive,
sizeof(
int));
1020 int DSL_Sockets3_Base::SetBroadcast(
DSL_SOCKET * sock,
bool broadcast) {
1021 int tmp = broadcast ? 1:0;
1022 int ret = setsockopt(sock->sock,SOL_SOCKET,SO_BROADCAST,(
char *)&tmp,
sizeof(tmp));
1028 #ifndef SIO_UDP_CONNRESET
1029 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
1031 bool DSL_Sockets3_Base::DisableUDPConnReset(
DSL_SOCKET * sock,
bool noconnreset) {
1032 DWORD dwBytesReturned = 0;
1033 BOOL bNewBehavior = noconnreset ?
false:
true;
1034 return (WSAIoctl(sock->sock, SIO_UDP_CONNRESET, &bNewBehavior,
sizeof(bNewBehavior), NULL, 0, &dwBytesReturned, NULL, NULL) == 0) ?
true:
false;
1037 bool DSL_Sockets3_Base::DisableUDPConnReset(
DSL_SOCKET * sock,
bool noconnreset) {
1043 int DSL_Sockets3_Base::SetRecvTimeout(
DSL_SOCKET * sock, uint32 millisec) {
1045 int ret = setsockopt(sock->sock,SOL_SOCKET,SO_RCVTIMEO,(
char *)&millisec,
sizeof(millisec));
1048 tv.tv_sec = millisec / 1000;
1049 tv.tv_usec = millisec - (tv.tv_sec * 1000);
1050 int ret = setsockopt(sock->sock,SOL_SOCKET,SO_RCVTIMEO,(
char *)&tv,
sizeof(tv));
1056 int DSL_Sockets3_Base::SetSendTimeout(
DSL_SOCKET * sock, uint32 millisec) {
1058 int ret = setsockopt(sock->sock,SOL_SOCKET,SO_SNDTIMEO,(
char *)&millisec,
sizeof(millisec));
1061 tv.tv_sec = millisec / 1000;
1062 tv.tv_usec = millisec - (tv.tv_sec * 1000);
1063 int ret = setsockopt(sock->sock,SOL_SOCKET,SO_SNDTIMEO,(
char *)&tv,
sizeof(tv));
1069 bool DSL_Sockets3_Base::IsNonBlocking(
DSL_SOCKET * sock) {
1070 return sock->nonblocking;
1073 void DSL_Sockets3_Base::SetNonBlocking(
DSL_SOCKET * sock,
bool non_blocking) {
1074 sock->nonblocking = non_blocking;
1076 unsigned long blah = non_blocking ? 1:0;
1077 ioctlsocket(sock->sock,FIONBIO,&blah);
1080 fcntl(sock->sock, F_SETFL, fcntl(sock->sock, F_GETFL) | O_NONBLOCK);
1082 fcntl(sock->sock, F_SETFL, fcntl(sock->sock, F_GETFL) & ~O_NONBLOCK);
1088 std::string DSL_Sockets3_Base::GetHostIP(
const char * host,
int type,
int proto) {
1089 struct addrinfo hints, *ret, *scan;
1092 memset(&hints, 0,
sizeof(hints));
1093 hints.ai_family = AF_UNSPEC;
1096 int error = WspiapiGetAddrInfo(host,
"", &hints, &ret);
1102 char buf[DS3_MAX_HOSTLEN];
1107 if (getnameinfo(scan->ai_addr, scan->ai_addrlen, buf,
sizeof(buf), NULL, 0, NI_NUMERICHOST|NI_NUMERICSERV) == 0) {
1111 scan = scan->ai_next;
1117 WspiapiFreeAddrInfo(ret);
1122 int DSL_Sockets3_Base::GetLastError(
D_SOCKET * sock) {
1123 if (sock) {
return sock->last_errno; }
1126 const char * DSL_Sockets3_Base::GetLastErrorString(
D_SOCKET * sock) {
1127 if (sock) {
return sock->last_error; }
1131 void DSL_Sockets3_Base::pUpdateError(
DSL_SOCKET * sock,
int serrno,
const char * errstr) {
1135 sock->last_errno = bErrNo;
1136 sstrcpy(sock->last_error, bError);
1138 if (!silent && bErrNo != 0 && bErrNo != EWOULDBLOCK && bErrNo != ENOTCONN && bErrNo != EINPROGRESS && bErrNo != ENOENT) {
1139 printf(
"pUpdateError(): %d -> %s\n",bErrNo,bError);
1143 void DSL_Sockets3_Base::pUpdateError(
DSL_SOCKET * sock) {
1145 bErrNo = WSAGetLastError();
1147 bError[
sizeof(bError)-1] = 0;
1148 if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, bErrNo, LANG_SYSTEM_DEFAULT, bError,
sizeof(bError)-1, NULL) == 0) {
1149 sstrcpy(bError,
"Error getting error message!");
1155 char *error = strerror(bErrNo);
1159 sprintf(bError,
"Unknown Error (Code: %d)",bErrNo);
1164 sock->last_errno = bErrNo;
1165 sstrcpy(sock->last_error, bError);
1167 if (bErrNo != 0 && bErrNo != EWOULDBLOCK && bErrNo != ENOTCONN && bErrNo != EINPROGRESS && bErrNo != ENOENT && !silent) {
1168 printf(
"pUpdateError(): %d -> %s\n",bErrNo,bError);
virtual int Select_Read_List(DSL_SOCKET_LIST *list, timeval *timeo)
same return value as select(). Use below functions to build your lists.
virtual bool IsSupported(unsigned int flag)
This lets you know if a feature is supported.
virtual int GetFamilyHint(const char *host, int port)
Returns PF_INET or PF_INET6 for a domain or IP address.
virtual bool IsEnabled(unsigned int flag)
This lets you know if a feature is supported and activated (ie. EnableSSL() has been called)
virtual int Select_List(DSL_SOCKET_LIST *list_r, DSL_SOCKET_LIST *list_w, timeval *timeo)
same return value as select()
virtual int Select_Read(DSL_SOCKET *sock, timeval *timeo)
same return value as select()
virtual bool BindToAddr(DSL_SOCKET *sock, const char *host, int port)
Bind to specific IP.
virtual int PeekFrom(DSL_SOCKET *sock, char *host, uint32 hostSize, int *port, char *buf, uint32 bufsize)
For UDP/datagram sockets, same details otherwise as Peek()
virtual int SendTo(DSL_SOCKET *sock, const char *host, int port, const char *buf, int datalen=-1)
For UDP/datagram sockets, same details otherwise as Send()
virtual bool Bind(DSL_SOCKET *sock, int port)
Bind to all interfaces (0.0.0.0)
virtual int RecvLineFrom(DSL_SOCKET *sock, char *host, uint32 hostSize, int *port, char *buf, uint32 bufsize)
For UDP/datagram sockets, same details otherwise as RecvLine()
virtual int Select_Write(DSL_SOCKET *sock, timeval *timeo)
same return value as select()
virtual bool ConnectWithTimeout(DSL_SOCKET *sock, const char *host, int port, uint32 timeout)
Connect with timeout in milliseconds.
virtual int RecvFrom(DSL_SOCKET *sock, char *host, uint32 hostSize, int *port, char *buf, uint32 bufsize)
For UDP/datagram sockets, same details otherwise as Recv()
virtual void Silent(bool bSilent)
Don't print socket errors to the console.
DSL_API void DSL_CC dsl_free(void *ptr)
DSL_API void dsl_cleanup()
DSL_API bool DSL_CC dsl_init()
DSL_API size_t DSL_CC strlcpy(char *dst, const char *src, size_t siz)