mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-25 22:01:33 +00:00
[net] Move found host caching into net_main
This unifies all the checks and plugs a set of potential buffer overflows.
This commit is contained in:
parent
a630c95eb6
commit
9fb337fac4
4 changed files with 85 additions and 72 deletions
|
@ -262,8 +262,9 @@ typedef struct {
|
|||
netadr_t addr;
|
||||
} hostcache_t;
|
||||
|
||||
extern int hostCacheCount;
|
||||
extern hostcache_t hostcache[HOSTCACHESIZE];
|
||||
void NET_AddCachedHost (const char *name, const char *map, const char *cname,
|
||||
int users, int maxusers, int driver, int ldriver,
|
||||
const netadr_t *addr);
|
||||
|
||||
extern double net_time;
|
||||
extern struct msg_s *net_message;
|
||||
|
|
|
@ -97,9 +97,11 @@ qboolean recording = false;
|
|||
|
||||
int net_driverlevel;
|
||||
|
||||
|
||||
double net_time;
|
||||
|
||||
static int hostCacheCount = 0;
|
||||
static hostcache_t hostcache[HOSTCACHESIZE];
|
||||
|
||||
double
|
||||
SetNetTime (void)
|
||||
{
|
||||
|
@ -265,6 +267,58 @@ PrintSlistHeader (void)
|
|||
slistLastShown = 0;
|
||||
}
|
||||
|
||||
void
|
||||
NET_AddCachedHost (const char *name, const char *map, const char *cname,
|
||||
int users, int maxusers, int driver, int ldriver,
|
||||
const netadr_t *addr)
|
||||
{
|
||||
if (hostCacheCount == HOSTCACHESIZE) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < hostCacheCount; i++) {
|
||||
// addr will be 0 for loopback, and there can be only one loopback
|
||||
// server.
|
||||
if (!addr || !memcmp (addr, &hostcache[i].addr, sizeof (netadr_t))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const int namesize = sizeof (hostcache[0].name) - 1;
|
||||
const int mapsize = sizeof (hostcache[0].map) - 1;
|
||||
const int cnamesize = sizeof (hostcache[0].cname) - 1;
|
||||
|
||||
hostcache_t *host = &hostcache[hostCacheCount++];
|
||||
strncpy (host->name, name, namesize);
|
||||
strncpy (host->map, map, mapsize);
|
||||
strncpy (host->cname, cname, cnamesize);
|
||||
host->name[namesize] = 0;
|
||||
host->map[mapsize] = 0;
|
||||
host->cname[cnamesize] = 0;
|
||||
|
||||
host->users = users;
|
||||
host->maxusers = maxusers;
|
||||
host->driver = driver;
|
||||
host->ldriver = ldriver;
|
||||
if (addr) {
|
||||
host->addr = *addr;
|
||||
} else {
|
||||
memset (&host->addr, 0, sizeof (host->addr));
|
||||
}
|
||||
|
||||
// check for and resolve name conflicts
|
||||
for (int i = 0; i < hostCacheCount - 1; i++) {
|
||||
if (strcasecmp (host->name, hostcache[i].name) == 0) {
|
||||
int len = strlen (host->name);
|
||||
if (len < namesize && host->name[len - 1] > '8') {
|
||||
host->name[len] = '0';
|
||||
host->name[len + 1] = 0;
|
||||
} else {
|
||||
host->name[len - 1]++;
|
||||
}
|
||||
i = -1; // restart loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
PrintSlist (void)
|
||||
|
@ -359,10 +413,6 @@ Slist_Poll (void *unused)
|
|||
slistLocal = true;
|
||||
}
|
||||
|
||||
|
||||
int hostCacheCount = 0;
|
||||
hostcache_t hostcache[HOSTCACHESIZE];
|
||||
|
||||
qsocket_t *
|
||||
NET_Connect (const char *host)
|
||||
{
|
||||
|
|
|
@ -880,8 +880,6 @@ static void
|
|||
_Datagram_SearchForHosts (qboolean xmit)
|
||||
{
|
||||
int ret;
|
||||
int n;
|
||||
int i;
|
||||
netadr_t readaddr;
|
||||
netadr_t myaddr;
|
||||
int control;
|
||||
|
@ -914,11 +912,6 @@ _Datagram_SearchForHosts (qboolean xmit)
|
|||
continue;
|
||||
}
|
||||
|
||||
// is the cache full?
|
||||
if (hostCacheCount == HOSTCACHESIZE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MSG_BeginReading (net_message);
|
||||
control = MSG_ReadLongBE (net_message);
|
||||
if (control == -1) {
|
||||
|
@ -935,53 +928,25 @@ _Datagram_SearchForHosts (qboolean xmit)
|
|||
continue;
|
||||
}
|
||||
|
||||
dfunc.GetAddrFromName (MSG_ReadString (net_message), &readaddr);
|
||||
// search the cache for this server
|
||||
for (n = 0; n < hostCacheCount; n++) {
|
||||
if (dfunc.AddrCompare (&readaddr, &hostcache[n].addr) == 0) {
|
||||
break;
|
||||
}
|
||||
const char *addrstr = MSG_ReadString (net_message);
|
||||
dfunc.GetAddrFromName (addrstr, &readaddr);
|
||||
|
||||
const char *name = MSG_ReadString (net_message);
|
||||
const char *map = MSG_ReadString (net_message);
|
||||
int users = MSG_ReadByte (net_message);
|
||||
int maxusers = MSG_ReadByte (net_message);
|
||||
int protocol = MSG_ReadByte (net_message);
|
||||
const char *cname = dfunc.AddrToString (&readaddr);
|
||||
|
||||
if (protocol != NET_PROTOCOL_VERSION) {
|
||||
char *new_name = alloca (strlen (name) + 2);
|
||||
new_name[0] = '*';
|
||||
strcpy (new_name + 1, name);
|
||||
name = new_name;
|
||||
}
|
||||
|
||||
// is it already there?
|
||||
if (n < hostCacheCount) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// add it
|
||||
hostCacheCount++;
|
||||
strcpy (hostcache[n].name, MSG_ReadString (net_message));
|
||||
strcpy (hostcache[n].map, MSG_ReadString (net_message));
|
||||
hostcache[n].users = MSG_ReadByte (net_message);
|
||||
hostcache[n].maxusers = MSG_ReadByte (net_message);
|
||||
if (MSG_ReadByte (net_message) != NET_PROTOCOL_VERSION) {
|
||||
strcpy (hostcache[n].cname, hostcache[n].name);
|
||||
hostcache[n].cname[14] = 0;
|
||||
strcpy (hostcache[n].name, "*");
|
||||
strcat (hostcache[n].name, hostcache[n].cname);
|
||||
}
|
||||
memcpy (&hostcache[n].addr, &readaddr, sizeof (netadr_t));
|
||||
|
||||
hostcache[n].driver = net_driverlevel;
|
||||
hostcache[n].ldriver = net_landriverlevel;
|
||||
strcpy (hostcache[n].cname, dfunc.AddrToString (&readaddr));
|
||||
|
||||
// check for a name conflict
|
||||
for (i = 0; i < hostCacheCount; i++) {
|
||||
if (i == n) {
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp (hostcache[n].name, hostcache[i].name) == 0) {
|
||||
i = strlen (hostcache[n].name);
|
||||
if (i < 15 && hostcache[n].name[i - 1] > '8') {
|
||||
hostcache[n].name[i] = '0';
|
||||
hostcache[n].name[i + 1] = 0;
|
||||
} else {
|
||||
hostcache[n].name[i - 1]++;
|
||||
}
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
NET_AddCachedHost (name, map, cname, users, maxusers, net_driverlevel,
|
||||
net_landriverlevel, &readaddr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -990,9 +955,6 @@ Datagram_SearchForHosts (qboolean xmit)
|
|||
{
|
||||
for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers;
|
||||
net_landriverlevel++) {
|
||||
if (hostCacheCount == HOSTCACHESIZE) {
|
||||
break;
|
||||
}
|
||||
if (net_landrivers[net_landriverlevel].initialized) {
|
||||
_Datagram_SearchForHosts (xmit);
|
||||
}
|
||||
|
|
|
@ -69,16 +69,16 @@ Loop_SearchForHosts (qboolean xmit)
|
|||
if (!sv.active)
|
||||
return;
|
||||
|
||||
hostCacheCount = 1;
|
||||
if (strcmp (hostname->string, "UNNAMED") == 0)
|
||||
strcpy (hostcache[0].name, "local");
|
||||
else
|
||||
strcpy (hostcache[0].name, hostname->string);
|
||||
strcpy (hostcache[0].map, sv.name);
|
||||
hostcache[0].users = net_activeconnections;
|
||||
hostcache[0].maxusers = svs.maxclients;
|
||||
hostcache[0].driver = net_driverlevel;
|
||||
strcpy (hostcache[0].cname, "local");
|
||||
const char *name = "local";
|
||||
if (strcmp (hostname->string, "UNNAMED") != 0) {
|
||||
name = hostname->string;
|
||||
}
|
||||
const char *map = sv.name;
|
||||
int users = net_activeconnections;
|
||||
int maxusers = svs.maxclients;
|
||||
const char *cname = "local";
|
||||
NET_AddCachedHost (name, map, cname, users, maxusers, net_driverlevel,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue