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