2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 // This is enables a simple IP banning mechanism
29 #include <sys/socket.h>
30 #include <arpa/inet.h>
32 #define AF_INET 2 /* internet */
37 struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
38 struct { unsigned short s_w1,s_w2; } S_un_w;
42 #define s_addr S_un.S_addr /* can be used for most tcp & ip code */
46 unsigned short sin_port;
47 struct in_addr sin_addr;
50 char *inet_ntoa(struct in_addr in);
51 unsigned long inet_addr(const char *cp);
57 #include "net_master.h"
59 cvar_t cl_port = {CVAR_SAVE, "cl_port", "0"};
61 // these two macros are to make the code more readable
62 #define sfunc net_landrivers[sock->landriver]
63 #define dfunc net_landrivers[net_landriverlevel]
65 static int net_landriverlevel;
67 /* statistic counters */
69 int packetsReSent = 0;
70 int packetsReceived = 0;
71 int receivedDuplicateCount = 0;
72 int shortPacketCount = 0;
75 static int myDriverLevel;
80 unsigned int sequence;
81 qbyte data[MAX_DATAGRAM];
86 char *StrAddr (struct qsockaddr *addr)
89 qbyte *p = (qbyte *)addr;
92 for (n = 0; n < 16; n++)
93 sprintf (buf + n * 2, "%02x", *p++);
100 unsigned long banAddr = 0x00000000;
101 unsigned long banMask = 0xffffffff;
103 void NET_Ban_f (void)
107 void (*print) (const char *fmt, ...);
109 if (cmd_source == src_command)
113 Cmd_ForwardToServer ();
120 if (pr_global_struct->deathmatch)
122 print = SV_ClientPrintf;
128 if (((struct in_addr *)&banAddr)->s_addr)
130 strcpy(addrStr, inet_ntoa(*(struct in_addr *)&banAddr));
131 strcpy(maskStr, inet_ntoa(*(struct in_addr *)&banMask));
132 print("Banning %s [%s]\n", addrStr, maskStr);
135 print("Banning not active\n");
139 if (strcasecmp(Cmd_Argv(1), "off") == 0)
140 banAddr = 0x00000000;
142 banAddr = inet_addr(Cmd_Argv(1));
143 banMask = 0xffffffff;
147 banAddr = inet_addr(Cmd_Argv(1));
148 banMask = inet_addr(Cmd_Argv(2));
152 print("BAN ip_address [mask]\n");
159 int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data)
161 unsigned int packetLen;
162 unsigned int dataLen;
166 if (data->cursize == 0)
167 Sys_Error("Datagram_SendMessage: zero length message\n");
169 if (data->cursize > NET_MAXMESSAGE)
170 Sys_Error("Datagram_SendMessage: message too big %u\n", data->cursize);
172 if (sock->canSend == false)
173 Sys_Error("SendMessage: called with canSend == false\n");
176 memcpy(sock->sendMessage, data->data, data->cursize);
177 sock->sendMessageLength = data->cursize;
179 if (data->cursize <= MAX_DATAGRAM)
181 dataLen = data->cursize;
186 dataLen = MAX_DATAGRAM;
189 packetLen = NET_HEADERSIZE + dataLen;
191 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
192 packetBuffer.sequence = BigLong(sock->sendSequence++);
193 memcpy (packetBuffer.data, sock->sendMessage, dataLen);
195 sock->canSend = false;
197 if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1)
200 sock->lastSendTime = net_time;
206 int SendMessageNext (qsocket_t *sock)
208 unsigned int packetLen;
209 unsigned int dataLen;
212 if (sock->sendMessageLength <= MAX_DATAGRAM)
214 dataLen = sock->sendMessageLength;
219 dataLen = MAX_DATAGRAM;
222 packetLen = NET_HEADERSIZE + dataLen;
224 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
225 packetBuffer.sequence = BigLong(sock->sendSequence++);
226 memcpy (packetBuffer.data, sock->sendMessage, dataLen);
228 sock->sendNext = false;
230 if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1)
233 sock->lastSendTime = net_time;
239 int ReSendMessage (qsocket_t *sock)
241 unsigned int packetLen;
242 unsigned int dataLen;
245 if (sock->sendMessageLength <= MAX_DATAGRAM)
247 dataLen = sock->sendMessageLength;
252 dataLen = MAX_DATAGRAM;
255 packetLen = NET_HEADERSIZE + dataLen;
257 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
258 packetBuffer.sequence = BigLong(sock->sendSequence - 1);
259 memcpy (packetBuffer.data, sock->sendMessage, dataLen);
261 sock->sendNext = false;
263 if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1)
266 sock->lastSendTime = net_time;
272 qboolean Datagram_CanSendMessage (qsocket_t *sock)
275 SendMessageNext (sock);
277 return sock->canSend;
281 qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock)
287 int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
292 if (data->cursize == 0)
293 Sys_Error("Datagram_SendUnreliableMessage: zero length message\n");
295 if (data->cursize > MAX_DATAGRAM)
296 Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize);
299 packetLen = NET_HEADERSIZE + data->cursize;
301 packetBuffer.length = BigLong(packetLen | NETFLAG_UNRELIABLE);
302 packetBuffer.sequence = BigLong(sock->unreliableSendSequence++);
303 memcpy (packetBuffer.data, data->data, data->cursize);
305 if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1)
313 int Datagram_GetMessage (qsocket_t *sock)
318 struct qsockaddr readaddr;
319 unsigned int sequence;
323 if ((net_time - sock->lastSendTime) > 1.0)
324 ReSendMessage (sock);
328 length = sfunc.Read (sock->socket, (qbyte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr);
333 if ((int)length == -1)
335 Con_Printf("Read error\n");
339 if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0)
341 Con_DPrintf("Forged packet received\n");
342 Con_DPrintf("Expected: %s\n", StrAddr (&sock->addr));
343 Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
347 if (length < NET_HEADERSIZE)
353 length = BigLong(packetBuffer.length);
354 flags = length & (~NETFLAG_LENGTH_MASK);
355 length &= NETFLAG_LENGTH_MASK;
357 if (flags & NETFLAG_CTL)
360 sequence = BigLong(packetBuffer.sequence);
363 if (flags & NETFLAG_UNRELIABLE)
365 if (sequence < sock->unreliableReceiveSequence)
367 Con_DPrintf("Got a stale datagram\n");
371 if (sequence != sock->unreliableReceiveSequence)
373 count = sequence - sock->unreliableReceiveSequence;
374 droppedDatagrams += count;
375 Con_DPrintf("Dropped %u datagram(s)\n", count);
377 sock->unreliableReceiveSequence = sequence + 1;
379 length -= NET_HEADERSIZE;
381 SZ_Clear (&net_message);
382 SZ_Write (&net_message, packetBuffer.data, length);
388 if (flags & NETFLAG_ACK)
390 if (sequence != (sock->sendSequence - 1))
392 Con_DPrintf("Stale ACK received\n");
395 if (sequence == sock->ackSequence)
398 if (sock->ackSequence != sock->sendSequence)
399 Con_DPrintf("ack sequencing error\n");
403 Con_DPrintf("Duplicate ACK received\n");
406 sock->sendMessageLength -= MAX_DATAGRAM;
407 if (sock->sendMessageLength > 0)
409 memcpy(sock->sendMessage, sock->sendMessage+MAX_DATAGRAM, sock->sendMessageLength);
410 sock->sendNext = true;
414 sock->sendMessageLength = 0;
415 sock->canSend = true;
420 if (flags & NETFLAG_DATA)
422 packetBuffer.length = BigLong(NET_HEADERSIZE | NETFLAG_ACK);
423 packetBuffer.sequence = BigLong(sequence);
424 sfunc.Write (sock->socket, (qbyte *)&packetBuffer, NET_HEADERSIZE, &readaddr);
426 if (sequence != sock->receiveSequence)
428 receivedDuplicateCount++;
431 sock->receiveSequence++;
433 length -= NET_HEADERSIZE;
435 if (flags & NETFLAG_EOM)
437 SZ_Clear(&net_message);
438 SZ_Write(&net_message, sock->receiveMessage, sock->receiveMessageLength);
439 SZ_Write(&net_message, packetBuffer.data, length);
440 sock->receiveMessageLength = 0;
446 memcpy(sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length);
447 sock->receiveMessageLength += length;
453 SendMessageNext (sock);
459 void PrintStats(qsocket_t *s)
461 Con_Printf("canSend = %4u \n", s->canSend);
462 Con_Printf("sendSeq = %4u ", s->sendSequence);
463 Con_Printf("recvSeq = %4u \n", s->receiveSequence);
467 void NET_Stats_f (void)
471 if (Cmd_Argc () == 1)
473 Con_Printf("unreliable messages sent = %i\n", unreliableMessagesSent);
474 Con_Printf("unreliable messages recv = %i\n", unreliableMessagesReceived);
475 Con_Printf("reliable messages sent = %i\n", messagesSent);
476 Con_Printf("reliable messages received = %i\n", messagesReceived);
477 Con_Printf("packetsSent = %i\n", packetsSent);
478 Con_Printf("packetsReSent = %i\n", packetsReSent);
479 Con_Printf("packetsReceived = %i\n", packetsReceived);
480 Con_Printf("receivedDuplicateCount = %i\n", receivedDuplicateCount);
481 Con_Printf("shortPacketCount = %i\n", shortPacketCount);
482 Con_Printf("droppedDatagrams = %i\n", droppedDatagrams);
484 else if (strcmp(Cmd_Argv(1), "*") == 0)
486 for (s = net_activeSockets; s; s = s->next)
491 for (s = net_activeSockets; s; s = s->next)
492 if (strcasecmp(Cmd_Argv(1), s->address) == 0)
501 static qboolean testInProgress = false;
502 static int testPollCount;
503 static int testDriver;
504 static int testSocket;
506 static void Test_Poll(void);
507 PollProcedure testPollProcedure = {NULL, 0.0, Test_Poll};
509 static void Test_Poll(void)
511 struct qsockaddr clientaddr;
522 net_landriverlevel = testDriver;
526 len = dfunc.Read (testSocket, net_message.data, net_message.maxsize, &clientaddr);
527 if (len < (int)sizeof(int))
530 net_message.cursize = len;
533 control = BigLong(*((int *)net_message.data));
537 if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
539 if ((control & NETFLAG_LENGTH_MASK) != len)
543 if (c != CCREP_PLAYER_INFO)
544 Sys_Error("Unexpected repsonse to Player Info request\n");
546 playerNumber = MSG_ReadByte();
547 strcpy(name, MSG_ReadString());
548 colors = MSG_ReadLong();
549 frags = MSG_ReadLong();
550 connectTime = MSG_ReadLong();
551 strcpy(address, MSG_ReadString());
553 Con_Printf("%s\n frags:%3i colors:%u %u time:%u\n %s\n", name, frags, colors >> 4, colors & 0x0f, connectTime / 60, address);
559 SchedulePollProcedure(&testPollProcedure, 0.1);
563 dfunc.CloseSocket(testSocket);
564 testInProgress = false;
568 static void Test_f (void)
571 int n, max = MAX_SCOREBOARD;
572 struct qsockaddr sendaddr;
579 if (host && hostCacheCount)
581 for (n = 0; n < hostCacheCount; n++)
582 if (strcasecmp (host, hostcache[n].name) == 0)
584 if (hostcache[n].driver != myDriverLevel)
586 net_landriverlevel = hostcache[n].ldriver;
587 max = hostcache[n].maxusers;
588 memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
591 if (n < hostCacheCount)
595 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
597 if (!net_landrivers[net_landriverlevel].initialized)
600 // see if we can resolve the host name
601 if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
604 if (net_landriverlevel == net_numlandrivers)
608 testSocket = dfunc.OpenSocket(0);
609 if (testSocket == -1)
612 testInProgress = true;
614 testDriver = net_landriverlevel;
616 for (n = 0; n < max; n++)
618 SZ_Clear(&net_message);
619 // save space for the header, filled in later
620 MSG_WriteLong(&net_message, 0);
621 MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO);
622 MSG_WriteByte(&net_message, n);
623 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
624 dfunc.Write (testSocket, net_message.data, net_message.cursize, &sendaddr);
626 SZ_Clear(&net_message);
627 SchedulePollProcedure(&testPollProcedure, 0.1);
631 static qboolean test2InProgress = false;
632 static int test2Driver;
633 static int test2Socket;
635 static void Test2_Poll(void);
636 PollProcedure test2PollProcedure = {NULL, 0.0, Test2_Poll};
638 static void Test2_Poll(void)
640 struct qsockaddr clientaddr;
647 net_landriverlevel = test2Driver;
650 len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr);
651 if (len < (int)sizeof(int))
654 net_message.cursize = len;
657 control = BigLong(*((int *)net_message.data));
661 if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
663 if ((control & NETFLAG_LENGTH_MASK) != len)
667 if (c != CCREP_RULE_INFO)
670 strcpy(name, MSG_ReadString());
673 strcpy(value, MSG_ReadString());
675 Con_Printf("%-16.16s %-16.16s\n", name, value);
677 SZ_Clear(&net_message);
678 // save space for the header, filled in later
679 MSG_WriteLong(&net_message, 0);
680 MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
681 MSG_WriteString(&net_message, name);
682 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
683 dfunc.Write (test2Socket, net_message.data, net_message.cursize, &clientaddr);
684 SZ_Clear(&net_message);
687 SchedulePollProcedure(&test2PollProcedure, 0.05);
691 Con_Printf("Unexpected repsonse to Rule Info request\n");
693 dfunc.CloseSocket(test2Socket);
694 test2InProgress = false;
698 static void Test2_f (void)
702 struct qsockaddr sendaddr;
709 if (host && hostCacheCount)
711 for (n = 0; n < hostCacheCount; n++)
712 if (strcasecmp (host, hostcache[n].name) == 0)
714 if (hostcache[n].driver != myDriverLevel)
716 net_landriverlevel = hostcache[n].ldriver;
717 memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
720 if (n < hostCacheCount)
724 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
726 if (!net_landrivers[net_landriverlevel].initialized)
729 // see if we can resolve the host name
730 if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
733 if (net_landriverlevel == net_numlandrivers)
737 test2Socket = dfunc.OpenSocket(0);
738 if (test2Socket == -1)
741 test2InProgress = true;
742 test2Driver = net_landriverlevel;
744 SZ_Clear(&net_message);
745 // save space for the header, filled in later
746 MSG_WriteLong(&net_message, 0);
747 MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
748 MSG_WriteString(&net_message, "");
749 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
750 dfunc.Write (test2Socket, net_message.data, net_message.cursize, &sendaddr);
751 SZ_Clear(&net_message);
752 SchedulePollProcedure(&test2PollProcedure, 0.05);
756 int Datagram_Init (void)
761 myDriverLevel = net_driverlevel;
762 Cmd_AddCommand ("net_stats", NET_Stats_f);
763 Cvar_RegisterVariable (&cl_port);
765 if (COM_CheckParm("-nolan"))
768 for (i = 0; i < net_numlandrivers; i++)
770 csock = net_landrivers[i].Init ();
773 net_landrivers[i].initialized = true;
774 net_landrivers[i].controlSock = csock;
778 Cmd_AddCommand ("ban", NET_Ban_f);
780 //Cmd_AddCommand ("test", Test_f);
781 //Cmd_AddCommand ("test2", Test2_f);
787 void Datagram_Shutdown (void)
792 // shutdown the lan drivers
794 for (i = 0; i < net_numlandrivers; i++)
796 if (net_landrivers[i].initialized)
798 net_landrivers[i].Shutdown ();
799 net_landrivers[i].initialized = false;
805 void Datagram_Close (qsocket_t *sock)
807 sfunc.CloseSocket(sock->socket);
811 void Datagram_Listen (qboolean state)
815 for (i = 0; i < net_numlandrivers; i++)
816 if (net_landrivers[i].initialized)
817 net_landrivers[i].Listen (state);
821 static qsocket_t *_Datagram_CheckNewConnections (void)
823 struct qsockaddr clientaddr;
824 struct qsockaddr newaddr;
835 acceptsock = dfunc.CheckNewConnections();
836 if (acceptsock == -1)
839 SZ_Clear(&net_message);
841 len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr);
842 if (len < (int)sizeof(int))
844 net_message.cursize = len;
847 control = BigLong(*((int *)net_message.data));
850 // Messages starting by 0xFFFFFFFF are master server messages
851 if ((unsigned int)control == 0xFFFFFFFF)
853 int responsesize = Master_HandleMessage();
854 if (responsesize > 0)
856 dfunc.Write(acceptsock, net_message.data, responsesize, &clientaddr);
857 SZ_Clear(&net_message);
861 if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
863 if ((control & NETFLAG_LENGTH_MASK) != len)
866 command = MSG_ReadByte();
867 if (command == CCREQ_SERVER_INFO)
869 if (strcmp(MSG_ReadString(), "QUAKE") != 0)
872 Con_DPrintf("Datagram_CheckNewConnections: received CCREQ_SERVERINFO, replying.\n");
874 SZ_Clear(&net_message);
875 // save space for the header, filled in later
876 MSG_WriteLong(&net_message, 0);
877 MSG_WriteByte(&net_message, CCREP_SERVER_INFO);
878 dfunc.GetSocketAddr(acceptsock, &newaddr);
879 MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
880 MSG_WriteString(&net_message, hostname.string);
881 MSG_WriteString(&net_message, sv.name);
882 MSG_WriteByte(&net_message, net_activeconnections);
883 MSG_WriteByte(&net_message, svs.maxclients);
884 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
885 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
886 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
887 SZ_Clear(&net_message);
891 if (command == CCREQ_PLAYER_INFO)
898 playerNumber = MSG_ReadByte();
900 for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++)
905 if (activeNumber == playerNumber)
909 if (clientNumber == svs.maxclients)
912 SZ_Clear(&net_message);
913 // save space for the header, filled in later
914 MSG_WriteLong(&net_message, 0);
915 MSG_WriteByte(&net_message, CCREP_PLAYER_INFO);
916 MSG_WriteByte(&net_message, playerNumber);
917 MSG_WriteString(&net_message, client->name);
918 MSG_WriteLong(&net_message, client->colors);
919 MSG_WriteLong(&net_message, (int)client->edict->v->frags);
920 MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime));
921 MSG_WriteString(&net_message, client->netconnection->address);
922 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
923 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
924 SZ_Clear(&net_message);
929 if (command == CCREQ_RULE_INFO)
934 // find the search start location
935 prevCvarName = MSG_ReadString();
936 var = Cvar_FindVarAfter(prevCvarName, CVAR_NOTIFY);
940 SZ_Clear(&net_message);
941 // save space for the header, filled in later
942 MSG_WriteLong(&net_message, 0);
943 MSG_WriteByte(&net_message, CCREP_RULE_INFO);
946 MSG_WriteString(&net_message, var->name);
947 MSG_WriteString(&net_message, var->string);
949 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
950 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
951 SZ_Clear(&net_message);
956 if (command != CCREQ_CONNECT)
959 if (strcmp(MSG_ReadString(), "QUAKE") != 0)
963 if (c != NET_PROTOCOL_VERSION)
965 SZ_Clear(&net_message);
966 // save space for the header, filled in later
967 MSG_WriteLong(&net_message, 0);
968 MSG_WriteByte(&net_message, CCREP_REJECT);
969 MSG_WriteString(&net_message, "Incompatible version.\n");
970 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
971 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
972 SZ_Clear(&net_message);
978 if (clientaddr.sa_family == AF_INET)
980 unsigned long testAddr;
981 testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr;
982 if ((testAddr & banMask) == banAddr)
984 SZ_Clear(&net_message);
985 // save space for the header, filled in later
986 MSG_WriteLong(&net_message, 0);
987 MSG_WriteByte(&net_message, CCREP_REJECT);
988 MSG_WriteString(&net_message, "You have been banned.\n");
989 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
990 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
991 SZ_Clear(&net_message);
997 // see if this guy is already connected
998 for (s = net_activeSockets; s; s = s->next)
1000 if (s->driver != net_driverlevel)
1002 ret = dfunc.AddrCompare(&clientaddr, &s->addr);
1005 // is this a duplicate connection request?
1006 if (ret == 0 && net_time - s->connecttime < 2.0)
1008 // yes, so send a duplicate reply
1009 SZ_Clear(&net_message);
1010 // save space for the header, filled in later
1011 MSG_WriteLong(&net_message, 0);
1012 MSG_WriteByte(&net_message, CCREP_ACCEPT);
1013 dfunc.GetSocketAddr(s->socket, &newaddr);
1014 MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
1015 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1016 // LordHavoc: send from s->socket instead of acceptsock, this
1017 // way routers usually identify the connection correctly
1018 // (thanks to faded for provoking me to recite a lengthy
1019 // explanation of NAT nightmares, and realize this easy
1020 // workaround for quake)
1021 dfunc.Write (s->socket, net_message.data, net_message.cursize, &clientaddr);
1022 // LordHavoc: also send from acceptsock, for good measure
1023 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1024 SZ_Clear(&net_message);
1027 // it's somebody coming back in from a crash/disconnect
1028 // so close the old qsocket and let their retry get them back in
1034 // allocate a QSocket
1035 sock = NET_NewQSocket ();
1038 // no room; try to let him know
1039 SZ_Clear(&net_message);
1040 // save space for the header, filled in later
1041 MSG_WriteLong(&net_message, 0);
1042 MSG_WriteByte(&net_message, CCREP_REJECT);
1043 MSG_WriteString(&net_message, "Server is full.\n");
1044 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1045 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1046 SZ_Clear(&net_message);
1050 // allocate a network socket
1051 newsock = dfunc.OpenSocket(0);
1054 NET_FreeQSocket(sock);
1058 // connect to the client
1059 if (dfunc.Connect (newsock, &clientaddr) == -1)
1061 dfunc.CloseSocket(newsock);
1062 NET_FreeQSocket(sock);
1066 // everything is allocated, just fill in the details
1067 sock->socket = newsock;
1068 sock->landriver = net_landriverlevel;
1069 sock->addr = clientaddr;
1070 strcpy(sock->address, dfunc.AddrToString(&clientaddr));
1072 // send him back the info about the server connection he has been allocated
1073 SZ_Clear(&net_message);
1074 // save space for the header, filled in later
1075 MSG_WriteLong(&net_message, 0);
1076 MSG_WriteByte(&net_message, CCREP_ACCEPT);
1077 dfunc.GetSocketAddr(newsock, &newaddr);
1078 MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
1079 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1080 // LordHavoc: send from sock->socket instead of acceptsock, this way routers
1081 // usually identify the connection correctly (thanks to faded for provoking
1082 // me to recite a lengthy explanation of NAT nightmares, and realize this
1083 // easy workaround for quake)
1084 dfunc.Write (sock->socket, net_message.data, net_message.cursize, &clientaddr);
1085 // LordHavoc: also send from acceptsock, for good measure
1086 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1087 SZ_Clear(&net_message);
1092 qsocket_t *Datagram_CheckNewConnections (void)
1094 qsocket_t *ret = NULL;
1096 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1097 if (net_landrivers[net_landriverlevel].initialized)
1098 if ((ret = _Datagram_CheckNewConnections ()) != NULL)
1104 static qboolean Datagram_HandleServerInfo (struct qsockaddr *readaddr)
1106 //struct qsockaddr myaddr;
1111 if (net_message.cursize < (int)sizeof(int))
1114 // don't answer our own query
1115 //dfunc.GetSocketAddr (dfunc.controlSock, &myaddr);
1116 //if (dfunc.AddrCompare(readaddr, &myaddr) >= 0)
1119 // is the cache full?
1120 if (hostCacheCount == HOSTCACHESIZE)
1123 MSG_BeginReading ();
1124 control = BigLong(*((int *)net_message.data));
1128 if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
1130 if ((control & NETFLAG_LENGTH_MASK) != net_message.cursize)
1134 if (c != CCREP_SERVER_INFO)
1137 // LordHavoc: because the UDP driver reports 0.0.0.0:26000 as the address
1138 // string we just ignore it and keep the real address
1140 // hostcache only uses text addresses
1141 strcpy(cname, dfunc.AddrToString(readaddr));
1142 // search the cache for this server
1143 for (n = 0; n < hostCacheCount; n++)
1144 //if (dfunc.AddrCompare(readaddr, &hostcache[n].addr) == 0)
1145 if (!strcmp(cname, hostcache[n].cname))
1150 strcpy(hostcache[n].name, MSG_ReadString());
1151 strcpy(hostcache[n].map, MSG_ReadString());
1152 hostcache[n].users = MSG_ReadByte();
1153 hostcache[n].maxusers = MSG_ReadByte();
1155 if (c != NET_PROTOCOL_VERSION)
1157 strncpy(hostcache[n].cname, hostcache[n].name, sizeof(hostcache[n].cname) - 1);
1158 hostcache[n].cname[sizeof(hostcache[n].cname) - 1] = 0;
1159 strcpy(hostcache[n].name, "*");
1160 strncat(hostcache[n].name, hostcache[n].cname, sizeof(hostcache[n].name) - 1);
1161 hostcache[n].name[sizeof(hostcache[n].name) - 1] = 0;
1163 strcpy(hostcache[n].cname, cname);
1164 //memcpy(&hostcache[n].addr, readaddr, sizeof(struct qsockaddr));
1165 //hostcache[n].driver = net_driverlevel;
1166 //hostcache[n].ldriver = net_landriverlevel;
1169 // check for a name conflict
1170 for (i = 0; i < hostCacheCount; i++)
1174 if (strcasecmp (hostcache[n].name, hostcache[i].name) == 0)
1176 i = strlen(hostcache[n].name);
1177 if (i < 15 && hostcache[n].name[i-1] > '8')
1179 hostcache[n].name[i] = '0';
1180 hostcache[n].name[i+1] = 0;
1183 hostcache[n].name[i-1]++;
1193 static void _Datagram_SearchForHosts (qboolean xmit)
1196 struct qsockaddr readaddr;
1200 SZ_Clear(&net_message);
1201 // save space for the header, filled in later
1202 MSG_WriteLong(&net_message, 0);
1203 MSG_WriteByte(&net_message, CCREQ_SERVER_INFO);
1204 MSG_WriteString(&net_message, "QUAKE");
1205 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
1206 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1207 dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize);
1208 SZ_Clear(&net_message);
1211 while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0)
1213 net_message.cursize = ret;
1214 Datagram_HandleServerInfo (&readaddr);
1218 void Datagram_SearchForHosts (qboolean xmit)
1220 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1222 if (hostCacheCount == HOSTCACHESIZE)
1224 if (net_landrivers[net_landriverlevel].initialized)
1225 _Datagram_SearchForHosts (xmit);
1230 static qboolean _Datagram_SearchForInetHosts (const char *master)
1232 qboolean result = false;
1233 struct qsockaddr masteraddr;
1234 struct qsockaddr readaddr;
1239 if (dfunc.GetAddrFromName(master, &masteraddr) != -1)
1242 const char* port = strrchr (master, ':');
1244 portnum = atoi (port + 1);
1246 portnum = MASTER_PORT;
1247 Con_DPrintf("Datagram_SearchForInetHosts: sending %d byte message to master %s port %i\n", net_message.cursize, master, portnum);
1248 dfunc.SetSocketPort (&masteraddr, portnum);
1249 dfunc.Write (dfunc.controlSock, net_message.data, net_message.cursize, &masteraddr);
1253 while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0)
1255 net_message.cursize = ret;
1256 Con_DPrintf("Datagram_SearchForInetHosts: Read received %d byte message\n", net_message.cursize);
1257 if (Datagram_HandleServerInfo (&readaddr))
1260 Master_ParseServerList (&dfunc);
1267 qboolean Datagram_SearchForInetHosts (const char *master)
1269 qboolean result = false;
1270 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1272 if (hostCacheCount == HOSTCACHESIZE)
1274 if (net_landrivers[net_landriverlevel].initialized)
1275 if (_Datagram_SearchForInetHosts (master))
1283 static qsocket_t *_Datagram_Connect (const char *host)
1285 struct qsockaddr sendaddr;
1286 struct qsockaddr readaddr;
1287 struct qsockaddr testaddr;
1296 // see if we can resolve the host name
1297 if (dfunc.GetAddrFromName(host, &sendaddr) == -1)
1300 newsock = dfunc.OpenSocket (cl_port.integer);
1304 sock = NET_NewQSocket ();
1307 sock->socket = newsock;
1308 sock->landriver = net_landriverlevel;
1310 // connect to the host
1311 if (dfunc.Connect (newsock, &sendaddr) == -1)
1314 // send the connection request
1315 Con_Printf("trying...\n");CL_UpdateScreen();CL_UpdateScreen();
1316 start_time = net_time;
1318 for (reps = 0; reps < 3; reps++)
1320 SZ_Clear(&net_message);
1321 // save space for the header, filled in later
1322 MSG_WriteLong(&net_message, 0);
1323 MSG_WriteByte(&net_message, CCREQ_CONNECT);
1324 MSG_WriteString(&net_message, "QUAKE");
1325 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
1326 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1327 dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr);
1328 SZ_Clear(&net_message);
1331 ret = dfunc.Read (newsock, net_message.data, net_message.maxsize, &readaddr);
1332 // if we got something, validate it
1335 // is it from the right place?
1336 // we don't care if the port matches (this adds support for
1337 // the NAT fix in the server inspired by faded)
1338 memcpy(&testaddr, &sendaddr, sizeof(struct qsockaddr));
1339 dfunc.SetSocketPort (&testaddr, dfunc.GetSocketPort(&readaddr));
1340 if (sfunc.AddrCompare(&readaddr, &testaddr) != 0)
1342 Con_Printf("wrong reply address\n");
1343 Con_Printf("Expected: %s\n", StrAddr (&sendaddr));
1344 Con_Printf("Received: %s\n", StrAddr (&readaddr));
1351 if (ret < (int)sizeof(int))
1357 net_message.cursize = ret;
1358 MSG_BeginReading ();
1360 control = BigLong(*((int *)net_message.data));
1367 if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL)
1372 if ((control & NETFLAG_LENGTH_MASK) != ret)
1379 while (ret == 0 && (SetNetTime() - start_time) < 2.5);
1382 Con_Printf("still trying...\n");CL_UpdateScreen();CL_UpdateScreen();
1383 start_time = SetNetTime();
1388 reason = "No Response";
1389 Con_Printf("%s\n", reason);
1390 strcpy(m_return_reason, reason);
1396 reason = "Network Error";
1397 Con_Printf("%s\n", reason);
1398 strcpy(m_return_reason, reason);
1402 ret = MSG_ReadByte();
1403 if (ret == CCREP_REJECT)
1405 reason = MSG_ReadString();
1406 Con_Printf("%s", reason);
1407 strncpy(m_return_reason, reason, 31);
1411 if (ret == CCREP_ACCEPT)
1413 memcpy(&sock->addr, &sendaddr, sizeof(struct qsockaddr));
1414 dfunc.SetSocketPort (&sock->addr, MSG_ReadLong());
1418 reason = "Bad Response";
1419 Con_Printf("%s\n", reason);
1420 strcpy(m_return_reason, reason);
1424 dfunc.GetNameFromAddr (&sendaddr, sock->address);
1426 Con_Printf ("Connection accepted to %s\n", sock->address);
1427 sock->lastMessageTime = SetNetTime();
1429 // switch the connection to the specified address
1430 if (dfunc.Connect (newsock, &sock->addr) == -1)
1432 reason = "Connect to Game failed";
1433 Con_Printf("%s\n", reason);
1434 strcpy(m_return_reason, reason);
1438 m_return_onerror = false;
1442 NET_FreeQSocket(sock);
1444 dfunc.CloseSocket(newsock);
1445 if (m_return_onerror)
1447 key_dest = key_menu;
1448 m_state = m_return_state;
1449 m_return_onerror = false;
1454 qsocket_t *Datagram_Connect (const char *host)
1456 qsocket_t *ret = NULL;
1458 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1459 if (net_landrivers[net_landriverlevel].initialized)
1460 if ((ret = _Datagram_Connect (host)) != NULL)
1465 static void _Datagram_Heartbeat (const char *master)
1467 struct qsockaddr masteraddr;
1471 if (dfunc.GetAddrFromName(master, &masteraddr) == -1)
1475 port = strrchr (master, ':');
1477 portnum = atoi (port + 1);
1479 portnum = MASTER_PORT;
1480 dfunc.SetSocketPort (&masteraddr, portnum);
1482 // FIXME: this is the only use of UDP_Send in the entire engine, add a dfunc.acceptSock to get rid of this function!
1483 dfunc.Send (net_message.data, net_message.cursize, &masteraddr);
1486 void Datagram_Heartbeat (const char *master)
1488 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1489 if (net_landrivers[net_landriverlevel].initialized)
1490 _Datagram_Heartbeat (master);