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 cvar_t cl_port = {CVAR_SAVE, "cl_port", "0"};
60 // these two macros are to make the code more readable
61 #define sfunc net_landrivers[sock->landriver]
62 #define dfunc net_landrivers[net_landriverlevel]
64 static int net_landriverlevel;
66 /* statistic counters */
68 int packetsReSent = 0;
69 int packetsReceived = 0;
70 int receivedDuplicateCount = 0;
71 int shortPacketCount = 0;
74 static int myDriverLevel;
79 unsigned int sequence;
80 qbyte data[MAX_DATAGRAM];
85 char *StrAddr (struct qsockaddr *addr)
88 qbyte *p = (qbyte *)addr;
91 for (n = 0; n < 16; n++)
92 sprintf (buf + n * 2, "%02x", *p++);
99 unsigned long banAddr = 0x00000000;
100 unsigned long banMask = 0xffffffff;
102 void NET_Ban_f (void)
106 void (*print) (char *fmt, ...);
108 if (cmd_source == src_command)
112 Cmd_ForwardToServer ();
119 if (pr_global_struct->deathmatch)
121 print = SV_ClientPrintf;
127 if (((struct in_addr *)&banAddr)->s_addr)
129 strcpy(addrStr, inet_ntoa(*(struct in_addr *)&banAddr));
130 strcpy(maskStr, inet_ntoa(*(struct in_addr *)&banMask));
131 print("Banning %s [%s]\n", addrStr, maskStr);
134 print("Banning not active\n");
138 if (Q_strcasecmp(Cmd_Argv(1), "off") == 0)
139 banAddr = 0x00000000;
141 banAddr = inet_addr(Cmd_Argv(1));
142 banMask = 0xffffffff;
146 banAddr = inet_addr(Cmd_Argv(1));
147 banMask = inet_addr(Cmd_Argv(2));
151 print("BAN ip_address [mask]\n");
158 int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data)
160 unsigned int packetLen;
161 unsigned int dataLen;
165 if (data->cursize == 0)
166 Sys_Error("Datagram_SendMessage: zero length message\n");
168 if (data->cursize > NET_MAXMESSAGE)
169 Sys_Error("Datagram_SendMessage: message too big %u\n", data->cursize);
171 if (sock->canSend == false)
172 Sys_Error("SendMessage: called with canSend == false\n");
175 memcpy(sock->sendMessage, data->data, data->cursize);
176 sock->sendMessageLength = data->cursize;
178 if (data->cursize <= MAX_DATAGRAM)
180 dataLen = data->cursize;
185 dataLen = MAX_DATAGRAM;
188 packetLen = NET_HEADERSIZE + dataLen;
190 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
191 packetBuffer.sequence = BigLong(sock->sendSequence++);
192 memcpy (packetBuffer.data, sock->sendMessage, dataLen);
194 sock->canSend = false;
196 if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1)
199 sock->lastSendTime = net_time;
205 int SendMessageNext (qsocket_t *sock)
207 unsigned int packetLen;
208 unsigned int dataLen;
211 if (sock->sendMessageLength <= MAX_DATAGRAM)
213 dataLen = sock->sendMessageLength;
218 dataLen = MAX_DATAGRAM;
221 packetLen = NET_HEADERSIZE + dataLen;
223 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
224 packetBuffer.sequence = BigLong(sock->sendSequence++);
225 memcpy (packetBuffer.data, sock->sendMessage, dataLen);
227 sock->sendNext = false;
229 if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1)
232 sock->lastSendTime = net_time;
238 int ReSendMessage (qsocket_t *sock)
240 unsigned int packetLen;
241 unsigned int dataLen;
244 if (sock->sendMessageLength <= MAX_DATAGRAM)
246 dataLen = sock->sendMessageLength;
251 dataLen = MAX_DATAGRAM;
254 packetLen = NET_HEADERSIZE + dataLen;
256 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
257 packetBuffer.sequence = BigLong(sock->sendSequence - 1);
258 memcpy (packetBuffer.data, sock->sendMessage, dataLen);
260 sock->sendNext = false;
262 if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1)
265 sock->lastSendTime = net_time;
271 qboolean Datagram_CanSendMessage (qsocket_t *sock)
274 SendMessageNext (sock);
276 return sock->canSend;
280 qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock)
286 int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
291 if (data->cursize == 0)
292 Sys_Error("Datagram_SendUnreliableMessage: zero length message\n");
294 if (data->cursize > MAX_DATAGRAM)
295 Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize);
298 packetLen = NET_HEADERSIZE + data->cursize;
300 packetBuffer.length = BigLong(packetLen | NETFLAG_UNRELIABLE);
301 packetBuffer.sequence = BigLong(sock->unreliableSendSequence++);
302 memcpy (packetBuffer.data, data->data, data->cursize);
304 if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1)
312 int Datagram_GetMessage (qsocket_t *sock)
317 struct qsockaddr readaddr;
318 unsigned int sequence;
322 if ((net_time - sock->lastSendTime) > 1.0)
323 ReSendMessage (sock);
327 length = sfunc.Read (sock->socket, (qbyte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr);
329 // if ((rand() & 255) > 220)
337 Con_Printf("Read error\n");
341 if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0)
344 Con_DPrintf("Forged packet received\n");
345 Con_DPrintf("Expected: %s\n", StrAddr (&sock->addr));
346 Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
351 if (length < NET_HEADERSIZE)
357 length = BigLong(packetBuffer.length);
358 flags = length & (~NETFLAG_LENGTH_MASK);
359 length &= NETFLAG_LENGTH_MASK;
361 if (flags & NETFLAG_CTL)
364 sequence = BigLong(packetBuffer.sequence);
367 if (flags & NETFLAG_UNRELIABLE)
369 if (sequence < sock->unreliableReceiveSequence)
371 Con_DPrintf("Got a stale datagram\n");
375 if (sequence != sock->unreliableReceiveSequence)
377 count = sequence - sock->unreliableReceiveSequence;
378 droppedDatagrams += count;
379 Con_DPrintf("Dropped %u datagram(s)\n", count);
381 sock->unreliableReceiveSequence = sequence + 1;
383 length -= NET_HEADERSIZE;
385 SZ_Clear (&net_message);
386 SZ_Write (&net_message, packetBuffer.data, length);
392 if (flags & NETFLAG_ACK)
394 if (sequence != (sock->sendSequence - 1))
396 Con_DPrintf("Stale ACK received\n");
399 if (sequence == sock->ackSequence)
402 if (sock->ackSequence != sock->sendSequence)
403 Con_DPrintf("ack sequencing error\n");
407 Con_DPrintf("Duplicate ACK received\n");
410 sock->sendMessageLength -= MAX_DATAGRAM;
411 if (sock->sendMessageLength > 0)
413 memcpy(sock->sendMessage, sock->sendMessage+MAX_DATAGRAM, sock->sendMessageLength);
414 sock->sendNext = true;
418 sock->sendMessageLength = 0;
419 sock->canSend = true;
424 if (flags & NETFLAG_DATA)
426 packetBuffer.length = BigLong(NET_HEADERSIZE | NETFLAG_ACK);
427 packetBuffer.sequence = BigLong(sequence);
428 sfunc.Write (sock->socket, (qbyte *)&packetBuffer, NET_HEADERSIZE, &readaddr);
430 if (sequence != sock->receiveSequence)
432 receivedDuplicateCount++;
435 sock->receiveSequence++;
437 length -= NET_HEADERSIZE;
439 if (flags & NETFLAG_EOM)
441 SZ_Clear(&net_message);
442 SZ_Write(&net_message, sock->receiveMessage, sock->receiveMessageLength);
443 SZ_Write(&net_message, packetBuffer.data, length);
444 sock->receiveMessageLength = 0;
450 memcpy(sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length);
451 sock->receiveMessageLength += length;
457 SendMessageNext (sock);
463 void PrintStats(qsocket_t *s)
465 Con_Printf("canSend = %4u \n", s->canSend);
466 Con_Printf("sendSeq = %4u ", s->sendSequence);
467 Con_Printf("recvSeq = %4u \n", s->receiveSequence);
471 void NET_Stats_f (void)
475 if (Cmd_Argc () == 1)
477 Con_Printf("unreliable messages sent = %i\n", unreliableMessagesSent);
478 Con_Printf("unreliable messages recv = %i\n", unreliableMessagesReceived);
479 Con_Printf("reliable messages sent = %i\n", messagesSent);
480 Con_Printf("reliable messages received = %i\n", messagesReceived);
481 Con_Printf("packetsSent = %i\n", packetsSent);
482 Con_Printf("packetsReSent = %i\n", packetsReSent);
483 Con_Printf("packetsReceived = %i\n", packetsReceived);
484 Con_Printf("receivedDuplicateCount = %i\n", receivedDuplicateCount);
485 Con_Printf("shortPacketCount = %i\n", shortPacketCount);
486 Con_Printf("droppedDatagrams = %i\n", droppedDatagrams);
488 else if (strcmp(Cmd_Argv(1), "*") == 0)
490 for (s = net_activeSockets; s; s = s->next)
492 // LordHavoc: sockets are dynamically allocated now
493 //for (s = net_freeSockets; s; s = s->next)
498 for (s = net_activeSockets; s; s = s->next)
499 if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0)
501 // LordHavoc: sockets are dynamically allocated now
503 // for (s = net_freeSockets; s; s = s->next)
504 // if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0)
513 static qboolean testInProgress = false;
514 static int testPollCount;
515 static int testDriver;
516 static int testSocket;
518 static void Test_Poll(void);
519 PollProcedure testPollProcedure = {NULL, 0.0, Test_Poll};
521 static void Test_Poll(void)
523 struct qsockaddr clientaddr;
534 net_landriverlevel = testDriver;
538 len = dfunc.Read (testSocket, net_message.data, net_message.maxsize, &clientaddr);
539 if (len < sizeof(int))
542 net_message.cursize = len;
545 control = BigLong(*((int *)net_message.data));
549 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
551 if ((control & NETFLAG_LENGTH_MASK) != len)
555 if (c != CCREP_PLAYER_INFO)
556 Sys_Error("Unexpected repsonse to Player Info request\n");
558 playerNumber = MSG_ReadByte();
559 strcpy(name, MSG_ReadString());
560 colors = MSG_ReadLong();
561 frags = MSG_ReadLong();
562 connectTime = MSG_ReadLong();
563 strcpy(address, MSG_ReadString());
565 Con_Printf("%s\n frags:%3i colors:%u %u time:%u\n %s\n", name, frags, colors >> 4, colors & 0x0f, connectTime / 60, address);
571 SchedulePollProcedure(&testPollProcedure, 0.1);
575 dfunc.CloseSocket(testSocket);
576 testInProgress = false;
580 static void Test_f (void)
584 int max = MAX_SCOREBOARD;
585 struct qsockaddr sendaddr;
592 if (host && hostCacheCount)
594 for (n = 0; n < hostCacheCount; n++)
595 if (Q_strcasecmp (host, hostcache[n].name) == 0)
597 if (hostcache[n].driver != myDriverLevel)
599 net_landriverlevel = hostcache[n].ldriver;
600 max = hostcache[n].maxusers;
601 memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
604 if (n < hostCacheCount)
608 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
610 if (!net_landrivers[net_landriverlevel].initialized)
613 // see if we can resolve the host name
614 if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
617 if (net_landriverlevel == net_numlandrivers)
621 testSocket = dfunc.OpenSocket(0);
622 if (testSocket == -1)
625 testInProgress = true;
627 testDriver = net_landriverlevel;
629 for (n = 0; n < max; n++)
631 SZ_Clear(&net_message);
632 // save space for the header, filled in later
633 MSG_WriteLong(&net_message, 0);
634 MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO);
635 MSG_WriteByte(&net_message, n);
636 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
637 dfunc.Write (testSocket, net_message.data, net_message.cursize, &sendaddr);
639 SZ_Clear(&net_message);
640 SchedulePollProcedure(&testPollProcedure, 0.1);
644 static qboolean test2InProgress = false;
645 static int test2Driver;
646 static int test2Socket;
648 static void Test2_Poll(void);
649 PollProcedure test2PollProcedure = {NULL, 0.0, Test2_Poll};
651 static void Test2_Poll(void)
653 struct qsockaddr clientaddr;
660 net_landriverlevel = test2Driver;
663 len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr);
664 if (len < sizeof(int))
667 net_message.cursize = len;
670 control = BigLong(*((int *)net_message.data));
674 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
676 if ((control & NETFLAG_LENGTH_MASK) != len)
680 if (c != CCREP_RULE_INFO)
683 strcpy(name, MSG_ReadString());
686 strcpy(value, MSG_ReadString());
688 Con_Printf("%-16.16s %-16.16s\n", name, value);
690 SZ_Clear(&net_message);
691 // save space for the header, filled in later
692 MSG_WriteLong(&net_message, 0);
693 MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
694 MSG_WriteString(&net_message, name);
695 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
696 dfunc.Write (test2Socket, net_message.data, net_message.cursize, &clientaddr);
697 SZ_Clear(&net_message);
700 SchedulePollProcedure(&test2PollProcedure, 0.05);
704 Con_Printf("Unexpected repsonse to Rule Info request\n");
706 dfunc.CloseSocket(test2Socket);
707 test2InProgress = false;
711 static void Test2_f (void)
715 struct qsockaddr sendaddr;
722 if (host && hostCacheCount)
724 for (n = 0; n < hostCacheCount; n++)
725 if (Q_strcasecmp (host, hostcache[n].name) == 0)
727 if (hostcache[n].driver != myDriverLevel)
729 net_landriverlevel = hostcache[n].ldriver;
730 memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
733 if (n < hostCacheCount)
737 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
739 if (!net_landrivers[net_landriverlevel].initialized)
742 // see if we can resolve the host name
743 if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
746 if (net_landriverlevel == net_numlandrivers)
750 test2Socket = dfunc.OpenSocket(0);
751 if (test2Socket == -1)
754 test2InProgress = true;
755 test2Driver = net_landriverlevel;
757 SZ_Clear(&net_message);
758 // save space for the header, filled in later
759 MSG_WriteLong(&net_message, 0);
760 MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
761 MSG_WriteString(&net_message, "");
762 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
763 dfunc.Write (test2Socket, net_message.data, net_message.cursize, &sendaddr);
764 SZ_Clear(&net_message);
765 SchedulePollProcedure(&test2PollProcedure, 0.05);
769 int Datagram_Init (void)
774 myDriverLevel = net_driverlevel;
775 Cmd_AddCommand ("net_stats", NET_Stats_f);
776 Cvar_RegisterVariable (&cl_port);
778 if (COM_CheckParm("-nolan"))
781 for (i = 0; i < net_numlandrivers; i++)
783 csock = net_landrivers[i].Init ();
786 net_landrivers[i].initialized = true;
787 net_landrivers[i].controlSock = csock;
791 Cmd_AddCommand ("ban", NET_Ban_f);
793 Cmd_AddCommand ("test", Test_f);
794 Cmd_AddCommand ("test2", Test2_f);
800 void Datagram_Shutdown (void)
805 // shutdown the lan drivers
807 for (i = 0; i < net_numlandrivers; i++)
809 if (net_landrivers[i].initialized)
811 net_landrivers[i].Shutdown ();
812 net_landrivers[i].initialized = false;
818 void Datagram_Close (qsocket_t *sock)
820 sfunc.CloseSocket(sock->socket);
824 void Datagram_Listen (qboolean state)
828 for (i = 0; i < net_numlandrivers; i++)
829 if (net_landrivers[i].initialized)
830 net_landrivers[i].Listen (state);
834 static qsocket_t *_Datagram_CheckNewConnections (void)
836 struct qsockaddr clientaddr;
837 struct qsockaddr newaddr;
848 acceptsock = dfunc.CheckNewConnections();
849 if (acceptsock == -1)
852 SZ_Clear(&net_message);
854 len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr);
855 if (len < sizeof(int))
857 net_message.cursize = len;
860 control = BigLong(*((int *)net_message.data));
864 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
866 if ((control & NETFLAG_LENGTH_MASK) != len)
869 command = MSG_ReadByte();
870 if (command == CCREQ_SERVER_INFO)
872 if (strcmp(MSG_ReadString(), "QUAKE") != 0)
875 SZ_Clear(&net_message);
876 // save space for the header, filled in later
877 MSG_WriteLong(&net_message, 0);
878 MSG_WriteByte(&net_message, CCREP_SERVER_INFO);
879 dfunc.GetSocketAddr(acceptsock, &newaddr);
880 MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
881 MSG_WriteString(&net_message, hostname.string);
882 MSG_WriteString(&net_message, sv.name);
883 MSG_WriteByte(&net_message, net_activeconnections);
884 MSG_WriteByte(&net_message, svs.maxclients);
885 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
886 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
887 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
888 SZ_Clear(&net_message);
892 if (command == CCREQ_PLAYER_INFO)
899 playerNumber = MSG_ReadByte();
901 for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++)
906 if (activeNumber == playerNumber)
910 if (clientNumber == svs.maxclients)
913 SZ_Clear(&net_message);
914 // save space for the header, filled in later
915 MSG_WriteLong(&net_message, 0);
916 MSG_WriteByte(&net_message, CCREP_PLAYER_INFO);
917 MSG_WriteByte(&net_message, playerNumber);
918 MSG_WriteString(&net_message, client->name);
919 MSG_WriteLong(&net_message, client->colors);
920 MSG_WriteLong(&net_message, (int)client->edict->v.frags);
921 MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime));
922 MSG_WriteString(&net_message, client->netconnection->address);
923 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
924 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
925 SZ_Clear(&net_message);
930 if (command == CCREQ_RULE_INFO)
935 // find the search start location
936 prevCvarName = MSG_ReadString();
939 var = Cvar_FindVar (prevCvarName);
947 // search for the next server cvar
950 if (var->flags & CVAR_NOTIFY)
957 SZ_Clear(&net_message);
958 // save space for the header, filled in later
959 MSG_WriteLong(&net_message, 0);
960 MSG_WriteByte(&net_message, CCREP_RULE_INFO);
963 MSG_WriteString(&net_message, var->name);
964 MSG_WriteString(&net_message, var->string);
966 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
967 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
968 SZ_Clear(&net_message);
973 if (command != CCREQ_CONNECT)
976 if (strcmp(MSG_ReadString(), "QUAKE") != 0)
980 if (c != NET_PROTOCOL_VERSION)
982 SZ_Clear(&net_message);
983 // save space for the header, filled in later
984 MSG_WriteLong(&net_message, 0);
985 MSG_WriteByte(&net_message, CCREP_REJECT);
986 MSG_WriteString(&net_message, "Incompatible version.\n");
987 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
988 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
989 SZ_Clear(&net_message);
995 if (clientaddr.sa_family == AF_INET)
997 unsigned long testAddr;
998 testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr;
999 if ((testAddr & banMask) == banAddr)
1001 SZ_Clear(&net_message);
1002 // save space for the header, filled in later
1003 MSG_WriteLong(&net_message, 0);
1004 MSG_WriteByte(&net_message, CCREP_REJECT);
1005 MSG_WriteString(&net_message, "You have been banned.\n");
1006 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1007 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1008 SZ_Clear(&net_message);
1014 // see if this guy is already connected
1015 for (s = net_activeSockets; s; s = s->next)
1017 if (s->driver != net_driverlevel)
1019 ret = dfunc.AddrCompare(&clientaddr, &s->addr);
1022 // is this a duplicate connection reqeust?
1023 if (ret == 0 && net_time - s->connecttime < 2.0)
1025 // yes, so send a duplicate reply
1026 SZ_Clear(&net_message);
1027 // save space for the header, filled in later
1028 MSG_WriteLong(&net_message, 0);
1029 MSG_WriteByte(&net_message, CCREP_ACCEPT);
1030 dfunc.GetSocketAddr(s->socket, &newaddr);
1031 MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
1032 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1033 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1034 SZ_Clear(&net_message);
1037 // it's somebody coming back in from a crash/disconnect
1038 // so close the old qsocket and let their retry get them back in
1044 // allocate a QSocket
1045 sock = NET_NewQSocket ();
1048 // no room; try to let him know
1049 SZ_Clear(&net_message);
1050 // save space for the header, filled in later
1051 MSG_WriteLong(&net_message, 0);
1052 MSG_WriteByte(&net_message, CCREP_REJECT);
1053 MSG_WriteString(&net_message, "Server is full.\n");
1054 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1055 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1056 SZ_Clear(&net_message);
1060 // allocate a network socket
1061 newsock = dfunc.OpenSocket(0);
1064 NET_FreeQSocket(sock);
1068 // connect to the client
1069 if (dfunc.Connect (newsock, &clientaddr) == -1)
1071 dfunc.CloseSocket(newsock);
1072 NET_FreeQSocket(sock);
1076 // everything is allocated, just fill in the details
1077 sock->socket = newsock;
1078 sock->landriver = net_landriverlevel;
1079 sock->addr = clientaddr;
1080 strcpy(sock->address, dfunc.AddrToString(&clientaddr));
1082 // send him back the info about the server connection he has been allocated
1083 SZ_Clear(&net_message);
1084 // save space for the header, filled in later
1085 MSG_WriteLong(&net_message, 0);
1086 MSG_WriteByte(&net_message, CCREP_ACCEPT);
1087 dfunc.GetSocketAddr(newsock, &newaddr);
1088 MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
1089 // MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
1090 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1091 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1092 SZ_Clear(&net_message);
1097 qsocket_t *Datagram_CheckNewConnections (void)
1099 qsocket_t *ret = NULL;
1101 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1102 if (net_landrivers[net_landriverlevel].initialized)
1103 if ((ret = _Datagram_CheckNewConnections ()) != NULL)
1109 static void _Datagram_SearchForHosts (qboolean xmit)
1114 struct qsockaddr readaddr;
1115 struct qsockaddr myaddr;
1119 dfunc.GetSocketAddr (dfunc.controlSock, &myaddr);
1122 SZ_Clear(&net_message);
1123 // save space for the header, filled in later
1124 MSG_WriteLong(&net_message, 0);
1125 MSG_WriteByte(&net_message, CCREQ_SERVER_INFO);
1126 MSG_WriteString(&net_message, "QUAKE");
1127 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
1128 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1129 dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize);
1130 SZ_Clear(&net_message);
1133 while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0)
1135 if (ret < sizeof(int))
1137 net_message.cursize = ret;
1139 // don't answer our own query
1140 if (dfunc.AddrCompare(&readaddr, &myaddr) >= 0)
1143 // is the cache full?
1144 if (hostCacheCount == HOSTCACHESIZE)
1147 MSG_BeginReading ();
1148 control = BigLong(*((int *)net_message.data));
1152 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
1154 if ((control & NETFLAG_LENGTH_MASK) != ret)
1158 if (c != CCREP_SERVER_INFO)
1161 dfunc.GetAddrFromName(MSG_ReadString(), &readaddr);
1162 // search the cache for this server
1163 for (n = 0; n < hostCacheCount; n++)
1164 if (dfunc.AddrCompare(&readaddr, &hostcache[n].addr) == 0)
1167 // is it already there?
1168 if (n < hostCacheCount)
1173 strcpy(hostcache[n].name, MSG_ReadString());
1174 strcpy(hostcache[n].map, MSG_ReadString());
1175 hostcache[n].users = MSG_ReadByte();
1176 hostcache[n].maxusers = MSG_ReadByte();
1178 if (c != NET_PROTOCOL_VERSION)
1180 strcpy(hostcache[n].cname, hostcache[n].name);
1181 hostcache[n].cname[14] = 0;
1182 strcpy(hostcache[n].name, "*");
1183 strcat(hostcache[n].name, hostcache[n].cname);
1185 memcpy(&hostcache[n].addr, &readaddr, sizeof(struct qsockaddr));
1186 hostcache[n].driver = net_driverlevel;
1187 hostcache[n].ldriver = net_landriverlevel;
1188 strcpy(hostcache[n].cname, dfunc.AddrToString(&readaddr));
1190 // check for a name conflict
1191 for (i = 0; i < hostCacheCount; i++)
1195 if (Q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0)
1197 i = strlen(hostcache[n].name);
1198 if (i < 15 && hostcache[n].name[i-1] > '8')
1200 hostcache[n].name[i] = '0';
1201 hostcache[n].name[i+1] = 0;
1204 hostcache[n].name[i-1]++;
1211 void Datagram_SearchForHosts (qboolean xmit)
1213 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1215 if (hostCacheCount == HOSTCACHESIZE)
1217 if (net_landrivers[net_landriverlevel].initialized)
1218 _Datagram_SearchForHosts (xmit);
1223 static qsocket_t *_Datagram_Connect (char *host)
1225 struct qsockaddr sendaddr;
1226 struct qsockaddr readaddr;
1235 // see if we can resolve the host name
1236 if (dfunc.GetAddrFromName(host, &sendaddr) == -1)
1239 newsock = dfunc.OpenSocket (cl_port.integer);
1243 sock = NET_NewQSocket ();
1246 sock->socket = newsock;
1247 sock->landriver = net_landriverlevel;
1249 // connect to the host
1250 if (dfunc.Connect (newsock, &sendaddr) == -1)
1253 // send the connection request
1254 Con_Printf("trying...\n");CL_UpdateScreen();CL_UpdateScreen();
1255 start_time = net_time;
1257 for (reps = 0; reps < 3; reps++)
1259 SZ_Clear(&net_message);
1260 // save space for the header, filled in later
1261 MSG_WriteLong(&net_message, 0);
1262 MSG_WriteByte(&net_message, CCREQ_CONNECT);
1263 MSG_WriteString(&net_message, "QUAKE");
1264 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
1265 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1266 dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr);
1267 SZ_Clear(&net_message);
1270 ret = dfunc.Read (newsock, net_message.data, net_message.maxsize, &readaddr);
1271 // if we got something, validate it
1274 // is it from the right place?
1275 if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0)
1278 Con_DPrintf("wrong reply address\n");
1279 Con_DPrintf("Expected: %s\n", StrAddr (&sendaddr));
1280 Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
1287 if (ret < sizeof(int))
1293 net_message.cursize = ret;
1294 MSG_BeginReading ();
1296 control = BigLong(*((int *)net_message.data));
1303 if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL)
1308 if ((control & NETFLAG_LENGTH_MASK) != ret)
1315 while (ret == 0 && (SetNetTime() - start_time) < 2.5);
1318 Con_Printf("still trying...\n");CL_UpdateScreen();CL_UpdateScreen();
1319 start_time = SetNetTime();
1324 reason = "No Response";
1325 Con_Printf("%s\n", reason);
1326 strcpy(m_return_reason, reason);
1332 reason = "Network Error";
1333 Con_Printf("%s\n", reason);
1334 strcpy(m_return_reason, reason);
1338 ret = MSG_ReadByte();
1339 if (ret == CCREP_REJECT)
1341 reason = MSG_ReadString();
1342 Con_Printf("%s", reason);
1343 strncpy(m_return_reason, reason, 31);
1347 if (ret == CCREP_ACCEPT)
1349 memcpy(&sock->addr, &sendaddr, sizeof(struct qsockaddr));
1350 dfunc.SetSocketPort (&sock->addr, MSG_ReadLong());
1354 reason = "Bad Response";
1355 Con_Printf("%s\n", reason);
1356 strcpy(m_return_reason, reason);
1360 dfunc.GetNameFromAddr (&sendaddr, sock->address);
1362 Con_Printf ("Connection accepted to %s\n", sock->address);
1363 sock->lastMessageTime = SetNetTime();
1365 // switch the connection to the specified address
1366 if (dfunc.Connect (newsock, &sock->addr) == -1)
1368 reason = "Connect to Game failed";
1369 Con_Printf("%s\n", reason);
1370 strcpy(m_return_reason, reason);
1374 m_return_onerror = false;
1378 NET_FreeQSocket(sock);
1380 dfunc.CloseSocket(newsock);
1381 if (m_return_onerror)
1383 key_dest = key_menu;
1384 m_state = m_return_state;
1385 m_return_onerror = false;
1390 qsocket_t *Datagram_Connect (char *host)
1392 qsocket_t *ret = NULL;
1394 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1395 if (net_landrivers[net_landriverlevel].initialized)
1396 if ((ret = _Datagram_Connect (host)) != NULL)