DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
lhnet.h File Reference
#include <stddef.h>
#include "com_list.h"
+ Include dependency graph for lhnet.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  lhnetaddress_t
 
struct  lhnetsocket_t
 

Enumerations

enum  lhnetaddresstype_t { LHNETADDRESSTYPE_NONE , LHNETADDRESSTYPE_LOOP , LHNETADDRESSTYPE_INET4 , LHNETADDRESSTYPE_INET6 }
 

Functions

lhnetaddress_tLHNET_AddressFromSocket (lhnetsocket_t *sock)
 
void LHNET_CloseSocket (lhnetsocket_t *lhnetsocket)
 
int LHNET_DefaultDSCP (int dscp)
 
void LHNET_Init (void)
 
lhnetsocket_tLHNET_OpenSocket_Connectionless (lhnetaddress_t *address)
 
int LHNET_Read (lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, lhnetaddress_t *address)
 
void LHNET_Shutdown (void)
 
void LHNET_SleepUntilPacket_Microseconds (int microseconds)
 
int LHNET_Write (lhnetsocket_t *lhnetsocket, const void *content, int contentlength, const lhnetaddress_t *address)
 
int LHNETADDRESS_Compare (const lhnetaddress_t *address1, const lhnetaddress_t *address2)
 
int LHNETADDRESS_FromPort (lhnetaddress_t *address, lhnetaddresstype_t addresstype, int port)
 
int LHNETADDRESS_FromString (lhnetaddress_t *address, const char *string, int defaultport)
 
static lhnetaddresstype_t LHNETADDRESS_GetAddressType (const lhnetaddress_t *address)
 
const char * LHNETADDRESS_GetInterfaceName (const lhnetaddress_t *address, char *ifname, size_t ifnamelength)
 
int LHNETADDRESS_GetPort (const lhnetaddress_t *address)
 
int LHNETADDRESS_SetPort (lhnetaddress_t *address, int port)
 
int LHNETADDRESS_ToString (const lhnetaddress_t *address, char *string, int stringbuffersize, int includeport)
 Returns the number of bytes written to *string excluding the \0 terminator.
 

Variables

lhnetsocket_t lhnet_socketlist
 

Enumeration Type Documentation

◆ lhnetaddresstype_t

Enumerator
LHNETADDRESSTYPE_NONE 
LHNETADDRESSTYPE_LOOP 
LHNETADDRESSTYPE_INET4 
LHNETADDRESSTYPE_INET6 

Definition at line 10 of file lhnet.h.

11{
16}
@ LHNETADDRESSTYPE_INET6
Definition lhnet.h:15
@ LHNETADDRESSTYPE_NONE
Definition lhnet.h:12
@ LHNETADDRESSTYPE_INET4
Definition lhnet.h:14
@ LHNETADDRESSTYPE_LOOP
Definition lhnet.h:13

Function Documentation

◆ LHNET_AddressFromSocket()

lhnetaddress_t * LHNET_AddressFromSocket ( lhnetsocket_t * sock)

Definition at line 1026 of file lhnet.c.

1027{
1028 if (sock)
1029 return &sock->address;
1030 else
1031 return NULL;
1032}
#define NULL
Definition qtypes.h:12
lhnetaddress_t address
Definition lhnet.h:45

References lhnetsocket_t::address, and NULL.

Referenced by NetConn_ChooseClientSocketForAddress(), NetConn_ChooseServerSocketForAddress(), NetConn_OpenClientPort(), NetConn_OpenServerPort(), NetConn_Read(), NetConn_ServerParsePacket(), and NetConn_Write().

◆ LHNET_CloseSocket()

void LHNET_CloseSocket ( lhnetsocket_t * lhnetsocket)

Definition at line 1012 of file lhnet.c.

1013{
1014 if (lhnetsocket)
1015 {
1016 List_Delete(&lhnetsocket->list);
1017 // no special close code for loopback, just inet
1019 {
1020 closesocket(lhnetsocket->inetsocket);
1021 }
1022 Z_Free(lhnetsocket);
1023 }
1024}
static void List_Delete(llist_t *node)
Definition com_list.h:274
#define closesocket
Definition lhnet.c:84
lhnetaddresstype_t addresstype
Definition lhnet.h:21
llist_t list
Definition lhnet.h:47
int inetsocket
Definition lhnet.h:46
#define Z_Free(data)
Definition zone.h:164

References lhnetsocket_t::address, lhnetaddress_t::addresstype, closesocket, lhnetsocket_t::inetsocket, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, lhnetsocket_t::list, List_Delete(), and Z_Free.

Referenced by LHNET_Shutdown(), NetConn_CloseClientPorts(), and NetConn_CloseServerPorts().

◆ LHNET_DefaultDSCP()

int LHNET_DefaultDSCP ( int dscp)

Definition at line 739 of file lhnet.c.

740{
741#ifdef IP_TOS
742 int prev = lhnet_default_dscp;
743 if(dscp >= 0)
744 lhnet_default_dscp = dscp;
745 return prev;
746#else
747 return -1;
748#endif
749}
static int lhnet_default_dscp
Definition lhnet.c:719

References lhnet_default_dscp.

Referenced by NetConn_UpdateSockets().

◆ LHNET_Init()

void LHNET_Init ( void )

Definition at line 725 of file lhnet.c.

726{
727 if (lhnet_active)
728 return;
731 lhnet_active = 1;
732#ifdef WIN32
733 lhnet_didWSAStartup = !WSAStartup(MAKEWORD(1, 1), &lhnet_winsockdata);
734 if (!lhnet_didWSAStartup)
735 Con_Print("LHNET_Init: WSAStartup failed, networking disabled\n");
736#endif
737}
static void List_Create(llist_t *list)
Definition com_list.h:220
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
static lhnetpacket_t lhnet_packetlist
Definition lhnet.c:718
lhnetsocket_t lhnet_socketlist
Definition lhnet.c:717
static int lhnet_active
Definition lhnet.c:716
llist_t list
Definition lhnet.c:712

References Con_Print(), lhnet_active, lhnet_packetlist, lhnet_socketlist, lhnetpacket_t::list, lhnetsocket_t::list, and List_Create().

Referenced by NetConn_Init().

◆ LHNET_OpenSocket_Connectionless()

lhnetsocket_t * LHNET_OpenSocket_Connectionless ( lhnetaddress_t * address)

Definition at line 832 of file lhnet.c.

833{
834 lhnetsocket_t *lhnetsocket, *s;
835 if (!address)
836 return NULL;
837 lhnetsocket = (lhnetsocket_t *)Z_Malloc(sizeof(*lhnetsocket));
838 if (lhnetsocket)
839 {
840 memset(lhnetsocket, 0, sizeof(*lhnetsocket));
841 lhnetsocket->address = *address;
842 switch(lhnetsocket->address.addresstype)
843 {
845 if (lhnetsocket->address.port == 0)
846 {
847 // allocate a port dynamically
848 // this search will always terminate because there is never
849 // an allocated socket with port 0, so if the number wraps it
850 // will find the port is unused, and then refuse to use port
851 // 0, causing an intentional failure condition
852 lhnetsocket->address.port = 1024;
853 for (;;)
854 {
856 if (s->address.addresstype == lhnetsocket->address.addresstype && s->address.port == lhnetsocket->address.port)
857 break;
858 if (s == &lhnet_socketlist)
859 break;
860 lhnetsocket->address.port++;
861 }
862 }
863 // check if the port is available
865 if (s->address.addresstype == lhnetsocket->address.addresstype && s->address.port == lhnetsocket->address.port)
866 break;
867 if (s == &lhnet_socketlist && lhnetsocket->address.port != 0)
868 {
869 List_Add_Tail(&lhnetsocket->list, &lhnet_socketlist.list);
870 return lhnetsocket;
871 }
872 break;
874#ifndef NOSUPPORTIPV6
876#endif
877#ifdef WIN32
878 if (lhnet_didWSAStartup)
879 {
880#endif
881#ifndef NOSUPPORTIPV6
882 if ((lhnetsocket->inetsocket = socket(address->addresstype == LHNETADDRESSTYPE_INET6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1)
883#else
884 if ((lhnetsocket->inetsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1)
885#endif
886 {
887#ifdef WIN32
888 u_long _false = 0;
889#endif
890#ifdef MSG_DONTWAIT
891 if (1)
892#else
893#ifdef WIN32
894 u_long _true = 1;
895#else
896 char _true = 1;
897#endif
898 if (ioctlsocket(lhnetsocket->inetsocket, FIONBIO, &_true) != -1)
899#endif
900 {
901#ifdef IPV6_V6ONLY
902 // We need to set this flag to tell the OS that we only listen on IPv6. If we don't
903 // most OSes will create a dual-protocol socket that also listens on IPv4. In this case
904 // if an IPv4 socket is already bound to the port we want, our bind() call will fail.
905 int ipv6_only = 1;
906 if (address->addresstype != LHNETADDRESSTYPE_INET6
907 || setsockopt (lhnetsocket->inetsocket, IPPROTO_IPV6, IPV6_V6ONLY,
908 (const char *)&ipv6_only, sizeof(ipv6_only)) == 0
909#ifdef WIN32
910 // The Win32 API only supports IPV6_V6ONLY since Windows Vista, but fortunately
911 // the default value is what we want on Win32 anyway (IPV6_V6ONLY = true)
912 || SOCKETERRNO == WSAENOPROTOOPT
913#endif
914 )
915#endif
916 {
917 lhnetaddressnative_t *localaddress = (lhnetaddressnative_t *)&lhnetsocket->address;
918 SOCKLEN_T namelen;
919 int bindresult;
920
921#if defined(SOL_RFC1149) && defined(RFC1149_1149ONLY)
922 // we got reports of massive lags when this protocol was chosen as transport
923 // so better turn it off
924 {
925 int rfc1149only = 0;
926 int rfc1149enabled = 0;
927 if(setsockopt(lhnetsocket->inetsocket, SOL_RFC1149, RFC1149_1149ONLY, &rfc1149only))
928 Con_Printf(CON_ERROR "LHNET_OpenSocket_Connectionless: warning: setsockopt(RFC1149_1149ONLY) returned error: %s\n", LHNETPRIVATE_StrError());
929 if(setsockopt(lhnetsocket->inetsocket, SOL_RFC1149, RFC1149_ENABLED, &rfc1149enabled))
930 Con_Printf(CON_ERROR "LHNET_OpenSocket_Connectionless: warning: setsockopt(RFC1149_ENABLED) returned error: %s\n", LHNETPRIVATE_StrError());
931 }
932#endif
933
934#ifndef NOSUPPORTIPV6
935 if (address->addresstype == LHNETADDRESSTYPE_INET6)
936 {
937 namelen = sizeof(localaddress->addr.in6);
938 bindresult = bind(lhnetsocket->inetsocket, &localaddress->addr.sock, namelen);
939 if (bindresult != -1)
940 {
941 if (getsockname(lhnetsocket->inetsocket, &localaddress->addr.sock, &namelen))
942 {
943 // If getsockname failed, we can assume the bound socket is useless.
944 bindresult = -1;
945 }
946 }
947 }
948 else
949#endif
950 {
951 namelen = sizeof(localaddress->addr.in);
952 bindresult = bind(lhnetsocket->inetsocket, &localaddress->addr.sock, namelen);
953 if (bindresult != -1)
954 {
955 if (getsockname(lhnetsocket->inetsocket, &localaddress->addr.sock, &namelen))
956 {
957 // If getsockname failed, we can assume the bound socket is useless.
958 bindresult = -1;
959 }
960 }
961 }
962 if (bindresult != -1)
963 {
964 int i = 1;
965 // enable broadcast on this socket
966 setsockopt(lhnetsocket->inetsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i));
967#ifdef IP_TOS
968 {
969 // enable DSCP for ToS support
970 int tos = lhnet_default_dscp << 2;
971 if (setsockopt(lhnetsocket->inetsocket, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)))
972 {
973 // Error in setsockopt - fine, we'll simply set no TOS then.
974 }
975 }
976#endif
977 List_Add_Tail(&lhnetsocket->list, &lhnet_socketlist.list);
978#ifdef WIN32
979 if (ioctlsocket(lhnetsocket->inetsocket, SIO_UDP_CONNRESET, &_false) == -1)
980 Con_DPrintf("LHNET_OpenSocket_Connectionless: ioctlsocket SIO_UDP_CONNRESET returned error: %s\n", LHNETPRIVATE_StrError());
981#endif
982 return lhnetsocket;
983 }
984 else
985 Con_Printf("LHNET_OpenSocket_Connectionless: bind returned error: %s\n", LHNETPRIVATE_StrError());
986 }
987#ifdef IPV6_V6ONLY
988 else
989 Con_Printf("LHNET_OpenSocket_Connectionless: setsockopt(IPV6_V6ONLY) returned error: %s\n", LHNETPRIVATE_StrError());
990#endif
991 }
992 else
993 Con_Printf("LHNET_OpenSocket_Connectionless: ioctlsocket returned error: %s\n", LHNETPRIVATE_StrError());
994 closesocket(lhnetsocket->inetsocket);
995 }
996 else
997 Con_Printf("LHNET_OpenSocket_Connectionless: socket returned error: %s\n", LHNETPRIVATE_StrError());
998#ifdef WIN32
999 }
1000 else
1001 Con_Print("LHNET_OpenSocket_Connectionless: can't open a socket (WSAStartup failed during LHNET_Init)\n");
1002#endif
1003 break;
1004 default:
1005 break;
1006 }
1007 Z_Free(lhnetsocket);
1008 }
1009 return NULL;
1010}
static void List_Add_Tail(llist_t *node, llist_t *head)
Definition com_list.h:249
#define List_For_Each_Entry(pos, head, type, member)
Definition com_list.h:121
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define CON_ERROR
Definition console.h:102
#define SOCKETERRNO
Definition lhnet.c:85
#define SOCKLEN_T
Definition lhnet.c:87
#define ioctlsocket
Definition lhnet.c:83
static const char * LHNETPRIVATE_StrError(void)
Definition lhnet.c:774
int i
#define Z_Malloc(size)
Definition zone.h:161

References lhnetaddressnative_t::addr, lhnetsocket_t::address, lhnetaddress_t::addresstype, closesocket, Con_DPrintf(), CON_ERROR, Con_Print(), Con_Printf(), i, lhnetaddressnative_t::in, lhnetaddressnative_t::in6, lhnetsocket_t::inetsocket, ioctlsocket, lhnet_default_dscp, lhnet_socketlist, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, LHNETPRIVATE_StrError(), lhnetsocket_t::list, List_Add_Tail(), List_For_Each_Entry, NULL, lhnetaddress_t::port, lhnetaddressnative_t::sock, SOCKETERRNO, SOCKLEN_T, Z_Free, and Z_Malloc.

Referenced by NetConn_OpenClientPort(), and NetConn_OpenServerPort().

◆ LHNET_Read()

int LHNET_Read ( lhnetsocket_t * lhnetsocket,
void * content,
int maxcontentlength,
lhnetaddress_t * address )

Definition at line 1034 of file lhnet.c.

1035{
1036 lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
1037 int value = 0;
1038 if (!lhnetsocket || !address || !content || maxcontentlength < 1)
1039 return -1;
1040 if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_LOOP)
1041 {
1042 time_t currenttime;
1043 lhnetpacket_t *p, *pnext;
1044 // scan for any old packets to timeout while searching for a packet
1045 // that is waiting to be delivered to this socket
1046 currenttime = time(NULL);
1048 {
1049 if (p->timeout < currenttime)
1050 {
1051 // unlink and free
1052 List_Delete(&p->list);
1053 Z_Free(p);
1054 continue;
1055 }
1056#ifndef STANDALONETEST
1057 if (net_fakelag.value && (host.realtime - net_fakelag.value * (1.0 / 2000.0)) < p->sentdoubletime)
1058 continue;
1059#endif
1060 if (value == 0 && p->destinationport == lhnetsocket->address.port)
1061 {
1062 if (p->length <= maxcontentlength)
1063 {
1064 lhnetaddressnative_t *localaddress = (lhnetaddressnative_t *)&lhnetsocket->address;
1065 *address = *localaddress;
1066 address->port = p->sourceport;
1067 memcpy(content, p->data, p->length);
1068 value = p->length;
1069 }
1070 else
1071 value = -1;
1072 // unlink and free
1073 List_Delete(&p->list);
1074 Z_Free(p);
1075 }
1076 }
1077 }
1078 else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET4)
1079 {
1080 SOCKLEN_T inetaddresslength;
1082 inetaddresslength = sizeof(address->addr.in);
1083 value = recvfrom(lhnetsocket->inetsocket, (char *)content, maxcontentlength, LHNET_RECVFROM_FLAGS, &address->addr.sock, &inetaddresslength);
1084 if (value > 0)
1085 {
1087 address->port = ntohs(address->addr.in.sin_port);
1088 return value;
1089 }
1090 else if (value < 0)
1091 {
1092 int e = SOCKETERRNO;
1093 if (e == EWOULDBLOCK)
1094 return 0;
1095 switch (e)
1096 {
1097 case ECONNREFUSED:
1098 Con_Print("Connection refused\n");
1099 return 0;
1100 }
1101 Con_DPrintf("LHNET_Read: recvfrom returned error: %s\n", LHNETPRIVATE_StrError());
1102 }
1103 }
1104#ifndef NOSUPPORTIPV6
1105 else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET6)
1106 {
1107 SOCKLEN_T inetaddresslength;
1109 inetaddresslength = sizeof(address->addr.in6);
1110 value = recvfrom(lhnetsocket->inetsocket, (char *)content, maxcontentlength, LHNET_RECVFROM_FLAGS, &address->addr.sock, &inetaddresslength);
1111 if (value > 0)
1112 {
1114 address->port = ntohs(address->addr.in6.sin6_port);
1115 return value;
1116 }
1117 else if (value == -1)
1118 {
1119 int e = SOCKETERRNO;
1120 if (e == EWOULDBLOCK)
1121 return 0;
1122 switch (e)
1123 {
1124 case ECONNREFUSED:
1125 Con_Print("Connection refused\n");
1126 return 0;
1127 }
1128 Con_DPrintf("LHNET_Read: recvfrom returned error: %s\n", LHNETPRIVATE_StrError());
1129 }
1130 }
1131#endif
1132 return value;
1133}
#define List_For_Each_Entry_Safe(pos, n, head, type, member)
Definition com_list.h:173
float time
GLsizei const GLfloat * value
Definition glquake.h:740
host_static_t host
Definition host.c:41
#define LHNET_RECVFROM_FLAGS
Definition lhnet.c:94
cvar_t net_fakelag
Definition netconn.c:91
float value
Definition cvar.h:74
double realtime
the accumulated mainloop time since application started (with filtering), without any slowmo or clamp...
Definition host.h:46
struct sockaddr sock
Definition lhnet.c:104
union lhnetaddressnative_t::@15 addr
struct sockaddr_in6 in6
Definition lhnet.c:107
struct sockaddr_in in
Definition lhnet.c:105
lhnetaddresstype_t addresstype
Definition lhnet.c:100
int destinationport
Definition lhnet.c:707
void * data
Definition lhnet.c:704
int sourceport
Definition lhnet.c:706
double sentdoubletime
Definition lhnet.c:710
time_t timeout
Definition lhnet.c:708

References lhnetaddressnative_t::addr, lhnetsocket_t::address, lhnetaddress_t::addresstype, lhnetaddressnative_t::addresstype, Con_DPrintf(), Con_Print(), lhnetpacket_t::data, lhnetpacket_t::destinationport, host, lhnetaddressnative_t::in, lhnetaddressnative_t::in6, lhnetsocket_t::inetsocket, lhnetpacket_t::length, lhnet_packetlist, LHNET_RECVFROM_FLAGS, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, LHNETADDRESSTYPE_NONE, LHNETPRIVATE_StrError(), lhnetpacket_t::list, List_Delete(), List_For_Each_Entry_Safe, net_fakelag, NULL, lhnetaddress_t::port, lhnetaddressnative_t::port, host_static_t::realtime, lhnetpacket_t::sentdoubletime, lhnetaddressnative_t::sock, SOCKETERRNO, SOCKLEN_T, lhnetpacket_t::sourceport, time, lhnetpacket_t::timeout, cvar_t::value, value, and Z_Free.

Referenced by NetConn_Read().

◆ LHNET_Shutdown()

void LHNET_Shutdown ( void )

Definition at line 751 of file lhnet.c.

752{
753 lhnetsocket_t *s, *snext;
754 lhnetpacket_t *p, *pnext;
755 if (!lhnet_active)
756 return;
760 {
761 List_Delete(&p->list);
762 Z_Free(p);
763 }
764#ifdef WIN32
765 if (lhnet_didWSAStartup)
766 {
767 lhnet_didWSAStartup = 0;
768 WSACleanup();
769 }
770#endif
771 lhnet_active = 0;
772}
void LHNET_CloseSocket(lhnetsocket_t *lhnetsocket)
Definition lhnet.c:1012

References lhnet_active, LHNET_CloseSocket(), lhnet_packetlist, lhnet_socketlist, lhnetpacket_t::list, lhnetsocket_t::list, List_Delete(), List_For_Each_Entry_Safe, and Z_Free.

Referenced by NetConn_Shutdown().

◆ LHNET_SleepUntilPacket_Microseconds()

void LHNET_SleepUntilPacket_Microseconds ( int microseconds)

◆ LHNET_Write()

int LHNET_Write ( lhnetsocket_t * lhnetsocket,
const void * content,
int contentlength,
const lhnetaddress_t * address )

Definition at line 1135 of file lhnet.c.

1136{
1137 lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
1138 int value = -1;
1139 if (!lhnetsocket || !address || !content || contentlength < 1)
1140 return -1;
1141 if (lhnetsocket->address.addresstype != address->addresstype)
1142 return -1;
1143 if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_LOOP)
1144 {
1145 lhnetpacket_t *p;
1146 p = (lhnetpacket_t *)Z_Malloc(sizeof(*p) + contentlength);
1147 p->data = (void *)(p + 1);
1148 memcpy(p->data, content, contentlength);
1149 p->length = contentlength;
1150 p->sourceport = lhnetsocket->address.port;
1151 p->destinationport = address->port;
1152 p->timeout = time(NULL) + 10;
1154
1155#ifndef STANDALONETEST
1157#endif
1158 value = contentlength;
1159 }
1160 else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET4)
1161 {
1162 value = sendto(lhnetsocket->inetsocket, (char *)content, contentlength, LHNET_SENDTO_FLAGS, (struct sockaddr *)&address->addr.in, sizeof(struct sockaddr_in));
1163 if (value == -1)
1164 {
1165 if (SOCKETERRNO == EWOULDBLOCK)
1166 return 0;
1167 Con_DPrintf("LHNET_Write: sendto returned error: %s\n", LHNETPRIVATE_StrError());
1168 }
1169 }
1170#ifndef NOSUPPORTIPV6
1171 else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET6)
1172 {
1173 value = sendto(lhnetsocket->inetsocket, (char *)content, contentlength, 0, (struct sockaddr *)&address->addr.in6, sizeof(struct sockaddr_in6));
1174 if (value == -1)
1175 {
1176 if (SOCKETERRNO == EWOULDBLOCK)
1177 return 0;
1178 Con_DPrintf("LHNET_Write: sendto returned error: %s\n", LHNETPRIVATE_StrError());
1179 }
1180 }
1181#endif
1182 return value;
1183}
#define LHNET_SENDTO_FLAGS
Definition lhnet.c:95

References lhnetaddressnative_t::addr, lhnetsocket_t::address, lhnetaddress_t::addresstype, lhnetaddressnative_t::addresstype, Con_DPrintf(), lhnetpacket_t::data, lhnetpacket_t::destinationport, host, lhnetaddressnative_t::in, lhnetaddressnative_t::in6, lhnetsocket_t::inetsocket, lhnetpacket_t::length, lhnet_packetlist, LHNET_SENDTO_FLAGS, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, LHNETPRIVATE_StrError(), lhnetpacket_t::list, List_Add_Tail(), NULL, lhnetaddress_t::port, lhnetaddressnative_t::port, host_static_t::realtime, lhnetpacket_t::sentdoubletime, SOCKETERRNO, lhnetpacket_t::sourceport, time, lhnetpacket_t::timeout, value, and Z_Malloc.

Referenced by NetConn_Write().

◆ LHNETADDRESS_Compare()

int LHNETADDRESS_Compare ( const lhnetaddress_t * address1,
const lhnetaddress_t * address2 )

Definition at line 665 of file lhnet.c.

666{
667 lhnetaddressnative_t *address1 = (lhnetaddressnative_t *)vaddress1;
668 lhnetaddressnative_t *address2 = (lhnetaddressnative_t *)vaddress2;
669 if (!address1 || !address2)
670 return 1;
671 if (address1->addresstype != address2->addresstype)
672 return 1;
673 switch(address1->addresstype)
674 {
676 if (address1->port != address2->port)
677 return -1;
678 return 0;
680 if (address1->addr.in.sin_family != address2->addr.in.sin_family)
681 return 1;
682 if (memcmp(&address1->addr.in.sin_addr, &address2->addr.in.sin_addr, sizeof(address1->addr.in.sin_addr)))
683 return 1;
684 if (address1->port != address2->port)
685 return -1;
686 return 0;
687#ifndef NOSUPPORTIPV6
689 if (address1->addr.in6.sin6_family != address2->addr.in6.sin6_family)
690 return 1;
691 if (memcmp(&address1->addr.in6.sin6_addr, &address2->addr.in6.sin6_addr, sizeof(address1->addr.in6.sin6_addr)))
692 return 1;
693 if (address1->port != address2->port)
694 return -1;
695 return 0;
696#endif
697 default:
698 return 1;
699 }
700}

References lhnetaddressnative_t::addr, lhnetaddressnative_t::addresstype, lhnetaddressnative_t::in, lhnetaddressnative_t::in6, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, and lhnetaddressnative_t::port.

Referenced by CL_Rcon_f(), Crypto_ClearHostKey(), Crypto_ClientParsePacket(), Crypto_RetrieveHostKey(), Crypto_ServerFindInstance(), Crypto_ServerParsePacket_Internal(), Crypto_StoreHostKey(), hmac_mdfour_challenge_matching(), NetConn_ClearFlood(), NetConn_ClientParsePacket(), NetConn_PreventFlood(), and NetConn_ServerParsePacket().

◆ LHNETADDRESS_FromPort()

int LHNETADDRESS_FromPort ( lhnetaddress_t * address,
lhnetaddresstype_t addresstype,
int port )

Definition at line 125 of file lhnet.c.

126{
127 lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
128 if (!address)
129 return 0;
130 switch(addresstype)
131 {
132 default:
133 break;
135 // local:port (loopback)
136 memset(address, 0, sizeof(*address));
138 address->port = port;
139 return 1;
141 // 0.0.0.0:port (INADDR_ANY, binds to all interfaces)
142 memset(address, 0, sizeof(*address));
144 address->port = port;
145 address->addr.in.sin_family = AF_INET;
146 address->addr.in.sin_port = htons((unsigned short)port);
147 return 1;
148#ifndef NOSUPPORTIPV6
150 // [0:0:0:0:0:0:0:0]:port (IN6ADDR_ANY, binds to all interfaces)
151 memset(address, 0, sizeof(*address));
153 address->port = port;
154 address->addr.in6.sin6_family = AF_INET6;
155 address->addr.in6.sin6_port = htons((unsigned short)port);
156 return 1;
157#endif
158 }
159 return 0;
160}

References lhnetaddressnative_t::addr, lhnetaddressnative_t::addresstype, lhnetaddressnative_t::in, lhnetaddressnative_t::in6, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, and lhnetaddressnative_t::port.

Referenced by NetConn_OpenClientPort(), and NetConn_OpenServerPort().

◆ LHNETADDRESS_FromString()

int LHNETADDRESS_FromString ( lhnetaddress_t * address,
const char * string,
int defaultport )

Definition at line 204 of file lhnet.c.

205{
206 lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
207 int i, port, d1, d2, d3, d4, resolved;
208 size_t namelen;
209 unsigned char *a;
210 char name[128];
211#ifdef STANDALONETEST
212 char string2[128];
213#endif
214 const char* addr_start;
215 const char* addr_end = NULL;
216 const char* port_name = NULL;
217 int addr_family = AF_UNSPEC;
218
219 if (!address || !string || !*string)
220 return 0;
221 memset(address, 0, sizeof(*address));
223 port = 0;
224
225 // If it's a bracketed IPv6 address
226 if (string[0] == '[')
227 {
228 const char* end_bracket = strchr(string, ']');
229
230 if (end_bracket == NULL)
231 return 0;
232
233 if (end_bracket[1] == ':')
234 port_name = end_bracket + 2;
235 else if (end_bracket[1] != '\0')
236 return 0;
237
238 addr_family = AF_INET6;
239 addr_start = &string[1];
240 addr_end = end_bracket;
241 }
242 else
243 {
244 const char* first_colon;
245
246 addr_start = string;
247
248 // If it's a numeric non-bracket IPv6 address (-> no port),
249 // or it's a numeric IPv4 address, or a name, with a port
250 first_colon = strchr(string, ':');
251 if (first_colon != NULL)
252 {
253 const char* last_colon = strrchr(first_colon + 1, ':');
254
255 // If it's an numeric IPv4 address, or a name, with a port
256 if (last_colon == NULL)
257 {
258 addr_end = first_colon;
259 port_name = first_colon + 1;
260 }
261 else
262 addr_family = AF_INET6;
263 }
264 }
265
266 if (addr_end != NULL)
267 namelen = addr_end - addr_start;
268 else
269 namelen = strlen (addr_start);
270
271 if (namelen >= sizeof(name))
272 namelen = sizeof(name) - 1;
273 memcpy (name, addr_start, namelen);
274 name[namelen] = 0;
275
276 if (port_name)
277 port = atoi(port_name);
278
279 if (port == 0)
280 port = defaultport;
281
282 // handle loopback
283 if (!strcmp(name, "local"))
284 {
286 address->port = port;
287 return 1;
288 }
289 // try to parse as dotted decimal ipv4 address first
290 // note this supports partial ip addresses
291 d1 = d2 = d3 = d4 = 0;
292#if _MSC_VER >= 1400
293#define sscanf sscanf_s
294#endif
295 if (addr_family != AF_INET6 &&
296 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)
297 {
298 // parsed a valid ipv4 address
300 address->port = port;
301 address->addr.in.sin_family = AF_INET;
302 address->addr.in.sin_port = htons((unsigned short)port);
303 a = (unsigned char *)&address->addr.in.sin_addr;
304 a[0] = d1;
305 a[1] = d2;
306 a[2] = d3;
307 a[3] = d4;
308#ifdef STANDALONETEST
309 LHNETADDRESS_ToString(address, string2, sizeof(string2), 1);
310 printf("manual parsing of ipv4 dotted decimal address \"%s\" successful: %s\n", string, string2);
311#endif
312 return 1;
313 }
314 for (i = 0;i < MAX_NAMECACHE;i++)
315 if (!strcmp(namecache[i].name, name))
316 break;
317#ifdef STANDALONETEST
318 if (i < MAX_NAMECACHE)
319#else
321#endif
322 {
323 *address = namecache[i].address;
324 address->port = port;
325 if (address->addresstype == LHNETADDRESSTYPE_INET6)
326 {
327 address->addr.in6.sin6_port = htons((unsigned short)port);
328 return 1;
329 }
330 else if (address->addresstype == LHNETADDRESSTYPE_INET4)
331 {
332 address->addr.in.sin_port = htons((unsigned short)port);
333 return 1;
334 }
335 return 0;
336 }
337
338 for (i = 0;i < (int)sizeof(namecache[namecacheposition].name)-1 && name[i];i++)
341#ifndef STANDALONETEST
342 namecache[namecacheposition].expirationtime = host.realtime + 12 * 3600; // 12 hours
343#endif
344
345 // try resolving the address (handles dns and other ip formats)
346 resolved = LHNETADDRESS_Resolve(address, name, port);
347 if (resolved)
348 {
349#ifdef STANDALONETEST
350 const char *protoname;
351
352 switch (address->addresstype)
353 {
355 protoname = "ipv6";
356 break;
358 protoname = "ipv4";
359 break;
360 default:
361 protoname = "UNKNOWN";
362 break;
363 }
364 LHNETADDRESS_ToString(vaddress, string2, sizeof(string2), 1);
365 Con_Printf("LHNETADDRESS_Resolve(\"%s\") returned %s address %s\n", string, protoname, string2);
366#endif
368 }
369 else
370 {
371#ifdef STANDALONETEST
372 printf("name resolution failed on address \"%s\"\n", name);
373#endif
375 }
376
378 return resolved;
379}
static int(ZEXPORT *qz_inflate)(z_stream *strm
GLsizei const GLchar ** string
Definition glquake.h:728
const GLchar * name
Definition glquake.h:601
int LHNETADDRESS_ToString(const lhnetaddress_t *vaddress, char *string, int stringbuffersize, int includeport)
Returns the number of bytes written to *string excluding the \0 terminator.
Definition lhnet.c:540
#define MAX_NAMECACHE
Definition lhnet.c:115
static int namecacheposition
Definition lhnet.c:123
static int LHNETADDRESS_Resolve(lhnetaddressnative_t *address, const char *name, int port)
Definition lhnet.c:163
static struct namecache_s namecache[MAX_NAMECACHE]
float strlen(string s)
ret a
char name[64]
Definition lhnet.c:120
double expirationtime
Definition lhnet.c:119
lhnetaddressnative_t address
Definition lhnet.c:118

References a, lhnetaddressnative_t::addr, namecache_s::address, lhnetaddressnative_t::addresstype, Con_Printf(), namecache_s::expirationtime, host, i, lhnetaddressnative_t::in, lhnetaddressnative_t::in6, int(), LHNETADDRESS_Resolve(), LHNETADDRESS_ToString(), LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, LHNETADDRESSTYPE_NONE, MAX_NAMECACHE, name, namecache_s::name, namecache, namecacheposition, NULL, lhnetaddressnative_t::port, host_static_t::realtime, string, and strlen().

Referenced by CL_EstablishConnection(), CL_Packet_f(), CL_PQRcon_f(), CL_Rcon_f(), Crypto_HostKey_Clear_f(), Log_DestBuffer_Flush_NoLock(), NetConn_Heartbeat(), NetConn_Init(), NetConn_OpenClientPort(), NetConn_OpenServerPort(), VM_M_crypto_getencryptlevel(), VM_M_crypto_getidfp(), VM_M_crypto_getidstatus(), VM_M_crypto_getkeyfp(), and VM_netaddress_resolve().

◆ LHNETADDRESS_GetAddressType()

static lhnetaddresstype_t LHNETADDRESS_GetAddressType ( const lhnetaddress_t * address)
inlinestatic

◆ LHNETADDRESS_GetInterfaceName()

const char * LHNETADDRESS_GetInterfaceName ( const lhnetaddress_t * address,
char * ifname,
size_t ifnamelength )

Definition at line 608 of file lhnet.c.

609{
610#ifndef NOSUPPORTIPV6
611 lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
612
613 if (address && address->addresstype == LHNETADDRESSTYPE_INET6)
614 {
615#ifndef _WIN32
616
617 if (if_indextoname(address->addr.in6.sin6_scope_id, ifname) == ifname)
618 return ifname;
619
620#else
621
622 // The Win32 API doesn't have if_indextoname() until Windows Vista,
623 // but luckily it just uses the interface ID as the interface name
624
625 if (dpsnprintf(ifname, ifnamelength, "%lu", address->addr.in6.sin6_scope_id) > 0)
626 return ifname;
627
628#endif
629 }
630#endif
631
632 return NULL;
633}
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997

References lhnetaddressnative_t::addr, lhnetaddressnative_t::addresstype, dpsnprintf(), lhnetaddressnative_t::in6, LHNETADDRESSTYPE_INET6, and NULL.

◆ LHNETADDRESS_GetPort()

int LHNETADDRESS_GetPort ( const lhnetaddress_t * address)

Definition at line 635 of file lhnet.c.

636{
637 if (!address)
638 return -1;
639 return address->port;
640}

References lhnetaddress_t::port.

Referenced by NetConn_ServerParsePacket().

◆ LHNETADDRESS_SetPort()

int LHNETADDRESS_SetPort ( lhnetaddress_t * address,
int port )

Definition at line 642 of file lhnet.c.

643{
644 lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
645 if (!address)
646 return 0;
647 address->port = port;
648 switch(address->addresstype)
649 {
651 return 1;
653 address->addr.in.sin_port = htons((unsigned short)port);
654 return 1;
655#ifndef NOSUPPORTIPV6
657 address->addr.in6.sin6_port = htons((unsigned short)port);
658 return 1;
659#endif
660 default:
661 return 0;
662 }
663}

References lhnetaddressnative_t::addr, lhnetaddressnative_t::addresstype, lhnetaddressnative_t::in, lhnetaddressnative_t::in6, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, and lhnetaddressnative_t::port.

Referenced by NetConn_ClearFlood(), NetConn_ClientParsePacket(), and NetConn_PreventFlood().

◆ LHNETADDRESS_ToString()

int LHNETADDRESS_ToString ( const lhnetaddress_t * address,
char * string,
int stringbuffersize,
int includeport )

Returns the number of bytes written to *string excluding the \0 terminator.

Definition at line 540 of file lhnet.c.

541{
542 lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
543 const unsigned char *a;
544 if (!address || !string || stringbuffersize < 1)
545 return 0;
546 *string = 0;
547 switch(address->addresstype)
548 {
549 default:
550 break;
552 if (includeport)
553 {
554 if (stringbuffersize >= 12)
555 {
556 return dpsnprintf(string, stringbuffersize, "local:%d", address->port);
557 }
558 }
559 else
560 {
561 if (stringbuffersize >= 6)
562 {
563 memcpy(string, "local", 6);
564 return 5;
565 }
566 }
567 break;
569 a = (const unsigned char *)(&address->addr.in.sin_addr);
570 if (includeport)
571 {
572 if (stringbuffersize >= 22)
573 {
574 return dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d:%d", a[0], a[1], a[2], a[3], address->port);
575 }
576 }
577 else
578 {
579 if (stringbuffersize >= 16)
580 {
581 return dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
582 }
583 }
584 break;
585#ifndef NOSUPPORTIPV6
587 a = (const unsigned char *)(&address->addr.in6.sin6_addr);
588 if (includeport)
589 {
590 if (stringbuffersize >= 88)
591 {
592 return dpsnprintf(string, stringbuffersize, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d", a[0] * 256 + a[1], a[2] * 256 + a[3], a[4] * 256 + a[5], a[6] * 256 + a[7], a[8] * 256 + a[9], a[10] * 256 + a[11], a[12] * 256 + a[13], a[14] * 256 + a[15], address->port);
593 }
594 }
595 else
596 {
597 if (stringbuffersize >= 80)
598 {
599 return dpsnprintf(string, stringbuffersize, "%x:%x:%x:%x:%x:%x:%x:%x", a[0] * 256 + a[1], a[2] * 256 + a[3], a[4] * 256 + a[5], a[6] * 256 + a[7], a[8] * 256 + a[9], a[10] * 256 + a[11], a[12] * 256 + a[13], a[14] * 256 + a[15]);
600 }
601 }
602 break;
603#endif
604 }
605 return 0;
606}

References a, lhnetaddressnative_t::addr, lhnetaddressnative_t::addresstype, dpsnprintf(), lhnetaddressnative_t::in, lhnetaddressnative_t::in6, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, and lhnetaddressnative_t::port.

Referenced by CL_Rcon_f(), Crypto_ClearHostKey(), Crypto_HostKeys_f(), Crypto_RetrieveHostKey(), Crypto_StoreHostKey(), LHNETADDRESS_FromString(), NetConn_ClientFrame(), NetConn_ClientParsePacket(), NetConn_Open(), NetConn_OpenClientPort(), NetConn_OpenServerPort(), NetConn_Read(), NetConn_ServerParsePacket(), NetConn_UpdateSockets(), NetConn_Write(), SV_SendServerinfo(), SVVM_init_edict(), and VM_netaddress_resolve().

Variable Documentation

◆ lhnet_socketlist

lhnetsocket_t lhnet_socketlist
extern

Definition at line 717 of file lhnet.c.

Referenced by LHNET_Init(), LHNET_OpenSocket_Connectionless(), LHNET_Shutdown(), and Sys_Sleep().