/* Relay -- a tool to record and play Quake2 demos Copyright (C) 2000 Conor Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Conor Davis cedavis@planetquake.com */ #include "sv_local.h" typedef struct challenge_s { struct sockaddr_in addr; int id; size_t time; struct challenge_s *next; } challenge_t; static challenge_t *challenge_head; int NewChallenge(struct sockaddr_in *addr) { challenge_t *ch; // search for existing challenges from the // same address for (ch = challenge_head; ch; ch = ch->next) { if (!UDP_AddrCompare(addr, &ch->addr)) { ch->time = mstime() + CHALLENGE_TIMEOUT; return ch->id; } } // create a new challenge ch = Z_Malloc(sizeof(challenge_t)); ch->addr = *addr; ch->id = rand(); ch->time = mstime() + CHALLENGE_TIMEOUT; ch->next = challenge_head; challenge_head = ch; return ch->id; } qboolean FindChallenge(struct sockaddr_in *addr, int id) { challenge_t *ch, *prev; int ch_id; for (prev = NULL, ch = challenge_head; ch; prev = ch, ch = ch->next) { if (!UDP_AddrCompare(addr, &ch->addr)) { ch_id = ch->id; // remove the challenge if (prev) prev->next = ch->next; else challenge_head = ch->next; Z_Free(ch); return (id == ch_id); } } return false; } void TimeoutChallenges() { challenge_t *ch, *prev, *next; size_t now; now = mstime(); prev = NULL; for (ch = challenge_head; ch; ch = next) { next = ch->next; if (ch->time <= now) { if (prev) prev->next = ch->next; else challenge_head = ch->next; Z_Free(ch); } else prev = ch; } } void FreeAllChallenges() { challenge_t *ch, *next; for (ch = challenge_head; ch; ch = next) { next = ch->next; Z_Free(ch); } challenge_head = NULL; }