X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=lhnet.c;h=fde0f4e772663fda706ba93d931e3c56e4c1d4bb;hb=a3a9fdaf8edba37e4c895b2f10926481c46916a0;hp=4b33180bb31b179ed9336f6892b0807c06435d16;hpb=0ca4c729a5ff7502e5551eb4f1eacf3c6d0f04f7;p=xonotic%2Fdarkplaces.git diff --git a/lhnet.c b/lhnet.c index 4b33180b..fde0f4e7 100644 --- a/lhnet.c +++ b/lhnet.c @@ -1,6 +1,10 @@ // Written by Forest Hale 2003-06-15 and placed into public domain. +#ifndef STANDALONETEST +#include "quakedef.h" +#endif + #include #include #include @@ -8,18 +12,21 @@ #ifdef WIN32 #include #else -#include -#include -//#include #include #include #include #include +#include +#include +#include +#endif + +#ifdef __MORPHOS__ +#include #endif // for Z_Malloc/Z_Free in quake #ifndef STANDALONETEST -#include "quakedef.h" #include "zone.h" #include "sys.h" #include "netconn.h" @@ -32,6 +39,42 @@ #include "lhnet.h" +#if defined(WIN32) +#define EWOULDBLOCK WSAEWOULDBLOCK +#define ECONNREFUSED WSAECONNREFUSED + +#define SOCKETERRNO WSAGetLastError() + +#define IOC_VENDOR 0x18000000 +#define _WSAIOW(x,y) (IOC_IN|(x)|(y)) +#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) + +#define SOCKLEN_T int +#elif defined(__MORPHOS__) +#define ioctlsocket IoctlSocket +#define closesocket CloseSocket +#define SOCKETERRNO Errno() + +#define SOCKLEN_T int +#else +#define ioctlsocket ioctl +#define closesocket close +#define SOCKETERRNO errno + +#define SOCKLEN_T socklen_t +#endif + +// to make LHNETADDRESS_FromString resolve repeated hostnames faster, cache them +#define MAX_NAMECACHE 64 +static struct namecache_s +{ + lhnetaddress_t address; + double expirationtime; + char name[64]; +} +namecache[MAX_NAMECACHE]; +static int namecacheposition = 0; + int LHNETADDRESS_FromPort(lhnetaddress_t *address, int addresstype, int port) { if (!address) @@ -64,11 +107,11 @@ int LHNETADDRESS_FromPort(lhnetaddress_t *address, int addresstype, int port) int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int defaultport) { - int port, namelen, d1, d2, d3, d4; + int i, port, namelen, d1, d2, d3, d4; struct hostent *hostentry; const char *colon; char name[128]; - if (!address || !string) + if (!address || !string || !*string) return 0; memset(address, 0, sizeof(*address)); address->addresstype = LHNETADDRESSTYPE_NONE; @@ -98,7 +141,12 @@ int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int def return 1; } // try to parse as dotted decimal ipv4 address first - if (sscanf(name, "%d.%d.%d.%d", &d1, &d2, &d3, &d4) == 4 && (unsigned int)d1 < 256 && (unsigned int)d2 < 256 && (unsigned int)d3 < 256 && (unsigned int)d4 < 256) + // note this supports partial ip addresses + d1 = d2 = d3 = d4 = 0; +#if _MSC_VER >= 1400 +#define sscanf sscanf_s +#endif + if (sscanf(name, "%d.%d.%d.%d", &d1, &d2, &d3, &d4) >= 1 && (unsigned int)d1 < 256 && (unsigned int)d2 < 256 && (unsigned int)d3 < 256 && (unsigned int)d4 < 256) { // parsed a valid ipv4 address address->addresstype = LHNETADDRESSTYPE_INET4; @@ -113,6 +161,28 @@ int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int def #endif return 1; } + for (i = 0;i < MAX_NAMECACHE;i++) + if (!strcmp(namecache[i].name, name)) + break; +#ifdef STANDALONETEST + if (i < MAX_NAMECACHE) +#else + if (i < MAX_NAMECACHE && realtime < namecache[i].expirationtime) +#endif + { + *address = namecache[i].address; + if (address->addresstype == LHNETADDRESSTYPE_INET6) + { + address->addressdata.inet6.port = htons((unsigned short)port); + return 1; + } + else if (address->addresstype == LHNETADDRESSTYPE_INET4) + { + address->addressdata.inet4.port = htons((unsigned short)port); + return 1; + } + return 0; + } // try gethostbyname (handles dns and other ip formats) hostentry = gethostbyname(name); if (hostentry) @@ -124,6 +194,14 @@ int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int def address->addressdata.inet6.family = hostentry->h_addrtype; address->addressdata.inet6.port = htons((unsigned short)port); memcpy(address->addressdata.inet6.address, hostentry->h_addr_list[0], sizeof(address->addressdata.inet6.address)); + for (i = 0;i < (int)sizeof(namecache[namecacheposition].name)-1 && name[i];i++) + namecache[namecacheposition].name[i] = name[i]; + namecache[namecacheposition].name[i] = 0; +#ifndef STANDALONETEST + namecache[namecacheposition].expirationtime = realtime + 12 * 3600; // 12 hours +#endif + namecache[namecacheposition].address = *address; + namecacheposition = (namecacheposition + 1) % MAX_NAMECACHE; #ifdef STANDALONETEST printf("gethostbyname(\"%s\") returned ipv6 address [%x:%x:%x:%x:%x:%x:%x:%x]:%d\n", name, (int)address->addressdata.inet6.address[0], (int)address->addressdata.inet6.address[1], (int)address->addressdata.inet6.address[2], (int)address->addressdata.inet6.address[3], (int)address->addressdata.inet6.address[4], (int)address->addressdata.inet6.address[5], (int)address->addressdata.inet6.address[6], (int)address->addressdata.inet6.address[7], (int)ntohs(address->addressdata.inet6.port)); #endif @@ -136,6 +214,14 @@ int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int def address->addressdata.inet4.family = hostentry->h_addrtype; address->addressdata.inet4.port = htons((unsigned short)port); memcpy(address->addressdata.inet4.address, hostentry->h_addr_list[0], sizeof(address->addressdata.inet4.address)); + for (i = 0;i < (int)sizeof(namecache[namecacheposition].name)-1 && name[i];i++) + namecache[namecacheposition].name[i] = name[i]; + namecache[namecacheposition].name[i] = 0; +#ifndef STANDALONETEST + namecache[namecacheposition].expirationtime = realtime + 12 * 3600; // 12 hours +#endif + namecache[namecacheposition].address = *address; + namecacheposition = (namecacheposition + 1) % MAX_NAMECACHE; #ifdef STANDALONETEST printf("gethostbyname(\"%s\") returned ipv4 address %d.%d.%d.%d:%d\n", name, (int)address->addressdata.inet4.address[0], (int)address->addressdata.inet4.address[1], (int)address->addressdata.inet4.address[2], (int)address->addressdata.inet4.address[3], (int)ntohs(address->addressdata.inet4.port)); #endif @@ -145,6 +231,14 @@ int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int def #ifdef STANDALONETEST printf("gethostbyname failed on address \"%s\"\n", name); #endif + for (i = 0;i < (int)sizeof(namecache[namecacheposition].name)-1 && name[i];i++) + namecache[namecacheposition].name[i] = name[i]; + namecache[namecacheposition].name[i] = 0; +#ifndef STANDALONETEST + namecache[namecacheposition].expirationtime = realtime + 12 * 3600; // 12 hours +#endif + namecache[namecacheposition].address.addresstype = LHNETADDRESSTYPE_NONE; + namecacheposition = (namecacheposition + 1) % MAX_NAMECACHE; return 0; } @@ -162,7 +256,7 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int strin { if (stringbuffersize >= 12) { - sprintf(string, "local:%d", (int)address->addressdata.loop.port); + dpsnprintf(string, stringbuffersize, "local:%d", (int)address->addressdata.loop.port); return 1; } } @@ -170,7 +264,7 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int strin { if (stringbuffersize >= 6) { - strcpy(string, "local"); + memcpy(string, "local", 6); return 1; } } @@ -180,7 +274,7 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int strin { if (stringbuffersize >= 22) { - sprintf(string, "%d.%d.%d.%d:%d", (int)address->addressdata.inet4.address[0], (int)address->addressdata.inet4.address[1], (int)address->addressdata.inet4.address[2], (int)address->addressdata.inet4.address[3], (int)ntohs(address->addressdata.inet4.port)); + dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d:%d", (int)address->addressdata.inet4.address[0], (int)address->addressdata.inet4.address[1], (int)address->addressdata.inet4.address[2], (int)address->addressdata.inet4.address[3], (int)ntohs(address->addressdata.inet4.port)); return 1; } } @@ -188,7 +282,7 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int strin { if (stringbuffersize >= 16) { - sprintf(string, "%d.%d.%d.%d", (int)address->addressdata.inet4.address[0], (int)address->addressdata.inet4.address[1], (int)address->addressdata.inet4.address[2], (int)address->addressdata.inet4.address[3]); + dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d", (int)address->addressdata.inet4.address[0], (int)address->addressdata.inet4.address[1], (int)address->addressdata.inet4.address[2], (int)address->addressdata.inet4.address[3]); return 1; } } @@ -198,7 +292,7 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int strin { if (stringbuffersize >= 88) { - sprintf(string, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d", (int)address->addressdata.inet6.address[0], (int)address->addressdata.inet6.address[1], (int)address->addressdata.inet6.address[2], (int)address->addressdata.inet6.address[3], (int)address->addressdata.inet6.address[4], (int)address->addressdata.inet6.address[5], (int)address->addressdata.inet6.address[6], (int)address->addressdata.inet6.address[7], (int)ntohs(address->addressdata.inet6.port)); + dpsnprintf(string, stringbuffersize, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d", (int)address->addressdata.inet6.address[0], (int)address->addressdata.inet6.address[1], (int)address->addressdata.inet6.address[2], (int)address->addressdata.inet6.address[3], (int)address->addressdata.inet6.address[4], (int)address->addressdata.inet6.address[5], (int)address->addressdata.inet6.address[6], (int)address->addressdata.inet6.address[7], (int)ntohs(address->addressdata.inet6.port)); return 1; } } @@ -206,7 +300,7 @@ int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int strin { if (stringbuffersize >= 80) { - sprintf(string, "%x:%x:%x:%x:%x:%x:%x:%x", (int)address->addressdata.inet6.address[0], (int)address->addressdata.inet6.address[1], (int)address->addressdata.inet6.address[2], (int)address->addressdata.inet6.address[3], (int)address->addressdata.inet6.address[4], (int)address->addressdata.inet6.address[5], (int)address->addressdata.inet6.address[6], (int)address->addressdata.inet6.address[7]); + dpsnprintf(string, stringbuffersize, "%x:%x:%x:%x:%x:%x:%x:%x", (int)address->addressdata.inet6.address[0], (int)address->addressdata.inet6.address[1], (int)address->addressdata.inet6.address[2], (int)address->addressdata.inet6.address[3], (int)address->addressdata.inet6.address[4], (int)address->addressdata.inet6.address[5], (int)address->addressdata.inet6.address[6], (int)address->addressdata.inet6.address[7]); return 1; } } @@ -322,6 +416,11 @@ void LHNET_Init(void) lhnet_socketlist.next = lhnet_socketlist.prev = &lhnet_socketlist; lhnet_packetlist.next = lhnet_packetlist.prev = &lhnet_packetlist; lhnet_active = 1; +#ifdef WIN32 + lhnet_didWSAStartup = !WSAStartup(MAKEWORD(1, 1), &lhnet_winsockdata); + if (!lhnet_didWSAStartup) + Con_Print("LHNET_Init: WSAStartup failed, networking disabled\n"); +#endif } void LHNET_Shutdown(void) @@ -338,6 +437,13 @@ void LHNET_Shutdown(void) p->next->prev = p->prev; Z_Free(p); } +#ifdef WIN32 + if (lhnet_didWSAStartup) + { + lhnet_didWSAStartup = 0; + WSACleanup(); + } +#endif lhnet_active = 0; } @@ -347,9 +453,9 @@ static const char *LHNETPRIVATE_StrError(void) int i = WSAGetLastError(); switch (i) { - case WSAEINTR: return "WSAEINTR"; + case WSAEINTR: return "WSAEINTR"; case WSAEBADF: return "WSAEBADF"; - case WSAEACCES: return "WSAEACCES"; + case WSAEACCES: return "WSAEACCES"; case WSAEFAULT: return "WSAEFAULT"; case WSAEINVAL: return "WSAEINVAL"; case WSAEMFILE: return "WSAEMFILE"; @@ -392,19 +498,41 @@ static const char *LHNETPRIVATE_StrError(void) case WSAEREMOTE: return "WSAEREMOTE"; case WSAEDISCON: return "WSAEDISCON"; case 0: return "no error"; - default: return "unknown WSAE error"; + default: return "unknown WSAE error"; } #else return strerror(errno); #endif } +void LHNET_SleepUntilPacket_Microseconds(int microseconds) +{ + fd_set fdreadset; + struct timeval tv; + int lastfd; + lhnetsocket_t *s; + FD_ZERO(&fdreadset); + lastfd = 0; + for (s = lhnet_socketlist.next;s != &lhnet_socketlist;s = s->next) + { + if (s->address.addresstype == LHNETADDRESSTYPE_INET4 || s->address.addresstype == LHNETADDRESSTYPE_INET6) + { + if (lastfd < s->inetsocket) + lastfd = s->inetsocket; + FD_SET((unsigned int)s->inetsocket, &fdreadset); + } + } + tv.tv_sec = microseconds / 1000000; + tv.tv_usec = microseconds % 1000000; + select(lastfd + 1, &fdreadset, NULL, NULL, &tv); +} + lhnetsocket_t *LHNET_OpenSocket_Connectionless(lhnetaddress_t *address) { lhnetsocket_t *lhnetsocket, *s; if (!address) return NULL; - lhnetsocket = Z_Malloc(sizeof(*lhnetsocket)); + lhnetsocket = (lhnetsocket_t *)Z_Malloc(sizeof(*lhnetsocket)); if (lhnetsocket) { memset(lhnetsocket, 0, sizeof(*lhnetsocket)); @@ -446,32 +574,35 @@ lhnetsocket_t *LHNET_OpenSocket_Connectionless(lhnetaddress_t *address) case LHNETADDRESSTYPE_INET4: case LHNETADDRESSTYPE_INET6: #ifdef WIN32 - if (lhnet_didWSAStartup || (lhnet_didWSAStartup = !WSAStartup(MAKEWORD(1, 1), &lhnet_winsockdata))) + if (lhnet_didWSAStartup) { #endif if ((lhnetsocket->inetsocket = socket(address->addresstype == LHNETADDRESSTYPE_INET6 ? LHNETADDRESSTYPE_INET6_FAMILY : LHNETADDRESSTYPE_INET4_FAMILY, SOCK_DGRAM, IPPROTO_UDP)) != -1) { #ifdef WIN32 u_long _true = 1; - if (ioctlsocket(lhnetsocket->inetsocket, FIONBIO, &_true) != -1) + u_long _false = 0; #else char _true = 1; - if (ioctl(lhnetsocket->inetsocket, FIONBIO, &_true) != -1) #endif + if (ioctlsocket(lhnetsocket->inetsocket, FIONBIO, &_true) != -1) { -#ifdef WIN32 - int namelen; -#else - socklen_t namelen; -#endif + SOCKLEN_T namelen; namelen = address->addresstype == LHNETADDRESSTYPE_INET6 ? sizeof(lhnetsocket->address.addressdata.inet6) : sizeof(lhnetsocket->address.addressdata.inet4); - if (bind(lhnetsocket->inetsocket, (void *)&lhnetsocket->address.addressdata, namelen) != -1) + if (bind(lhnetsocket->inetsocket, (struct sockaddr *)&lhnetsocket->address.addressdata, namelen) != -1) { - getsockname(lhnetsocket->inetsocket, (void *)&lhnetsocket->address.addressdata, &namelen); + int i = 1; + getsockname(lhnetsocket->inetsocket, (struct sockaddr *)&lhnetsocket->address.addressdata, &namelen); + // enable broadcast on this socket + setsockopt(lhnetsocket->inetsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)); lhnetsocket->next = &lhnet_socketlist; lhnetsocket->prev = lhnetsocket->next->prev; lhnetsocket->next->prev = lhnetsocket; lhnetsocket->prev->next = lhnetsocket; +#ifdef WIN32 + if (ioctlsocket(lhnetsocket->inetsocket, SIO_UDP_CONNRESET, &_false) == -1) + Con_DPrintf("LHNET_OpenSocket_Connectionless: ioctlsocket SIO_UDP_CONNRESET returned error: %s\n", LHNETPRIVATE_StrError()); +#endif return lhnetsocket; } else @@ -479,18 +610,14 @@ lhnetsocket_t *LHNET_OpenSocket_Connectionless(lhnetaddress_t *address) } else Con_Printf("LHNET_OpenSocket_Connectionless: ioctlsocket returned error: %s\n", LHNETPRIVATE_StrError()); -#ifdef WIN32 closesocket(lhnetsocket->inetsocket); -#else - close(lhnetsocket->inetsocket); -#endif } else Con_Printf("LHNET_OpenSocket_Connectionless: socket returned error: %s\n", LHNETPRIVATE_StrError()); #ifdef WIN32 } else - Con_Print("LHNET_OpenSocket_Connectionless: WSAStartup failed\n"); + Con_Print("LHNET_OpenSocket_Connectionless: can't open a socket (WSAStartup failed during LHNET_Init)\n"); #endif break; default: @@ -516,19 +643,8 @@ void LHNET_CloseSocket(lhnetsocket_t *lhnetsocket) // no special close code for loopback, just inet if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET4 || lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET6) { -#ifdef WIN32 closesocket(lhnetsocket->inetsocket); -#else - close(lhnetsocket->inetsocket); -#endif - } -#ifdef WIN32 - if (lhnet_socketlist.next == &lhnet_socketlist && lhnet_didWSAStartup) - { - lhnet_didWSAStartup = 0; - WSACleanup(); } -#endif Z_Free(lhnetsocket); } } @@ -565,7 +681,7 @@ int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, continue; } #ifndef STANDALONETEST - if (cl_netlocalping.value && (Sys_DoubleTime() - cl_netlocalping.value * 1000.0) < p->sentdoubletime) + if (cl_netlocalping.value && (realtime - cl_netlocalping.value * (1.0 / 2000.0)) < p->sentdoubletime) continue; #endif if (value == 0 && p->destinationport == lhnetsocket->address.addressdata.loop.port) @@ -588,7 +704,7 @@ int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, } else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET4) { - int inetaddresslength; + unsigned int inetaddresslength; address->addresstype = LHNETADDRESSTYPE_NONE; inetaddresslength = sizeof(address->addressdata.inet4); value = recvfrom(lhnetsocket->inetsocket, content, maxcontentlength, 0, (struct sockaddr *)&address->addressdata.inet4, &inetaddresslength); @@ -599,31 +715,21 @@ int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, } else if (value == -1) { -#ifdef WIN32 - int e = WSAGetLastError(); - if (e == WSAEWOULDBLOCK) + int e = SOCKETERRNO; + if (e == EWOULDBLOCK) return 0; switch (e) - { - case WSAECONNREFUSED: - Con_Print("Connection refused\n"); - return 0; - } -#else - if (errno == EWOULDBLOCK) - return 0; - switch (errno) { case ECONNREFUSED: Con_Print("Connection refused\n"); return 0; } -#endif + Con_Printf("LHNET_Read: recvfrom returned error: %s\n", LHNETPRIVATE_StrError()); } } else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET6) { - int inetaddresslength; + unsigned int inetaddresslength; address->addresstype = LHNETADDRESSTYPE_NONE; inetaddresslength = sizeof(address->addressdata.inet6); value = recvfrom(lhnetsocket->inetsocket, content, maxcontentlength, 0, (struct sockaddr *)&address->addressdata.inet6, &inetaddresslength); @@ -634,26 +740,16 @@ int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, } else if (value == -1) { -#ifdef WIN32 - int e = WSAGetLastError(); - if (e == WSAEWOULDBLOCK) + int e = SOCKETERRNO; + if (e == EWOULDBLOCK) return 0; switch (e) - { - case WSAECONNREFUSED: - Con_Print("Connection refused\n"); - return 0; - } -#else - if (errno == EWOULDBLOCK) - return 0; - switch (errno) { case ECONNREFUSED: Con_Print("Connection refused\n"); return 0; } -#endif + Con_Printf("LHNET_Read: recvfrom returned error: %s\n", LHNETPRIVATE_StrError()); } } return value; @@ -669,7 +765,7 @@ int LHNET_Write(lhnetsocket_t *lhnetsocket, const void *content, int contentleng if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_LOOP) { lhnetpacket_t *p; - p = Z_Malloc(sizeof(*p) + contentlength); + p = (lhnetpacket_t *)Z_Malloc(sizeof(*p) + contentlength); p->data = (void *)(p + 1); memcpy(p->data, content, contentlength); p->length = contentlength; @@ -681,7 +777,7 @@ int LHNET_Write(lhnetsocket_t *lhnetsocket, const void *content, int contentleng p->next->prev = p; p->prev->next = p; #ifndef STANDALONETEST - p->sentdoubletime = Sys_DoubleTime(); + p->sentdoubletime = realtime; #endif value = contentlength; } @@ -690,14 +786,9 @@ int LHNET_Write(lhnetsocket_t *lhnetsocket, const void *content, int contentleng value = sendto(lhnetsocket->inetsocket, content, contentlength, 0, (struct sockaddr *)&address->addressdata.inet4, sizeof(address->addressdata.inet4)); if (value == -1) { -#ifdef WIN32 - int e = WSAGetLastError(); - if (e == WSAEWOULDBLOCK) - return 0; -#else - if (errno == EWOULDBLOCK) + if (SOCKETERRNO == EWOULDBLOCK) return 0; -#endif + Con_Printf("LHNET_Write: sendto returned error: %s\n", LHNETPRIVATE_StrError()); } } else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET6) @@ -705,14 +796,9 @@ int LHNET_Write(lhnetsocket_t *lhnetsocket, const void *content, int contentleng value = sendto(lhnetsocket->inetsocket, content, contentlength, 0, (struct sockaddr *)&address->addressdata.inet6, sizeof(address->addressdata.inet6)); if (value == -1) { -#ifdef WIN32 - int e = WSAGetLastError(); - if (e == WSAEWOULDBLOCK) + if (SOCKETERRNO == EWOULDBLOCK) return 0; -#else - if (errno == EWOULDBLOCK) - return 0; -#endif + Con_Printf("LHNET_Write: sendto returned error: %s\n", LHNETPRIVATE_StrError()); } } return value; @@ -721,6 +807,58 @@ int LHNET_Write(lhnetsocket_t *lhnetsocket, const void *content, int contentleng #ifdef STANDALONETEST int main(int argc, char **argv) { +#if 1 + char *buffer = "test", buffer2[1024]; + int blen = strlen(buffer); + int b2len = 1024; + lhnetsocket_t *sock1; + lhnetsocket_t *sock2; + lhnetaddress_t myaddy1; + lhnetaddress_t myaddy2; + lhnetaddress_t myaddy3; + lhnetaddress_t localhostaddy1; + lhnetaddress_t localhostaddy2; + int test1; + int test2; + + printf("calling LHNET_Init\n"); + LHNET_Init(); + + printf("calling LHNET_FromPort twice to create two local addresses\n"); + LHNETADDRESS_FromPort(&myaddy1, LHNETADDRESSTYPE_INET4, 4000); + LHNETADDRESS_FromPort(&myaddy2, LHNETADDRESSTYPE_INET4, 4001); + LHNETADDRESS_FromString(&localhostaddy1, "127.0.0.1", 4000); + LHNETADDRESS_FromString(&localhostaddy2, "127.0.0.1", 4001); + + printf("calling LHNET_OpenSocket_Connectionless twice to create two local sockets\n"); + sock1 = LHNET_OpenSocket_Connectionless(&myaddy1); + sock2 = LHNET_OpenSocket_Connectionless(&myaddy2); + + printf("calling LHNET_Write to send a packet from the first socket to the second socket\n"); + test1 = LHNET_Write(sock1, buffer, blen, &localhostaddy2); + printf("sleeping briefly\n"); +#ifdef WIN32 + Sleep (100); +#else + usleep (100000); +#endif + printf("calling LHNET_Read on the second socket to read the packet sent from the first socket\n"); + test2 = LHNET_Read(sock2, buffer2, b2len - 1, &myaddy3); + if (test2 > 0) + Con_Printf("socket to socket test succeeded\n"); + else + Con_Printf("socket to socket test failed\n"); + +#ifdef WIN32 + printf("press any key to exit\n"); + getchar(); +#endif + + printf("calling LHNET_Shutdown\n"); + LHNET_Shutdown(); + printf("exiting\n"); + return 0; +#else lhnetsocket_t *sock[16], *sendsock; int i; int numsockets; @@ -856,6 +994,7 @@ int main(int argc, char **argv) } printf("Testing code for lhnet.c\nusage: lhnettest [ ]\n"); return -1; +#endif } #endif