Index: messages.c =================================================================== --- messages.c (revision 853) +++ messages.c (working copy) @@ -25,6 +25,7 @@ #include "messages.h" #include "servers.h" +#include // ---------- Constants ---------- // @@ -185,7 +186,7 @@ } strncat (msg, server->challenge, sizeof (msg) - strlen (msg) - 1); - sendto (sock, msg, strlen (msg), 0, + sendto (querysock, msg, strlen (msg), 0, (const struct sockaddr*)&server->address, sizeof (server->address)); @@ -288,7 +289,8 @@ // Check protocol, options if (sv->protocol != protocol || (sv->nbclients == 0 && no_empty) || - (sv->nbclients == sv->maxclients && no_full)) + (sv->nbclients == sv->maxclients && no_full) || + (!sv->maxclients)) { // Skip it @@ -344,8 +346,8 @@ */ static void HandleInfoResponse (server_t* server, const char* msg) { - char* value; - unsigned int new_protocol = 0, new_maxclients = 0; + char* value, *host; + unsigned int new_protocol = 0, new_maxclients = 0, non_alpha = 0; MsgPrint (MSG_DEBUG, "%s ---> infoResponse\n", peer_address); @@ -365,6 +367,50 @@ return; } + value = host = SearchInfostring (msg, "hostname"); + + if (!value) + { + MsgPrint (MSG_ERROR, "ERROR: invalid hostname from %s\n", + peer_address); + return; + } + +#ifdef FILTER_SPAMMY_HOSTNAMES + while (value[0]) + { + if (isspace (value[0])) + { + non_alpha = 3; + break; + } + else if (!isalnum(value[0])) + { + non_alpha++; + } + else + break; + value++; + } + + if (non_alpha >= 3) + { + MsgPrint (MSG_WARNING, "WARNING: spammy hostname '%s' from %s (%d bad chars)\n", host, peer_address, non_alpha); + return; + } + value = host; +#endif + + while (value[0]) + { + if (value[0] < 32 || *(unsigned char *)value > 127) + { + MsgPrint (MSG_WARNING, "WARNING: non-alpha chars in hostname '%s' from %s\n", host, peer_address); + return; + } + value++; + } + // Check and save the values of "protocol" and "maxclients" value = SearchInfostring (msg, "protocol"); if (value) Index: master.c =================================================================== --- master.c (revision 853) +++ master.c (working copy) @@ -28,6 +28,7 @@ # include # include #endif +#include #include "common.h" #include "messages.h" @@ -87,6 +88,7 @@ // The master socket int sock = -1; +int querysock = -1; // The current time (updated every time we receive a packet) time_t crt_time; @@ -475,6 +477,14 @@ return qfalse; } + querysock = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (querysock < 0) + { + MsgPrint (MSG_ERROR, "ERROR: query socket creation failed (%s)\n", + strerror (errno)); + return qfalse; + } + // Bind it to the master port memset (&address, 0, sizeof (address)); address.sin_family = AF_INET; @@ -498,6 +508,20 @@ #endif return qfalse; } + + address.sin_port = 0; + if (bind (querysock, (struct sockaddr*)&address, sizeof (address)) != 0) + { + MsgPrint (MSG_ERROR, "ERROR: query socket binding failed (%s)\n", + strerror (errno)); +#ifdef WIN32 + closesocket (sock); +#else + close (sock); +#endif + return qfalse; + } + MsgPrint (MSG_NORMAL, "Listening on UDP port %hu\n", ntohs (address.sin_port)); @@ -682,7 +706,7 @@ { struct sockaddr_in address; socklen_t addrlen; - int nb_bytes; + int nb_bytes, maxsock, thesock; char packet [MAX_PACKET_SIZE + 1]; // "+ 1" because we append a '\0' qboolean valid_options; fd_set rfds; @@ -710,15 +734,21 @@ return EXIT_FAILURE; MsgPrint (MSG_NORMAL, "\n"); + if (querysock > sock) + maxsock = querysock; + else + maxsock = sock; + // Until the end of times... while( !exitNow ) { FD_ZERO( &rfds ); FD_SET( sock, &rfds ); + FD_SET( querysock, &rfds ); tv.tv_sec = tv.tv_usec = 0; // Check for new data every 100ms - if( select( sock + 1, &rfds, NULL, NULL, &tv ) <= 0 ) + if( select( maxsock + 1, &rfds, NULL, NULL, &tv ) <= 0 ) { #ifdef _WIN32 Sleep( 100 ); @@ -728,9 +758,16 @@ continue; } + if (FD_ISSET (sock, &rfds)) + thesock = sock; + else if (FD_ISSET (querysock, &rfds)) + thesock = querysock; + else + continue; + // Get the next valid message addrlen = sizeof (address); - nb_bytes = recvfrom (sock, packet, sizeof (packet) - 1, 0, + nb_bytes = recvfrom (thesock, packet, sizeof (packet) - 1, 0, (struct sockaddr*)&address, &addrlen); if (nb_bytes <= 0) { @@ -772,11 +809,11 @@ peer_address); continue; } - if (! ntohs (address.sin_port)) + if (! ntohs (address.sin_port) || ntohs (address.sin_port) < 1024) { MsgPrint (MSG_WARNING, - "WARNING: rejected packet from %s (source port = 0)\n", - peer_address); + "WARNING: rejected packet from %s (source port = %d)\n", + peer_address, ntohs (address.sin_port)); continue; } Index: Makefile =================================================================== --- Makefile (revision 853) +++ Makefile (working copy) @@ -9,8 +9,8 @@ MKDIR=mkdir else BINEXT= - RELEASE_LDFLAGS=-static -ltdb - DEBUG_LDFLAGS=-static -ltdb + RELEASE_LDFLAGS=-ltdb + DEBUG_LDFLAGS=-ltdb RM=rm -f MKDIR=mkdir endif Index: common.h =================================================================== --- common.h (revision 853) +++ common.h (working copy) @@ -64,6 +64,9 @@ // The master socket extern int sock; +// The query socket +extern int querysock; + // The current time (updated every time we receive a packet) extern time_t crt_time;