qbyte data[MAX_DATAGRAM];
} packetBuffer;
-
-//#ifdef DEBUG
+/*
+#ifdef DEBUG
char *StrAddr (struct qsockaddr *addr)
{
static char buf[34];
sprintf (buf + n * 2, "%02x", *p++);
return buf;
}
-//#endif
+#endif
+*/
#ifdef BAN_TEST
break;
case 2:
- if (Q_strcasecmp(Cmd_Argv(1), "off") == 0)
+ if (strcasecmp(Cmd_Argv(1), "off") == 0)
banAddr = 0x00000000;
else
banAddr = inet_addr(Cmd_Argv(1));
struct qsockaddr readaddr;
unsigned int sequence;
unsigned int count;
+ int temp;
if (!sock->canSend)
if ((net_time - sock->lastSendTime) > 1.0)
if (length == 0)
break;
- if (length == -1)
+ if ((int)length == -1)
{
Con_Printf("Read error\n");
return -1;
}
- if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0)
+ if ((temp = sfunc.AddrCompare(&readaddr, &sock->addr)) != 0)
{
-#ifdef DEBUG
- Con_DPrintf("Forged packet received\n");
- Con_DPrintf("Expected: %s\n", StrAddr (&sock->addr));
- Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
-#endif
- continue;
+ char tempaddress1[64], tempaddress2[64];
+ if (temp == 1)
+ {
+ if (developer_networking.integer)
+ {
+ dfunc.GetNameFromAddr (&sock->addr, tempaddress1);
+ dfunc.GetNameFromAddr (&readaddr, tempaddress2);
+ Con_Printf("Packet from wrong port received but accepted (Expected: %s Received: %s)\n", tempaddress1, tempaddress2);
+ }
+ }
+ else
+ {
+ dfunc.GetNameFromAddr (&sock->addr, tempaddress1);
+ dfunc.GetNameFromAddr (&readaddr, tempaddress2);
+ Con_Printf("Forged packet received (Expected: %s Received: %s)\n", tempaddress1, tempaddress2);
+ continue;
+ }
}
if (length < NET_HEADERSIZE)
else
{
for (s = net_activeSockets; s; s = s->next)
- if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0)
+ if (strcasecmp(Cmd_Argv(1), s->address) == 0)
break;
if (s == NULL)
return;
}
}
-
+/*
static qboolean testInProgress = false;
static int testPollCount;
static int testDriver;
while (1)
{
len = dfunc.Read (testSocket, net_message.data, net_message.maxsize, &clientaddr);
- if (len < sizeof(int))
+ if (len < (int)sizeof(int))
break;
net_message.cursize = len;
MSG_ReadLong();
if (control == -1)
break;
- if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
+ if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
break;
if ((control & NETFLAG_LENGTH_MASK) != len)
break;
if (host && hostCacheCount)
{
for (n = 0; n < hostCacheCount; n++)
- if (Q_strcasecmp (host, hostcache[n].name) == 0)
+ if (strcasecmp (host, hostcache[n].name) == 0)
{
if (hostcache[n].driver != myDriverLevel)
continue;
name[0] = 0;
len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr);
- if (len < sizeof(int))
+ if (len < (int)sizeof(int))
goto Reschedule;
net_message.cursize = len;
MSG_ReadLong();
if (control == -1)
goto Error;
- if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
+ if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
goto Error;
if ((control & NETFLAG_LENGTH_MASK) != len)
goto Error;
if (host && hostCacheCount)
{
for (n = 0; n < hostCacheCount; n++)
- if (Q_strcasecmp (host, hostcache[n].name) == 0)
+ if (strcasecmp (host, hostcache[n].name) == 0)
{
if (hostcache[n].driver != myDriverLevel)
continue;
SZ_Clear(&net_message);
SchedulePollProcedure(&test2PollProcedure, 0.05);
}
-
+*/
int Datagram_Init (void)
{
#ifdef BAN_TEST
Cmd_AddCommand ("ban", NET_Ban_f);
#endif
- Cmd_AddCommand ("test", Test_f);
- Cmd_AddCommand ("test2", Test2_f);
+ //Cmd_AddCommand ("test", Test_f);
+ //Cmd_AddCommand ("test2", Test2_f);
return 0;
}
SZ_Clear(&net_message);
len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr);
- if (len < sizeof(int))
+ if (len < (int)sizeof(int))
return NULL;
net_message.cursize = len;
MSG_BeginReading ();
control = BigLong(*((int *)net_message.data));
MSG_ReadLong();
-
+
// Messages starting by 0xFFFFFFFF are master server messages
- if (control == 0xFFFFFFFF)
+ if ((unsigned int)control == 0xFFFFFFFF)
{
int responsesize = Master_HandleMessage();
if (responsesize > 0)
}
return NULL;
}
- if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
+ if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
return NULL;
if ((control & NETFLAG_LENGTH_MASK) != len)
return NULL;
ret = dfunc.AddrCompare(&clientaddr, &s->addr);
if (ret >= 0)
{
- // is this a duplicate connection reqeust?
+ // is this a duplicate connection request?
if (ret == 0 && net_time - s->connecttime < 2.0)
{
// yes, so send a duplicate reply
dfunc.GetSocketAddr(s->socket, &newaddr);
MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
+ // LordHavoc: send from s->socket instead of acceptsock, this
+ // way routers usually identify the connection correctly
+ // (thanks to faded for provoking me to recite a lengthy
+ // explanation of NAT nightmares, and realize this easy
+ // workaround for quake)
+ dfunc.Write (s->socket, net_message.data, net_message.cursize, &clientaddr);
+ // LordHavoc: also send from acceptsock, for good measure
dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
SZ_Clear(&net_message);
return NULL;
dfunc.GetSocketAddr(newsock, &newaddr);
MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
+ // LordHavoc: send from sock->socket instead of acceptsock, this way routers
+ // usually identify the connection correctly (thanks to faded for provoking
+ // me to recite a lengthy explanation of NAT nightmares, and realize this
+ // easy workaround for quake)
+ dfunc.Write (sock->socket, net_message.data, net_message.cursize, &clientaddr);
+ // LordHavoc: also send from acceptsock, for good measure
dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
SZ_Clear(&net_message);
static qboolean Datagram_HandleServerInfo (struct qsockaddr *readaddr)
{
- struct qsockaddr myaddr;
+ //struct qsockaddr myaddr;
int control;
- int c, n, i;
+ int c, n;
+ char cname[256];
- if (net_message.cursize < sizeof(int))
+ if (net_message.cursize < (int)sizeof(int))
return false;
// don't answer our own query
- dfunc.GetSocketAddr (dfunc.controlSock, &myaddr);
+ //dfunc.GetSocketAddr (dfunc.controlSock, &myaddr);
//if (dfunc.AddrCompare(readaddr, &myaddr) >= 0)
// return false;
MSG_ReadLong();
if (control == -1)
return false;
- if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
+ if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
return false;
if ((control & NETFLAG_LENGTH_MASK) != net_message.cursize)
return false;
if (c != CCREP_SERVER_INFO)
return false;
- dfunc.GetAddrFromName(MSG_ReadString(), readaddr);
+ // LordHavoc: because the UDP driver reports 0.0.0.0:26000 as the address
+ // string we just ignore it and keep the real address
+ MSG_ReadString();
+ // hostcache only uses text addresses
+ strcpy(cname, dfunc.AddrToString(readaddr));
// search the cache for this server
for (n = 0; n < hostCacheCount; n++)
- if (dfunc.AddrCompare(readaddr, &hostcache[n].addr) == 0)
- break;
-
- // is it already there?
- if (n < hostCacheCount)
- return false;;
+ //if (dfunc.AddrCompare(readaddr, &hostcache[n].addr) == 0)
+ if (!strcmp(cname, hostcache[n].cname))
+ return false;
// add it
hostCacheCount++;
c = MSG_ReadByte();
if (c != NET_PROTOCOL_VERSION)
{
- strcpy(hostcache[n].cname, hostcache[n].name);
- hostcache[n].cname[14] = 0;
+ strncpy(hostcache[n].cname, hostcache[n].name, sizeof(hostcache[n].cname) - 1);
+ hostcache[n].cname[sizeof(hostcache[n].cname) - 1] = 0;
strcpy(hostcache[n].name, "*");
- strcat(hostcache[n].name, hostcache[n].cname);
+ strncat(hostcache[n].name, hostcache[n].cname, sizeof(hostcache[n].name) - 1);
+ hostcache[n].name[sizeof(hostcache[n].name) - 1] = 0;
}
- memcpy(&hostcache[n].addr, readaddr, sizeof(struct qsockaddr));
- hostcache[n].driver = net_driverlevel;
- hostcache[n].ldriver = net_landriverlevel;
- strcpy(hostcache[n].cname, dfunc.AddrToString(readaddr));
+ strcpy(hostcache[n].cname, cname);
+ //memcpy(&hostcache[n].addr, readaddr, sizeof(struct qsockaddr));
+ //hostcache[n].driver = net_driverlevel;
+ //hostcache[n].ldriver = net_landriverlevel;
+ /*
// check for a name conflict
for (i = 0; i < hostCacheCount; i++)
{
if (i == n)
continue;
- if (Q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0)
+ if (strcasecmp (hostcache[n].name, hostcache[i].name) == 0)
{
i = strlen(hostcache[n].name);
if (i < 15 && hostcache[n].name[i-1] > '8')
i = -1;
}
}
+ */
return true;
}
portnum = atoi (port + 1);
if (!portnum)
portnum = MASTER_PORT;
- Con_DPrintf("Datagram_SearchForInetHosts: sending %d byte message to master %s\n", net_message.cursize, master);
+ Con_DPrintf("Datagram_SearchForInetHosts: sending %d byte message to master %s port %i\n", net_message.cursize, master, portnum);
dfunc.SetSocketPort (&masteraddr, portnum);
- dfunc.Send (net_message.data, net_message.cursize, &masteraddr);
+ dfunc.Write (dfunc.controlSock, net_message.data, net_message.cursize, &masteraddr);
}
}
- while ((ret = dfunc.Recv (net_message.data, net_message.maxsize, &readaddr)) > 0)
- {
- net_message.cursize = ret;
- Con_DPrintf("Datagram_SearchForInetHosts: Recv received %d byte message\n", net_message.cursize);
- Master_ParseServerList (&dfunc);
- }
-
while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0)
{
net_message.cursize = ret;
Con_DPrintf("Datagram_SearchForInetHosts: Read received %d byte message\n", net_message.cursize);
if (Datagram_HandleServerInfo (&readaddr))
result = true;
+ else
+ Master_ParseServerList (&dfunc);
}
return result;
if (_Datagram_SearchForInetHosts (master))
result = true;
}
-
+
return result;
}
if (ret > 0)
{
// is it from the right place?
- if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0)
+ // we don't care if the port matches (this adds support for
+ // the NAT fix in the server inspired by faded)
+ if (sfunc.AddrCompare(&readaddr, &sendaddr) < 0)
{
- Con_DPrintf("wrong reply address\n");
- Con_DPrintf("Expected: %s\n", StrAddr (&sendaddr));
- Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
+ char tempaddress1[64], tempaddress2[64];
+ dfunc.GetNameFromAddr (&sendaddr, tempaddress1);
+ dfunc.GetNameFromAddr (&readaddr, tempaddress2);
+ Con_Printf("wrong reply address (Expected: %s Received: %s)\n", tempaddress1, tempaddress2);
+ CL_UpdateScreen ();
CL_UpdateScreen ();
ret = 0;
continue;
}
- if (ret < sizeof(int))
+ if (ret < (int)sizeof(int))
{
ret = 0;
continue;
ret = 0;
continue;
}
- if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
+ if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
{
ret = 0;
continue;
portnum = MASTER_PORT;
dfunc.SetSocketPort (&masteraddr, portnum);
+ // FIXME: this is the only use of UDP_Send in the entire engine, add a dfunc.acceptSock to get rid of this function!
dfunc.Send (net_message.data, net_message.cursize, &masteraddr);
}