#include <winsock.h>
#else
#include <netdb.h>
-//#include <netinet/in.h>
+#include <netinet/in.h>
//#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#endif
// for Z_Malloc/Z_Free in quake
-#if 1
+#ifndef STANDALONETEST
+#include "quakedef.h"
#include "zone.h"
+#include "sys.h"
+#include "netconn.h"
#else
#define Z_Malloc malloc
#define Z_Free free
int LHNETADDRESS_FromPort(lhnetaddress_t *address, int addresstype, int port)
{
+ if (!address)
+ return 0;
switch(addresstype)
{
case LHNETADDRESSTYPE_LOOP:
memset(address, 0, sizeof(*address));
address->addresstype = LHNETADDRESSTYPE_INET4;
address->addressdata.inet4.family = LHNETADDRESSTYPE_INET4_FAMILY;
- address->addressdata.inet4.port = htons(port);
+ address->addressdata.inet4.port = htons((unsigned short)port);
return 1;
case LHNETADDRESSTYPE_INET6:
// [0:0:0:0:0:0:0:0]:port (IN6ADDR_ANY, binds to all interfaces)
memset(address, 0, sizeof(*address));
address->addresstype = LHNETADDRESSTYPE_INET6;
address->addressdata.inet6.family = LHNETADDRESSTYPE_INET6_FAMILY;
- address->addressdata.inet6.port = htons(port);
+ address->addressdata.inet6.port = htons((unsigned short)port);
return 1;
}
return 0;
int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int defaultport)
{
- int i, port, namelen, number;
+ int port, namelen, d1, d2, d3, d4;
struct hostent *hostentry;
const char *colon;
char name[128];
+ if (!address || !string)
+ return 0;
memset(address, 0, sizeof(*address));
address->addresstype = LHNETADDRESSTYPE_NONE;
port = 0;
}
// try to parse with gethostbyname first, because it can handle ipv4 and
// ipv6 (in various address formats), as well as dns names
- for (i = 0;i < 3;i++)
+ hostentry = gethostbyname(name);
+ if (hostentry)
{
- if (i == 0)
- hostentry = gethostbyaddr(name, namelen, LHNETADDRESSTYPE_INET6_FAMILY);
- else if (i == 1)
- hostentry = gethostbyaddr(name, namelen, LHNETADDRESSTYPE_INET4_FAMILY);
- else
- hostentry = gethostbyname(name);
- if (hostentry)
+ if (hostentry->h_addrtype == LHNETADDRESSTYPE_INET6_FAMILY)
{
- if (hostentry->h_addrtype == LHNETADDRESSTYPE_INET6_FAMILY)
- {
- // great it worked
- address->addresstype = LHNETADDRESSTYPE_INET6;
- address->addressdata.inet6.family = hostentry->h_addrtype;
- address->addressdata.inet6.port = htons(port);
- memcpy(address->addressdata.inet6.address, hostentry->h_addr_list[0], sizeof(address->addressdata.inet6.address));
+ // great it worked
+ address->addresstype = LHNETADDRESSTYPE_INET6;
+ 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));
#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));
+ 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
- return 1;
- }
- else if (hostentry->h_addrtype == LHNETADDRESSTYPE_INET4_FAMILY)
- {
- // great it worked
- address->addresstype = LHNETADDRESSTYPE_INET4;
- address->addressdata.inet4.family = hostentry->h_addrtype;
- address->addressdata.inet4.port = htons(port);
- memcpy(address->addressdata.inet4.address, hostentry->h_addr_list[0], sizeof(address->addressdata.inet4.address));
+ return 1;
+ }
+ else if (hostentry->h_addrtype == LHNETADDRESSTYPE_INET4_FAMILY)
+ {
+ // great it worked
+ address->addresstype = LHNETADDRESSTYPE_INET4;
+ 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));
#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));
+ 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
- return 1;
- }
+ 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);
#endif
- for (i = 0, number = 0;i < 4;string++)
- {
- if (*string >= '0' && *string <= '9')
- number = number * 10 + (*string - '0');
- else if (number < 256 && (*string == '.' || *string == ':'))
- {
- address->addressdata.inet4.address[i++] = number;
- number = 0;
- }
- else
- break;
- if (*string == 0 || *string == ':')
- break;
- }
- if (i == 4)
+ 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(port);
+ 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
int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int stringbuffersize, int includeport)
{
*string = 0;
+ if (!address || !string || stringbuffersize < 1)
+ return 0;
switch(address->addresstype)
{
default:
int LHNETADDRESS_GetAddressType(const lhnetaddress_t *address)
{
- return address->addresstype;
+ if (address)
+ return address->addresstype;
+ else
+ return LHNETADDRESSTYPE_NONE;
}
int LHNETADDRESS_GetPort(const lhnetaddress_t *address)
{
+ if (!address)
+ return -1;
switch(address->addresstype)
{
case LHNETADDRESSTYPE_LOOP:
int LHNETADDRESS_SetPort(lhnetaddress_t *address, int port)
{
+ if (!address)
+ return 0;
switch(address->addresstype)
{
case LHNETADDRESSTYPE_LOOP:
address->addressdata.loop.port = port;
return 1;
case LHNETADDRESSTYPE_INET4:
- address->addressdata.inet4.port = htons(port);
+ address->addressdata.inet4.port = htons((unsigned short)port);
return 1;
case LHNETADDRESSTYPE_INET6:
- address->addressdata.inet6.port = htons(port);
+ address->addressdata.inet6.port = htons((unsigned short)port);
return 1;
default:
return 0;
int LHNETADDRESS_Compare(const lhnetaddress_t *address1, const lhnetaddress_t *address2)
{
+ if (!address1 || !address2)
+ return 1;
if (address1->addresstype != address2->addresstype)
return 1;
switch(address1->addresstype)
int sourceport;
int destinationport;
time_t timeout;
+#ifndef STANDALONETEST
+ double sentdoubletime;
+#endif
struct lhnetpacket_s *next, *prev;
}
lhnetpacket_t;
lhnetsocket_t *LHNET_OpenSocket_Connectionless(lhnetaddress_t *address)
{
lhnetsocket_t *lhnetsocket, *s;
+ if (!address)
+ return NULL;
lhnetsocket = Z_Malloc(sizeof(*lhnetsocket));
if (lhnetsocket)
{
lhnetaddress_t *LHNET_AddressFromSocket(lhnetsocket_t *sock)
{
- return &sock->address;
+ if (sock)
+ return &sock->address;
+ else
+ return NULL;
}
int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, lhnetaddress_t *address)
{
int value = 0;
+ if (!lhnetsocket || !address || !content || maxcontentlength < 1)
+ return -1;
if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_LOOP)
{
time_t currenttime;
for (p = lhnet_packetlist.next;p != &lhnet_packetlist;p = pnext)
{
pnext = p->next;
+ if (p->timeout < currenttime)
+ {
+ // unlink and free
+ p->next->prev = p->prev;
+ p->prev->next = p->next;
+ Z_Free(p);
+ continue;
+ }
+#ifndef STANDALONETEST
+ if (p->sentdoubletime && Sys_DoubleTime() < p->sentdoubletime)
+ continue;
+#endif
if (value == 0 && p->destinationport == lhnetsocket->address.addressdata.loop.port)
{
if (p->length <= maxcontentlength)
p->prev->next = p->next;
Z_Free(p);
}
- else if (p->timeout < currenttime)
- {
- // unlink and free
- p->next->prev = p->prev;
- p->prev->next = p->next;
- Z_Free(p);
- }
}
}
else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET4)
{
#ifdef WIN32
int e = WSAGetLastError();
- if (e == WSAEWOULDBLOCK || e == WSAECONNREFUSED)
+ if (e == WSAEWOULDBLOCK)
return 0;
+ switch (e)
+ {
+ case WSAECONNREFUSED:
+ Con_Printf("Connection refused\n");
+ return 0;
+ }
#else
- if (errno == EWOULDBLOCK || errno == ECONNREFUSED)
+ if (errno == EWOULDBLOCK)
return 0;
+ switch (errno)
+ {
+ case ECONNREFUSED:
+ Con_Printf("Connection refused\n");
+ return 0;
+ }
#endif
}
}
{
#ifdef WIN32
int e = WSAGetLastError();
- if (e == WSAEWOULDBLOCK || e == WSAECONNREFUSED)
+ if (e == WSAEWOULDBLOCK)
return 0;
+ switch (e)
+ {
+ case WSAECONNREFUSED:
+ Con_Printf("Connection refused\n");
+ return 0;
+ }
#else
- if (errno == EWOULDBLOCK || errno == ECONNREFUSED)
+ if (errno == EWOULDBLOCK)
return 0;
+ switch (errno)
+ {
+ case ECONNREFUSED:
+ Con_Printf("Connection refused\n");
+ return 0;
+ }
#endif
}
}
int LHNET_Write(lhnetsocket_t *lhnetsocket, const void *content, int contentlength, const lhnetaddress_t *address)
{
int value = -1;
+ if (!lhnetsocket || !address || !content || contentlength < 1)
+ return -1;
if (lhnetsocket->address.addresstype != address->addresstype)
return -1;
if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_LOOP)
p->prev = p->next->prev;
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;
+#endif
value = contentlength;
}
else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET4)