2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 // This is enables a simple IP banning mechanism
31 #include <sys/socket.h>
32 #include <arpa/inet.h>
34 #define AF_INET 2 /* internet */
39 struct { unsigned char s_b1
,s_b2
,s_b3
,s_b4
; } S_un_b
;
40 struct { unsigned short s_w1
,s_w2
; } S_un_w
;
44 #define s_addr S_un.S_addr /* can be used for most tcp & ip code */
48 unsigned short sin_port
;
49 struct in_addr sin_addr
;
52 char *inet_ntoa(struct in_addr in
);
53 unsigned long inet_addr(const char *cp
);
60 // these two macros are to make the code more readable
61 #define sfunc net_landrivers[sock->landriver]
62 #define dfunc net_landrivers[net_landriverlevel]
64 static int net_landriverlevel
;
66 /* statistic counters */
68 int packetsReSent
= 0;
69 int packetsReceived
= 0;
70 int receivedDuplicateCount
= 0;
71 int shortPacketCount
= 0;
74 static int myDriverLevel
;
79 unsigned int sequence
;
80 byte data
[MAX_DATAGRAM
];
83 extern int m_return_state
;
85 extern qboolean m_return_onerror
;
86 extern char m_return_reason
[32];
90 char *StrAddr (struct qsockaddr
*addr
)
93 byte
*p
= (byte
*)addr
;
96 for (n
= 0; n
< 16; n
++)
97 sprintf (buf
+ n
* 2, "%02x", *p
++);
104 unsigned long banAddr
= 0x00000000;
105 unsigned long banMask
= 0xffffffff;
107 void NET_Ban_f (void)
111 void (*print
) (char *fmt
, ...);
113 if (cmd_source
== src_command
)
117 Cmd_ForwardToServer ();
124 if (pr_global_struct
->deathmatch
&& !host_client
->privileged
)
126 print
= SV_ClientPrintf
;
132 if (((struct in_addr
*)&banAddr
)->s_addr
)
134 Q_strcpy(addrStr
, inet_ntoa(*(struct in_addr
*)&banAddr
));
135 Q_strcpy(maskStr
, inet_ntoa(*(struct in_addr
*)&banMask
));
136 print("Banning %s [%s]\n", addrStr
, maskStr
);
139 print("Banning not active\n");
143 if (Q_strcasecmp(Cmd_Argv(1), "off") == 0)
144 banAddr
= 0x00000000;
146 banAddr
= inet_addr(Cmd_Argv(1));
147 banMask
= 0xffffffff;
151 banAddr
= inet_addr(Cmd_Argv(1));
152 banMask
= inet_addr(Cmd_Argv(2));
156 print("BAN ip_address [mask]\n");
163 int Datagram_SendMessage (qsocket_t
*sock
, sizebuf_t
*data
)
165 unsigned int packetLen
;
166 unsigned int dataLen
;
170 if (data
->cursize
== 0)
171 Sys_Error("Datagram_SendMessage: zero length message\n");
173 if (data
->cursize
> NET_MAXMESSAGE
)
174 Sys_Error("Datagram_SendMessage: message too big %u\n", data
->cursize
);
176 if (sock
->canSend
== false)
177 Sys_Error("SendMessage: called with canSend == false\n");
180 Q_memcpy(sock
->sendMessage
, data
->data
, data
->cursize
);
181 sock
->sendMessageLength
= data
->cursize
;
183 if (data
->cursize
<= MAX_DATAGRAM
)
185 dataLen
= data
->cursize
;
190 dataLen
= MAX_DATAGRAM
;
193 packetLen
= NET_HEADERSIZE
+ dataLen
;
195 packetBuffer
.length
= BigLong(packetLen
| (NETFLAG_DATA
| eom
));
196 packetBuffer
.sequence
= BigLong(sock
->sendSequence
++);
197 Q_memcpy (packetBuffer
.data
, sock
->sendMessage
, dataLen
);
199 sock
->canSend
= false;
201 if (sfunc
.Write (sock
->socket
, (byte
*)&packetBuffer
, packetLen
, &sock
->addr
) == -1)
204 sock
->lastSendTime
= net_time
;
210 int SendMessageNext (qsocket_t
*sock
)
212 unsigned int packetLen
;
213 unsigned int dataLen
;
216 if (sock
->sendMessageLength
<= MAX_DATAGRAM
)
218 dataLen
= sock
->sendMessageLength
;
223 dataLen
= MAX_DATAGRAM
;
226 packetLen
= NET_HEADERSIZE
+ dataLen
;
228 packetBuffer
.length
= BigLong(packetLen
| (NETFLAG_DATA
| eom
));
229 packetBuffer
.sequence
= BigLong(sock
->sendSequence
++);
230 Q_memcpy (packetBuffer
.data
, sock
->sendMessage
, dataLen
);
232 sock
->sendNext
= false;
234 if (sfunc
.Write (sock
->socket
, (byte
*)&packetBuffer
, packetLen
, &sock
->addr
) == -1)
237 sock
->lastSendTime
= net_time
;
243 int ReSendMessage (qsocket_t
*sock
)
245 unsigned int packetLen
;
246 unsigned int dataLen
;
249 if (sock
->sendMessageLength
<= MAX_DATAGRAM
)
251 dataLen
= sock
->sendMessageLength
;
256 dataLen
= MAX_DATAGRAM
;
259 packetLen
= NET_HEADERSIZE
+ dataLen
;
261 packetBuffer
.length
= BigLong(packetLen
| (NETFLAG_DATA
| eom
));
262 packetBuffer
.sequence
= BigLong(sock
->sendSequence
- 1);
263 Q_memcpy (packetBuffer
.data
, sock
->sendMessage
, dataLen
);
265 sock
->sendNext
= false;
267 if (sfunc
.Write (sock
->socket
, (byte
*)&packetBuffer
, packetLen
, &sock
->addr
) == -1)
270 sock
->lastSendTime
= net_time
;
276 qboolean
Datagram_CanSendMessage (qsocket_t
*sock
)
279 SendMessageNext (sock
);
281 return sock
->canSend
;
285 qboolean
Datagram_CanSendUnreliableMessage (qsocket_t
*sock
)
291 int Datagram_SendUnreliableMessage (qsocket_t
*sock
, sizebuf_t
*data
)
296 if (data
->cursize
== 0)
297 Sys_Error("Datagram_SendUnreliableMessage: zero length message\n");
299 if (data
->cursize
> MAX_DATAGRAM
)
300 Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data
->cursize
);
303 packetLen
= NET_HEADERSIZE
+ data
->cursize
;
305 packetBuffer
.length
= BigLong(packetLen
| NETFLAG_UNRELIABLE
);
306 packetBuffer
.sequence
= BigLong(sock
->unreliableSendSequence
++);
307 Q_memcpy (packetBuffer
.data
, data
->data
, data
->cursize
);
309 if (sfunc
.Write (sock
->socket
, (byte
*)&packetBuffer
, packetLen
, &sock
->addr
) == -1)
317 int Datagram_GetMessage (qsocket_t
*sock
)
322 struct qsockaddr readaddr
;
323 unsigned int sequence
;
328 if ((net_time
- sock
->lastSendTime
) > 1.0)
329 ReSendMessage (sock
);
334 length
= sfunc
.Read (sock
->socket
, (byte
*)&packetBuffer
, NET_DATAGRAMSIZE
, &readaddr
);
336 // if ((rand() & 255) > 220)
344 Con_Printf("Read error\n");
348 if (sfunc
.AddrCompare(&readaddr
, &sock
->addr
) != 0)
351 Con_DPrintf("Forged packet received\n");
352 Con_DPrintf("Expected: %s\n", StrAddr (&sock
->addr
));
353 Con_DPrintf("Received: %s\n", StrAddr (&readaddr
));
358 if (length
< NET_HEADERSIZE
)
364 length
= BigLong(packetBuffer
.length
);
365 flags
= length
& (~NETFLAG_LENGTH_MASK
);
366 length
&= NETFLAG_LENGTH_MASK
;
368 if (flags
& NETFLAG_CTL
)
371 sequence
= BigLong(packetBuffer
.sequence
);
374 if (flags
& NETFLAG_UNRELIABLE
)
376 if (sequence
< sock
->unreliableReceiveSequence
)
378 Con_DPrintf("Got a stale datagram\n");
382 if (sequence
!= sock
->unreliableReceiveSequence
)
384 count
= sequence
- sock
->unreliableReceiveSequence
;
385 droppedDatagrams
+= count
;
386 Con_DPrintf("Dropped %u datagram(s)\n", count
);
388 sock
->unreliableReceiveSequence
= sequence
+ 1;
390 length
-= NET_HEADERSIZE
;
392 SZ_Clear (&net_message
);
393 SZ_Write (&net_message
, packetBuffer
.data
, length
);
399 if (flags
& NETFLAG_ACK
)
401 if (sequence
!= (sock
->sendSequence
- 1))
403 Con_DPrintf("Stale ACK received\n");
406 if (sequence
== sock
->ackSequence
)
409 if (sock
->ackSequence
!= sock
->sendSequence
)
410 Con_DPrintf("ack sequencing error\n");
414 Con_DPrintf("Duplicate ACK received\n");
417 sock
->sendMessageLength
-= MAX_DATAGRAM
;
418 if (sock
->sendMessageLength
> 0)
420 Q_memcpy(sock
->sendMessage
, sock
->sendMessage
+MAX_DATAGRAM
, sock
->sendMessageLength
);
421 sock
->sendNext
= true;
425 sock
->sendMessageLength
= 0;
426 sock
->canSend
= true;
431 if (flags
& NETFLAG_DATA
)
433 packetBuffer
.length
= BigLong(NET_HEADERSIZE
| NETFLAG_ACK
);
434 packetBuffer
.sequence
= BigLong(sequence
);
435 sfunc
.Write (sock
->socket
, (byte
*)&packetBuffer
, NET_HEADERSIZE
, &readaddr
);
437 if (sequence
!= sock
->receiveSequence
)
439 receivedDuplicateCount
++;
442 sock
->receiveSequence
++;
444 length
-= NET_HEADERSIZE
;
446 if (flags
& NETFLAG_EOM
)
448 SZ_Clear(&net_message
);
449 SZ_Write(&net_message
, sock
->receiveMessage
, sock
->receiveMessageLength
);
450 SZ_Write(&net_message
, packetBuffer
.data
, length
);
451 sock
->receiveMessageLength
= 0;
457 Q_memcpy(sock
->receiveMessage
+ sock
->receiveMessageLength
, packetBuffer
.data
, length
);
458 sock
->receiveMessageLength
+= length
;
464 SendMessageNext (sock
);
470 void PrintStats(qsocket_t
*s
)
472 Con_Printf("canSend = %4u \n", s
->canSend
);
473 Con_Printf("sendSeq = %4u ", s
->sendSequence
);
474 Con_Printf("recvSeq = %4u \n", s
->receiveSequence
);
478 void NET_Stats_f (void)
482 if (Cmd_Argc () == 1)
484 Con_Printf("unreliable messages sent = %i\n", unreliableMessagesSent
);
485 Con_Printf("unreliable messages recv = %i\n", unreliableMessagesReceived
);
486 Con_Printf("reliable messages sent = %i\n", messagesSent
);
487 Con_Printf("reliable messages received = %i\n", messagesReceived
);
488 Con_Printf("packetsSent = %i\n", packetsSent
);
489 Con_Printf("packetsReSent = %i\n", packetsReSent
);
490 Con_Printf("packetsReceived = %i\n", packetsReceived
);
491 Con_Printf("receivedDuplicateCount = %i\n", receivedDuplicateCount
);
492 Con_Printf("shortPacketCount = %i\n", shortPacketCount
);
493 Con_Printf("droppedDatagrams = %i\n", droppedDatagrams
);
495 else if (Q_strcmp(Cmd_Argv(1), "*") == 0)
497 for (s
= net_activeSockets
; s
; s
= s
->next
)
499 for (s
= net_freeSockets
; s
; s
= s
->next
)
504 for (s
= net_activeSockets
; s
; s
= s
->next
)
505 if (Q_strcasecmp(Cmd_Argv(1), s
->address
) == 0)
508 for (s
= net_freeSockets
; s
; s
= s
->next
)
509 if (Q_strcasecmp(Cmd_Argv(1), s
->address
) == 0)
518 static qboolean testInProgress
= false;
519 static int testPollCount
;
520 static int testDriver
;
521 static int testSocket
;
523 static void Test_Poll(void);
524 PollProcedure testPollProcedure
= {NULL
, 0.0, Test_Poll
};
526 static void Test_Poll(void)
528 struct qsockaddr clientaddr
;
538 net_landriverlevel
= testDriver
;
542 len
= dfunc
.Read (testSocket
, net_message
.data
, net_message
.maxsize
, &clientaddr
);
543 if (len
< sizeof(int))
546 net_message
.cursize
= len
;
549 control
= BigLong(*((int *)net_message
.data
));
553 if ((control
& (~NETFLAG_LENGTH_MASK
)) != NETFLAG_CTL
)
555 if ((control
& NETFLAG_LENGTH_MASK
) != len
)
558 if (MSG_ReadByte() != CCREP_PLAYER_INFO
)
559 Sys_Error("Unexpected repsonse to Player Info request\n");
561 playerNumber
= MSG_ReadByte();
562 Q_strcpy(name
, MSG_ReadString());
563 colors
= MSG_ReadLong();
564 frags
= MSG_ReadLong();
565 connectTime
= MSG_ReadLong();
566 Q_strcpy(address
, MSG_ReadString());
568 Con_Printf("%s\n frags:%3i colors:%u %u time:%u\n %s\n", name
, frags
, colors
>> 4, colors
& 0x0f, connectTime
/ 60, address
);
574 SchedulePollProcedure(&testPollProcedure
, 0.1);
578 dfunc
.CloseSocket(testSocket
);
579 testInProgress
= false;
583 static void Test_f (void)
587 int max
= MAX_SCOREBOARD
;
588 struct qsockaddr sendaddr
;
595 if (host
&& hostCacheCount
)
597 for (n
= 0; n
< hostCacheCount
; n
++)
598 if (Q_strcasecmp (host
, hostcache
[n
].name
) == 0)
600 if (hostcache
[n
].driver
!= myDriverLevel
)
602 net_landriverlevel
= hostcache
[n
].ldriver
;
603 max
= hostcache
[n
].maxusers
;
604 Q_memcpy(&sendaddr
, &hostcache
[n
].addr
, sizeof(struct qsockaddr
));
607 if (n
< hostCacheCount
)
611 for (net_landriverlevel
= 0; net_landriverlevel
< net_numlandrivers
; net_landriverlevel
++)
613 if (!net_landrivers
[net_landriverlevel
].initialized
)
616 // see if we can resolve the host name
617 if (dfunc
.GetAddrFromName(host
, &sendaddr
) != -1)
620 if (net_landriverlevel
== net_numlandrivers
)
624 testSocket
= dfunc
.OpenSocket(0);
625 if (testSocket
== -1)
628 testInProgress
= true;
630 testDriver
= net_landriverlevel
;
632 for (n
= 0; n
< max
; n
++)
634 SZ_Clear(&net_message
);
635 // save space for the header, filled in later
636 MSG_WriteLong(&net_message
, 0);
637 MSG_WriteByte(&net_message
, CCREQ_PLAYER_INFO
);
638 MSG_WriteByte(&net_message
, n
);
639 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
640 dfunc
.Write (testSocket
, net_message
.data
, net_message
.cursize
, &sendaddr
);
642 SZ_Clear(&net_message
);
643 SchedulePollProcedure(&testPollProcedure
, 0.1);
647 static qboolean test2InProgress
= false;
648 static int test2Driver
;
649 static int test2Socket
;
651 static void Test2_Poll(void);
652 PollProcedure test2PollProcedure
= {NULL
, 0.0, Test2_Poll
};
654 static void Test2_Poll(void)
656 struct qsockaddr clientaddr
;
662 net_landriverlevel
= test2Driver
;
665 len
= dfunc
.Read (test2Socket
, net_message
.data
, net_message
.maxsize
, &clientaddr
);
666 if (len
< sizeof(int))
669 net_message
.cursize
= len
;
672 control
= BigLong(*((int *)net_message
.data
));
676 if ((control
& (~NETFLAG_LENGTH_MASK
)) != NETFLAG_CTL
)
678 if ((control
& NETFLAG_LENGTH_MASK
) != len
)
681 if (MSG_ReadByte() != CCREP_RULE_INFO
)
684 Q_strcpy(name
, MSG_ReadString());
687 Q_strcpy(value
, MSG_ReadString());
689 Con_Printf("%-16.16s %-16.16s\n", name
, value
);
691 SZ_Clear(&net_message
);
692 // save space for the header, filled in later
693 MSG_WriteLong(&net_message
, 0);
694 MSG_WriteByte(&net_message
, CCREQ_RULE_INFO
);
695 MSG_WriteString(&net_message
, name
);
696 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
697 dfunc
.Write (test2Socket
, net_message
.data
, net_message
.cursize
, &clientaddr
);
698 SZ_Clear(&net_message
);
701 SchedulePollProcedure(&test2PollProcedure
, 0.05);
705 Con_Printf("Unexpected repsonse to Rule Info request\n");
707 dfunc
.CloseSocket(test2Socket
);
708 test2InProgress
= false;
712 static void Test2_f (void)
716 struct qsockaddr sendaddr
;
723 if (host
&& hostCacheCount
)
725 for (n
= 0; n
< hostCacheCount
; n
++)
726 if (Q_strcasecmp (host
, hostcache
[n
].name
) == 0)
728 if (hostcache
[n
].driver
!= myDriverLevel
)
730 net_landriverlevel
= hostcache
[n
].ldriver
;
731 Q_memcpy(&sendaddr
, &hostcache
[n
].addr
, sizeof(struct qsockaddr
));
734 if (n
< hostCacheCount
)
738 for (net_landriverlevel
= 0; net_landriverlevel
< net_numlandrivers
; net_landriverlevel
++)
740 if (!net_landrivers
[net_landriverlevel
].initialized
)
743 // see if we can resolve the host name
744 if (dfunc
.GetAddrFromName(host
, &sendaddr
) != -1)
747 if (net_landriverlevel
== net_numlandrivers
)
751 test2Socket
= dfunc
.OpenSocket(0);
752 if (test2Socket
== -1)
755 test2InProgress
= true;
756 test2Driver
= net_landriverlevel
;
758 SZ_Clear(&net_message
);
759 // save space for the header, filled in later
760 MSG_WriteLong(&net_message
, 0);
761 MSG_WriteByte(&net_message
, CCREQ_RULE_INFO
);
762 MSG_WriteString(&net_message
, "");
763 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
764 dfunc
.Write (test2Socket
, net_message
.data
, net_message
.cursize
, &sendaddr
);
765 SZ_Clear(&net_message
);
766 SchedulePollProcedure(&test2PollProcedure
, 0.05);
775 myDriverLevel
= net_driverlevel
;
776 if(!host_initialized
)
777 Cmd_AddCommand ("net_stats", NET_Stats_f
);
779 if (COM_CheckParm("-nolan"))
782 i
= net_driver_to_use
;//for (i = 0; i < net_numlandrivers; i++)
784 csock
= net_landrivers
[i
].Init ();
785 if (csock
== -1) return 0;
787 net_landrivers
[i
].initialized
= true;
788 net_landrivers
[i
].controlSock
= csock
;
791 if(!host_initialized
)
794 Cmd_AddCommand ("ban", NET_Ban_f
);
796 Cmd_AddCommand ("test", Test_f
);
797 Cmd_AddCommand ("test2", Test2_f
);
804 void Datagram_Shutdown (void)
809 // shutdown the lan drivers
811 for (i
= 0; i
< net_numlandrivers
; i
++)
813 if (net_landrivers
[i
].initialized
)
815 net_landrivers
[i
].Shutdown ();
816 net_landrivers
[i
].initialized
= false;
822 void Datagram_Close (qsocket_t
*sock
)
824 sfunc
.CloseSocket(sock
->socket
);
828 void Datagram_Listen (qboolean state
)
832 for (i
= 0; i
< net_numlandrivers
; i
++)
833 if (net_landrivers
[i
].initialized
)
834 net_landrivers
[i
].Listen (state
);
838 static qsocket_t
*_Datagram_CheckNewConnections (void)
840 struct qsockaddr clientaddr
;
841 struct qsockaddr newaddr
;
851 acceptsock
= dfunc
.CheckNewConnections();
852 if (acceptsock
== -1)
855 SZ_Clear(&net_message
);
857 len
= dfunc
.Read (acceptsock
, net_message
.data
, net_message
.maxsize
, &clientaddr
);
858 if (len
< sizeof(int))
860 net_message
.cursize
= len
;
863 control
= BigLong(*((int *)net_message
.data
));
867 if ((control
& (~NETFLAG_LENGTH_MASK
)) != NETFLAG_CTL
)
869 if ((control
& NETFLAG_LENGTH_MASK
) != len
)
872 command
= MSG_ReadByte();
873 if (command
== CCREQ_SERVER_INFO
)
875 if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0)
878 SZ_Clear(&net_message
);
879 // save space for the header, filled in later
880 MSG_WriteLong(&net_message
, 0);
881 MSG_WriteByte(&net_message
, CCREP_SERVER_INFO
);
882 dfunc
.GetSocketAddr(acceptsock
, &newaddr
);
883 MSG_WriteString(&net_message
, dfunc
.AddrToString(&newaddr
));
884 MSG_WriteString(&net_message
, hostname
.string
);
885 MSG_WriteString(&net_message
, sv
.name
);
886 MSG_WriteByte(&net_message
, net_activeconnections
);
887 MSG_WriteByte(&net_message
, svs
.maxclients
);
888 MSG_WriteByte(&net_message
, NET_PROTOCOL_VERSION
);
889 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
890 dfunc
.Write (acceptsock
, net_message
.data
, net_message
.cursize
, &clientaddr
);
891 SZ_Clear(&net_message
);
895 if (command
== CCREQ_PLAYER_INFO
)
902 playerNumber
= MSG_ReadByte();
904 for (clientNumber
= 0, client
= svs
.clients
; clientNumber
< svs
.maxclients
; clientNumber
++, client
++)
909 if (activeNumber
== playerNumber
)
913 if (clientNumber
== svs
.maxclients
)
916 SZ_Clear(&net_message
);
917 // save space for the header, filled in later
918 MSG_WriteLong(&net_message
, 0);
919 MSG_WriteByte(&net_message
, CCREP_PLAYER_INFO
);
920 MSG_WriteByte(&net_message
, playerNumber
);
921 MSG_WriteString(&net_message
, client
->name
);
922 MSG_WriteLong(&net_message
, client
->colors
);
923 MSG_WriteLong(&net_message
, (int)client
->edict
->v
.frags
);
924 MSG_WriteLong(&net_message
, (int)(net_time
- client
->netconnection
->connecttime
));
925 MSG_WriteString(&net_message
, client
->netconnection
->address
);
926 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
927 dfunc
.Write (acceptsock
, net_message
.data
, net_message
.cursize
, &clientaddr
);
928 SZ_Clear(&net_message
);
933 if (command
== CCREQ_RULE_INFO
)
938 // find the search start location
939 prevCvarName
= MSG_ReadString();
942 var
= Cvar_FindVar (prevCvarName
);
950 // search for the next server cvar
960 SZ_Clear(&net_message
);
961 // save space for the header, filled in later
962 MSG_WriteLong(&net_message
, 0);
963 MSG_WriteByte(&net_message
, CCREP_RULE_INFO
);
966 MSG_WriteString(&net_message
, var
->name
);
967 MSG_WriteString(&net_message
, var
->string
);
969 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
970 dfunc
.Write (acceptsock
, net_message
.data
, net_message
.cursize
, &clientaddr
);
971 SZ_Clear(&net_message
);
976 if (command
!= CCREQ_CONNECT
)
979 if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0)
982 if (MSG_ReadByte() != NET_PROTOCOL_VERSION
)
984 SZ_Clear(&net_message
);
985 // save space for the header, filled in later
986 MSG_WriteLong(&net_message
, 0);
987 MSG_WriteByte(&net_message
, CCREP_REJECT
);
988 MSG_WriteString(&net_message
, "Incompatible version.\n");
989 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
990 dfunc
.Write (acceptsock
, net_message
.data
, net_message
.cursize
, &clientaddr
);
991 SZ_Clear(&net_message
);
997 if (clientaddr
.sa_family
== AF_INET
)
999 unsigned long testAddr
;
1000 testAddr
= ((struct sockaddr_in
*)&clientaddr
)->sin_addr
.s_addr
;
1001 if ((testAddr
& banMask
) == banAddr
)
1003 SZ_Clear(&net_message
);
1004 // save space for the header, filled in later
1005 MSG_WriteLong(&net_message
, 0);
1006 MSG_WriteByte(&net_message
, CCREP_REJECT
);
1007 MSG_WriteString(&net_message
, "You have been banned.\n");
1008 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
1009 dfunc
.Write (acceptsock
, net_message
.data
, net_message
.cursize
, &clientaddr
);
1010 SZ_Clear(&net_message
);
1016 // see if this guy is already connected
1017 for (s
= net_activeSockets
; s
; s
= s
->next
)
1019 if (s
->driver
!= net_driverlevel
)
1021 ret
= dfunc
.AddrCompare(&clientaddr
, &s
->addr
);
1024 // is this a duplicate connection reqeust?
1025 if (ret
== 0 && net_time
- s
->connecttime
< 2.0)
1027 // yes, so send a duplicate reply
1028 SZ_Clear(&net_message
);
1029 // save space for the header, filled in later
1030 MSG_WriteLong(&net_message
, 0);
1031 MSG_WriteByte(&net_message
, CCREP_ACCEPT
);
1032 dfunc
.GetSocketAddr(s
->socket
, &newaddr
);
1033 MSG_WriteLong(&net_message
, dfunc
.GetSocketPort(&newaddr
));
1034 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
1035 dfunc
.Write (acceptsock
, net_message
.data
, net_message
.cursize
, &clientaddr
);
1036 SZ_Clear(&net_message
);
1039 // it's somebody coming back in from a crash/disconnect
1040 // so close the old qsocket and let their retry get them back in
1046 // allocate a QSocket
1047 sock
= NET_NewQSocket ();
1050 // no room; try to let him know
1051 SZ_Clear(&net_message
);
1052 // save space for the header, filled in later
1053 MSG_WriteLong(&net_message
, 0);
1054 MSG_WriteByte(&net_message
, CCREP_REJECT
);
1055 MSG_WriteString(&net_message
, "Server is full.\n");
1056 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
1057 dfunc
.Write (acceptsock
, net_message
.data
, net_message
.cursize
, &clientaddr
);
1058 SZ_Clear(&net_message
);
1062 // allocate a network socket
1063 newsock
= dfunc
.OpenSocket(0);
1066 NET_FreeQSocket(sock
);
1070 // connect to the client
1071 if (dfunc
.Connect (newsock
, &clientaddr
) == -1)
1073 dfunc
.CloseSocket(newsock
);
1074 NET_FreeQSocket(sock
);
1078 // everything is allocated, just fill in the details
1079 sock
->socket
= newsock
;
1080 sock
->landriver
= net_landriverlevel
;
1081 sock
->addr
= clientaddr
;
1082 Q_strcpy(sock
->address
, dfunc
.AddrToString(&clientaddr
));
1084 // send him back the info about the server connection he has been allocated
1085 SZ_Clear(&net_message
);
1086 // save space for the header, filled in later
1087 MSG_WriteLong(&net_message
, 0);
1088 MSG_WriteByte(&net_message
, CCREP_ACCEPT
);
1089 dfunc
.GetSocketAddr(newsock
, &newaddr
);
1090 MSG_WriteLong(&net_message
, dfunc
.GetSocketPort(&newaddr
));
1091 // MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
1092 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
1093 dfunc
.Write (acceptsock
, net_message
.data
, net_message
.cursize
, &clientaddr
);
1094 SZ_Clear(&net_message
);
1099 qsocket_t
*Datagram_CheckNewConnections (void)
1101 qsocket_t
*ret
= NULL
;
1103 for (net_landriverlevel
= 0; net_landriverlevel
< net_numlandrivers
; net_landriverlevel
++)
1104 if (net_landrivers
[net_landriverlevel
].initialized
)
1105 if ((ret
= _Datagram_CheckNewConnections ()) != NULL
)
1111 static void _Datagram_SearchForHosts (qboolean xmit
)
1116 struct qsockaddr readaddr
;
1117 struct qsockaddr myaddr
;
1120 dfunc
.GetSocketAddr (dfunc
.controlSock
, &myaddr
);
1123 SZ_Clear(&net_message
);
1124 // save space for the header, filled in later
1125 MSG_WriteLong(&net_message
, 0);
1126 MSG_WriteByte(&net_message
, CCREQ_SERVER_INFO
);
1127 MSG_WriteString(&net_message
, "QUAKE");
1128 MSG_WriteByte(&net_message
, NET_PROTOCOL_VERSION
);
1129 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
1130 dfunc
.Broadcast(dfunc
.controlSock
, net_message
.data
, net_message
.cursize
);
1131 SZ_Clear(&net_message
);
1134 while ((ret
= dfunc
.Read (dfunc
.controlSock
, net_message
.data
, net_message
.maxsize
, &readaddr
)) > 0)
1136 if (ret
< sizeof(int))
1138 net_message
.cursize
= ret
;
1140 // don't answer our own query
1141 if (dfunc
.AddrCompare(&readaddr
, &myaddr
) >= 0)
1144 // is the cache full?
1145 if (hostCacheCount
== HOSTCACHESIZE
)
1148 MSG_BeginReading ();
1149 control
= BigLong(*((int *)net_message
.data
));
1153 if ((control
& (~NETFLAG_LENGTH_MASK
)) != NETFLAG_CTL
)
1155 if ((control
& NETFLAG_LENGTH_MASK
) != ret
)
1158 if (MSG_ReadByte() != CCREP_SERVER_INFO
)
1161 dfunc
.GetAddrFromName(MSG_ReadString(), &readaddr
);
1162 // search the cache for this server
1163 for (n
= 0; n
< hostCacheCount
; n
++)
1164 if (dfunc
.AddrCompare(&readaddr
, &hostcache
[n
].addr
) == 0)
1167 // is it already there?
1168 if (n
< hostCacheCount
)
1173 Q_strcpy(hostcache
[n
].name
, MSG_ReadString());
1174 Q_strcpy(hostcache
[n
].map
, MSG_ReadString());
1175 hostcache
[n
].users
= MSG_ReadByte();
1176 hostcache
[n
].maxusers
= MSG_ReadByte();
1177 if (MSG_ReadByte() != NET_PROTOCOL_VERSION
)
1179 Q_strcpy(hostcache
[n
].cname
, hostcache
[n
].name
);
1180 hostcache
[n
].cname
[14] = 0;
1181 Q_strcpy(hostcache
[n
].name
, "*");
1182 Q_strcat(hostcache
[n
].name
, hostcache
[n
].cname
);
1184 Q_memcpy(&hostcache
[n
].addr
, &readaddr
, sizeof(struct qsockaddr
));
1185 hostcache
[n
].driver
= net_driverlevel
;
1186 hostcache
[n
].ldriver
= net_landriverlevel
;
1187 Q_strcpy(hostcache
[n
].cname
, dfunc
.AddrToString(&readaddr
));
1189 // check for a name conflict
1190 for (i
= 0; i
< hostCacheCount
; i
++)
1194 if (Q_strcasecmp (hostcache
[n
].name
, hostcache
[i
].name
) == 0)
1196 i
= Q_strlen(hostcache
[n
].name
);
1197 if (i
< 15 && hostcache
[n
].name
[i
-1] > '8')
1199 hostcache
[n
].name
[i
] = '0';
1200 hostcache
[n
].name
[i
+1] = 0;
1203 hostcache
[n
].name
[i
-1]++;
1210 void Datagram_SearchForHosts (qboolean xmit
)
1212 for (net_landriverlevel
= 0; net_landriverlevel
< net_numlandrivers
; net_landriverlevel
++)
1214 if (hostCacheCount
== HOSTCACHESIZE
)
1216 if (net_landrivers
[net_landriverlevel
].initialized
)
1217 _Datagram_SearchForHosts (xmit
);
1222 static qsocket_t
*_Datagram_Connect (char *host
)
1224 struct qsockaddr sendaddr
;
1225 struct qsockaddr readaddr
;
1234 // see if we can resolve the host name
1235 if (dfunc
.GetAddrFromName(host
, &sendaddr
) == -1)
1238 newsock
= dfunc
.OpenSocket (0);
1242 sock
= NET_NewQSocket ();
1245 sock
->socket
= newsock
;
1246 sock
->landriver
= net_landriverlevel
;
1248 // connect to the host
1249 if (dfunc
.Connect (newsock
, &sendaddr
) == -1)
1252 // send the connection request
1253 Con_Printf("trying...\n"); SCR_UpdateScreen ();
1254 start_time
= net_time
;
1256 for (reps
= 0; reps
< 3; reps
++)
1258 SZ_Clear(&net_message
);
1259 // save space for the header, filled in later
1260 MSG_WriteLong(&net_message
, 0);
1261 MSG_WriteByte(&net_message
, CCREQ_CONNECT
);
1262 MSG_WriteString(&net_message
, "QUAKE");
1263 MSG_WriteByte(&net_message
, NET_PROTOCOL_VERSION
);
1264 *((int *)net_message
.data
) = BigLong(NETFLAG_CTL
| (net_message
.cursize
& NETFLAG_LENGTH_MASK
));
1265 dfunc
.Write (newsock
, net_message
.data
, net_message
.cursize
, &sendaddr
);
1266 SZ_Clear(&net_message
);
1269 ret
= dfunc
.Read (newsock
, net_message
.data
, net_message
.maxsize
, &readaddr
);
1270 // if we got something, validate it
1273 // is it from the right place?
1274 if (sfunc
.AddrCompare(&readaddr
, &sendaddr
) != 0)
1277 Con_Printf("wrong reply address\n");
1278 Con_Printf("Expected: %s\n", StrAddr (&sendaddr
));
1279 Con_Printf("Received: %s\n", StrAddr (&readaddr
));
1280 SCR_UpdateScreen ();
1286 if (ret
< sizeof(int))
1292 net_message
.cursize
= ret
;
1293 MSG_BeginReading ();
1295 control
= BigLong(*((int *)net_message
.data
));
1302 if ((control
& (~NETFLAG_LENGTH_MASK
)) != NETFLAG_CTL
)
1307 if ((control
& NETFLAG_LENGTH_MASK
) != ret
)
1313 sceKernelDelayThread(10);
1315 while (ret
== 0 && (SetNetTime() - start_time
) < 5.5);
1318 Con_Printf("still trying...\n"); SCR_UpdateScreen ();
1319 start_time
= SetNetTime();
1324 reason
= "No Response";
1325 Con_Printf("%s\n", reason
);
1326 Q_strcpy(m_return_reason
, reason
);
1332 reason
= "Network Error";
1333 Con_Printf("%s\n", reason
);
1334 Q_strcpy(m_return_reason
, reason
);
1338 ret
= MSG_ReadByte();
1339 if (ret
== CCREP_REJECT
)
1341 reason
= MSG_ReadString();
1343 Q_strncpy(m_return_reason
, reason
, 31);
1347 if (ret
== CCREP_ACCEPT
)
1349 Q_memcpy(&sock
->addr
, &sendaddr
, sizeof(struct qsockaddr
));
1350 dfunc
.SetSocketPort (&sock
->addr
, MSG_ReadLong());
1354 reason
= "Bad Response";
1355 Con_Printf("%s\n", reason
);
1356 Q_strcpy(m_return_reason
, reason
);
1360 dfunc
.GetNameFromAddr (&sendaddr
, sock
->address
);
1362 Con_Printf ("Connection accepted\n");
1363 sock
->lastMessageTime
= SetNetTime();
1365 // switch the connection to the specified address
1366 if (dfunc
.Connect (newsock
, &sock
->addr
) == -1)
1368 reason
= "Connect to Game failed";
1369 Con_Printf("%s\n", reason
);
1370 Q_strcpy(m_return_reason
, reason
);
1374 m_return_onerror
= false;
1378 NET_FreeQSocket(sock
);
1380 dfunc
.CloseSocket(newsock
);
1381 if (m_return_onerror
)
1383 key_dest
= key_menu
;
1384 m_state
= m_return_state
;
1385 m_return_onerror
= false;
1390 qsocket_t
*Datagram_Connect (char *host
)
1392 qsocket_t
*ret
= NULL
;
1394 for (net_landriverlevel
= 0; net_landriverlevel
< net_numlandrivers
; net_landriverlevel
++)
1395 if (net_landrivers
[net_landriverlevel
].initialized
)
1396 if ((ret
= _Datagram_Connect (host
)) != NULL
)