|
|
1.1 root 1: // net_dgrm.c
2:
1.1.1.3 ! root 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:
1.1 root 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:
1.1.1.3 ! root 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:
1.1 root 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:
1.1.1.3 ! root 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:
1.1 root 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: }
1.1.1.3 ! root 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: }
1.1 root 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;
1.1.1.3 ! root 636: char name[256];
! 637: char value[256];
1.1 root 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:
1.1.1.3 ! root 767: #ifdef BAN_TEST
! 768: Cmd_AddCommand ("ban", NET_Ban_f);
! 769: #endif
1.1 root 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);
1.1.1.3 ! root 916: if (!var)
! 917: return NULL;
1.1 root 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:
1.1.1.3 ! root 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:
1.1 root 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;
1.1.1.3 ! root 1205: char *reason;
1.1 root 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: {
1.1.1.3 ! root 1296: reason = "No Response";
! 1297: Con_Printf("%s\n", reason);
! 1298: Q_strcpy(m_return_reason, reason);
1.1 root 1299: goto ErrorReturn;
1300: }
1301:
1302: if (ret == -1)
1303: {
1.1.1.3 ! root 1304: reason = "Network Error";
! 1305: Con_Printf("%s\n", reason);
! 1306: Q_strcpy(m_return_reason, reason);
1.1 root 1307: goto ErrorReturn;
1308: }
1309:
1310: ret = MSG_ReadByte();
1311: if (ret == CCREP_REJECT)
1312: {
1.1.1.3 ! root 1313: reason = MSG_ReadString();
! 1314: Con_Printf(reason);
! 1315: Q_strncpy(m_return_reason, reason, 31);
1.1 root 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: {
1.1.1.3 ! root 1326: reason = "Bad Response";
! 1327: Con_Printf("%s\n", reason);
! 1328: Q_strcpy(m_return_reason, reason);
1.1 root 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: {
1.1.1.3 ! root 1340: reason = "Connect to Game failed";
! 1341: Con_Printf("%s\n", reason);
! 1342: Q_strcpy(m_return_reason, reason);
1.1 root 1343: goto ErrorReturn;
1344: }
1345:
1.1.1.3 ! root 1346: m_return_onerror = false;
1.1 root 1347: return sock;
1348:
1349: ErrorReturn:
1350: NET_FreeQSocket(sock);
1351: ErrorReturn2:
1352: dfunc.CloseSocket(newsock);
1.1.1.3 ! root 1353: if (m_return_onerror)
! 1354: {
! 1355: key_dest = key_menu;
! 1356: m_state = m_return_state;
! 1357: m_return_onerror = false;
! 1358: }
1.1 root 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.