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);
58 // these two macros are to make the code more readable
59 #define sfunc net_landrivers[sock->landriver]
60 #define dfunc net_landrivers[net_landriverlevel]
62 static int net_landriverlevel;
64 /* statistic counters */
66 int packetsReSent = 0;
67 int packetsReceived = 0;
68 int receivedDuplicateCount = 0;
69 int shortPacketCount = 0;
72 static int myDriverLevel;
77 unsigned int sequence;
78 byte data[MAX_DATAGRAM];
83 char *StrAddr (struct qsockaddr *addr)
86 byte *p = (byte *)addr;
89 for (n = 0; n < 16; n++)
90 sprintf (buf + n * 2, "%02x", *p++);
97 unsigned long banAddr = 0x00000000;
98 unsigned long banMask = 0xffffffff;
100 void NET_Ban_f (void)
104 void (*print) (char *fmt, ...);
106 if (cmd_source == src_command)
110 Cmd_ForwardToServer ();
117 if (pr_global_struct->deathmatch)
119 print = SV_ClientPrintf;
125 if (((struct in_addr *)&banAddr)->s_addr)
127 strcpy(addrStr, inet_ntoa(*(struct in_addr *)&banAddr));
128 strcpy(maskStr, inet_ntoa(*(struct in_addr *)&banMask));
129 print("Banning %s [%s]\n", addrStr, maskStr);
132 print("Banning not active\n");
136 if (Q_strcasecmp(Cmd_Argv(1), "off") == 0)
137 banAddr = 0x00000000;
139 banAddr = inet_addr(Cmd_Argv(1));
140 banMask = 0xffffffff;
144 banAddr = inet_addr(Cmd_Argv(1));
145 banMask = inet_addr(Cmd_Argv(2));
149 print("BAN ip_address [mask]\n");
156 int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data)
158 unsigned int packetLen;
159 unsigned int dataLen;
163 if (data->cursize == 0)
164 Sys_Error("Datagram_SendMessage: zero length message\n");
166 if (data->cursize > NET_MAXMESSAGE)
167 Sys_Error("Datagram_SendMessage: message too big %u\n", data->cursize);
169 if (sock->canSend == false)
170 Sys_Error("SendMessage: called with canSend == false\n");
173 memcpy(sock->sendMessage, data->data, data->cursize);
174 sock->sendMessageLength = data->cursize;
176 if (data->cursize <= MAX_DATAGRAM)
178 dataLen = data->cursize;
183 dataLen = MAX_DATAGRAM;
186 packetLen = NET_HEADERSIZE + dataLen;
188 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
189 packetBuffer.sequence = BigLong(sock->sendSequence++);
190 memcpy (packetBuffer.data, sock->sendMessage, dataLen);
192 sock->canSend = false;
194 if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
197 sock->lastSendTime = net_time;
203 int SendMessageNext (qsocket_t *sock)
205 unsigned int packetLen;
206 unsigned int dataLen;
209 if (sock->sendMessageLength <= MAX_DATAGRAM)
211 dataLen = sock->sendMessageLength;
216 dataLen = MAX_DATAGRAM;
219 packetLen = NET_HEADERSIZE + dataLen;
221 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
222 packetBuffer.sequence = BigLong(sock->sendSequence++);
223 memcpy (packetBuffer.data, sock->sendMessage, dataLen);
225 sock->sendNext = false;
227 if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
230 sock->lastSendTime = net_time;
236 int ReSendMessage (qsocket_t *sock)
238 unsigned int packetLen;
239 unsigned int dataLen;
242 if (sock->sendMessageLength <= MAX_DATAGRAM)
244 dataLen = sock->sendMessageLength;
249 dataLen = MAX_DATAGRAM;
252 packetLen = NET_HEADERSIZE + dataLen;
254 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
255 packetBuffer.sequence = BigLong(sock->sendSequence - 1);
256 memcpy (packetBuffer.data, sock->sendMessage, dataLen);
258 sock->sendNext = false;
260 if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
263 sock->lastSendTime = net_time;
269 qboolean Datagram_CanSendMessage (qsocket_t *sock)
272 SendMessageNext (sock);
274 return sock->canSend;
278 qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock)
284 int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
289 if (data->cursize == 0)
290 Sys_Error("Datagram_SendUnreliableMessage: zero length message\n");
292 if (data->cursize > MAX_DATAGRAM)
293 Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize);
296 packetLen = NET_HEADERSIZE + data->cursize;
298 packetBuffer.length = BigLong(packetLen | NETFLAG_UNRELIABLE);
299 packetBuffer.sequence = BigLong(sock->unreliableSendSequence++);
300 memcpy (packetBuffer.data, data->data, data->cursize);
302 if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
310 int Datagram_GetMessage (qsocket_t *sock)
315 struct qsockaddr readaddr;
316 unsigned int sequence;
320 if ((net_time - sock->lastSendTime) > 1.0)
321 ReSendMessage (sock);
325 length = sfunc.Read (sock->socket, (byte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr);
327 // if ((rand() & 255) > 220)
335 Con_Printf("Read error\n");
339 if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0)
342 Con_DPrintf("Forged packet received\n");
343 Con_DPrintf("Expected: %s\n", StrAddr (&sock->addr));
344 Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
349 if (length < NET_HEADERSIZE)
355 length = BigLong(packetBuffer.length);
356 flags = length & (~NETFLAG_LENGTH_MASK);
357 length &= NETFLAG_LENGTH_MASK;
359 if (flags & NETFLAG_CTL)
362 sequence = BigLong(packetBuffer.sequence);
365 if (flags & NETFLAG_UNRELIABLE)
367 if (sequence < sock->unreliableReceiveSequence)
369 Con_DPrintf("Got a stale datagram\n");
373 if (sequence != sock->unreliableReceiveSequence)
375 count = sequence - sock->unreliableReceiveSequence;
376 droppedDatagrams += count;
377 Con_DPrintf("Dropped %u datagram(s)\n", count);
379 sock->unreliableReceiveSequence = sequence + 1;
381 length -= NET_HEADERSIZE;
383 SZ_Clear (&net_message);
384 SZ_Write (&net_message, packetBuffer.data, length);
390 if (flags & NETFLAG_ACK)
392 if (sequence != (sock->sendSequence - 1))
394 Con_DPrintf("Stale ACK received\n");
397 if (sequence == sock->ackSequence)
400 if (sock->ackSequence != sock->sendSequence)
401 Con_DPrintf("ack sequencing error\n");
405 Con_DPrintf("Duplicate ACK received\n");
408 sock->sendMessageLength -= MAX_DATAGRAM;
409 if (sock->sendMessageLength > 0)
411 memcpy(sock->sendMessage, sock->sendMessage+MAX_DATAGRAM, sock->sendMessageLength);
412 sock->sendNext = true;
416 sock->sendMessageLength = 0;
417 sock->canSend = true;
422 if (flags & NETFLAG_DATA)
424 packetBuffer.length = BigLong(NET_HEADERSIZE | NETFLAG_ACK);
425 packetBuffer.sequence = BigLong(sequence);
426 sfunc.Write (sock->socket, (byte *)&packetBuffer, NET_HEADERSIZE, &readaddr);
428 if (sequence != sock->receiveSequence)
430 receivedDuplicateCount++;
433 sock->receiveSequence++;
435 length -= NET_HEADERSIZE;
437 if (flags & NETFLAG_EOM)
439 SZ_Clear(&net_message);
440 SZ_Write(&net_message, sock->receiveMessage, sock->receiveMessageLength);
441 SZ_Write(&net_message, packetBuffer.data, length);
442 sock->receiveMessageLength = 0;
448 memcpy(sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length);
449 sock->receiveMessageLength += length;
455 SendMessageNext (sock);
461 void PrintStats(qsocket_t *s)
463 Con_Printf("canSend = %4u \n", s->canSend);
464 Con_Printf("sendSeq = %4u ", s->sendSequence);
465 Con_Printf("recvSeq = %4u \n", s->receiveSequence);
469 void NET_Stats_f (void)
473 if (Cmd_Argc () == 1)
475 Con_Printf("unreliable messages sent = %i\n", unreliableMessagesSent);
476 Con_Printf("unreliable messages recv = %i\n", unreliableMessagesReceived);
477 Con_Printf("reliable messages sent = %i\n", messagesSent);
478 Con_Printf("reliable messages received = %i\n", messagesReceived);
479 Con_Printf("packetsSent = %i\n", packetsSent);
480 Con_Printf("packetsReSent = %i\n", packetsReSent);
481 Con_Printf("packetsReceived = %i\n", packetsReceived);
482 Con_Printf("receivedDuplicateCount = %i\n", receivedDuplicateCount);
483 Con_Printf("shortPacketCount = %i\n", shortPacketCount);
484 Con_Printf("droppedDatagrams = %i\n", droppedDatagrams);
486 else if (strcmp(Cmd_Argv(1), "*") == 0)
488 for (s = net_activeSockets; s; s = s->next)
490 // LordHavoc: sockets are dynamically allocated now
491 //for (s = net_freeSockets; s; s = s->next)
496 for (s = net_activeSockets; s; s = s->next)
497 if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0)
499 // LordHavoc: sockets are dynamically allocated now
501 // for (s = net_freeSockets; s; s = s->next)
502 // if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0)
511 static qboolean testInProgress = false;
512 static int testPollCount;
513 static int testDriver;
514 static int testSocket;
516 static void Test_Poll(void);
517 PollProcedure testPollProcedure = {NULL, 0.0, Test_Poll};
519 static void Test_Poll(void)
521 struct qsockaddr clientaddr;
531 net_landriverlevel = testDriver;
535 len = dfunc.Read (testSocket, net_message.data, net_message.maxsize, &clientaddr);
536 if (len < sizeof(int))
539 net_message.cursize = len;
542 control = BigLong(*((int *)net_message.data));
546 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
548 if ((control & NETFLAG_LENGTH_MASK) != len)
551 if (MSG_ReadByte() != CCREP_PLAYER_INFO)
552 Sys_Error("Unexpected repsonse to Player Info request\n");
554 playerNumber = MSG_ReadByte();
555 strcpy(name, MSG_ReadString());
556 colors = MSG_ReadLong();
557 frags = MSG_ReadLong();
558 connectTime = MSG_ReadLong();
559 strcpy(address, MSG_ReadString());
561 Con_Printf("%s\n frags:%3i colors:%u %u time:%u\n %s\n", name, frags, colors >> 4, colors & 0x0f, connectTime / 60, address);
567 SchedulePollProcedure(&testPollProcedure, 0.1);
571 dfunc.CloseSocket(testSocket);
572 testInProgress = false;
576 static void Test_f (void)
580 int max = MAX_SCOREBOARD;
581 struct qsockaddr sendaddr;
588 if (host && hostCacheCount)
590 for (n = 0; n < hostCacheCount; n++)
591 if (Q_strcasecmp (host, hostcache[n].name) == 0)
593 if (hostcache[n].driver != myDriverLevel)
595 net_landriverlevel = hostcache[n].ldriver;
596 max = hostcache[n].maxusers;
597 memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
600 if (n < hostCacheCount)
604 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
606 if (!net_landrivers[net_landriverlevel].initialized)
609 // see if we can resolve the host name
610 if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
613 if (net_landriverlevel == net_numlandrivers)
617 testSocket = dfunc.OpenSocket(0);
618 if (testSocket == -1)
621 testInProgress = true;
623 testDriver = net_landriverlevel;
625 for (n = 0; n < max; n++)
627 SZ_Clear(&net_message);
628 // save space for the header, filled in later
629 MSG_WriteLong(&net_message, 0);
630 MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO);
631 MSG_WriteByte(&net_message, n);
632 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
633 dfunc.Write (testSocket, net_message.data, net_message.cursize, &sendaddr);
635 SZ_Clear(&net_message);
636 SchedulePollProcedure(&testPollProcedure, 0.1);
640 static qboolean test2InProgress = false;
641 static int test2Driver;
642 static int test2Socket;
644 static void Test2_Poll(void);
645 PollProcedure test2PollProcedure = {NULL, 0.0, Test2_Poll};
647 static void Test2_Poll(void)
649 struct qsockaddr clientaddr;
655 net_landriverlevel = test2Driver;
658 len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr);
659 if (len < sizeof(int))
662 net_message.cursize = len;
665 control = BigLong(*((int *)net_message.data));
669 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
671 if ((control & NETFLAG_LENGTH_MASK) != len)
674 if (MSG_ReadByte() != CCREP_RULE_INFO)
677 strcpy(name, MSG_ReadString());
680 strcpy(value, MSG_ReadString());
682 Con_Printf("%-16.16s %-16.16s\n", name, value);
684 SZ_Clear(&net_message);
685 // save space for the header, filled in later
686 MSG_WriteLong(&net_message, 0);
687 MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
688 MSG_WriteString(&net_message, name);
689 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
690 dfunc.Write (test2Socket, net_message.data, net_message.cursize, &clientaddr);
691 SZ_Clear(&net_message);
694 SchedulePollProcedure(&test2PollProcedure, 0.05);
698 Con_Printf("Unexpected repsonse to Rule Info request\n");
700 dfunc.CloseSocket(test2Socket);
701 test2InProgress = false;
705 static void Test2_f (void)
709 struct qsockaddr sendaddr;
716 if (host && hostCacheCount)
718 for (n = 0; n < hostCacheCount; n++)
719 if (Q_strcasecmp (host, hostcache[n].name) == 0)
721 if (hostcache[n].driver != myDriverLevel)
723 net_landriverlevel = hostcache[n].ldriver;
724 memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
727 if (n < hostCacheCount)
731 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
733 if (!net_landrivers[net_landriverlevel].initialized)
736 // see if we can resolve the host name
737 if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
740 if (net_landriverlevel == net_numlandrivers)
744 test2Socket = dfunc.OpenSocket(0);
745 if (test2Socket == -1)
748 test2InProgress = true;
749 test2Driver = net_landriverlevel;
751 SZ_Clear(&net_message);
752 // save space for the header, filled in later
753 MSG_WriteLong(&net_message, 0);
754 MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
755 MSG_WriteString(&net_message, "");
756 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
757 dfunc.Write (test2Socket, net_message.data, net_message.cursize, &sendaddr);
758 SZ_Clear(&net_message);
759 SchedulePollProcedure(&test2PollProcedure, 0.05);
763 int Datagram_Init (void)
768 myDriverLevel = net_driverlevel;
769 Cmd_AddCommand ("net_stats", NET_Stats_f);
771 if (COM_CheckParm("-nolan"))
774 for (i = 0; i < net_numlandrivers; i++)
776 csock = net_landrivers[i].Init ();
779 net_landrivers[i].initialized = true;
780 net_landrivers[i].controlSock = csock;
784 Cmd_AddCommand ("ban", NET_Ban_f);
786 Cmd_AddCommand ("test", Test_f);
787 Cmd_AddCommand ("test2", Test2_f);
793 void Datagram_Shutdown (void)
798 // shutdown the lan drivers
800 for (i = 0; i < net_numlandrivers; i++)
802 if (net_landrivers[i].initialized)
804 net_landrivers[i].Shutdown ();
805 net_landrivers[i].initialized = false;
811 void Datagram_Close (qsocket_t *sock)
813 sfunc.CloseSocket(sock->socket);
817 void Datagram_Listen (qboolean state)
821 for (i = 0; i < net_numlandrivers; i++)
822 if (net_landrivers[i].initialized)
823 net_landrivers[i].Listen (state);
827 static qsocket_t *_Datagram_CheckNewConnections (void)
829 struct qsockaddr clientaddr;
830 struct qsockaddr newaddr;
840 acceptsock = dfunc.CheckNewConnections();
841 if (acceptsock == -1)
844 SZ_Clear(&net_message);
846 len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr);
847 if (len < sizeof(int))
849 net_message.cursize = len;
852 control = BigLong(*((int *)net_message.data));
856 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
858 if ((control & NETFLAG_LENGTH_MASK) != len)
861 command = MSG_ReadByte();
862 if (command == CCREQ_SERVER_INFO)
864 if (strcmp(MSG_ReadString(), "QUAKE") != 0)
867 SZ_Clear(&net_message);
868 // save space for the header, filled in later
869 MSG_WriteLong(&net_message, 0);
870 MSG_WriteByte(&net_message, CCREP_SERVER_INFO);
871 dfunc.GetSocketAddr(acceptsock, &newaddr);
872 MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
873 MSG_WriteString(&net_message, hostname.string);
874 MSG_WriteString(&net_message, sv.name);
875 MSG_WriteByte(&net_message, net_activeconnections);
876 MSG_WriteByte(&net_message, svs.maxclients);
877 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
878 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
879 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
880 SZ_Clear(&net_message);
884 if (command == CCREQ_PLAYER_INFO)
891 playerNumber = MSG_ReadByte();
893 for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++)
898 if (activeNumber == playerNumber)
902 if (clientNumber == svs.maxclients)
905 SZ_Clear(&net_message);
906 // save space for the header, filled in later
907 MSG_WriteLong(&net_message, 0);
908 MSG_WriteByte(&net_message, CCREP_PLAYER_INFO);
909 MSG_WriteByte(&net_message, playerNumber);
910 MSG_WriteString(&net_message, client->name);
911 MSG_WriteLong(&net_message, client->colors);
912 MSG_WriteLong(&net_message, (int)client->edict->v.frags);
913 MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime));
914 MSG_WriteString(&net_message, client->netconnection->address);
915 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
916 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
917 SZ_Clear(&net_message);
922 if (command == CCREQ_RULE_INFO)
927 // find the search start location
928 prevCvarName = MSG_ReadString();
931 var = Cvar_FindVar (prevCvarName);
939 // search for the next server cvar
942 if (var->flags & CVAR_NOTIFY)
949 SZ_Clear(&net_message);
950 // save space for the header, filled in later
951 MSG_WriteLong(&net_message, 0);
952 MSG_WriteByte(&net_message, CCREP_RULE_INFO);
955 MSG_WriteString(&net_message, var->name);
956 MSG_WriteString(&net_message, var->string);
958 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
959 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
960 SZ_Clear(&net_message);
965 if (command != CCREQ_CONNECT)
968 if (strcmp(MSG_ReadString(), "QUAKE") != 0)
971 if (MSG_ReadByte() != NET_PROTOCOL_VERSION)
973 SZ_Clear(&net_message);
974 // save space for the header, filled in later
975 MSG_WriteLong(&net_message, 0);
976 MSG_WriteByte(&net_message, CCREP_REJECT);
977 MSG_WriteString(&net_message, "Incompatible version.\n");
978 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
979 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
980 SZ_Clear(&net_message);
986 if (clientaddr.sa_family == AF_INET)
988 unsigned long testAddr;
989 testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr;
990 if ((testAddr & banMask) == banAddr)
992 SZ_Clear(&net_message);
993 // save space for the header, filled in later
994 MSG_WriteLong(&net_message, 0);
995 MSG_WriteByte(&net_message, CCREP_REJECT);
996 MSG_WriteString(&net_message, "You have been banned.\n");
997 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
998 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
999 SZ_Clear(&net_message);
1005 // see if this guy is already connected
1006 for (s = net_activeSockets; s; s = s->next)
1008 if (s->driver != net_driverlevel)
1010 ret = dfunc.AddrCompare(&clientaddr, &s->addr);
1013 // is this a duplicate connection reqeust?
1014 if (ret == 0 && net_time - s->connecttime < 2.0)
1016 // yes, so send a duplicate reply
1017 SZ_Clear(&net_message);
1018 // save space for the header, filled in later
1019 MSG_WriteLong(&net_message, 0);
1020 MSG_WriteByte(&net_message, CCREP_ACCEPT);
1021 dfunc.GetSocketAddr(s->socket, &newaddr);
1022 MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
1023 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1024 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1025 SZ_Clear(&net_message);
1028 // it's somebody coming back in from a crash/disconnect
1029 // so close the old qsocket and let their retry get them back in
1035 // allocate a QSocket
1036 sock = NET_NewQSocket ();
1039 // no room; try to let him know
1040 SZ_Clear(&net_message);
1041 // save space for the header, filled in later
1042 MSG_WriteLong(&net_message, 0);
1043 MSG_WriteByte(&net_message, CCREP_REJECT);
1044 MSG_WriteString(&net_message, "Server is full.\n");
1045 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1046 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1047 SZ_Clear(&net_message);
1051 // allocate a network socket
1052 newsock = dfunc.OpenSocket(0);
1055 NET_FreeQSocket(sock);
1059 // connect to the client
1060 if (dfunc.Connect (newsock, &clientaddr) == -1)
1062 dfunc.CloseSocket(newsock);
1063 NET_FreeQSocket(sock);
1067 // everything is allocated, just fill in the details
1068 sock->socket = newsock;
1069 sock->landriver = net_landriverlevel;
1070 sock->addr = clientaddr;
1071 strcpy(sock->address, dfunc.AddrToString(&clientaddr));
1073 // send him back the info about the server connection he has been allocated
1074 SZ_Clear(&net_message);
1075 // save space for the header, filled in later
1076 MSG_WriteLong(&net_message, 0);
1077 MSG_WriteByte(&net_message, CCREP_ACCEPT);
1078 dfunc.GetSocketAddr(newsock, &newaddr);
1079 MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
1080 // MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
1081 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1082 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1083 SZ_Clear(&net_message);
1088 qsocket_t *Datagram_CheckNewConnections (void)
1090 qsocket_t *ret = NULL;
1092 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1093 if (net_landrivers[net_landriverlevel].initialized)
1094 if ((ret = _Datagram_CheckNewConnections ()) != NULL)
1100 static void _Datagram_SearchForHosts (qboolean xmit)
1105 struct qsockaddr readaddr;
1106 struct qsockaddr myaddr;
1109 dfunc.GetSocketAddr (dfunc.controlSock, &myaddr);
1112 SZ_Clear(&net_message);
1113 // save space for the header, filled in later
1114 MSG_WriteLong(&net_message, 0);
1115 MSG_WriteByte(&net_message, CCREQ_SERVER_INFO);
1116 MSG_WriteString(&net_message, "QUAKE");
1117 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
1118 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1119 dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize);
1120 SZ_Clear(&net_message);
1123 while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0)
1125 if (ret < sizeof(int))
1127 net_message.cursize = ret;
1129 // don't answer our own query
1130 if (dfunc.AddrCompare(&readaddr, &myaddr) >= 0)
1133 // is the cache full?
1134 if (hostCacheCount == HOSTCACHESIZE)
1137 MSG_BeginReading ();
1138 control = BigLong(*((int *)net_message.data));
1142 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
1144 if ((control & NETFLAG_LENGTH_MASK) != ret)
1147 if (MSG_ReadByte() != CCREP_SERVER_INFO)
1150 dfunc.GetAddrFromName(MSG_ReadString(), &readaddr);
1151 // search the cache for this server
1152 for (n = 0; n < hostCacheCount; n++)
1153 if (dfunc.AddrCompare(&readaddr, &hostcache[n].addr) == 0)
1156 // is it already there?
1157 if (n < hostCacheCount)
1162 strcpy(hostcache[n].name, MSG_ReadString());
1163 strcpy(hostcache[n].map, MSG_ReadString());
1164 hostcache[n].users = MSG_ReadByte();
1165 hostcache[n].maxusers = MSG_ReadByte();
1166 if (MSG_ReadByte() != NET_PROTOCOL_VERSION)
1168 strcpy(hostcache[n].cname, hostcache[n].name);
1169 hostcache[n].cname[14] = 0;
1170 strcpy(hostcache[n].name, "*");
1171 strcat(hostcache[n].name, hostcache[n].cname);
1173 memcpy(&hostcache[n].addr, &readaddr, sizeof(struct qsockaddr));
1174 hostcache[n].driver = net_driverlevel;
1175 hostcache[n].ldriver = net_landriverlevel;
1176 strcpy(hostcache[n].cname, dfunc.AddrToString(&readaddr));
1178 // check for a name conflict
1179 for (i = 0; i < hostCacheCount; i++)
1183 if (Q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0)
1185 i = strlen(hostcache[n].name);
1186 if (i < 15 && hostcache[n].name[i-1] > '8')
1188 hostcache[n].name[i] = '0';
1189 hostcache[n].name[i+1] = 0;
1192 hostcache[n].name[i-1]++;
1199 void Datagram_SearchForHosts (qboolean xmit)
1201 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1203 if (hostCacheCount == HOSTCACHESIZE)
1205 if (net_landrivers[net_landriverlevel].initialized)
1206 _Datagram_SearchForHosts (xmit);
1211 static qsocket_t *_Datagram_Connect (char *host)
1213 struct qsockaddr sendaddr;
1214 struct qsockaddr readaddr;
1223 // see if we can resolve the host name
1224 if (dfunc.GetAddrFromName(host, &sendaddr) == -1)
1227 newsock = dfunc.OpenSocket (0);
1231 sock = NET_NewQSocket ();
1234 sock->socket = newsock;
1235 sock->landriver = net_landriverlevel;
1237 // connect to the host
1238 if (dfunc.Connect (newsock, &sendaddr) == -1)
1241 // send the connection request
1242 Con_Printf("trying...\n"); CL_UpdateScreen ();
1243 start_time = net_time;
1245 for (reps = 0; reps < 3; reps++)
1247 SZ_Clear(&net_message);
1248 // save space for the header, filled in later
1249 MSG_WriteLong(&net_message, 0);
1250 MSG_WriteByte(&net_message, CCREQ_CONNECT);
1251 MSG_WriteString(&net_message, "QUAKE");
1252 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
1253 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1254 dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr);
1255 SZ_Clear(&net_message);
1258 ret = dfunc.Read (newsock, net_message.data, net_message.maxsize, &readaddr);
1259 // if we got something, validate it
1262 // is it from the right place?
1263 if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0)
1266 Con_DPrintf("wrong reply address\n");
1267 Con_DPrintf("Expected: %s\n", StrAddr (&sendaddr));
1268 Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
1275 if (ret < sizeof(int))
1281 net_message.cursize = ret;
1282 MSG_BeginReading ();
1284 control = BigLong(*((int *)net_message.data));
1291 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
1296 if ((control & NETFLAG_LENGTH_MASK) != ret)
1303 while (ret == 0 && (SetNetTime() - start_time) < 2.5);
1306 Con_Printf("still trying...\n"); CL_UpdateScreen ();
1307 start_time = SetNetTime();
1312 reason = "No Response";
1313 Con_Printf("%s\n", reason);
1314 strcpy(m_return_reason, reason);
1320 reason = "Network Error";
1321 Con_Printf("%s\n", reason);
1322 strcpy(m_return_reason, reason);
1326 ret = MSG_ReadByte();
1327 if (ret == CCREP_REJECT)
1329 reason = MSG_ReadString();
1330 Con_Printf("%s", reason);
1331 strncpy(m_return_reason, reason, 31);
1335 if (ret == CCREP_ACCEPT)
1337 memcpy(&sock->addr, &sendaddr, sizeof(struct qsockaddr));
1338 dfunc.SetSocketPort (&sock->addr, MSG_ReadLong());
1342 reason = "Bad Response";
1343 Con_Printf("%s\n", reason);
1344 strcpy(m_return_reason, reason);
1348 dfunc.GetNameFromAddr (&sendaddr, sock->address);
1350 Con_Printf ("Connection accepted\n");
1351 sock->lastMessageTime = SetNetTime();
1353 // switch the connection to the specified address
1354 if (dfunc.Connect (newsock, &sock->addr) == -1)
1356 reason = "Connect to Game failed";
1357 Con_Printf("%s\n", reason);
1358 strcpy(m_return_reason, reason);
1362 m_return_onerror = false;
1366 NET_FreeQSocket(sock);
1368 dfunc.CloseSocket(newsock);
1369 if (m_return_onerror)
1371 key_dest = key_menu;
1372 m_state = m_return_state;
1373 m_return_onerror = false;
1378 qsocket_t *Datagram_Connect (char *host)
1380 qsocket_t *ret = NULL;
1382 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1383 if (net_landrivers[net_landriverlevel].initialized)
1384 if ((ret = _Datagram_Connect (host)) != NULL)