X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=lhnet.c;h=8c9c845562355afcd9700d09b0ff12dc77d69510;hp=d6372548ce3c649d84d8c06414339ace6fe08fdf;hb=17fdc60aff5ea50886d4fd180ff00af11f7272d9;hpb=fd530671d1dad60bbe6ec5951ef808de18c8d840 diff --git a/lhnet.c b/lhnet.c index d6372548..8c9c8455 100644 --- a/lhnet.c +++ b/lhnet.c @@ -8,13 +8,13 @@ #ifdef WIN32 #include #else -#include -//#include -//#include #include #include #include #include +#include +#include +#include #endif // for Z_Malloc/Z_Free in quake @@ -24,6 +24,8 @@ #include "sys.h" #include "netconn.h" #else +#define Con_Print printf +#define Con_Printf printf #define Z_Malloc malloc #define Z_Free free #endif @@ -95,8 +97,23 @@ int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int def address->addressdata.loop.port = port; return 1; } - // try to parse with gethostbyname first, because it can handle ipv4 and - // ipv6 (in various address formats), as well as dns names + // 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) + { + // parsed a valid ipv4 address + address->addresstype = LHNETADDRESSTYPE_INET4; + address->addressdata.inet4.family = LHNETADDRESSTYPE_INET4_FAMILY; + address->addressdata.inet4.port = htons((unsigned short)port); + address->addressdata.inet4.address[0] = (unsigned char)d1; + address->addressdata.inet4.address[1] = (unsigned char)d2; + address->addressdata.inet4.address[2] = (unsigned char)d3; + address->addressdata.inet4.address[3] = (unsigned char)d4; +#ifdef STANDALONETEST + printf("manual parsing of ipv4 dotted decimal address \"%s\" successful: %d.%d.%d.%d:%d\n", string, (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 + return 1; + } + // try gethostbyname (handles dns and other ip formats) hostentry = gethostbyname(name); if (hostentry) { @@ -125,25 +142,9 @@ int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int def return 1; } } - // failed, try to parse as an ipv4 address as a fallback (is this needed?) #ifdef STANDALONETEST - printf("gethostbyname and gethostbyaddr failed on address \"%s\"\n", name); + printf("gethostbyname failed on address \"%s\"\n", name); #endif - 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) - { - // parsed a valid ipv4 address - address->addresstype = LHNETADDRESSTYPE_INET4; - address->addressdata.inet4.family = LHNETADDRESSTYPE_INET4_FAMILY; - address->addressdata.inet4.port = htons((unsigned short)port); - address->addressdata.inet4.address[0] = (unsigned char)d1; - address->addressdata.inet4.address[1] = (unsigned char)d2; - address->addressdata.inet4.address[2] = (unsigned char)d3; - address->addressdata.inet4.address[3] = (unsigned char)d4; -#ifdef STANDALONETEST - printf("manual parsing of ipv4 dotted decimal address \"%s\" successful: %d.%d.%d.%d:%d\n", string, (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 - return 1; - } return 0; } @@ -340,6 +341,64 @@ void LHNET_Shutdown(void) lhnet_active = 0; } +static const char *LHNETPRIVATE_StrError(void) +{ +#ifdef WIN32 + int i = WSAGetLastError(); + switch (i) + { + case WSAEINTR: return "WSAEINTR"; + case WSAEBADF: return "WSAEBADF"; + case WSAEACCES: return "WSAEACCES"; + case WSAEFAULT: return "WSAEFAULT"; + case WSAEINVAL: return "WSAEINVAL"; + case WSAEMFILE: return "WSAEMFILE"; + case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK"; + case WSAEINPROGRESS: return "WSAEINPROGRESS"; + case WSAEALREADY: return "WSAEALREADY"; + case WSAENOTSOCK: return "WSAENOTSOCK"; + case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ"; + case WSAEMSGSIZE: return "WSAEMSGSIZE"; + case WSAEPROTOTYPE: return "WSAEPROTOTYPE"; + case WSAENOPROTOOPT: return "WSAENOPROTOOPT"; + case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT"; + case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT"; + case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP"; + case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT"; + case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT"; + case WSAEADDRINUSE: return "WSAEADDRINUSE"; + case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL"; + case WSAENETDOWN: return "WSAENETDOWN"; + case WSAENETUNREACH: return "WSAENETUNREACH"; + case WSAENETRESET: return "WSAENETRESET"; + case WSAECONNABORTED: return "WSAECONNABORTED"; + case WSAECONNRESET: return "WSAECONNRESET"; + case WSAENOBUFS: return "WSAENOBUFS"; + case WSAEISCONN: return "WSAEISCONN"; + case WSAENOTCONN: return "WSAENOTCONN"; + case WSAESHUTDOWN: return "WSAESHUTDOWN"; + case WSAETOOMANYREFS: return "WSAETOOMANYREFS"; + case WSAETIMEDOUT: return "WSAETIMEDOUT"; + case WSAECONNREFUSED: return "WSAECONNREFUSED"; + case WSAELOOP: return "WSAELOOP"; + case WSAENAMETOOLONG: return "WSAENAMETOOLONG"; + case WSAEHOSTDOWN: return "WSAEHOSTDOWN"; + case WSAEHOSTUNREACH: return "WSAEHOSTUNREACH"; + case WSAENOTEMPTY: return "WSAENOTEMPTY"; + case WSAEPROCLIM: return "WSAEPROCLIM"; + case WSAEUSERS: return "WSAEUSERS"; + case WSAEDQUOT: return "WSAEDQUOT"; + case WSAESTALE: return "WSAESTALE"; + case WSAEREMOTE: return "WSAEREMOTE"; + case WSAEDISCON: return "WSAEDISCON"; + case 0: return "no error"; + default: return "unknown WSAE error"; + } +#else + return strerror(errno); +#endif +} + lhnetsocket_t *LHNET_OpenSocket_Connectionless(lhnetaddress_t *address) { lhnetsocket_t *lhnetsocket, *s; @@ -387,17 +446,10 @@ lhnetsocket_t *LHNET_OpenSocket_Connectionless(lhnetaddress_t *address) case LHNETADDRESSTYPE_INET4: case LHNETADDRESSTYPE_INET6: #ifdef WIN32 - if (!lhnet_didWSAStartup && !WSAStartup(MAKEWORD(1, 1), &lhnet_winsockdata)) - { - lhnet_didWSAStartup = 1; -#else + if (lhnet_didWSAStartup || (lhnet_didWSAStartup = !WSAStartup(MAKEWORD(1, 1), &lhnet_winsockdata))) { #endif - if (address->addresstype == LHNETADDRESSTYPE_INET6) - lhnetsocket->inetsocket = socket(LHNETADDRESSTYPE_INET6_FAMILY, SOCK_DGRAM, IPPROTO_UDP); - else - lhnetsocket->inetsocket = socket(LHNETADDRESSTYPE_INET4_FAMILY, SOCK_DGRAM, IPPROTO_UDP); - if (lhnetsocket->inetsocket != -1) + 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; @@ -407,22 +459,42 @@ lhnetsocket_t *LHNET_OpenSocket_Connectionless(lhnetaddress_t *address) if (ioctl(lhnetsocket->inetsocket, FIONBIO, &_true) != -1) #endif { - if (bind(lhnetsocket->inetsocket, (void *)&lhnetsocket->address.addressdata, address->addresstype == LHNETADDRESSTYPE_INET6 ? sizeof(lhnetsocket->address.addressdata.inet6) : sizeof(lhnetsocket->address.addressdata.inet4)) != -1) +#ifdef WIN32 + int namelen; +#else + socklen_t namelen; +#endif + 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) { + int i = 1; + getsockname(lhnetsocket->inetsocket, (void *)&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; return lhnetsocket; } + else + Con_Printf("LHNET_OpenSocket_Connectionless: bind returned error: %s\n", LHNETPRIVATE_StrError()); } + 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"); +#endif break; default: break; @@ -496,7 +568,7 @@ int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, continue; } #ifndef STANDALONETEST - if (p->sentdoubletime && Sys_DoubleTime() < p->sentdoubletime) + if (cl_netlocalping.value && (Sys_DoubleTime() - cl_netlocalping.value * (1.0 / 1000.0)) < p->sentdoubletime) continue; #endif if (value == 0 && p->destinationport == lhnetsocket->address.addressdata.loop.port) @@ -537,7 +609,7 @@ int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, switch (e) { case WSAECONNREFUSED: - Con_Printf("Connection refused\n"); + Con_Print("Connection refused\n"); return 0; } #else @@ -546,7 +618,7 @@ int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, switch (errno) { case ECONNREFUSED: - Con_Printf("Connection refused\n"); + Con_Print("Connection refused\n"); return 0; } #endif @@ -572,7 +644,7 @@ int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, switch (e) { case WSAECONNREFUSED: - Con_Printf("Connection refused\n"); + Con_Print("Connection refused\n"); return 0; } #else @@ -581,7 +653,7 @@ int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, switch (errno) { case ECONNREFUSED: - Con_Printf("Connection refused\n"); + Con_Print("Connection refused\n"); return 0; } #endif @@ -612,8 +684,7 @@ int LHNET_Write(lhnetsocket_t *lhnetsocket, const void *content, int contentleng p->next->prev = p; p->prev->next = p; #ifndef STANDALONETEST - if (cl_fakelocalping_min.integer || cl_fakelocalping_max.integer) - p->sentdoubletime = Sys_DoubleTime() + (cl_fakelocalping_min.integer + ((cl_fakelocalping_max.integer - cl_fakelocalping_min.integer) * (rand() & 255) / 256)) / 1000.0; + p->sentdoubletime = Sys_DoubleTime(); #endif value = contentlength; }