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 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 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 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 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 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 276 qboolean Datagram_CanSendMessage (qsocket_t *sock) 277 { 278 if (sock->sendNext) 279 SendMessageNext (sock); 280 281 return sock->canSend; 282 } 283 284 285 qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock) 286 { 287 return true; 288 } 289 290 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 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 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 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 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 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 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 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 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 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 816 void Datagram_Close (qsocket_t *sock) 817 { 818 sfunc.CloseSocket(sock->socket); 819 } 820 821 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 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 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 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 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 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 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