mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-29 15:41:59 +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;
|
netadr_t addr;
|
||||||
} hostcache_t;
|
} hostcache_t;
|
||||||
|
|
||||||
extern int hostCacheCount;
|
void NET_AddCachedHost (const char *name, const char *map, const char *cname,
|
||||||
extern hostcache_t hostcache[HOSTCACHESIZE];
|
int users, int maxusers, int driver, int ldriver,
|
||||||
|
const netadr_t *addr);
|
||||||
|
|
||||||
extern double net_time;
|
extern double net_time;
|
||||||
extern struct msg_s *net_message;
|
extern struct msg_s *net_message;
|
||||||
|
|
|
@ -97,9 +97,11 @@ qboolean recording = false;
|
||||||
|
|
||||||
int net_driverlevel;
|
int net_driverlevel;
|
||||||
|
|
||||||
|
|
||||||
double net_time;
|
double net_time;
|
||||||
|
|
||||||
|
static int hostCacheCount = 0;
|
||||||
|
static hostcache_t hostcache[HOSTCACHESIZE];
|
||||||
|
|
||||||
double
|
double
|
||||||
SetNetTime (void)
|
SetNetTime (void)
|
||||||
{
|
{
|
||||||
|
@ -265,6 +267,58 @@ PrintSlistHeader (void)
|
||||||
slistLastShown = 0;
|
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
|
static void
|
||||||
PrintSlist (void)
|
PrintSlist (void)
|
||||||
|
@ -359,10 +413,6 @@ Slist_Poll (void *unused)
|
||||||
slistLocal = true;
|
slistLocal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int hostCacheCount = 0;
|
|
||||||
hostcache_t hostcache[HOSTCACHESIZE];
|
|
||||||
|
|
||||||
qsocket_t *
|
qsocket_t *
|
||||||
NET_Connect (const char *host)
|
NET_Connect (const char *host)
|
||||||
{
|
{
|
||||||
|
|
|
@ -880,8 +880,6 @@ static void
|
||||||
_Datagram_SearchForHosts (qboolean xmit)
|
_Datagram_SearchForHosts (qboolean xmit)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int n;
|
|
||||||
int i;
|
|
||||||
netadr_t readaddr;
|
netadr_t readaddr;
|
||||||
netadr_t myaddr;
|
netadr_t myaddr;
|
||||||
int control;
|
int control;
|
||||||
|
@ -914,11 +912,6 @@ _Datagram_SearchForHosts (qboolean xmit)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the cache full?
|
|
||||||
if (hostCacheCount == HOSTCACHESIZE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSG_BeginReading (net_message);
|
MSG_BeginReading (net_message);
|
||||||
control = MSG_ReadLongBE (net_message);
|
control = MSG_ReadLongBE (net_message);
|
||||||
if (control == -1) {
|
if (control == -1) {
|
||||||
|
@ -935,53 +928,25 @@ _Datagram_SearchForHosts (qboolean xmit)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dfunc.GetAddrFromName (MSG_ReadString (net_message), &readaddr);
|
const char *addrstr = MSG_ReadString (net_message);
|
||||||
// search the cache for this server
|
dfunc.GetAddrFromName (addrstr, &readaddr);
|
||||||
for (n = 0; n < hostCacheCount; n++) {
|
|
||||||
if (dfunc.AddrCompare (&readaddr, &hostcache[n].addr) == 0) {
|
const char *name = MSG_ReadString (net_message);
|
||||||
break;
|
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?
|
NET_AddCachedHost (name, map, cname, users, maxusers, net_driverlevel,
|
||||||
if (n < hostCacheCount) {
|
net_landriverlevel, &readaddr);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -990,9 +955,6 @@ Datagram_SearchForHosts (qboolean xmit)
|
||||||
{
|
{
|
||||||
for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers;
|
for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers;
|
||||||
net_landriverlevel++) {
|
net_landriverlevel++) {
|
||||||
if (hostCacheCount == HOSTCACHESIZE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (net_landrivers[net_landriverlevel].initialized) {
|
if (net_landrivers[net_landriverlevel].initialized) {
|
||||||
_Datagram_SearchForHosts (xmit);
|
_Datagram_SearchForHosts (xmit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,16 +69,16 @@ Loop_SearchForHosts (qboolean xmit)
|
||||||
if (!sv.active)
|
if (!sv.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hostCacheCount = 1;
|
const char *name = "local";
|
||||||
if (strcmp (hostname->string, "UNNAMED") == 0)
|
if (strcmp (hostname->string, "UNNAMED") != 0) {
|
||||||
strcpy (hostcache[0].name, "local");
|
name = hostname->string;
|
||||||
else
|
}
|
||||||
strcpy (hostcache[0].name, hostname->string);
|
const char *map = sv.name;
|
||||||
strcpy (hostcache[0].map, sv.name);
|
int users = net_activeconnections;
|
||||||
hostcache[0].users = net_activeconnections;
|
int maxusers = svs.maxclients;
|
||||||
hostcache[0].maxusers = svs.maxclients;
|
const char *cname = "local";
|
||||||
hostcache[0].driver = net_driverlevel;
|
NET_AddCachedHost (name, map, cname, users, maxusers, net_driverlevel,
|
||||||
strcpy (hostcache[0].cname, "local");
|
0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue