static qboolean Datagram_HandleServerInfo (struct qsockaddr *readaddr)
{
- struct qsockaddr myaddr;
+ //struct qsockaddr myaddr;
int control;
int c, n, i;
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;
portnum = MASTER_PORT;
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;
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);
}
Master_ParseServerList
Parse getserverResponse messages
+Returns true if it was a valid getserversResponse
====================
*/
-void Master_ParseServerList (net_landriver_t* dfunc)
+int Master_ParseServerList (net_landriver_t* dfunc)
{
+ int servercount = 0;
int control;
qbyte* servers;
qbyte* crtserver;
- unsigned int ipaddr;
struct qsockaddr svaddr;
char ipstring [32];
+ char string[32];
if (developer.integer)
{
SZ_HexDumpToConsole(&net_message);
}
- if (net_message.cursize < (int)sizeof(int))
- return;
+ if (net_message.cursize < 23)
+ return 0;
// is the cache full?
if (hostCacheCount == HOSTCACHESIZE)
- return;
+ return 0;
MSG_BeginReading ();
- control = BigLong(*((int *)net_message.data));
- MSG_ReadLong();
+ control = MSG_ReadBigLong();
if (control != -1)
- return;
+ return 0;
- if (strncmp (net_message.data + 4, "getserversResponse\\", 19))
- return;
-
- // Skip the next 19 bytes
- MSG_ReadLong(); MSG_ReadLong(); MSG_ReadLong(); MSG_ReadLong();
- MSG_ReadShort(); MSG_ReadByte();
+ if (MSG_ReadBytes(19, string) < 19 || memcmp(string, "getserversResponse\\", 19))
+ return 0;
crtserver = servers = Z_Malloc (net_message.cursize - 23);
memcpy (servers , net_message.data + 23, net_message.cursize - 23);
// Extract the IP addresses
- while ((ipaddr = (crtserver[3] << 24) | (crtserver[2] << 16) | (crtserver[1] << 8) | crtserver[0]) != 0xFFFFFFFF)
+ while ((crtserver[0] != 0xFF || crtserver[1] != 0xFF || crtserver[2] != 0xFF || crtserver[3] != 0xFF) && (crtserver[4] != 0 || crtserver[5] != 0))
{
- int port = (crtserver[5] << 8) | crtserver[4];
-
- if (port < 1 || port >= 65535)
- break;
-
- port = ((port >> 8) & 0xFF) + ((port & 0xFF) << 8);
- sprintf (ipstring, "%u.%u.%u.%u:%hu",
- ipaddr & 0xFF, (ipaddr >> 8) & 0xFF,
- (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF,
- port);
+ // LordHavoc: FIXME: this could be much faster than converting to a string and back
+ // LordHavoc: FIXME: this code is very UDP specific, perhaps it should be part of net_udp?
+ sprintf (ipstring, "%u.%u.%u.%u:%u", crtserver[0], crtserver[1], crtserver[2], crtserver[3], (crtserver[4] << 8) | crtserver[5]);
dfunc->GetAddrFromName (ipstring, &svaddr);
-
Con_DPrintf("Requesting info from server %s\n", ipstring);
+
// Send a request at this address
SZ_Clear(&net_message);
MSG_WriteLong(&net_message, 0); // save space for the header, filled in later
dfunc->Write(dfunc->controlSock, net_message.data, net_message.cursize, &svaddr);
SZ_Clear(&net_message);
+ servercount++;
+
if (crtserver[6] != '\\')
break;
crtserver += 7;
}
Z_Free (servers);
+
+ return servercount;
}
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
const char* Master_BuildHeartbeat (void);
int Master_HandleMessage (void);
void Master_Init (void);
-void Master_ParseServerList (net_landriver_t* dfunc);
+int Master_ParseServerList (net_landriver_t* dfunc);
#endif