1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
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.
8
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.
12
13 See the GNU General Public License for more details.
14
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.
18
19 */
20 // net_dgrm.c
21
22 // This is enables a simple IP banning mechanism
23 #define BAN_TEST
24
25 #ifdef BAN_TEST
26 #if defined(_WIN32)
27 #include <windows.h>
28 #elif defined (NeXT)
29 #include <sys/socket.h>
30 #include <arpa/inet.h>
31 #else
32
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #endif
38 #endif // BAN_TEST
39
40 #include "quakedef.h"
41 #include "net_dgrm.h"
42
43 // these two macros are to make the code more readable
44 #define sfunc net_landrivers[sock->landriver]
45 #define dfunc net_landrivers[net_landriverlevel]
46
47 static int net_landriverlevel;
48
49 /* statistic counters */
50 int packetsSent = 0;
51 int packetsReSent = 0;
52 int packetsReceived = 0;
53 int receivedDuplicateCount = 0;
54 int shortPacketCount = 0;
55 int droppedDatagrams;
56
57 static int myDriverLevel;
58
59 struct packetBuffer_t
60 {
61 unsigned int length;
62 unsigned int sequence;
63 byte data[MAX_DATAGRAM];
64 } packetBuffer;
65
66 extern int m_return_state;
67 extern int m_state;
68 extern qboolean m_return_onerror;
69 extern char m_return_reason[32];
70
71
72 #ifdef DEBUG
StrAddr(struct qsockaddr * addr)73 char *StrAddr (struct qsockaddr *addr)
74 {
75 static char buf[34];
76 byte *p = (byte *)addr;
77 int n;
78
79 for (n = 0; n < 16; n++)
80 sprintf (buf + n * 2, "%02x", *p++);
81 return buf;
82 }
83 #endif
84
85
86 #ifdef BAN_TEST
87 typedef union {
88 unsigned long ul;
89 struct in_addr addr;
90 } ulongaddr;
91
92 typedef union {
93 qsockaddr q;
94 sockaddr_in i;
95 } qsockaddr2sockaddr_in;
96
97 unsigned long banAddr = 0x00000000;
98 unsigned long banMask = 0xffffffff;
99
NET_Ban_f(void)100 void NET_Ban_f (void)
101 {
102 char addrStr [32];
103 char maskStr [32];
104 void (*print) (const char *fmt, ...);
105
106 if (cmd_source == src_command)
107 {
108 if (!sv.active)
109 {
110 Cmd_ForwardToServer ();
111 return;
112 }
113 print = Con_Printf;
114 }
115 else
116 {
117 if (pr_global_struct->deathmatch && !host_client->privileged)
118 return;
119 print = SV_ClientPrintf;
120 }
121
122 switch (Cmd_Argc ())
123 {
124 case 1:
125 {
126 ulongaddr addrTemp;
127 addrTemp.ul = banAddr;
128 ulongaddr maskTemp;
129 maskTemp.ul - banMask;
130
131 if (addrTemp.addr.s_addr)
132 {
133 Q_strcpy(addrStr, inet_ntoa(addrTemp.addr));
134 Q_strcpy(maskStr, inet_ntoa(maskTemp.addr));
135 print("Banning %s [%s]\n", addrStr, maskStr);
136 }
137 else
138 print("Banning not active\n");
139 }
140 break;
141
142 case 2:
143 if (Q_strcasecmp(Cmd_Argv(1), "off") == 0)
144 banAddr = 0x00000000;
145 else
146 banAddr = inet_addr(Cmd_Argv(1));
147 banMask = 0xffffffff;
148 break;
149
150 case 3:
151 banAddr = inet_addr(Cmd_Argv(1));
152 banMask = inet_addr(Cmd_Argv(2));
153 break;
154
155 default:
156 print("BAN ip_address [mask]\n");
157 break;
158 }
159 }
160 #endif
161
162
Datagram_SendMessage(qsocket_t * sock,sizebuf_t * data)163 int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data)
164 {
165 unsigned int packetLen;
166 unsigned int dataLen;
167 unsigned int eom;
168
169 #ifdef DEBUG
170 if (data->cursize == 0)
171 Sys_Error("Datagram_SendMessage: zero length message\n");
172
173 if (data->cursize > NET_MAXMESSAGE)
174 Sys_Error("Datagram_SendMessage: message too big %u\n", data->cursize);
175
176 if (sock->canSend == false)
177 Sys_Error("SendMessage: called with canSend == false\n");
178 #endif
179
180 Q_memcpy(sock->sendMessage, data->data, data->cursize);
181 sock->sendMessageLength = data->cursize;
182
183 if (data->cursize <= MAX_DATAGRAM)
184 {
185 dataLen = data->cursize;
186 eom = NETFLAG_EOM;
187 }
188 else
189 {
190 dataLen = MAX_DATAGRAM;
191 eom = 0;
192 }
193 packetLen = NET_HEADERSIZE + dataLen;
194
195 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
196 packetBuffer.sequence = BigLong(sock->sendSequence++);
197 Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen);
198
199 sock->canSend = false;
200
201 if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
202 return -1;
203
204 sock->lastSendTime = net_time;
205 packetsSent++;
206 return 1;
207 }
208
209
SendMessageNext(qsocket_t * sock)210 int SendMessageNext (qsocket_t *sock)
211 {
212 unsigned int packetLen;
213 unsigned int dataLen;
214 unsigned int eom;
215
216 if (sock->sendMessageLength <= MAX_DATAGRAM)
217 {
218 dataLen = sock->sendMessageLength;
219 eom = NETFLAG_EOM;
220 }
221 else
222 {
223 dataLen = MAX_DATAGRAM;
224 eom = 0;
225 }
226 packetLen = NET_HEADERSIZE + dataLen;
227
228 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
229 packetBuffer.sequence = BigLong(sock->sendSequence++);
230 Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen);
231
232 sock->sendNext = false;
233
234 if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
235 return -1;
236
237 sock->lastSendTime = net_time;
238 packetsSent++;
239 return 1;
240 }
241
242
ReSendMessage(qsocket_t * sock)243 int ReSendMessage (qsocket_t *sock)
244 {
245 unsigned int packetLen;
246 unsigned int dataLen;
247 unsigned int eom;
248
249 if (sock->sendMessageLength <= MAX_DATAGRAM)
250 {
251 dataLen = sock->sendMessageLength;
252 eom = NETFLAG_EOM;
253 }
254 else
255 {
256 dataLen = MAX_DATAGRAM;
257 eom = 0;
258 }
259 packetLen = NET_HEADERSIZE + dataLen;
260
261 packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
262 packetBuffer.sequence = BigLong(sock->sendSequence - 1);
263 Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen);
264
265 sock->sendNext = false;
266
267 if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
268 return -1;
269
270 sock->lastSendTime = net_time;
271 packetsReSent++;
272 return 1;
273 }
274
275
Datagram_CanSendMessage(qsocket_t * sock)276 qboolean Datagram_CanSendMessage (qsocket_t *sock)
277 {
278 if (sock->sendNext)
279 SendMessageNext (sock);
280
281 return sock->canSend;
282 }
283
284
Datagram_CanSendUnreliableMessage(qsocket_t * sock)285 qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock)
286 {
287 return true;
288 }
289
290
Datagram_SendUnreliableMessage(qsocket_t * sock,sizebuf_t * data)291 int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
292 {
293 int packetLen;
294
295 #ifdef DEBUG
296 if (data->cursize == 0)
297 Sys_Error("Datagram_SendUnreliableMessage: zero length message\n");
298
299 if (data->cursize > MAX_DATAGRAM)
300 Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize);
301 #endif
302
303 packetLen = NET_HEADERSIZE + data->cursize;
304
305 packetBuffer.length = BigLong(packetLen | NETFLAG_UNRELIABLE);
306 packetBuffer.sequence = BigLong(sock->unreliableSendSequence++);
307 Q_memcpy (packetBuffer.data, data->data, data->cursize);
308
309 if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
310 return -1;
311
312 packetsSent++;
313 return 1;
314 }
315
316
Datagram_GetMessage(qsocket_t * sock)317 int Datagram_GetMessage (qsocket_t *sock)
318 {
319 unsigned int length;
320 unsigned int flags;
321 int ret = 0;
322 struct qsockaddr readaddr;
323 unsigned int sequence;
324 unsigned int count;
325
326 if (!sock->canSend)
327 if ((net_time - sock->lastSendTime) > 1.0)
328 ReSendMessage (sock);
329
330 while(1)
331 {
332 length = sfunc.Read (sock->socket, (byte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr);
333
334 // if ((rand() & 255) > 220)
335 // continue;
336
337 if (length == 0)
338 break;
339
340 if (length == (unsigned int) -1)
341 {
342 Con_Printf("Read error\n");
343 return -1;
344 }
345
346 if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0)
347 {
348 #ifdef DEBUG
349 Con_DPrintf("Forged packet received\n");
350 Con_DPrintf("Expected: %s\n", StrAddr (&sock->addr));
351 Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
352 #endif
353 continue;
354 }
355
356 if (length < NET_HEADERSIZE)
357 {
358 shortPacketCount++;
359 continue;
360 }
361
362 length = BigLong(packetBuffer.length);
363 flags = length & (~NETFLAG_LENGTH_MASK);
364 length &= NETFLAG_LENGTH_MASK;
365
366 if (flags & NETFLAG_CTL)
367 continue;
368
369 sequence = BigLong(packetBuffer.sequence);
370 packetsReceived++;
371
372 if (flags & NETFLAG_UNRELIABLE)
373 {
374 if (sequence < sock->unreliableReceiveSequence)
375 {
376 Con_DPrintf("Got a stale datagram\n");
377 ret = 0;
378 break;
379 }
380 if (sequence != sock->unreliableReceiveSequence)
381 {
382 count = sequence - sock->unreliableReceiveSequence;
383 droppedDatagrams += count;
384 Con_DPrintf("Dropped %u datagram(s)\n", count);
385 }
386 sock->unreliableReceiveSequence = sequence + 1;
387
388 length -= NET_HEADERSIZE;
389
390 SZ_Clear (&net_message);
391 SZ_Write (&net_message, packetBuffer.data, length);
392
393 ret = 2;
394 break;
395 }
396
397 if (flags & NETFLAG_ACK)
398 {
399 if (sequence != (sock->sendSequence - 1))
400 {
401 Con_DPrintf("Stale ACK received\n");
402 continue;
403 }
404 if (sequence == sock->ackSequence)
405 {
406 sock->ackSequence++;
407 if (sock->ackSequence != sock->sendSequence)
408 Con_DPrintf("ack sequencing error\n");
409 }
410 else
411 {
412 Con_DPrintf("Duplicate ACK received\n");
413 continue;
414 }
415 sock->sendMessageLength -= MAX_DATAGRAM;
416 if (sock->sendMessageLength > 0)
417 {
418 Q_memcpy(sock->sendMessage, sock->sendMessage+MAX_DATAGRAM, sock->sendMessageLength);
419 sock->sendNext = true;
420 }
421 else
422 {
423 sock->sendMessageLength = 0;
424 sock->canSend = true;
425 }
426 continue;
427 }
428
429 if (flags & NETFLAG_DATA)
430 {
431 packetBuffer.length = BigLong(NET_HEADERSIZE | NETFLAG_ACK);
432 packetBuffer.sequence = BigLong(sequence);
433 sfunc.Write (sock->socket, (byte *)&packetBuffer, NET_HEADERSIZE, &readaddr);
434
435 if (sequence != sock->receiveSequence)
436 {
437 receivedDuplicateCount++;
438 continue;
439 }
440 sock->receiveSequence++;
441
442 length -= NET_HEADERSIZE;
443
444 if (flags & NETFLAG_EOM)
445 {
446 SZ_Clear(&net_message);
447 SZ_Write(&net_message, sock->receiveMessage, sock->receiveMessageLength);
448 SZ_Write(&net_message, packetBuffer.data, length);
449 sock->receiveMessageLength = 0;
450
451 ret = 1;
452 break;
453 }
454
455 Q_memcpy(sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length);
456 sock->receiveMessageLength += length;
457 continue;
458 }
459 }
460
461 if (sock->sendNext)
462 SendMessageNext (sock);
463
464 return ret;
465 }
466
467
PrintStats(qsocket_t * s)468 void PrintStats(qsocket_t *s)
469 {
470 Con_Printf("canSend = %4u \n", s->canSend);
471 Con_Printf("sendSeq = %4u ", s->sendSequence);
472 Con_Printf("recvSeq = %4u \n", s->receiveSequence);
473 Con_Printf("\n");
474 }
475
NET_Stats_f(void)476 void NET_Stats_f (void)
477 {
478 qsocket_t *s;
479
480 if (Cmd_Argc () == 1)
481 {
482 Con_Printf("unreliable messages sent = %i\n", unreliableMessagesSent);
483 Con_Printf("unreliable messages recv = %i\n", unreliableMessagesReceived);
484 Con_Printf("reliable messages sent = %i\n", messagesSent);
485 Con_Printf("reliable messages received = %i\n", messagesReceived);
486 Con_Printf("packetsSent = %i\n", packetsSent);
487 Con_Printf("packetsReSent = %i\n", packetsReSent);
488 Con_Printf("packetsReceived = %i\n", packetsReceived);
489 Con_Printf("receivedDuplicateCount = %i\n", receivedDuplicateCount);
490 Con_Printf("shortPacketCount = %i\n", shortPacketCount);
491 Con_Printf("droppedDatagrams = %i\n", droppedDatagrams);
492 }
493 else if (Q_strcmp(Cmd_Argv(1), "*") == 0)
494 {
495 for (s = net_activeSockets; s; s = s->next)
496 PrintStats(s);
497 for (s = net_freeSockets; s; s = s->next)
498 PrintStats(s);
499 }
500 else
501 {
502 for (s = net_activeSockets; s; s = s->next)
503 if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0)
504 break;
505 if (s == NULL)
506 for (s = net_freeSockets; s; s = s->next)
507 if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0)
508 break;
509 if (s == NULL)
510 return;
511 PrintStats(s);
512 }
513 }
514
515
516 static qboolean testInProgress = false;
517 static int testPollCount;
518 static int testDriver;
519 static int testSocket;
520
521 static void Test_Poll(void* arg);
522 PollProcedure testPollProcedure = {NULL, 0.0, Test_Poll, NULL};
523
Test_Poll(void *)524 static void Test_Poll(void* /* arg */)
525 {
526 struct qsockaddr clientaddr;
527 int control;
528 int len;
529 char name[32];
530 char address[64];
531 int colors;
532 int frags;
533 int connectTime;
534 byte playerNumber;
535
536 net_landriverlevel = testDriver;
537
538 while (1)
539 {
540 len = dfunc.Read (testSocket, net_message.data, net_message.maxsize, &clientaddr);
541 if (len < (int) sizeof(int))
542 break;
543
544 net_message.cursize = len;
545
546 MSG_BeginReading ();
547 control = BigLong(*((int *)net_message.data));
548 MSG_ReadLong();
549 if (control == -1)
550 break;
551 if ((control & (~NETFLAG_LENGTH_MASK)) != (int) NETFLAG_CTL)
552 break;
553 if ((control & NETFLAG_LENGTH_MASK) != len)
554 break;
555
556 if (MSG_ReadByte() != CCREP_PLAYER_INFO)
557 Sys_Error("Unexpected repsonse to Player Info request\n");
558
559 playerNumber = MSG_ReadByte();
560 Q_strcpy(name, MSG_ReadString());
561 colors = MSG_ReadLong();
562 frags = MSG_ReadLong();
563 connectTime = MSG_ReadLong();
564 Q_strcpy(address, MSG_ReadString());
565
566 Con_Printf("%s\n frags:%3i colors:%u %u time:%u\n %s\n", name, frags, colors >> 4, colors & 0x0f, connectTime / 60, address);
567 }
568
569 testPollCount--;
570 if (testPollCount)
571 {
572 SchedulePollProcedure(&testPollProcedure, 0.1);
573 }
574 else
575 {
576 dfunc.CloseSocket(testSocket);
577 testInProgress = false;
578 }
579 }
580
Test_f(void)581 static void Test_f (void)
582 {
583 char *host;
584 int n;
585 int max = MAX_SCOREBOARD;
586 struct qsockaddr sendaddr;
587
588 if (testInProgress)
589 return;
590
591 host = Cmd_Argv (1);
592
593 if (host && hostCacheCount)
594 {
595 for (n = 0; n < hostCacheCount; n++)
596 if (Q_strcasecmp (host, hostcache[n].name) == 0)
597 {
598 if (hostcache[n].driver != myDriverLevel)
599 continue;
600 net_landriverlevel = hostcache[n].ldriver;
601 max = hostcache[n].maxusers;
602 Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
603 break;
604 }
605 if (n < hostCacheCount)
606 goto JustDoIt;
607 }
608
609 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
610 {
611 if (!net_landrivers[net_landriverlevel].initialized)
612 continue;
613
614 // see if we can resolve the host name
615 if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
616 break;
617 }
618 if (net_landriverlevel == net_numlandrivers)
619 return;
620
621 JustDoIt:
622 testSocket = dfunc.OpenSocket(0);
623 if (testSocket == -1)
624 return;
625
626 testInProgress = true;
627 testPollCount = 20;
628 testDriver = net_landriverlevel;
629
630 for (n = 0; n < max; n++)
631 {
632 SZ_Clear(&net_message);
633 // save space for the header, filled in later
634 MSG_WriteLong(&net_message, 0);
635 MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO);
636 MSG_WriteByte(&net_message, n);
637 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
638 dfunc.Write (testSocket, net_message.data, net_message.cursize, &sendaddr);
639 }
640 SZ_Clear(&net_message);
641 SchedulePollProcedure(&testPollProcedure, 0.1);
642 }
643
644
645 static qboolean test2InProgress = false;
646 static int test2Driver;
647 static int test2Socket;
648
649 static void Test2_Poll(void*);
650 PollProcedure test2PollProcedure = {NULL, 0.0, Test2_Poll, NULL};
651
Test2_Poll(void *)652 static void Test2_Poll(void* /* arg */)
653 {
654 struct qsockaddr clientaddr;
655 int control;
656 int len;
657 char name[256];
658 char value[256];
659
660 net_landriverlevel = test2Driver;
661 name[0] = 0;
662
663 len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr);
664 if (len < (int) sizeof(int))
665 goto Reschedule;
666
667 net_message.cursize = len;
668
669 MSG_BeginReading ();
670 control = BigLong(*((int *)net_message.data));
671 MSG_ReadLong();
672 if (control == -1)
673 goto Error;
674 if ((control & (~NETFLAG_LENGTH_MASK)) != (int) NETFLAG_CTL)
675 goto Error;
676 if ((control & NETFLAG_LENGTH_MASK) != len)
677 goto Error;
678
679 if (MSG_ReadByte() != CCREP_RULE_INFO)
680 goto Error;
681
682 Q_strcpy(name, MSG_ReadString());
683 if (name[0] == 0)
684 goto Done;
685 Q_strcpy(value, MSG_ReadString());
686
687 Con_Printf("%-16.16s %-16.16s\n", name, value);
688
689 SZ_Clear(&net_message);
690 // save space for the header, filled in later
691 MSG_WriteLong(&net_message, 0);
692 MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
693 MSG_WriteString(&net_message, name);
694 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
695 dfunc.Write (test2Socket, net_message.data, net_message.cursize, &clientaddr);
696 SZ_Clear(&net_message);
697
698 Reschedule:
699 SchedulePollProcedure(&test2PollProcedure, 0.05);
700 return;
701
702 Error:
703 Con_Printf("Unexpected repsonse to Rule Info request\n");
704 Done:
705 dfunc.CloseSocket(test2Socket);
706 test2InProgress = false;
707 return;
708 }
709
Test2_f(void)710 static void Test2_f (void)
711 {
712 char *host;
713 int n;
714 struct qsockaddr sendaddr;
715
716 if (test2InProgress)
717 return;
718
719 host = Cmd_Argv (1);
720
721 if (host && hostCacheCount)
722 {
723 for (n = 0; n < hostCacheCount; n++)
724 if (Q_strcasecmp (host, hostcache[n].name) == 0)
725 {
726 if (hostcache[n].driver != myDriverLevel)
727 continue;
728 net_landriverlevel = hostcache[n].ldriver;
729 Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
730 break;
731 }
732 if (n < hostCacheCount)
733 goto JustDoIt;
734 }
735
736 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
737 {
738 if (!net_landrivers[net_landriverlevel].initialized)
739 continue;
740
741 // see if we can resolve the host name
742 if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
743 break;
744 }
745 if (net_landriverlevel == net_numlandrivers)
746 return;
747
748 JustDoIt:
749 test2Socket = dfunc.OpenSocket(0);
750 if (test2Socket == -1)
751 return;
752
753 test2InProgress = true;
754 test2Driver = net_landriverlevel;
755
756 SZ_Clear(&net_message);
757 // save space for the header, filled in later
758 MSG_WriteLong(&net_message, 0);
759 MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
760 MSG_WriteString(&net_message, "");
761 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
762 dfunc.Write (test2Socket, net_message.data, net_message.cursize, &sendaddr);
763 SZ_Clear(&net_message);
764 SchedulePollProcedure(&test2PollProcedure, 0.05);
765 }
766
767
Datagram_Init(void)768 int Datagram_Init (void)
769 {
770 int i;
771 int csock;
772
773 myDriverLevel = net_driverlevel;
774 Cmd_AddCommand ("net_stats", NET_Stats_f);
775
776 if (COM_CheckParm("-nolan"))
777 return -1;
778
779 for (i = 0; i < net_numlandrivers; i++)
780 {
781 csock = net_landrivers[i].Init ();
782 if (csock == -1)
783 continue;
784 net_landrivers[i].initialized = true;
785 net_landrivers[i].controlSock = csock;
786 }
787
788 #ifdef BAN_TEST
789 Cmd_AddCommand ("ban", NET_Ban_f);
790 #endif
791 Cmd_AddCommand ("test", Test_f);
792 Cmd_AddCommand ("test2", Test2_f);
793
794 return 0;
795 }
796
797
Datagram_Shutdown(void)798 void Datagram_Shutdown (void)
799 {
800 int i;
801
802 //
803 // shutdown the lan drivers
804 //
805 for (i = 0; i < net_numlandrivers; i++)
806 {
807 if (net_landrivers[i].initialized)
808 {
809 net_landrivers[i].Shutdown ();
810 net_landrivers[i].initialized = false;
811 }
812 }
813 }
814
815
Datagram_Close(qsocket_t * sock)816 void Datagram_Close (qsocket_t *sock)
817 {
818 sfunc.CloseSocket(sock->socket);
819 }
820
821
Datagram_Listen(qboolean state)822 void Datagram_Listen (qboolean state)
823 {
824 int i;
825
826 for (i = 0; i < net_numlandrivers; i++)
827 if (net_landrivers[i].initialized)
828 net_landrivers[i].Listen (state);
829 }
830
831
_Datagram_CheckNewConnections(void)832 static qsocket_t *_Datagram_CheckNewConnections (void)
833 {
834 struct qsockaddr clientaddr;
835 struct qsockaddr newaddr;
836 int newsock;
837 int acceptsock;
838 qsocket_t *sock;
839 qsocket_t *s;
840 int len;
841 int command;
842 int control;
843 int ret;
844
845 acceptsock = dfunc.CheckNewConnections();
846 if (acceptsock == -1)
847 return NULL;
848
849 SZ_Clear(&net_message);
850
851 len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr);
852 if (len < (int) sizeof(int))
853 return NULL;
854 net_message.cursize = len;
855
856 MSG_BeginReading ();
857 control = BigLong(*((int *)net_message.data));
858 MSG_ReadLong();
859 if (control == -1)
860 return NULL;
861 if ((control & (~NETFLAG_LENGTH_MASK)) != (int) NETFLAG_CTL)
862 return NULL;
863 if ((control & NETFLAG_LENGTH_MASK) != len)
864 return NULL;
865
866 command = MSG_ReadByte();
867 if (command == CCREQ_SERVER_INFO)
868 {
869 if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0)
870 return NULL;
871
872 SZ_Clear(&net_message);
873 // save space for the header, filled in later
874 MSG_WriteLong(&net_message, 0);
875 MSG_WriteByte(&net_message, CCREP_SERVER_INFO);
876 dfunc.GetSocketAddr(acceptsock, &newaddr);
877 MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
878 MSG_WriteString(&net_message, hostname.string);
879 MSG_WriteString(&net_message, sv.name);
880 MSG_WriteByte(&net_message, net_activeconnections);
881 MSG_WriteByte(&net_message, svs.maxclients);
882 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
883 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
884 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
885 SZ_Clear(&net_message);
886 return NULL;
887 }
888
889 if (command == CCREQ_PLAYER_INFO)
890 {
891 int playerNumber;
892 int activeNumber;
893 int clientNumber;
894 client_t *client;
895
896 playerNumber = MSG_ReadByte();
897 activeNumber = -1;
898 for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++)
899 {
900 if (client->active)
901 {
902 activeNumber++;
903 if (activeNumber == playerNumber)
904 break;
905 }
906 }
907 if (clientNumber == svs.maxclients)
908 return NULL;
909
910 SZ_Clear(&net_message);
911 // save space for the header, filled in later
912 MSG_WriteLong(&net_message, 0);
913 MSG_WriteByte(&net_message, CCREP_PLAYER_INFO);
914 MSG_WriteByte(&net_message, playerNumber);
915 MSG_WriteString(&net_message, client->name);
916 MSG_WriteLong(&net_message, client->colors);
917 MSG_WriteLong(&net_message, (int)client->edict->u.v.frags);
918 MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime));
919 MSG_WriteString(&net_message, client->netconnection->address);
920 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
921 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
922 SZ_Clear(&net_message);
923
924 return NULL;
925 }
926
927 if (command == CCREQ_RULE_INFO)
928 {
929 char *prevCvarName;
930 cvar_t *var;
931
932 // find the search start location
933 prevCvarName = MSG_ReadString();
934 if (*prevCvarName)
935 {
936 var = Cvar_FindVar (prevCvarName);
937 if (!var)
938 return NULL;
939 var = var->next;
940 }
941 else
942 var = cvar_vars;
943
944 // search for the next server cvar
945 while (var)
946 {
947 if (var->server)
948 break;
949 var = var->next;
950 }
951
952 // send the response
953
954 SZ_Clear(&net_message);
955 // save space for the header, filled in later
956 MSG_WriteLong(&net_message, 0);
957 MSG_WriteByte(&net_message, CCREP_RULE_INFO);
958 if (var)
959 {
960 MSG_WriteString(&net_message, var->name);
961 MSG_WriteString(&net_message, var->string);
962 }
963 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
964 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
965 SZ_Clear(&net_message);
966
967 return NULL;
968 }
969
970 if (command != CCREQ_CONNECT)
971 return NULL;
972
973 if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0)
974 return NULL;
975
976 if (MSG_ReadByte() != NET_PROTOCOL_VERSION)
977 {
978 SZ_Clear(&net_message);
979 // save space for the header, filled in later
980 MSG_WriteLong(&net_message, 0);
981 MSG_WriteByte(&net_message, CCREP_REJECT);
982 MSG_WriteString(&net_message, "Incompatible version.\n");
983 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
984 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
985 SZ_Clear(&net_message);
986 return NULL;
987 }
988
989 #ifdef BAN_TEST
990 // check for a ban
991 if (clientaddr.sa_family == AF_INET)
992 {
993 qsockaddr2sockaddr_in temp;
994 temp.q = clientaddr;
995 unsigned long testAddr = temp.i.sin_addr.s_addr;
996 if ((testAddr & banMask) == banAddr)
997 {
998 SZ_Clear(&net_message);
999 // save space for the header, filled in later
1000 MSG_WriteLong(&net_message, 0);
1001 MSG_WriteByte(&net_message, CCREP_REJECT);
1002 MSG_WriteString(&net_message, "You have been banned.\n");
1003 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1004 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1005 SZ_Clear(&net_message);
1006 return NULL;
1007 }
1008 }
1009 #endif
1010
1011 // see if this guy is already connected
1012 for (s = net_activeSockets; s; s = s->next)
1013 {
1014 if (s->driver != net_driverlevel)
1015 continue;
1016 ret = dfunc.AddrCompare(&clientaddr, &s->addr);
1017 if (ret >= 0)
1018 {
1019 // is this a duplicate connection reqeust?
1020 if (ret == 0 && net_time - s->connecttime < 2.0)
1021 {
1022 // yes, so send a duplicate reply
1023 SZ_Clear(&net_message);
1024 // save space for the header, filled in later
1025 MSG_WriteLong(&net_message, 0);
1026 MSG_WriteByte(&net_message, CCREP_ACCEPT);
1027 dfunc.GetSocketAddr(s->socket, &newaddr);
1028 MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
1029 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1030 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1031 SZ_Clear(&net_message);
1032 return NULL;
1033 }
1034 // it's somebody coming back in from a crash/disconnect
1035 // so close the old qsocket and let their retry get them back in
1036 NET_Close(s);
1037 return NULL;
1038 }
1039 }
1040
1041 // allocate a QSocket
1042 sock = NET_NewQSocket ();
1043 if (sock == NULL)
1044 {
1045 // no room; try to let him know
1046 SZ_Clear(&net_message);
1047 // save space for the header, filled in later
1048 MSG_WriteLong(&net_message, 0);
1049 MSG_WriteByte(&net_message, CCREP_REJECT);
1050 MSG_WriteString(&net_message, "Server is full.\n");
1051 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1052 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1053 SZ_Clear(&net_message);
1054 return NULL;
1055 }
1056
1057 // allocate a network socket
1058 newsock = dfunc.OpenSocket(0);
1059 if (newsock == -1)
1060 {
1061 NET_FreeQSocket(sock);
1062 return NULL;
1063 }
1064
1065 // connect to the client
1066 if (dfunc.Connect (newsock, &clientaddr) == -1)
1067 {
1068 dfunc.CloseSocket(newsock);
1069 NET_FreeQSocket(sock);
1070 return NULL;
1071 }
1072
1073 // everything is allocated, just fill in the details
1074 sock->socket = newsock;
1075 sock->landriver = net_landriverlevel;
1076 sock->addr = clientaddr;
1077 Q_strcpy(sock->address, dfunc.AddrToString(&clientaddr));
1078
1079 // send him back the info about the server connection he has been allocated
1080 SZ_Clear(&net_message);
1081 // save space for the header, filled in later
1082 MSG_WriteLong(&net_message, 0);
1083 MSG_WriteByte(&net_message, CCREP_ACCEPT);
1084 dfunc.GetSocketAddr(newsock, &newaddr);
1085 MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
1086 // MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
1087 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1088 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
1089 SZ_Clear(&net_message);
1090
1091 return sock;
1092 }
1093
Datagram_CheckNewConnections(void)1094 qsocket_t *Datagram_CheckNewConnections (void)
1095 {
1096 qsocket_t *ret = NULL;
1097
1098 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1099 if (net_landrivers[net_landriverlevel].initialized)
1100 if ((ret = _Datagram_CheckNewConnections ()) != NULL)
1101 break;
1102 return ret;
1103 }
1104
1105
_Datagram_SearchForHosts(qboolean xmit)1106 static void _Datagram_SearchForHosts (qboolean xmit)
1107 {
1108 int ret;
1109 int n;
1110 int i;
1111 struct qsockaddr readaddr;
1112 struct qsockaddr myaddr;
1113 int control;
1114
1115 dfunc.GetSocketAddr (dfunc.controlSock, &myaddr);
1116 if (xmit)
1117 {
1118 SZ_Clear(&net_message);
1119 // save space for the header, filled in later
1120 MSG_WriteLong(&net_message, 0);
1121 MSG_WriteByte(&net_message, CCREQ_SERVER_INFO);
1122 MSG_WriteString(&net_message, "QUAKE");
1123 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
1124 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1125 dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize);
1126 SZ_Clear(&net_message);
1127 }
1128
1129 while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0)
1130 {
1131 if (ret < (int) sizeof(int))
1132 continue;
1133 net_message.cursize = ret;
1134
1135 // don't answer our own query
1136 if (dfunc.AddrCompare(&readaddr, &myaddr) >= 0)
1137 continue;
1138
1139 // is the cache full?
1140 if (hostCacheCount == HOSTCACHESIZE)
1141 continue;
1142
1143 MSG_BeginReading ();
1144 control = BigLong(*((int *)net_message.data));
1145 MSG_ReadLong();
1146 if (control == -1)
1147 continue;
1148 if ((control & (~NETFLAG_LENGTH_MASK)) != (int) NETFLAG_CTL)
1149 continue;
1150 if ((control & NETFLAG_LENGTH_MASK) != ret)
1151 continue;
1152
1153 if (MSG_ReadByte() != CCREP_SERVER_INFO)
1154 continue;
1155
1156 dfunc.GetAddrFromName(MSG_ReadString(), &readaddr);
1157 // search the cache for this server
1158 for (n = 0; n < hostCacheCount; n++)
1159 if (dfunc.AddrCompare(&readaddr, &hostcache[n].addr) == 0)
1160 break;
1161
1162 // is it already there?
1163 if (n < hostCacheCount)
1164 continue;
1165
1166 // add it
1167 hostCacheCount++;
1168 Q_strcpy(hostcache[n].name, MSG_ReadString());
1169 Q_strcpy(hostcache[n].map, MSG_ReadString());
1170 hostcache[n].users = MSG_ReadByte();
1171 hostcache[n].maxusers = MSG_ReadByte();
1172 if (MSG_ReadByte() != NET_PROTOCOL_VERSION)
1173 {
1174 Q_strcpy(hostcache[n].cname, hostcache[n].name);
1175 hostcache[n].cname[14] = 0;
1176 Q_strcpy(hostcache[n].name, "*");
1177 Q_strcat(hostcache[n].name, hostcache[n].cname);
1178 }
1179 Q_memcpy(&hostcache[n].addr, &readaddr, sizeof(struct qsockaddr));
1180 hostcache[n].driver = net_driverlevel;
1181 hostcache[n].ldriver = net_landriverlevel;
1182 Q_strcpy(hostcache[n].cname, dfunc.AddrToString(&readaddr));
1183
1184 // check for a name conflict
1185 for (i = 0; i < hostCacheCount; i++)
1186 {
1187 if (i == n)
1188 continue;
1189 if (Q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0)
1190 {
1191 i = Q_strlen(hostcache[n].name);
1192 if (i < 15 && hostcache[n].name[i-1] > '8')
1193 {
1194 hostcache[n].name[i] = '0';
1195 hostcache[n].name[i+1] = 0;
1196 }
1197 else
1198 hostcache[n].name[i-1]++;
1199 i = -1;
1200 }
1201 }
1202 }
1203 }
1204
Datagram_SearchForHosts(qboolean xmit)1205 void Datagram_SearchForHosts (qboolean xmit)
1206 {
1207 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1208 {
1209 if (hostCacheCount == HOSTCACHESIZE)
1210 break;
1211 if (net_landrivers[net_landriverlevel].initialized)
1212 _Datagram_SearchForHosts (xmit);
1213 }
1214 }
1215
1216
_Datagram_Connect(const char * host)1217 static qsocket_t *_Datagram_Connect (const char *host)
1218 {
1219 struct qsockaddr sendaddr;
1220 struct qsockaddr readaddr;
1221 qsocket_t *sock;
1222 int newsock;
1223 int ret;
1224 int reps;
1225 double start_time;
1226 int control;
1227 const char *reason;
1228
1229 // see if we can resolve the host name
1230 if (dfunc.GetAddrFromName(host, &sendaddr) == -1)
1231 return NULL;
1232
1233 newsock = dfunc.OpenSocket (0);
1234 if (newsock == -1)
1235 return NULL;
1236
1237 sock = NET_NewQSocket ();
1238 if (sock == NULL)
1239 goto ErrorReturn2;
1240 sock->socket = newsock;
1241 sock->landriver = net_landriverlevel;
1242
1243 // connect to the host
1244 if (dfunc.Connect (newsock, &sendaddr) == -1)
1245 goto ErrorReturn;
1246
1247 // send the connection request
1248 Con_Printf("trying...\n"); SCR_UpdateScreen ();
1249 start_time = net_time;
1250
1251 for (reps = 0; reps < 3; reps++)
1252 {
1253 SZ_Clear(&net_message);
1254 // save space for the header, filled in later
1255 MSG_WriteLong(&net_message, 0);
1256 MSG_WriteByte(&net_message, CCREQ_CONNECT);
1257 MSG_WriteString(&net_message, "QUAKE");
1258 MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
1259 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
1260 dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr);
1261 SZ_Clear(&net_message);
1262 do
1263 {
1264 ret = dfunc.Read (newsock, net_message.data, net_message.maxsize, &readaddr);
1265 // if we got something, validate it
1266 if (ret > 0)
1267 {
1268 // is it from the right place?
1269 if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0)
1270 {
1271 #ifdef DEBUG
1272 Con_Printf("wrong reply address\n");
1273 Con_Printf("Expected: %s\n", StrAddr (&sendaddr));
1274 Con_Printf("Received: %s\n", StrAddr (&readaddr));
1275 SCR_UpdateScreen ();
1276 #endif
1277 ret = 0;
1278 continue;
1279 }
1280
1281 if (ret < (int) sizeof(int))
1282 {
1283 ret = 0;
1284 continue;
1285 }
1286
1287 net_message.cursize = ret;
1288 MSG_BeginReading ();
1289
1290 control = BigLong(*((int *)net_message.data));
1291 MSG_ReadLong();
1292 if (control == -1)
1293 {
1294 ret = 0;
1295 continue;
1296 }
1297 if ((control & (~NETFLAG_LENGTH_MASK)) != (int) NETFLAG_CTL)
1298 {
1299 ret = 0;
1300 continue;
1301 }
1302 if ((control & NETFLAG_LENGTH_MASK) != ret)
1303 {
1304 ret = 0;
1305 continue;
1306 }
1307 }
1308 }
1309 while (ret == 0 && (SetNetTime() - start_time) < 2.5);
1310 if (ret)
1311 break;
1312 Con_Printf("still trying...\n"); SCR_UpdateScreen ();
1313 start_time = SetNetTime();
1314 }
1315
1316 if (ret == 0)
1317 {
1318 reason = "No Response";
1319 Con_Printf("%s\n", reason);
1320 Q_strcpy(m_return_reason, reason);
1321 goto ErrorReturn;
1322 }
1323
1324 if (ret == -1)
1325 {
1326 reason = "Network Error";
1327 Con_Printf("%s\n", reason);
1328 Q_strcpy(m_return_reason, reason);
1329 goto ErrorReturn;
1330 }
1331
1332 ret = MSG_ReadByte();
1333 if (ret == CCREP_REJECT)
1334 {
1335 reason = MSG_ReadString();
1336 Con_Printf(reason);
1337 Q_strncpy(m_return_reason, reason, 31);
1338 goto ErrorReturn;
1339 }
1340
1341 if (ret == CCREP_ACCEPT)
1342 {
1343 Q_memcpy(&sock->addr, &sendaddr, sizeof(struct qsockaddr));
1344 dfunc.SetSocketPort (&sock->addr, MSG_ReadLong());
1345 }
1346 else
1347 {
1348 reason = "Bad Response";
1349 Con_Printf("%s\n", reason);
1350 Q_strcpy(m_return_reason, reason);
1351 goto ErrorReturn;
1352 }
1353
1354 dfunc.GetNameFromAddr (&sendaddr, sock->address);
1355
1356 Con_Printf ("Connection accepted\n");
1357 sock->lastMessageTime = SetNetTime();
1358
1359 // switch the connection to the specified address
1360 if (dfunc.Connect (newsock, &sock->addr) == -1)
1361 {
1362 reason = "Connect to Game failed";
1363 Con_Printf("%s\n", reason);
1364 Q_strcpy(m_return_reason, reason);
1365 goto ErrorReturn;
1366 }
1367
1368 m_return_onerror = false;
1369 return sock;
1370
1371 ErrorReturn:
1372 NET_FreeQSocket(sock);
1373 ErrorReturn2:
1374 dfunc.CloseSocket(newsock);
1375 if (m_return_onerror)
1376 {
1377 key_dest = key_menu;
1378 m_state = m_return_state;
1379 m_return_onerror = false;
1380 }
1381 return NULL;
1382 }
1383
Datagram_Connect(const char * host)1384 qsocket_t *Datagram_Connect (const char *host)
1385 {
1386 qsocket_t *ret = NULL;
1387
1388 for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
1389 if (net_landrivers[net_landriverlevel].initialized)
1390 if ((ret = _Datagram_Connect (host)) != NULL)
1391 break;
1392 return ret;
1393 }
1394