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