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