DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
netconn.c File Reference
#include "quakedef.h"
#include "thread.h"
#include "lhnet.h"
#include "hmac.h"
#include "mdfour.h"
#include <time.h>
+ Include dependency graph for netconn.c:

Go to the source code of this file.

Macros

#define DPMASTER_COUNT   sizeof(sv_masters) / sizeof(cvar_t)
 
#define DPMASTER_PORT   27950
 
#define QWMASTER_COUNT   sizeof(sv_qwmasters) / sizeof(cvar_t)
 
#define QWMASTER_PORT   27000
 

Typedefs

typedef qbool(* rcon_matchfunc_t) (lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
 

Functions

static qbool hmac_mdfour_challenge_matching (lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
 
static qbool hmac_mdfour_time_matching (lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
 
static void Net_Heartbeat_f (cmd_state_t *cmd)
 
void Net_Stats_f (cmd_state_t *cmd)
 
static int NetConn_AddCryptoFlag (crypto_t *crypto)
 
static void NetConn_BuildChallengeString (char *buffer, int bufferlength)
 
static qbool NetConn_BuildStatusResponse (const char *challenge, char *out_msg, size_t out_size, qbool fullstatus)
 (div0) build the full response only if possible; better a getinfo response than no response at all if getstatus won't fit
 
qbool NetConn_CanSend (netconn_t *conn)
 
lhnetsocket_tNetConn_ChooseClientSocketForAddress (lhnetaddress_t *address)
 
lhnetsocket_tNetConn_ChooseServerSocketForAddress (lhnetaddress_t *address)
 
static void NetConn_CL_UpdateSockets_Callback (cvar_t *var)
 
void NetConn_ClearFlood (lhnetaddress_t *peeraddress, server_floodaddress_t *floodlist, size_t floodlength)
 
void NetConn_ClientFrame (void)
 
static int NetConn_ClientParsePacket (lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress)
 
void NetConn_Close (netconn_t *conn)
 
void NetConn_CloseClientPorts (void)
 
void NetConn_CloseServerPorts (void)
 
static void NetConn_ConnectionEstablished (lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, protocolversion_t initialprotocol)
 
qbool NetConn_HaveClientPorts (void)
 
qbool NetConn_HaveServerPorts (void)
 
void NetConn_Heartbeat (int priority)
 
void NetConn_Init (void)
 
int NetConn_IsLocalGame (void)
 
netconn_tNetConn_Open (lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress)
 
static void NetConn_OpenClientPort (const char *addressstring, lhnetaddresstype_t addresstype, int defaultport)
 
void NetConn_OpenClientPorts (void)
 
static qbool NetConn_OpenServerPort (const char *addressstring, lhnetaddresstype_t addresstype, int defaultport, int range)
 
void NetConn_OpenServerPorts (int opennetports)
 
static qbool NetConn_PreventFlood (lhnetaddress_t *peeraddress, server_floodaddress_t *floodlist, size_t floodlength, double floodtime, qbool renew)
 
int NetConn_Read (lhnetsocket_t *mysocket, void *data, int maxlength, lhnetaddress_t *peeraddress)
 
static int NetConn_ReceivedMessage (netconn_t *conn, const unsigned char *data, size_t length, protocolversion_t protocol, double newtimeout)
 
int NetConn_SendUnreliableMessage (netconn_t *conn, sizebuf_t *data, protocolversion_t protocol, int rate, int burstsize, qbool quakesignon_suppressreliables)
 
void NetConn_ServerFrame (void)
 
static int NetConn_ServerParsePacket (lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress)
 
void NetConn_Shutdown (void)
 
static void NetConn_sv_netport_Callback (cvar_t *var)
 
static void NetConn_UpdateCleartime (double *cleartime, int rate, int burstsize, int len)
 
void NetConn_UpdateSockets (void)
 
int NetConn_Write (lhnetsocket_t *mysocket, const void *data, int length, const lhnetaddress_t *peeraddress)
 
int NetConn_WriteString (lhnetsocket_t *mysocket, const char *string, const lhnetaddress_t *peeraddress)
 
static qbool plaintext_matching (lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
 
static void PrintStats (netconn_t *conn)
 
static const char * RCon_Authenticate (lhnetaddress_t *peeraddress, const char *password, const char *s, const char *endpos, rcon_matchfunc_t comparator, const char *cs, int cslen)
 returns a string describing the user level, or NULL for auth failure
 
static void RCon_Execute (lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const char *addressstring2, const char *userlevel, const char *s, const char *endpos, qbool proquakeprotocol)
 

Variables

challenge_t challenges [MAX_CHALLENGES]
 
sizebuf_t cl_message
 
static unsigned char cl_message_buf [NET_MAXMESSAGE]
 
char cl_net_extresponse [NET_EXTRESPONSE_MAX][1400]
 
unsigned cl_net_extresponse_count = 0
 
unsigned cl_net_extresponse_last = 0
 
cvar_t cl_netport = {CF_CLIENT, "cl_port", "0", "forces client to use chosen port number if not 0"}
 
static unsigned cl_numsockets
 
char cl_readstring [MAX_INPUTLINE]
 
static lhnetsocket_tcl_sockets [16]
 
static int clientport = -1
 
static int clientport2 = -1
 
cvar_t developer_networking = {CF_CLIENT | CF_SERVER, "developer_networking", "0", "prints all received and sent packets (recommended only for debugging)"}
 
static cvar_t gameversion = {CF_SERVER, "gameversion", "0", "version of game data (mod-specific) to be sent to querying clients"}
 
static cvar_t gameversion_max = {CF_CLIENT | CF_SERVER, "gameversion_max", "-1", "maximum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"}
 
static cvar_t gameversion_min = {CF_CLIENT | CF_SERVER, "gameversion_min", "-1", "minimum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"}
 
cvar_t hostname = {CF_SERVER | CF_ARCHIVE, "hostname", "UNNAMED", "server message to show in server browser"}
 
static int hostport = -1
 
unsigned masterquerycount = 0
 
double masterquerytime = -1000
 
unsigned masterreplycount = 0
 
cvar_t net_address = {CF_CLIENT | CF_SERVER, "net_address", "", "network address to open ipv4 ports on (if empty, use default interfaces)"}
 
cvar_t net_address_ipv6 = {CF_CLIENT | CF_SERVER, "net_address_ipv6", "", "network address to open ipv6 ports on (if empty, use default interfaces)"}
 
cvar_t net_burstreserve = {CF_SERVER, "net_burstreserve", "0.3", "how much of the burst time to reserve for packet size spikes"}
 
cvar_t net_challengefloodblockingtimeout = {CF_SERVER, "net_challengefloodblockingtimeout", "0.5", "when a challenge packet is received, it will block all future challenge packets from that IP address for this many seconds (cuts down on challenge floods). DarkPlaces clients retry once per second, so this should be <= 1. Failure here may lead to connect attempts failing."}
 
cvar_t net_connect_entnum_ofs = {CF_SERVER, "net_connect_entnum_ofs", "0", "entity number offset of human clients (for developer testing only)"}
 
cvar_t net_connectfloodblockingtimeout = {CF_SERVER, "net_connectfloodblockingtimeout", "5", "when a connection packet is received, it will block all future connect packets from that IP address for this many seconds (cuts down on connect floods). Note that this does not include retries from the same IP; these are handled earlier and let in."}
 
cvar_t net_connecttimeout = {CF_CLIENT | CF_SERVER, "net_connecttimeout","15", "after requesting a connection, the client must reply within this many seconds or be dropped (cuts down on connect floods). Must be above 10 seconds."}
 
cvar_t net_fakelag = {CF_CLIENT, "net_fakelag","0", "lags local loopback connection by this much ping time (useful to play more fairly on your own server with people with higher pings)"}
 
static cvar_t net_fakeloss_receive = {CF_CLIENT, "net_fakeloss_receive","0", "drops this percentage of incoming packets, useful for testing network protocol robustness (jerky movement, effects failing to start, sounds failing to play, etc)"}
 
static cvar_t net_fakeloss_send = {CF_CLIENT, "net_fakeloss_send","0", "drops this percentage of outgoing packets, useful for testing network protocol robustness (jerky movement, prediction errors, etc)"}
 
cvar_t net_getstatusfloodblockingtimeout = {CF_SERVER, "net_getstatusfloodblockingtimeout", "1", "when a getstatus packet is received, it will block all future getstatus packets from that IP address for this many seconds (cuts down on getstatus floods). DarkPlaces retries every net_slist_timeout seconds, and qstat retries once per second, so this should be <= 1. Failure here may lead to server not showing up in the server list."}
 
cvar_t net_messagetimeout = {CF_CLIENT | CF_SERVER, "net_messagetimeout","300", "drops players who have not sent any packets for this many seconds"}
 
cvar_t net_sourceaddresscheck = {CF_CLIENT, "net_sourceaddresscheck", "1", "compare the source IP address for replies (more secure, may break some bad multihoming setups"}
 
cvar_t net_test = {CF_CLIENT | CF_SERVER, "net_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"}
 
static cvar_t net_tos_dscp = {CF_CLIENT | CF_ARCHIVE, "net_tos_dscp", "32", "DiffServ Codepoint for network sockets (may need game restart to apply)"}
 
cvar_t net_usesizelimit = {CF_SERVER, "net_usesizelimit", "2", "use packet size limiting (0: never, 1: in non-CSQC mode, 2: always)"}
 
netconn_tnetconn_list = NULL
 
mempool_tnetconn_mempool = NULL
 
voidnetconn_mutex = NULL
 
static double nextheartbeattime = 0
 
static cvar_t rcon_restricted_commands = {CF_SERVER, "rcon_restricted_commands", "", "allowed commands for rcon when the restricted mode password was used"}
 
static cvar_t rcon_restricted_password = {CF_SERVER | CF_PRIVATE, "rcon_restricted_password", "", "password to authenticate rcon commands in restricted mode; may be set to a string of the form user1:pass1 user2:pass2 user3:pass3 to allow multiple user accounts - the client then has to specify ONE of these combinations"}
 
cvar_t rcon_secure
 
cvar_t rcon_secure_challengetimeout
 
static cvar_t rcon_secure_maxdiff = {CF_SERVER, "rcon_secure_maxdiff", "5", "maximum time difference between rcon request and server system clock (to protect against replay attack)"}
 
uint8_t serverlist_querystage = 0
 bitfield because in theory we could be doing QW & DP simultaneously
 
unsigned serverquerycount = 0
 
unsigned serverreplycount = 0
 
static cvar_t sv_heartbeatperiod = {CF_SERVER | CF_ARCHIVE, "sv_heartbeatperiod", "120", "how often to send heartbeat in seconds (only used if sv_public is 1)"}
 
static cvar_t sv_masters []
 
sizebuf_t sv_message
 
static unsigned char sv_message_buf [NET_MAXMESSAGE]
 
char sv_net_extresponse [NET_EXTRESPONSE_MAX][1400]
 
unsigned sv_net_extresponse_count = 0
 
unsigned sv_net_extresponse_last = 0
 
cvar_t sv_netport = {CF_SERVER, "port", "26000", "server port for players to connect to"}
 
static unsigned sv_numsockets
 
cvar_t sv_public = {CF_SERVER, "sv_public", "0", "1: advertises this server on the master server (so that players can find it in the server browser); 0: allow direct queries only; -1: do not respond to direct queries; -2: do not allow anyone to connect; -3: already block at getchallenge level"}
 
cvar_t sv_public_rejectreason = {CF_SERVER, "sv_public_rejectreason", "The server is closing.", "Rejection reason for connects when sv_public is -2"}
 
char sv_readstring [MAX_INPUTLINE]
 
static lhnetsocket_tsv_sockets [16]
 
cvar_t sv_status_privacy
 

Macro Definition Documentation

◆ DPMASTER_COUNT

#define DPMASTER_COUNT   sizeof(sv_masters) / sizeof(cvar_t)

Definition at line 125 of file netconn.c.

Referenced by NetConn_Heartbeat(), and NetConn_Init().

◆ DPMASTER_PORT

#define DPMASTER_PORT   27950

Definition at line 33 of file netconn.c.

Referenced by NetConn_Heartbeat().

◆ QWMASTER_COUNT

#define QWMASTER_COUNT   sizeof(sv_qwmasters) / sizeof(cvar_t)

Definition at line 126 of file netconn.c.

Referenced by NetConn_Init().

◆ QWMASTER_PORT

#define QWMASTER_PORT   27000

Definition at line 32 of file netconn.c.

Typedef Documentation

◆ rcon_matchfunc_t

typedef qbool(* rcon_matchfunc_t) (lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)

Definition at line 2986 of file netconn.c.

Function Documentation

◆ hmac_mdfour_challenge_matching()

static qbool hmac_mdfour_challenge_matching ( lhnetaddress_t * peeraddress,
const char * password,
const char * hash,
const char * s,
int slen )
static

Definition at line 3009 of file netconn.c.

3010{
3011 char mdfourbuf[16];
3012 int i;
3013
3014 if (!password[0]) {
3015 Con_Print(CON_ERROR "LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
3016 return false;
3017 }
3018
3019 if(slen < (int)(sizeof(challenges[0].string)) - 1)
3020 return false;
3021
3022 // validate the challenge
3023 for (i = 0;i < MAX_CHALLENGES;i++)
3024 if(challenges[i].time > 0)
3025 if (!LHNETADDRESS_Compare(peeraddress, &challenges[i].address) && !strncmp(challenges[i].string, s, sizeof(challenges[0].string) - 1))
3026 break;
3027 // if the challenge is not recognized, drop the packet
3028 if (i == MAX_CHALLENGES)
3029 return false;
3030
3031 if(!HMAC_MDFOUR_16BYTES((unsigned char *) mdfourbuf, (unsigned char *) s, slen, (unsigned char *) password, (int)strlen(password)))
3032 return false;
3033
3034 if(memcmp(mdfourbuf, hash, 16))
3035 return false;
3036
3037 // unmark challenge to prevent replay attacks
3038 challenges[i].time = 0;
3039
3040 return true;
3041}
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
#define CON_ERROR
Definition console.h:102
float time
#define HMAC_MDFOUR_16BYTES(out, in, n, key, k)
Definition hmac.h:14
int LHNETADDRESS_Compare(const lhnetaddress_t *vaddress1, const lhnetaddress_t *vaddress2)
Definition lhnet.c:665
float strlen(string s)
challenge_t challenges[MAX_CHALLENGES]
Definition netconn.c:123
#define MAX_CHALLENGES
Definition netconn.h:476
int i
double time
Definition netconn.h:480

References challenges, CON_ERROR, Con_Print(), HMAC_MDFOUR_16BYTES, i, LHNETADDRESS_Compare(), MAX_CHALLENGES, strlen(), challenge_t::time, and time.

Referenced by NetConn_ServerParsePacket().

◆ hmac_mdfour_time_matching()

static qbool hmac_mdfour_time_matching ( lhnetaddress_t * peeraddress,
const char * password,
const char * hash,
const char * s,
int slen )
static

Definition at line 2988 of file netconn.c.

2989{
2990 char mdfourbuf[16];
2991 long t1, t2;
2992
2993 if (!password[0]) {
2994 Con_Print(CON_ERROR "LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
2995 return false;
2996 }
2997
2998 t1 = (long) time(NULL);
2999 t2 = strtol(s, NULL, 0);
3000 if(labs(t1 - t2) > rcon_secure_maxdiff.integer)
3001 return false;
3002
3003 if(!HMAC_MDFOUR_16BYTES((unsigned char *) mdfourbuf, (unsigned char *) s, slen, (unsigned char *) password, (int)strlen(password)))
3004 return false;
3005
3006 return !memcmp(mdfourbuf, hash, 16);
3007}
static cvar_t rcon_secure_maxdiff
Definition netconn.c:113
#define NULL
Definition qtypes.h:12
int integer
Definition cvar.h:73

References CON_ERROR, Con_Print(), HMAC_MDFOUR_16BYTES, cvar_t::integer, NULL, rcon_secure_maxdiff, strlen(), and time.

Referenced by NetConn_ServerParsePacket().

◆ Net_Heartbeat_f()

static void Net_Heartbeat_f ( cmd_state_t * cmd)
static

Definition at line 4017 of file netconn.c.

4018{
4019 if (sv.active)
4021 else
4022 Con_Print("No server running, can not heartbeat to master server.\n");
4023}
void NetConn_Heartbeat(int priority)
Definition netconn.c:3984
server_t sv
local server
Definition sv_main.c:223
qbool active
false if only a net client
Definition server.h:66

References server_t::active, Con_Print(), NetConn_Heartbeat(), and sv.

Referenced by NetConn_Init().

◆ Net_Stats_f()

void Net_Stats_f ( cmd_state_t * cmd)

Definition at line 4042 of file netconn.c.

4043{
4044 netconn_t *conn;
4045 Con_Print("connections =\n");
4046 for (conn = netconn_list;conn;conn = conn->next)
4047 PrintStats(conn);
4048}
static void PrintStats(netconn_t *conn)
Definition netconn.c:4025
netconn_t * netconn_list
Definition netconn.c:151
struct netconn_s * next
Definition netconn.h:144

References Con_Print(), netconn_list, netconn_t::next, and PrintStats().

Referenced by NetConn_Init().

◆ NetConn_AddCryptoFlag()

static int NetConn_AddCryptoFlag ( crypto_t * crypto)
static

Definition at line 823 of file netconn.c.

824{
825 // HACK: if an encrypted connection is used, randomly set some unused
826 // flags. When AES encryption is enabled, that will make resends differ
827 // from the original, so that e.g. substring filters in a router/IPS
828 // are unlikely to match a second time. See also "startkeylogger".
829 int flag = 0;
830 if (crypto->authenticated)
831 {
832 // Let's always set at least one of the bits.
833 int r = rand() % 7 + 1;
834 if (r & 1)
835 flag |= NETFLAG_CRYPTO0;
836 if (r & 2)
837 flag |= NETFLAG_CRYPTO1;
838 if (r & 4)
839 flag |= NETFLAG_CRYPTO2;
840 }
841 return flag;
842}
#define NETFLAG_CRYPTO0
Definition netconn.h:41
#define NETFLAG_CRYPTO1
Definition netconn.h:42
#define NETFLAG_CRYPTO2
Definition netconn.h:43
dp_FragColor r
qbool authenticated
Definition crypto.h:50

References crypto_t::authenticated, NETFLAG_CRYPTO0, NETFLAG_CRYPTO1, NETFLAG_CRYPTO2, and r.

Referenced by NetConn_ReceivedMessage(), and NetConn_SendUnreliableMessage().

◆ NetConn_BuildChallengeString()

static void NetConn_BuildChallengeString ( char * buffer,
int bufferlength )
static

Definition at line 2741 of file netconn.c.

2742{
2743 int i;
2744 char c;
2745 for (i = 0;i < bufferlength - 1;i++)
2746 {
2747 do
2748 {
2749 c = rand () % (127 - 33) + 33;
2750 } while (c == '\\' || c == ';' || c == '"' || c == '%' || c == '/');
2751 buffer[i] = c;
2752 }
2753 buffer[i] = 0;
2754}
GLuint buffer
Definition glquake.h:630

References buffer, and i.

Referenced by NetConn_ServerParsePacket().

◆ NetConn_BuildStatusResponse()

static qbool NetConn_BuildStatusResponse ( const char * challenge,
char * out_msg,
size_t out_size,
qbool fullstatus )
static

(div0) build the full response only if possible; better a getinfo response than no response at all if getstatus won't fit

\TODO: we should add more information for the full status string

Definition at line 2757 of file netconn.c.

2758{
2759 prvm_prog_t *prog = SVVM_prog;
2760 char qcstatus[256];
2761 unsigned int nb_clients = 0, nb_bots = 0, i;
2762 int length;
2763 char teambuf[3];
2764 const char *crypto_idstring;
2765 const char *worldstatusstr;
2766
2767 // How many clients are there?
2768 for (i = 0;i < (unsigned int)svs.maxclients;i++)
2769 {
2770 if (svs.clients[i].active)
2771 {
2772 nb_clients++;
2773 if (!svs.clients[i].netconnection)
2774 nb_bots++;
2775 }
2776 }
2777
2778 *qcstatus = 0;
2779 worldstatusstr = PRVM_GetString(prog, PRVM_serverglobalstring(worldstatus));
2780 if(worldstatusstr && *worldstatusstr)
2781 {
2782 char *p;
2783 const char *q;
2784 p = qcstatus;
2785 for(q = worldstatusstr; *q && (size_t)(p - qcstatus) < (sizeof(qcstatus) - 1); ++q)
2786 if(*q != '\\' && *q != '\n')
2787 *p++ = *q;
2788 *p = 0;
2789 }
2790
2793 length = dpsnprintf(out_msg, out_size,
2794 "\377\377\377\377%s\x0A"
2795 "\\gamename\\%s\\modname\\%s\\gameversion\\%d\\sv_maxclients\\%d"
2796 "\\clients\\%d\\bots\\%d\\mapname\\%s\\hostname\\%s\\protocol\\%d"
2797 "%s%s"
2798 "%s%s"
2799 "%s%s"
2800 "%s",
2801 fullstatus ? "statusResponse" : "infoResponse",
2803 nb_clients, nb_bots, sv.worldbasename, hostname.string, NET_PROTOCOL_VERSION,
2804 *qcstatus ? "\\qcstatus\\" : "", qcstatus,
2805 challenge ? "\\challenge\\" : "", challenge ? challenge : "",
2806 crypto_idstring ? "\\d0_blind_id\\" : "", crypto_idstring ? crypto_idstring : "",
2807 fullstatus ? "\n" : "");
2808
2809 // Make sure it fits in the buffer
2810 if (length < 0)
2811 goto bad;
2812
2813 if (fullstatus)
2814 {
2815 char *ptr;
2816 int left;
2817 int savelength;
2818
2819 savelength = length;
2820
2821 ptr = out_msg + length;
2822 left = (int)out_size - length;
2823
2824 for (i = 0;i < (unsigned int)svs.maxclients;i++)
2825 {
2826 client_t *client = &svs.clients[i];
2827 if (client->active)
2828 {
2829 int nameind, cleanind, pingvalue;
2830 char curchar;
2831 char cleanname [sizeof(client->name)];
2832 const char *statusstr;
2833 prvm_edict_t *ed;
2834
2835 // Remove all characters '"' and '\' in the player name
2836 nameind = 0;
2837 cleanind = 0;
2838 do
2839 {
2840 curchar = client->name[nameind++];
2841 if (curchar != '"' && curchar != '\\')
2842 {
2843 cleanname[cleanind++] = curchar;
2844 if (cleanind == sizeof(cleanname) - 1)
2845 break;
2846 }
2847 } while (curchar != '\0');
2848 cleanname[cleanind] = 0; // cleanind is always a valid index even at this point
2849
2850 pingvalue = (int)(client->ping * 1000.0f);
2851 if(client->netconnection)
2852 pingvalue = bound(1, pingvalue, 9999);
2853 else
2854 pingvalue = 0;
2855
2856 *qcstatus = 0;
2857 ed = PRVM_EDICT_NUM(i + 1);
2858 statusstr = PRVM_GetString(prog, PRVM_serveredictstring(ed, clientstatus));
2859 if(statusstr && *statusstr)
2860 {
2861 char *p;
2862 const char *q;
2863 p = qcstatus;
2864 for(q = statusstr; *q && p != qcstatus + sizeof(qcstatus) - 1; ++q)
2865 if(*q != '\\' && *q != '"' && !ISWHITESPACE(*q))
2866 *p++ = *q;
2867 *p = 0;
2868 }
2869
2870 if (IS_NEXUIZ_DERIVED(gamemode) && (teamplay.integer > 0))
2871 {
2872 if(client->frags == -666) // spectator
2873 dp_strlcpy(teambuf, " 0", sizeof(teambuf));
2874 else if(client->colors == 0x44) // red team
2875 dp_strlcpy(teambuf, " 1", sizeof(teambuf));
2876 else if(client->colors == 0xDD) // blue team
2877 dp_strlcpy(teambuf, " 2", sizeof(teambuf));
2878 else if(client->colors == 0xCC) // yellow team
2879 dp_strlcpy(teambuf, " 3", sizeof(teambuf));
2880 else if(client->colors == 0x99) // pink team
2881 dp_strlcpy(teambuf, " 4", sizeof(teambuf));
2882 else
2883 dp_strlcpy(teambuf, " 0", sizeof(teambuf));
2884 }
2885 else
2886 *teambuf = 0;
2887
2888 // note: team number is inserted according to SoF2 protocol
2889 if(*qcstatus)
2890 length = dpsnprintf(ptr, left, "%s %d%s \"%s\"\n",
2891 qcstatus,
2892 pingvalue,
2893 teambuf,
2894 cleanname);
2895 else
2896 length = dpsnprintf(ptr, left, "%d %d%s \"%s\"\n",
2897 client->frags,
2898 pingvalue,
2899 teambuf,
2900 cleanname);
2901
2902 if(length < 0)
2903 {
2904 // out of space?
2905 // turn it into an infoResponse!
2906 out_msg[savelength] = 0;
2907 memcpy(out_msg + 4, "infoResponse\x0A", 13);
2908 memmove(out_msg + 17, out_msg + 19, savelength - 19);
2909 break;
2910 }
2911 left -= length;
2912 ptr += length;
2913 }
2914 }
2915 }
2916
2917 return true;
2918
2919bad:
2920 return false;
2921}
char com_modname[MAX_OSPATH]
Definition com_game.c:33
gamemode_t gamemode
Definition com_game.c:26
const char * gamenetworkfiltername
Definition com_game.c:28
#define IS_NEXUIZ_DERIVED(g)
Definition com_game.h:71
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
static const char * crypto_idstring
Definition crypto.c:42
const char * Crypto_GetInfoResponseDataString(void)
Definition crypto.c:1689
string clientstatus
string worldstatus
static int(ZEXPORT *qz_inflate)(z_stream *strm
GLenum GLuint GLenum GLsizei length
Definition glquake.h:657
#define bound(min, num, max)
Definition mathlib.h:34
static cvar_t gameversion
Definition netconn.c:108
cvar_t hostname
Definition netconn.c:88
#define NET_PROTOCOL_VERSION
Definition netconn.h:47
float teamplay
Definition progsdefs.qc:31
#define PRVM_EDICT_NUM(n)
Definition progsvm.h:867
const char * PRVM_GetString(prvm_prog_t *prog, int num)
#define PRVM_serverglobalstring(fieldname)
Definition progsvm.h:179
#define PRVM_serveredictstring(ed, fieldname)
Definition progsvm.h:174
#define SVVM_prog
Definition progsvm.h:766
#define ISWHITESPACE(ch)
Definition qdefs.h:184
server_static_t svs
persistant server info
Definition sv_main.c:224
qbool active
false = empty client slot
Definition server.h:185
int colors
Definition server.h:236
int frags
Definition server.h:237
char name[MAX_SCOREBOARDNAME]
Definition server.h:235
netconn_t * netconnection
communications handle
Definition server.h:210
float ping
LadyHavoc: can be used for prediction or whatever...
Definition server.h:224
const char * string
Definition cvar.h:71
struct client_s * clients
client slots
Definition server.h:30
int maxclients
number of svs.clients slots (updated by maxplayers command)
Definition server.h:28
char worldbasename[MAX_QPATH]
Definition server.h:109

References client_t::active, bound, server_static_t::clients, clientstatus, client_t::colors, com_modname, Crypto_GetInfoResponseDataString(), crypto_idstring, dp_strlcpy, dpsnprintf(), client_t::frags, gamemode, gamenetworkfiltername, gameversion, hostname, i, int(), cvar_t::integer, IS_NEXUIZ_DERIVED, ISWHITESPACE, length, server_static_t::maxclients, client_t::name, NET_PROTOCOL_VERSION, client_t::netconnection, client_t::ping, PRVM_EDICT_NUM, PRVM_GetString(), PRVM_serveredictstring, PRVM_serverglobalstring, cvar_t::string, sv, svs, SVVM_prog, teamplay, server_t::worldbasename, and worldstatus.

Referenced by NetConn_ServerParsePacket().

◆ NetConn_CanSend()

qbool NetConn_CanSend ( netconn_t * conn)

Definition at line 789 of file netconn.c.

790{
797 if (host.realtime > conn->cleartime)
798 return true;
799 else
800 {
802 return false;
803 }
804}
host_static_t host
Definition host.c:41
#define NETGRAPH_NOPACKET
Definition netconn.h:223
#define NETGRAPH_PACKETS
Definition netconn.h:222
#define NETGRAPH_CHOKEDPACKET
Definition netconn.h:225
double realtime
the accumulated mainloop time since application started (with filtering), without any slowmo or clamp...
Definition host.h:46
int outgoing_packetcounter
Definition netconn.h:228
double cleartime
Definition netconn.h:217
netgraphitem_t outgoing_netgraph[NETGRAPH_PACKETS]
Definition netconn.h:229
double time
Definition netconn.h:134
double cleartime
Definition netconn.h:138
int unreliablebytes
Definition netconn.h:136
int reliablebytes
Definition netconn.h:135

References netgraphitem_t::ackbytes, netconn_t::cleartime, netgraphitem_t::cleartime, host, NETGRAPH_CHOKEDPACKET, NETGRAPH_NOPACKET, NETGRAPH_PACKETS, netconn_t::outgoing_netgraph, netconn_t::outgoing_packetcounter, host_static_t::realtime, netgraphitem_t::reliablebytes, netgraphitem_t::time, and netgraphitem_t::unreliablebytes.

Referenced by CL_SendMove(), and SV_SendClientDatagram().

◆ NetConn_ChooseClientSocketForAddress()

lhnetsocket_t * NetConn_ChooseClientSocketForAddress ( lhnetaddress_t * address)

Definition at line 1198 of file netconn.c.

1199{
1200 unsigned i;
1202
1203 for (i = 0;i < cl_numsockets;i++)
1205 return cl_sockets[i];
1206 return NULL;
1207}
lhnetaddress_t * LHNET_AddressFromSocket(lhnetsocket_t *sock)
Definition lhnet.c:1026
lhnetaddresstype_t
Definition lhnet.h:11
static lhnetaddresstype_t LHNETADDRESS_GetAddressType(const lhnetaddress_t *address)
Definition lhnet.h:31
static lhnetsocket_t * cl_sockets[16]
Definition netconn.c:147
static unsigned cl_numsockets
Definition netconn.c:146
ret a

References a, cl_numsockets, cl_sockets, i, LHNET_AddressFromSocket(), LHNETADDRESS_GetAddressType(), and NULL.

Referenced by CL_EstablishConnection(), CL_Packet_f(), CL_PQRcon_f(), CL_Rcon_f(), and Log_DestBuffer_Flush_NoLock().

◆ NetConn_ChooseServerSocketForAddress()

lhnetsocket_t * NetConn_ChooseServerSocketForAddress ( lhnetaddress_t * address)

Definition at line 1209 of file netconn.c.

1210{
1211 unsigned i;
1213
1214 for (i = 0;i < sv_numsockets;i++)
1216 return sv_sockets[i];
1217 return NULL;
1218}
static unsigned sv_numsockets
Definition netconn.c:148
static lhnetsocket_t * sv_sockets[16]
Definition netconn.c:149

References a, i, LHNET_AddressFromSocket(), LHNETADDRESS_GetAddressType(), NULL, sv_numsockets, and sv_sockets.

Referenced by CL_Packet_f(), Log_DestBuffer_Flush_NoLock(), and NetConn_Heartbeat().

◆ NetConn_CL_UpdateSockets_Callback()

static void NetConn_CL_UpdateSockets_Callback ( cvar_t * var)
static

Definition at line 1272 of file netconn.c.

1273{
1274 if(cls.state != ca_dedicated)
1275 {
1276 if (clientport2 != var->integer)
1277 {
1278 clientport2 = var->integer;
1279 if (cls.state == ca_connected)
1280 Con_Print("Changing \"cl_port\" will not take effect until you reconnect.\n");
1281 }
1282
1284 {
1287 }
1288 if (cl_numsockets == 0)
1290 }
1291}
client_static_t cls
Definition cl_main.c:116
@ ca_dedicated
Definition client.h:530
@ ca_connected
Definition client.h:532
@ ca_disconnected
Definition client.h:531
void NetConn_OpenClientPorts(void)
Definition netconn.c:1098
static int clientport
Definition netconn.c:1268
static int clientport2
Definition netconn.c:1269
void NetConn_CloseClientPorts(void)
Definition netconn.c:1062
cactive_t state
Definition client.h:568

References ca_connected, ca_dedicated, ca_disconnected, cl_numsockets, clientport, clientport2, cls, Con_Print(), cvar_t::integer, NetConn_CloseClientPorts(), NetConn_OpenClientPorts(), and client_static_t::state.

Referenced by NetConn_Init().

◆ NetConn_ClearFlood()

void NetConn_ClearFlood ( lhnetaddress_t * peeraddress,
server_floodaddress_t * floodlist,
size_t floodlength )

Definition at line 2966 of file netconn.c.

2967{
2968 size_t floodslotnum;
2969 lhnetaddress_t noportpeeraddress;
2970 // see if this is a connect flood
2971 noportpeeraddress = *peeraddress;
2972 LHNETADDRESS_SetPort(&noportpeeraddress, 0);
2973 for (floodslotnum = 0;floodslotnum < floodlength;floodslotnum++)
2974 {
2975 if (floodlist[floodslotnum].lasttime && LHNETADDRESS_Compare(&noportpeeraddress, &floodlist[floodslotnum].address) == 0)
2976 {
2977 // this address matches an ongoing flood address
2978 // remove the ban
2979 floodlist[floodslotnum].address.addresstype = LHNETADDRESSTYPE_NONE;
2980 floodlist[floodslotnum].lasttime = 0;
2981 //Con_Printf("Flood cleared!\n");
2982 }
2983 }
2984}
int LHNETADDRESS_SetPort(lhnetaddress_t *vaddress, int port)
Definition lhnet.c:642
@ LHNETADDRESSTYPE_NONE
Definition lhnet.h:12
lhnetaddresstype_t addresstype
Definition lhnet.h:21
lhnetaddress_t address
Definition server.h:59

References server_floodaddress_t::address, lhnetaddress_t::addresstype, server_floodaddress_t::lasttime, LHNETADDRESS_Compare(), LHNETADDRESS_SetPort(), and LHNETADDRESSTYPE_NONE.

Referenced by NetConn_Close().

◆ NetConn_ClientFrame()

void NetConn_ClientFrame ( void )

Definition at line 2674 of file netconn.c.

2675{
2676 unsigned i;
2677 int length;
2678 lhnetaddress_t peeraddress;
2679 unsigned char readbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
2680
2682
2684 {
2686 {
2688 dpsnprintf(cl_connect_status, sizeof(cl_connect_status), "Connect: sending initial request, %i %s left...", cls.connect_remainingtries, cls.connect_remainingtries == 1 ? "retry" : "retries");
2689 }
2690 else
2691 {
2692 char address[128];
2693
2694 cls.connect_trying = false;
2695 LHNETADDRESS_ToString(&cls.connect_address, address, sizeof(address), true);
2696 dp_strlcpy(cl_connect_status, "Connect: failed, no reply", sizeof(cl_connect_status));
2697 Con_Printf(CON_ERROR "%s from %s\n", cl_connect_status, address);
2698 return;
2699 }
2701
2702 // try challenge first (newer DP server or QW)
2703 NetConn_WriteString(cls.connect_mysocket, "\377\377\377\377getchallenge", &cls.connect_address);
2704 // then try netquake as a fallback (old server, or netquake)
2706 // save space for the header, filled in later
2709 MSG_WriteString(&cl_message, "QUAKE");
2711 // extended proquake stuff
2712 MSG_WriteByte(&cl_message, 1); // mod = MOD_PROQUAKE
2713 // this version matches ProQuake 3.40, the first version to support
2714 // the NAT fix, and it only supports the NAT fix for ProQuake 3.40 or
2715 // higher clients, so we pretend we are that version...
2716 MSG_WriteByte(&cl_message, 34); // version * 10
2717 MSG_WriteByte(&cl_message, 0); // flags
2718 MSG_WriteLong(&cl_message, 0); // password
2719 // write the packetsize now...
2723 }
2724
2725 for (i = 0;i < cl_numsockets;i++)
2726 {
2727 while (cl_sockets[i] && (length = NetConn_Read(cl_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0)
2728 {
2729// R_TimeReport("clientreadnetwork");
2730 NetConn_ClientParsePacket(cl_sockets[i], readbuffer, length, &peeraddress);
2731// R_TimeReport("clientparsepacket");
2732 }
2733 }
2734#ifdef CONFIG_MENU
2735 NetConn_QueryQueueFrame();
2736#endif
2738 CL_DisconnectEx(true, "Connection timed out");
2739}
void CL_DisconnectEx(qbool kicked, const char *fmt,...)
Definition cl_main.c:370
char cl_connect_status[MAX_QPATH]
User-friendly connection status for the menu and/or loading screen, colours and not supported.
Definition cl_screen.c:1573
void MSG_WriteString(sizebuf_t *sb, const char *s)
Definition com_msg.c:173
void MSG_WriteLong(sizebuf_t *sb, int c)
Definition com_msg.c:147
void MSG_WriteByte(sizebuf_t *sb, int c)
Definition com_msg.c:130
void StoreBigLong(unsigned char *buffer, unsigned int i)
Encode a big endian 32bit int to the given buffer.
Definition com_msg.c:81
void SZ_Clear(sizebuf_t *buf)
Definition common.c:44
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
int LHNETADDRESS_ToString(const lhnetaddress_t *vaddress, char *string, int stringbuffersize, int includeport)
Returns the number of bytes written to *string excluding the \0 terminator.
Definition lhnet.c:540
int NetConn_Write(lhnetsocket_t *mysocket, const void *data, int length, const lhnetaddress_t *peeraddress)
Definition netconn.c:758
int NetConn_WriteString(lhnetsocket_t *mysocket, const char *string, const lhnetaddress_t *peeraddress)
Definition netconn.c:783
int NetConn_Read(lhnetsocket_t *mysocket, void *data, int maxlength, lhnetaddress_t *peeraddress)
Definition netconn.c:726
sizebuf_t cl_message
Definition netconn.c:71
void NetConn_UpdateSockets(void)
Definition netconn.c:1306
static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress)
Definition netconn.c:2019
#define NETFLAG_CTL
Definition netconn.h:44
#define NET_HEADERSIZE
Definition netconn.h:32
#define NETFLAG_LENGTH_MASK
Definition netconn.h:35
#define CCREQ_CONNECT
Definition netconn.h:119
#define NET_MAXMESSAGE
max reliable packet size (sent as multiple fragments of MAX_PACKETFRAGMENT)
Definition qdefs.h:103
qbool connect_trying
Definition client.h:609
int connect_remainingtries
Definition client.h:610
netconn_t * netcon
Definition client.h:630
double connect_nextsendtime
Definition client.h:611
lhnetaddress_t connect_address
Definition client.h:613
lhnetsocket_t * connect_mysocket
Definition client.h:612
double timeout
Definition netconn.h:153
unsigned char * data
Definition common.h:52
int cursize
Definition common.h:54

References server_t::active, CCREQ_CONNECT, cl_connect_status, CL_DisconnectEx(), cl_message, cl_numsockets, cl_sockets, cls, CON_ERROR, Con_Printf(), client_static_t::connect_address, client_static_t::connect_mysocket, client_static_t::connect_nextsendtime, client_static_t::connect_remainingtries, client_static_t::connect_trying, sizebuf_t::cursize, sizebuf_t::data, dp_strlcpy, dpsnprintf(), host, i, length, LHNETADDRESS_ToString(), MSG_WriteByte(), MSG_WriteLong(), MSG_WriteString(), NET_HEADERSIZE, NET_MAXMESSAGE, NET_PROTOCOL_VERSION, client_static_t::netcon, NetConn_ClientParsePacket(), NetConn_Read(), NetConn_UpdateSockets(), NetConn_Write(), NetConn_WriteString(), NETFLAG_CTL, NETFLAG_LENGTH_MASK, host_static_t::realtime, StoreBigLong(), sv, SZ_Clear(), and netconn_t::timeout.

Referenced by CL_Frame(), and CL_KeepaliveMessage().

◆ NetConn_ClientParsePacket()

static int NetConn_ClientParsePacket ( lhnetsocket_t * mysocket,
unsigned char * data,
int length,
lhnetaddress_t * peeraddress )
static

Definition at line 2019 of file netconn.c.

2020{
2021 qbool fromserver;
2022 int ret, c;
2023 char *string, addressstring2[128];
2024 char stringbuf[16384];
2026 size_t sendlength;
2027#ifdef CONFIG_MENU
2028 char infostringvalue[MAX_INPUTLINE];
2029#endif
2030
2031 // quakeworld ingame packet
2032 fromserver = cls.netcon && mysocket == cls.netcon->mysocket && !LHNETADDRESS_Compare(&cls.netcon->peeraddress, peeraddress);
2033
2034 // convert the address to a string incase we need it
2035 LHNETADDRESS_ToString(peeraddress, addressstring2, sizeof(addressstring2), true);
2036
2037 if (length >= 5 && data[0] == 255 && data[1] == 255 && data[2] == 255 && data[3] == 255)
2038 {
2039 // received a command string - strip off the packaging and put it
2040 // into our string buffer with NULL termination
2041 data += 4;
2042 length -= 4;
2043 length = min(length, (int)sizeof(stringbuf) - 1);
2044 memcpy(stringbuf, data, length);
2045 stringbuf[length] = 0;
2046 string = stringbuf;
2047
2049 {
2050 Con_Printf("NetConn_ClientParsePacket: %s sent us a command:\n", addressstring2);
2052 }
2053
2054 sendlength = sizeof(senddata) - 4;
2055 switch(Crypto_ClientParsePacket(string, length, senddata+4, &sendlength, peeraddress, addressstring2))
2056 {
2057 case CRYPTO_NOMATCH:
2058 // nothing to do
2059 break;
2060 case CRYPTO_MATCH:
2061 if(sendlength)
2062 {
2063 memcpy(senddata, "\377\377\377\377", 4);
2064 NetConn_Write(mysocket, senddata, (int)sendlength+4, peeraddress);
2065 }
2066 break;
2067 case CRYPTO_DISCARD:
2068 if(sendlength)
2069 {
2070 memcpy(senddata, "\377\377\377\377", 4);
2071 NetConn_Write(mysocket, senddata, (int)sendlength+4, peeraddress);
2072 }
2073 return true;
2074 break;
2075 case CRYPTO_REPLACE:
2076 string = senddata+4;
2077 length = (int)sendlength;
2078 break;
2079 }
2080
2081 if (length >= 10 && !memcmp(string, "challenge ", 10) && cls.rcon_trying)
2082 {
2083 int i = 0, j;
2084 for (j = 0;j < MAX_RCONS;j++)
2085 {
2086 // note: this value from i is used outside the loop too...
2087 i = (cls.rcon_ringpos + j) % MAX_RCONS;
2088 if(cls.rcon_commands[i][0])
2089 if (!LHNETADDRESS_Compare(peeraddress, &cls.rcon_addresses[i]))
2090 break;
2091 }
2092 if (j < MAX_RCONS)
2093 {
2094 char buf[1500];
2095 char argbuf[1500];
2096 const char *e;
2097 int n;
2098 dpsnprintf(argbuf, sizeof(argbuf), "%s %s", string + 10, cls.rcon_commands[i]);
2099 memcpy(buf, "\377\377\377\377srcon HMAC-MD4 CHALLENGE ", 29);
2100
2101 e = strchr(rcon_password.string, ' ');
2103
2104 if(HMAC_MDFOUR_16BYTES((unsigned char *) (buf + 29), (unsigned char *) argbuf, (int)strlen(argbuf), (unsigned char *) rcon_password.string, n))
2105 {
2106 int k;
2107 buf[45] = ' ';
2108 dp_strlcpy(buf + 46, argbuf, sizeof(buf) - 46);
2109 NetConn_Write(mysocket, buf, 46 + (int)strlen(buf + 46), peeraddress);
2110 cls.rcon_commands[i][0] = 0;
2111 --cls.rcon_trying;
2112
2113 for (k = 0;k < MAX_RCONS;k++)
2114 if(cls.rcon_commands[k][0])
2115 if (!LHNETADDRESS_Compare(peeraddress, &cls.rcon_addresses[k]))
2116 break;
2117 if(k < MAX_RCONS)
2118 {
2119 int l;
2120 NetConn_WriteString(mysocket, "\377\377\377\377getchallenge", peeraddress);
2121 // extend the timeout on other requests as we asked for a challenge
2122 for (l = 0;l < MAX_RCONS;l++)
2123 if(cls.rcon_commands[l][0])
2124 if (!LHNETADDRESS_Compare(peeraddress, &cls.rcon_addresses[l]))
2126 }
2127
2128 return true; // we used up the challenge, so we can't use this oen for connecting now anyway
2129 }
2130 }
2131 }
2132 if (length >= 10 && !memcmp(string, "challenge ", 10) && cls.connect_trying)
2133 {
2134 // darkplaces or quake3
2135 char protocolnames[1400];
2136
2138 Con_Printf(CON_WARN "ignoring challenge message from wrong server %s\n", addressstring2);
2139 return true;
2140 }
2141 Con_DPrintf("\"%s\" received, sending connect request back to %s\n", string, addressstring2);
2142 dp_strlcpy(cl_connect_status, "Connect: replying to challenge...", sizeof(cl_connect_status));
2143
2144 Protocol_Names(protocolnames, sizeof(protocolnames));
2145 // update the server IP in the userinfo (QW servers expect this, and it is used by the reconnect command)
2146 InfoString_SetValue(cls.userinfo, sizeof(cls.userinfo), "*ip", addressstring2);
2147 // TODO: add userinfo stuff here instead of using NQ commands?
2148 memcpy(senddata, "\377\377\377\377", 4);
2149 dpsnprintf(senddata+4, sizeof(senddata)-4, "connect\\protocol\\darkplaces 3\\protocols\\%s%s\\challenge\\%s", protocolnames, cls.connect_userinfo, string + 10);
2150 NetConn_WriteString(mysocket, senddata, peeraddress);
2151 return true;
2152 }
2153 if (length == 6 && !memcmp(string, "accept", 6) && cls.connect_trying)
2154 {
2155 // darkplaces or quake3
2157 Con_Printf(CON_WARN "ignoring accept message from wrong server %s\n", addressstring2);
2158 return true;
2159 }
2161 return true;
2162 }
2163 if (length > 7 && !memcmp(string, "reject ", 7) && cls.connect_trying)
2164 {
2166 Con_Printf(CON_WARN "ignoring reject message from wrong server %s\n", addressstring2);
2167 return true;
2168 }
2169 cls.connect_trying = false;
2170 string += 7;
2171 length = min(length - 7, (int)sizeof(cl_connect_status) - 1);
2172 dpsnprintf(cl_connect_status, sizeof(cl_connect_status), "Connect: rejected, %.*s", length, string);
2173 Con_Printf(CON_ERROR "Connect: rejected by %s\n" CON_ERROR "%.*s\n", addressstring2, length, string);
2174 return true;
2175 }
2176#ifdef CONFIG_MENU
2177 if(key_dest != key_game)
2178 {
2179 if (length >= 15 && !memcmp(string, "statusResponse\x0A", 15))
2180 {
2181 serverlist_info_t *info;
2182 char *p;
2183 int n;
2184
2185 string += 15;
2186 // search the cache for this server and update it
2187 // the challenge is (ab)used to return the query time
2188 InfoString_GetValue(string, "challenge", infostringvalue, sizeof(infostringvalue));
2189 n = NetConn_ClientParsePacket_ServerList_ProcessReply(addressstring2, infostringvalue);
2190 if (n < 0)
2191 return true;
2192
2193 info = &serverlist_cache[n].info;
2194 p = strchr(string, '\n');
2195 if(p)
2196 {
2197 *p = 0; // cut off the string there
2198 ++p;
2199 info->players_len = dp_strlcpy(info->players, p, sizeof(info->players));
2200 }
2201 else
2202 {
2203 Con_Printf("statusResponse without players block?\n");
2204 info->players_len = info->players[0] = 0;
2205 }
2206 info->game_len = InfoString_GetValue(string, "gamename", info->game, sizeof(info->game));
2207 info->mod_len = InfoString_GetValue(string, "modname", info->mod, sizeof(info->mod));
2208 info->map_len = InfoString_GetValue(string, "mapname", info->map, sizeof(info->map));
2209 info->name_len = InfoString_GetValue(string, "hostname", info->name, sizeof(info->name));
2210 info->qcstatus_len = InfoString_GetValue(string, "qcstatus", info->qcstatus, sizeof(info->qcstatus));
2211 info->protocol = InfoString_GetValue(string, "protocol" , infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : -1;
2212 info->numplayers = InfoString_GetValue(string, "clients" , infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : 0;
2213 info->numbots = InfoString_GetValue(string, "bots" , infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : -1;
2214 info->maxplayers = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : 0;
2215 info->gameversion = InfoString_GetValue(string, "gameversion" , infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : 0;
2216 info->numhumans = info->numplayers - max(0, info->numbots);
2217 info->freeslots = info->maxplayers - info->numplayers;
2218
2219 NetConn_ClientParsePacket_ServerList_UpdateCache(n);
2220
2221 return true;
2222 }
2223 if (length >= 13 && !memcmp(string, "infoResponse\x0A", 13))
2224 {
2225 serverlist_info_t *info;
2226 int n;
2227
2228 string += 13;
2229 // search the cache for this server and update it
2230 // the challenge is (ab)used to return the query time
2231 InfoString_GetValue(string, "challenge", infostringvalue, sizeof(infostringvalue));
2232 n = NetConn_ClientParsePacket_ServerList_ProcessReply(addressstring2, infostringvalue);
2233 if (n < 0)
2234 return true;
2235
2236 info = &serverlist_cache[n].info;
2237 info->players_len = info->players[0] = 0;
2238 info->game_len = InfoString_GetValue(string, "gamename", info->game, sizeof(info->game));
2239 info->mod_len = InfoString_GetValue(string, "modname", info->mod, sizeof(info->mod));
2240 info->map_len = InfoString_GetValue(string, "mapname", info->map, sizeof(info->map));
2241 info->name_len = InfoString_GetValue(string, "hostname", info->name, sizeof(info->name));
2242 info->qcstatus_len = InfoString_GetValue(string, "qcstatus", info->qcstatus, sizeof(info->qcstatus));
2243 info->protocol = InfoString_GetValue(string, "protocol" , infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : -1;
2244 info->numplayers = InfoString_GetValue(string, "clients" , infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : 0;
2245 info->numbots = InfoString_GetValue(string, "bots" , infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : -1;
2246 info->maxplayers = InfoString_GetValue(string, "sv_maxclients", infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : 0;
2247 info->gameversion = InfoString_GetValue(string, "gameversion" , infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : 0;
2248 info->numhumans = info->numplayers - max(0, info->numbots);
2249 info->freeslots = info->maxplayers - info->numplayers;
2250
2251 NetConn_ClientParsePacket_ServerList_UpdateCache(n);
2252
2253 return true;
2254 }
2255 if (!strncmp(string, "getserversResponse\\", 19) && serverlist_cachecount < SERVERLIST_TOTALSIZE)
2256 {
2257 // Extract the IP addresses
2258 data += 18;
2259 length -= 18;
2260 NetConn_ClientParsePacket_ServerList_ParseDPList(peeraddress, addressstring2, data, length, false);
2261 return true;
2262 }
2263 if (!strncmp(string, "getserversExtResponse", 21) && serverlist_cachecount < SERVERLIST_TOTALSIZE)
2264 {
2265 // Extract the IP addresses
2266 data += 21;
2267 length -= 21;
2268 NetConn_ClientParsePacket_ServerList_ParseDPList(peeraddress, addressstring2, data, length, true);
2269 return true;
2270 }
2271 if (!memcmp(string, "d\n", 2) && serverlist_cachecount < SERVERLIST_TOTALSIZE)
2272 {
2273 // Extract the IP addresses
2274 data += 2;
2275 length -= 2;
2276 NetConn_ClientParsePacket_ServerList_ParseQWList(peeraddress, addressstring2, data, length);
2277 return true;
2278 }
2279 }
2280#endif
2281 if (!strncmp(string, "extResponse ", 12))
2282 {
2287 dpsnprintf(cl_net_extresponse[cl_net_extresponse_last], sizeof(cl_net_extresponse[cl_net_extresponse_last]), "\"%s\" %s", addressstring2, string + 12);
2288 return true;
2289 }
2290 if (!strncmp(string, "ping", 4))
2291 {
2293 Con_DPrintf("Received ping from %s, sending ack\n", addressstring2);
2294 NetConn_WriteString(mysocket, "\377\377\377\377ack", peeraddress);
2295 return true;
2296 }
2297 if (!strncmp(string, "ack", 3))
2298 return true;
2299 // QuakeWorld compatibility
2300 if (length > 1 && string[0] == 'c' && (string[1] == '-' || (string[1] >= '0' && string[1] <= '9')) && cls.connect_trying)
2301 {
2302 // challenge message
2304 Con_Printf(CON_WARN "ignoring c message from wrong server %s\n", addressstring2);
2305 return true;
2306 }
2307 Con_DPrintf("challenge %s received, sending QuakeWorld connect request back to %s\n", string + 1, addressstring2);
2308 dp_strlcpy(cl_connect_status, "Connect: replying to challenge...", sizeof(cl_connect_status));
2309
2311 // update the server IP in the userinfo (QW servers expect this, and it is used by the reconnect command)
2312 InfoString_SetValue(cls.userinfo, sizeof(cls.userinfo), "*ip", addressstring2);
2313 memcpy(senddata, "\377\377\377\377", 4);
2314 dpsnprintf(senddata+4, sizeof(senddata)-4, "connect %i %i %i \"%s%s\"\n", 28, cls.qw_qport, atoi(string + 1), cls.userinfo, cls.connect_userinfo);
2315 NetConn_WriteString(mysocket, senddata, peeraddress);
2316 return true;
2317 }
2318 if (length >= 1 && string[0] == 'j' && cls.connect_trying)
2319 {
2320 // accept message
2322 Con_Printf(CON_WARN "ignoring j message from wrong server %s\n", addressstring2);
2323 return true;
2324 }
2325 NetConn_ConnectionEstablished(mysocket, peeraddress, PROTOCOL_QUAKEWORLD);
2326 return true;
2327 }
2328 if (length > 2 && !memcmp(string, "n\\", 2))
2329 {
2330#ifdef CONFIG_MENU
2331 serverlist_info_t *info;
2332 int n;
2333 const char *s;
2334
2335 // qw server status
2336 if (serverlist_consoleoutput && developer_networking.integer >= 2)
2337 Con_Printf("QW server status from server at %s:\n%s\n", addressstring2, string + 1);
2338
2339 string += 1;
2340 // search the cache for this server and update it
2341 n = NetConn_ClientParsePacket_ServerList_ProcessReply(addressstring2, NULL);
2342 if (n < 0)
2343 return true;
2344
2345 info = &serverlist_cache[n].info;
2346 dp_strlcpy(info->game, "QuakeWorld", sizeof(info->game));
2347 info->mod_len = InfoString_GetValue(string, "*gamedir", info->mod, sizeof(info->mod));
2348 info->map_len = InfoString_GetValue(string, "map" , info->map, sizeof(info->map));
2349 info->name_len = InfoString_GetValue(string, "hostname", info->name, sizeof(info->name));
2350 info->protocol = 0;
2351 info->numplayers = 0; // updated below
2352 info->numhumans = 0; // updated below
2353 info->maxplayers = InfoString_GetValue(string, "maxclients" , infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : 0;
2354 info->gameversion = InfoString_GetValue(string, "gameversion", infostringvalue, sizeof(infostringvalue)) ? atoi(infostringvalue) : 0;
2355
2356 // count active players on server
2357 // (we could gather more info, but we're just after the number)
2358 s = strchr(string, '\n');
2359 if (s)
2360 {
2361 s++;
2362 while (s < string + length)
2363 {
2364 for (;s < string + length && *s != '\n';s++)
2365 ;
2366 if (s >= string + length)
2367 break;
2368 info->numplayers++;
2369 info->numhumans++;
2370 s++;
2371 }
2372 }
2373
2374 NetConn_ClientParsePacket_ServerList_UpdateCache(n);
2375#endif
2376 return true;
2377 }
2378 if (string[0] == 'n')
2379 {
2380 // qw print command, used by rcon replies too
2382 Con_Printf(CON_WARN "ignoring n message from wrong server %s\n", addressstring2);
2383 return true;
2384 }
2385 Con_Printf("QW print command from server at %s:\n%s\n", addressstring2, string + 1);
2386 }
2387 // we may not have liked the packet, but it was a command packet, so
2388 // we're done processing this packet now
2389 return true;
2390 }
2391 // quakeworld ingame packet
2393 {
2394 ret = 0;
2396 return ret;
2397 }
2398 // netquake control packets, supported for compatibility only
2399 if (length >= 5 && BuffBigLong(data) == ((int)NETFLAG_CTL | length) && !ENCRYPTION_REQUIRED)
2400 {
2401#ifdef CONFIG_MENU
2402 int n;
2403 serverlist_info_t *info;
2404#endif
2405
2406 data += 4;
2407 length -= 4;
2412 switch (c)
2413 {
2414 case CCREP_ACCEPT:
2416 Con_DPrintf("Datagram_ParseConnectionless: received CCREP_ACCEPT from %s.\n", addressstring2);
2417 if (cls.connect_trying)
2418 {
2419 lhnetaddress_t clientportaddress;
2421 Con_Printf(CON_WARN "ignoring CCREP_ACCEPT message from wrong server %s\n", addressstring2);
2422 break;
2423 }
2424 clientportaddress = *peeraddress;
2425 LHNETADDRESS_SetPort(&clientportaddress, MSG_ReadLong(&cl_message));
2426 // extra ProQuake stuff
2427 if (length >= 6)
2428 cls.proquake_servermod = MSG_ReadByte(&cl_message); // MOD_PROQUAKE
2429 else
2431 if (length >= 7)
2433 else
2435 if (length >= 8)
2436 cls.proquake_serverflags = MSG_ReadByte(&cl_message); // flags (mainly PQF_CHEATFREE)
2437 else
2439 if (cls.proquake_servermod == 1)
2440 Con_Printf("Connected to ProQuake %.1f server, enabling precise aim\n", cls.proquake_serverversion / 10.0f);
2441 // update the server IP in the userinfo (QW servers expect this, and it is used by the reconnect command)
2442 InfoString_SetValue(cls.userinfo, sizeof(cls.userinfo), "*ip", addressstring2);
2443 NetConn_ConnectionEstablished(mysocket, &clientportaddress, PROTOCOL_QUAKE);
2444 }
2445 break;
2446 case CCREP_REJECT:
2448 {
2449 Con_Printf(CON_WARN "ignoring CCREP_REJECT message from wrong server %s\n", addressstring2);
2450 break;
2451 }
2452 cls.connect_trying = false;
2454 Con_Printf(CON_ERROR "Connect: rejected by %s\n%s\n", addressstring2, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)));
2455 break;
2456 case CCREP_SERVER_INFO:
2458 Con_DPrintf("Datagram_ParseConnectionless: received CCREP_SERVER_INFO from %s.\n", addressstring2);
2459#ifdef CONFIG_MENU
2460 // LadyHavoc: because the quake server may report weird addresses
2461 // we just ignore it and keep the real address
2463 // search the cache for this server and update it
2464 n = NetConn_ClientParsePacket_ServerList_ProcessReply(addressstring2, NULL);
2465 if (n < 0)
2466 break;
2467
2468 info = &serverlist_cache[n].info;
2469 info->game_len = dp_strlcpy(info->game, "Quake", sizeof(info->game));
2470 info->mod_len = dp_strlcpy(info->mod, "", sizeof(info->mod)); // mod name is not specified
2471 info->name_len = dp_strlcpy(info->name, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(info->name));
2472 info->map_len = dp_strlcpy(info->map, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof(info->map));
2473 info->numplayers = MSG_ReadByte(&cl_message);
2474 info->maxplayers = MSG_ReadByte(&cl_message);
2475 info->protocol = MSG_ReadByte(&cl_message);
2476
2477 NetConn_ClientParsePacket_ServerList_UpdateCache(n);
2478#endif
2479 break;
2480 case CCREP_RCON: // RocketGuy: ProQuake rcon support
2482 Con_Printf(CON_WARN "ignoring CCREP_RCON message from wrong server %s\n", addressstring2);
2483 break;
2484 }
2486 Con_DPrintf("Datagram_ParseConnectionless: received CCREP_RCON from %s.\n", addressstring2);
2487
2489 break;
2490 case CCREP_PLAYER_INFO:
2491 // we got a CCREP_PLAYER_INFO??
2492 //if (developer_extra.integer)
2493 Con_Printf("Datagram_ParseConnectionless: received CCREP_PLAYER_INFO from %s.\n", addressstring2);
2494 break;
2495 case CCREP_RULE_INFO:
2496 // we got a CCREP_RULE_INFO??
2497 //if (developer_extra.integer)
2498 Con_Printf("Datagram_ParseConnectionless: received CCREP_RULE_INFO from %s.\n", addressstring2);
2499 break;
2500 default:
2501 break;
2502 }
2504 // we may not have liked the packet, but it was a valid control
2505 // packet, so we're done processing this packet now
2506 return true;
2507 }
2508 ret = 0;
2511 return ret;
2512}
cvar_t qport
Definition cl_main.c:90
void CL_ParseServerMessage(void)
Definition cl_parse.c:3435
cvar_t rcon_password
Definition console.c:89
#define MAX_RCONS
Definition client.h:619
void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, const char *value)
size_t InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuesize)
Returns the number of bytes written to *value excluding the \0 terminator.
void MSG_BeginReading(sizebuf_t *sb)
Definition com_msg.c:257
char * MSG_ReadString(sizebuf_t *sb, char *string, size_t maxstring)
Definition com_msg.c:341
int BuffBigLong(const unsigned char *buffer)
Extract a big endian 32bit int from the given buffer.
Definition com_msg.c:49
void Com_HexDumpToConsole(const unsigned char *data, int size)
Definition common.c:82
void SZ_Write(sizebuf_t *buf, const unsigned char *data, int length)
Definition common.c:72
@ PROTOCOL_DARKPLACES3
uses EntityFrame4 entity snapshot encoder/decoder which is broken, this attempted to do partial snaps...
Definition common.h:139
@ PROTOCOL_QUAKE
quake (aka netquake/normalquake/nq) protocol
Definition common.h:144
@ PROTOCOL_QUAKEWORLD
quakeworld protocol
Definition common.h:145
#define MSG_ReadLong
Definition common.h:192
#define MSG_ReadByte(sb)
Definition common.h:188
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
#define CON_WARN
Definition console.h:101
int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out, size_t *len_out, lhnetaddress_t *peeraddress, const char *peeraddressstring)
Definition crypto.c:2107
#define CRYPTO_DISCARD
Definition crypto.h:66
#define CRYPTO_HEADERSIZE
Definition crypto.h:34
#define CRYPTO_MATCH
Definition crypto.h:65
#define CRYPTO_REPLACE
Definition crypto.h:67
#define CRYPTO_NOMATCH
Definition crypto.h:64
#define ENCRYPTION_REQUIRED
Definition crypto.h:30
#define n(x, y)
GLsizei const GLchar ** string
Definition glquake.h:728
GLsizeiptr const GLvoid * data
Definition glquake.h:639
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657
cvar_t developer_extra
Definition host.c:49
keydest_t key_dest
Definition keys.c:37
@ key_game
Definition keys.h:372
#define max(A, B)
Definition mathlib.h:38
#define min(A, B)
Definition mathlib.h:37
cvar_t net_messagetimeout
Definition netconn.c:81
unsigned cl_net_extresponse_last
Definition netconn.c:162
static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, size_t length, protocolversion_t protocol, double newtimeout)
Definition netconn.c:1331
char cl_readstring[MAX_INPUTLINE]
Definition netconn.c:75
cvar_t developer_networking
Definition netconn.c:89
cvar_t rcon_secure_challengetimeout
Definition console.c:91
unsigned cl_net_extresponse_count
Definition netconn.c:161
char cl_net_extresponse[NET_EXTRESPONSE_MAX][1400]
Definition netconn.c:160
cvar_t net_sourceaddresscheck
Definition netconn.c:87
static void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, protocolversion_t initialprotocol)
Definition netconn.c:1641
#define CCREP_SERVER_INFO
Definition netconn.h:127
#define CCREP_ACCEPT
Definition netconn.h:125
#define CCREP_PLAYER_INFO
Definition netconn.h:128
#define NET_EXTRESPONSE_MAX
Definition netconn.h:48
#define CCREP_REJECT
Definition netconn.h:126
#define CCREP_RULE_INFO
Definition netconn.h:129
#define CCREP_RCON
Definition netconn.h:130
void Protocol_Names(char *buffer, size_t buffersize)
Definition protocol.c:104
#define MAX_INPUTLINE
maximum size of console commandline, QuakeC strings, and many other text processing buffers
Definition qdefs.h:94
#define SERVERLIST_TOTALSIZE
max servers in the server list
Definition qdefs.h:160
bool qbool
Definition qtypes.h:9
return ret
char connect_userinfo[MAX_USERINFO_STRING]
Definition client.h:672
int proquake_serverflags
Definition client.h:685
int proquake_serverversion
Definition client.h:684
lhnetaddress_t rcon_addresses[MAX_RCONS]
Definition client.h:621
double rcon_timeout[MAX_RCONS]
Definition client.h:623
lhnetaddress_t rcon_address
Definition client.h:614
int proquake_servermod
Definition client.h:683
char rcon_commands[MAX_RCONS][MAX_INPUTLINE]
Definition client.h:622
protocolversion_t protocol
Definition client.h:617
char userinfo[MAX_USERINFO_STRING]
Definition client.h:669
float value
Definition cvar.h:74
lhnetaddress_t peeraddress
Definition netconn.h:147
lhnetsocket_t * mysocket
Definition netconn.h:146

References buf, BuffBigLong(), CCREP_ACCEPT, CCREP_PLAYER_INFO, CCREP_RCON, CCREP_REJECT, CCREP_RULE_INFO, CCREP_SERVER_INFO, cl_connect_status, cl_message, cl_net_extresponse, cl_net_extresponse_count, cl_net_extresponse_last, CL_ParseServerMessage(), cl_readstring, cls, Com_HexDumpToConsole(), Con_DPrintf(), CON_ERROR, Con_Printf(), CON_WARN, client_static_t::connect_address, client_static_t::connect_trying, client_static_t::connect_userinfo, Crypto_ClientParsePacket(), CRYPTO_DISCARD, CRYPTO_HEADERSIZE, CRYPTO_MATCH, CRYPTO_NOMATCH, CRYPTO_REPLACE, data, developer_extra, developer_networking, dp_strlcpy, dpsnprintf(), ENCRYPTION_REQUIRED, HMAC_MDFOUR_16BYTES, host, i, InfoString_GetValue(), InfoString_SetValue(), int(), cvar_t::integer, key_dest, key_game, length, LHNETADDRESS_Compare(), LHNETADDRESS_SetPort(), LHNETADDRESS_ToString(), max, MAX_INPUTLINE, MAX_RCONS, min, MSG_BeginReading(), MSG_ReadByte, MSG_ReadLong, MSG_ReadString(), netconn_t::mysocket, n, NET_EXTRESPONSE_MAX, NET_HEADERSIZE, NET_MAXMESSAGE, net_messagetimeout, net_sourceaddresscheck, client_static_t::netcon, NetConn_ConnectionEstablished(), NetConn_ReceivedMessage(), NetConn_Write(), NetConn_WriteString(), NETFLAG_CTL, NULL, netconn_t::peeraddress, client_static_t::proquake_serverflags, client_static_t::proquake_servermod, client_static_t::proquake_serverversion, client_static_t::protocol, PROTOCOL_DARKPLACES3, Protocol_Names(), PROTOCOL_QUAKE, PROTOCOL_QUAKEWORLD, qport, client_static_t::qw_qport, client_static_t::rcon_address, client_static_t::rcon_addresses, client_static_t::rcon_commands, rcon_password, client_static_t::rcon_ringpos, rcon_secure_challengetimeout, client_static_t::rcon_timeout, client_static_t::rcon_trying, host_static_t::realtime, ret, SERVERLIST_TOTALSIZE, cvar_t::string, string, strlen(), SZ_Clear(), SZ_Write(), client_static_t::userinfo, and cvar_t::value.

Referenced by NetConn_ClientFrame().

◆ NetConn_Close()

void NetConn_Close ( netconn_t * conn)

Definition at line 1240 of file netconn.c.

1241{
1242 netconn_t *c;
1243 // remove connection from list
1244
1245 // allow the client to reconnect immediately
1247
1248 if (conn == netconn_list)
1249 netconn_list = conn->next;
1250 else
1251 {
1252 for (c = netconn_list;c;c = c->next)
1253 {
1254 if (c->next == conn)
1255 {
1256 c->next = conn->next;
1257 break;
1258 }
1259 }
1260 // not found in list, we'll avoid crashing here...
1261 if (!c)
1262 return;
1263 }
1264 // free connection
1265 Mem_Free(conn);
1266}
void NetConn_ClearFlood(lhnetaddress_t *peeraddress, server_floodaddress_t *floodlist, size_t floodlength)
Definition netconn.c:2966
server_floodaddress_t connectfloodaddresses[MAX_CONNECTFLOODADDRESSES]
connection flood blocking note this is in server_t rather than server_static_t so that it is reset on...
Definition server.h:140
#define Mem_Free(mem)
Definition zone.h:96

References server_t::connectfloodaddresses, Mem_Free, NetConn_ClearFlood(), netconn_list, netconn_t::next, netconn_t::peeraddress, and sv.

Referenced by CL_DisconnectEx(), and SV_DropClient().

◆ NetConn_CloseClientPorts()

void NetConn_CloseClientPorts ( void )

Definition at line 1062 of file netconn.c.

1063{
1064 for (;cl_numsockets > 0;cl_numsockets--)
1065 if (cl_sockets[cl_numsockets - 1])
1067}
void LHNET_CloseSocket(lhnetsocket_t *lhnetsocket)
Definition lhnet.c:1012

References cl_numsockets, cl_sockets, and LHNET_CloseSocket().

Referenced by NetConn_CL_UpdateSockets_Callback(), NetConn_OpenClientPorts(), and NetConn_Shutdown().

◆ NetConn_CloseServerPorts()

void NetConn_CloseServerPorts ( void )

◆ NetConn_ConnectionEstablished()

static void NetConn_ConnectionEstablished ( lhnetsocket_t * mysocket,
lhnetaddress_t * peeraddress,
protocolversion_t initialprotocol )
static

Definition at line 1641 of file netconn.c.

1642{
1643 crypto_t *crypto;
1644
1645 cls.connect_trying = false;
1646 // Disconnect from the current server or stop demo playback
1648 CL_Disconnect();
1649 // allocate a net connection to keep track of things
1650 cls.netcon = NetConn_Open(mysocket, peeraddress);
1651 dp_strlcpy(cl_connect_status, "Connection established", sizeof(cl_connect_status));
1652 crypto = &cls.netcon->crypto;
1654 {
1656 Con_Printf("%s connection to %s has been established: server is %s@%s%.*s, I am %.*s@%s%.*s\n",
1657 crypto->use_aes ? "Encrypted" : "Authenticated",
1659 crypto->server_idfp[0] ? crypto->server_idfp : "-",
1660 (crypto->server_issigned || !crypto->server_keyfp[0]) ? "" : "~",
1661 crypto_keyfp_recommended_length, crypto->server_keyfp[0] ? crypto->server_keyfp : "-",
1662 crypto_keyfp_recommended_length, crypto->client_idfp[0] ? crypto->client_idfp : "-",
1663 (crypto->client_issigned || !crypto->client_keyfp[0]) ? "" : "~",
1665 );
1666 }
1667 else
1669
1671#ifdef CONFIG_MENU
1672 m_state = m_none;
1673#endif
1674 cls.demonum = -1; // not in the demo loop now
1676 cls.signon = 0; // need all the signon messages before playing
1677 cls.protocol = initialprotocol;
1678 // reset move sequence numbering on this new connection
1681 CL_ForwardToServer("new");
1683 {
1684 // write a keepalive (clc_nop) as it seems to greatly improve the
1685 // chances of connecting to a netquake server
1686 sizebuf_t msg;
1687 unsigned char buf[4];
1688 memset(&msg, 0, sizeof(msg));
1689 msg.data = buf;
1690 msg.maxsize = sizeof(buf);
1691 MSG_WriteChar(&msg, clc_nop);
1692 NetConn_SendUnreliableMessage(cls.netcon, &msg, cls.protocol, 10000, 0, false);
1693 }
1694}
void CL_ForwardToServer(const char *s)
adds the string as a clc_stringcmd to the client message.
Definition cl_cmd.c:54
void CL_Disconnect(void)
Definition cl_main.c:478
void MSG_WriteChar(sizebuf_t *sb, int c)
Definition com_msg.c:122
int crypto_keyfp_recommended_length
Definition crypto.c:41
qbool Crypto_FinishInstance(crypto_t *out, crypto_t *crypto)
Definition crypto.c:558
enum m_state_e m_state
Definition menu.c:36
@ m_none
Definition menu.h:28
netconn_t * NetConn_Open(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress)
Definition netconn.c:1220
int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolversion_t protocol, int rate, int burstsize, qbool quakesignon_suppressreliables)
Definition netconn.c:844
#define clc_nop
Definition protocol.h:288
unsigned int servermovesequence
Definition client.h:637
qbool demoplayback
Definition client.h:587
crypto_t crypto
Definition client.h:680
char server_keyfp[FP64_SIZE+1]
Definition crypto.h:48
qbool server_issigned
Definition crypto.h:49
char client_idfp[FP64_SIZE+1]
Definition crypto.h:44
char client_keyfp[FP64_SIZE+1]
Definition crypto.h:45
qbool client_issigned
Definition crypto.h:46
char server_idfp[FP64_SIZE+1]
Definition crypto.h:47
qbool use_aes
Definition crypto.h:51
char address[128]
Definition netconn.h:231
crypto_t crypto
Definition netconn.h:232
int maxsize
Definition common.h:53

References netconn_t::address, crypto_t::authenticated, buf, ca_connected, cl_connect_status, CL_Disconnect(), CL_ForwardToServer(), clc_nop, crypto_t::client_idfp, crypto_t::client_issigned, crypto_t::client_keyfp, cls, Con_Printf(), client_static_t::connect_trying, client_static_t::crypto, netconn_t::crypto, Crypto_FinishInstance(), crypto_keyfp_recommended_length, sizebuf_t::data, client_static_t::demonum, client_static_t::demoplayback, dp_strlcpy, key_dest, key_game, m_none, m_state, sizebuf_t::maxsize, MSG_WriteChar(), client_static_t::netcon, NetConn_Open(), NetConn_SendUnreliableMessage(), client_static_t::protocol, PROTOCOL_QUAKE, PROTOCOL_QUAKEWORLD, crypto_t::server_idfp, crypto_t::server_issigned, crypto_t::server_keyfp, client_static_t::servermovesequence, client_static_t::signon, client_static_t::state, and crypto_t::use_aes.

Referenced by NetConn_ClientParsePacket().

◆ NetConn_HaveClientPorts()

qbool NetConn_HaveClientPorts ( void )

Definition at line 1052 of file netconn.c.

1053{
1054 return !!cl_numsockets;
1055}

References cl_numsockets.

Referenced by Log_DestBuffer_Flush_NoLock().

◆ NetConn_HaveServerPorts()

qbool NetConn_HaveServerPorts ( void )

Definition at line 1057 of file netconn.c.

1058{
1059 return !!sv_numsockets;
1060}

References sv_numsockets.

Referenced by Log_DestBuffer_Flush_NoLock().

◆ NetConn_Heartbeat()

void NetConn_Heartbeat ( int priority)

Definition at line 3984 of file netconn.c.

3985{
3986 lhnetaddress_t masteraddress;
3987 uint8_t masternum;
3988 lhnetsocket_t *mysocket;
3989
3990 // if it's a state change (client connected), limit next heartbeat to no
3991 // more than 30 sec in the future
3992 if (priority == 1 && nextheartbeattime > host.realtime + 30.0)
3994
3995 // limit heartbeatperiod to 30 to 270 second range,
3996 // lower limit is to avoid abusing master servers with excess traffic,
3997 // upper limit is to avoid timing out on the master server (which uses
3998 // 300 sec timeout)
3999 if (sv_heartbeatperiod.value < 30)
4001 if (sv_heartbeatperiod.value > 270)
4003
4004 // make advertising optional and don't advertise singleplayer games, and
4005 // only send a heartbeat as often as the admin wants
4006 if (sv.active && sv_public.integer > 0 && svs.maxclients >= 2 && (priority > 1 || host.realtime > nextheartbeattime))
4007 {
4009 for (masternum = 0; masternum < DPMASTER_COUNT; ++masternum)
4010 if (sv_masters[masternum].string[0]
4011 && LHNETADDRESS_FromString(&masteraddress, sv_masters[masternum].string, DPMASTER_PORT)
4012 && (mysocket = NetConn_ChooseServerSocketForAddress(&masteraddress)))
4013 NetConn_WriteString(mysocket, "\377\377\377\377heartbeat DarkPlaces\x0A", &masteraddress);
4014 }
4015}
void Cvar_SetValueQuick(cvar_t *var, float value)
Definition cvar.c:473
int LHNETADDRESS_FromString(lhnetaddress_t *vaddress, const char *string, int defaultport)
Definition lhnet.c:204
#define DPMASTER_PORT
Definition netconn.c:33
cvar_t sv_public
Definition netconn.c:36
static cvar_t sv_masters[]
Definition netconn.c:41
static double nextheartbeattime
Definition netconn.c:69
static cvar_t sv_heartbeatperiod
Definition netconn.c:38
#define DPMASTER_COUNT
Definition netconn.c:125
lhnetsocket_t * NetConn_ChooseServerSocketForAddress(lhnetaddress_t *address)
Definition netconn.c:1209

References server_t::active, Cvar_SetValueQuick(), DPMASTER_COUNT, DPMASTER_PORT, host, cvar_t::integer, LHNETADDRESS_FromString(), server_static_t::maxclients, NetConn_ChooseServerSocketForAddress(), NetConn_WriteString(), nextheartbeattime, host_static_t::realtime, sv, sv_heartbeatperiod, sv_masters, sv_public, svs, and cvar_t::value.

Referenced by Net_Heartbeat_f(), NetConn_ServerParsePacket(), SV_DropClient(), SV_Frame(), SV_Shutdown(), SV_SpawnServer(), and SV_ThreadFunc().

◆ NetConn_Init()

void NetConn_Init ( void )

Definition at line 4094 of file netconn.c.

4095{
4096 int i;
4097 unsigned j;
4098 lhnetaddress_t tempaddress;
4099
4100 netconn_mempool = Mem_AllocPool("network connections", 0, NULL);
4101 Cmd_AddCommand(CF_SHARED, "net_stats", Net_Stats_f, "print network statistics");
4102#ifdef CONFIG_MENU
4103 Cmd_AddCommand(CF_CLIENT, "net_slist", Net_Slist_f, "query dp master servers and print all server information");
4104 Cmd_AddCommand(CF_CLIENT, "net_slistqw", Net_SlistQW_f, "query qw master servers and print all server information");
4105 Cmd_AddCommand(CF_CLIENT, "net_refresh", Net_Refresh_f, "query dp master servers and refresh all server information");
4106#endif
4107 Cmd_AddCommand(CF_SERVER, "heartbeat", Net_Heartbeat_f, "send a heartbeat to the master server (updates your server information)");
4114
4115#ifdef CONFIG_MENU
4116 Cvar_RegisterVariable(&net_slist_debug);
4117 Cvar_RegisterVariable(&net_slist_favorites);
4118 Cvar_RegisterCallback(&net_slist_favorites, NetConn_UpdateFavorites_c);
4119 Cvar_RegisterVariable(&net_slist_interval);
4120 Cvar_RegisterVariable(&net_slist_maxping);
4121 Cvar_RegisterVariable(&net_slist_maxtries);
4122 Cvar_RegisterVariable(&net_slist_pause);
4123 Cvar_RegisterCallback(&net_slist_pause, ServerList_RebuildViewList);
4124 Cvar_RegisterVariable(&net_slist_queriespersecond);
4125 Cvar_RegisterVariable(&net_slist_queriesperframe);
4126 Cvar_RegisterVariable(&net_slist_timeout);
4127#endif
4128
4129#ifdef IP_TOS // register cvar only if supported
4131#endif
4142 Cvar_RegisterVirtual(&net_fakelag, "cl_netlocalping");
4143 Cvar_RegisterVirtual(&net_fakeloss_send, "cl_netpacketloss_send");
4144 Cvar_RegisterVirtual(&net_fakeloss_receive, "cl_netpacketloss_receive");
4156 for (j = 0; j < DPMASTER_COUNT; ++j)
4158#ifdef CONFIG_MENU
4159 for (j = 0; j < QWMASTER_COUNT; ++j)
4160 Cvar_RegisterVariable(&sv_qwmasters[j]);
4161#endif
4165// COMMANDLINEOPTION: Server: -ip <ipaddress> sets the ip address of this machine for purposes of networking (default 0.0.0.0 also known as INADDR_ANY), use only if you have multiple network adapters and need to choose one specifically.
4166 if ((i = Sys_CheckParm("-ip")) && i + 1 < sys.argc)
4167 {
4168 if (LHNETADDRESS_FromString(&tempaddress, sys.argv[i + 1], 0) == 1)
4169 {
4170 Con_Printf("-ip option used, setting net_address to \"%s\"\n", sys.argv[i + 1]);
4172 }
4173 else
4174 Con_Printf(CON_ERROR "-ip option used, but unable to parse the address \"%s\"\n", sys.argv[i + 1]);
4175 }
4176// COMMANDLINEOPTION: Server: -port <portnumber> sets the port to use for a server (default 26000, the same port as QUAKE itself), useful if you host multiple servers on your machine
4177 if (((i = Sys_CheckParm("-port")) || (i = Sys_CheckParm("-ipport")) || (i = Sys_CheckParm("-udpport"))) && i + 1 < sys.argc)
4178 {
4179 i = atoi(sys.argv[i + 1]);
4180 if (i >= 0 && i < 65536)
4181 {
4182 Con_Printf("-port option used, setting port cvar to %i\n", i);
4184 }
4185 else
4186 Con_Printf(CON_ERROR "-port option used, but %i is not a valid port number\n", i);
4187 }
4188 cl_numsockets = 0;
4189 sv_numsockets = 0;
4192 cl_message.cursize = 0;
4195 sv_message.cursize = 0;
4196 LHNET_Init();
4197 if (Thread_HasThreads())
4199}
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
Definition cmd.c:1661
#define CF_SHARED
Definition cmd.h:67
#define CF_SERVER
cvar/command that only the server can change/execute
Definition cmd.h:49
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
void Cvar_SetQuick(cvar_t *var, const char *value)
Definition cvar.c:436
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599
void Cvar_RegisterVirtual(cvar_t *variable, const char *name)
Definition cvar.c:513
void Cvar_RegisterCallback(cvar_t *variable, void(*callback)(cvar_t *))
Definition cvar.c:495
void LHNET_Init(void)
Definition lhnet.c:725
void * netconn_mutex
Definition netconn.c:153
cvar_t net_burstreserve
Definition netconn.c:80
mempool_t * netconn_mempool
Definition netconn.c:152
cvar_t net_address_ipv6
Definition netconn.c:158
cvar_t net_fakelag
Definition netconn.c:91
void Net_Stats_f(cmd_state_t *cmd)
Definition netconn.c:4042
static void NetConn_CL_UpdateSockets_Callback(cvar_t *var)
Definition netconn.c:1272
cvar_t net_connecttimeout
Definition netconn.c:82
static cvar_t rcon_restricted_commands
Definition netconn.c:112
static cvar_t gameversion_min
Definition netconn.c:109
cvar_t sv_public_rejectreason
Definition netconn.c:37
static cvar_t net_tos_dscp
Definition netconn.c:107
cvar_t net_usesizelimit
Definition netconn.c:79
static cvar_t net_fakeloss_receive
Definition netconn.c:93
static unsigned char cl_message_buf[NET_MAXMESSAGE]
Definition netconn.c:73
static void Net_Heartbeat_f(cmd_state_t *cmd)
Definition netconn.c:4017
#define QWMASTER_COUNT
Definition netconn.c:126
static cvar_t rcon_restricted_password
Definition netconn.c:111
cvar_t net_challengefloodblockingtimeout
Definition netconn.c:85
cvar_t net_test
Definition netconn.c:78
cvar_t net_getstatusfloodblockingtimeout
Definition netconn.c:86
static unsigned char sv_message_buf[NET_MAXMESSAGE]
Definition netconn.c:74
sizebuf_t sv_message
Definition netconn.c:72
cvar_t cl_netport
Definition netconn.c:155
static void NetConn_sv_netport_Callback(cvar_t *var)
Definition netconn.c:1296
cvar_t net_address
Definition netconn.c:157
cvar_t net_connect_entnum_ofs
Definition netconn.c:83
static cvar_t gameversion_max
Definition netconn.c:110
static cvar_t net_fakeloss_send
Definition netconn.c:92
cvar_t net_connectfloodblockingtimeout
Definition netconn.c:84
cvar_t sv_netport
Definition netconn.c:156
int argc
Definition sys.h:146
const char ** argv
Definition sys.h:147
sys_t sys
Definition sys_shared.c:42
int Sys_CheckParm(const char *parm)
Definition sys_shared.c:327
qbool Thread_HasThreads(void)
Definition thread_null.c:13
#define Thread_CreateMutex()
Definition thread.h:15
#define Mem_AllocPool(name, flags, parent)
Definition zone.h:104

References sys_t::argc, sys_t::argv, CF_CLIENT, CF_SERVER, CF_SHARED, cl_message, cl_message_buf, cl_netport, cl_numsockets, Cmd_AddCommand(), CON_ERROR, Con_Printf(), sizebuf_t::cursize, Cvar_RegisterCallback(), Cvar_RegisterVariable(), Cvar_RegisterVirtual(), Cvar_SetQuick(), Cvar_SetValueQuick(), sizebuf_t::data, developer_networking, DPMASTER_COUNT, gameversion, gameversion_max, gameversion_min, hostname, i, LHNET_Init(), LHNETADDRESS_FromString(), sizebuf_t::maxsize, Mem_AllocPool, net_address, net_address_ipv6, net_burstreserve, net_challengefloodblockingtimeout, net_connect_entnum_ofs, net_connectfloodblockingtimeout, net_connecttimeout, net_fakelag, net_fakeloss_receive, net_fakeloss_send, net_getstatusfloodblockingtimeout, Net_Heartbeat_f(), net_messagetimeout, net_sourceaddresscheck, Net_Stats_f(), net_test, net_tos_dscp, net_usesizelimit, NetConn_CL_UpdateSockets_Callback(), netconn_mempool, netconn_mutex, NetConn_sv_netport_Callback(), NULL, QWMASTER_COUNT, rcon_restricted_commands, rcon_restricted_password, rcon_secure_maxdiff, sv_heartbeatperiod, sv_masters, sv_message, sv_message_buf, sv_netport, sv_numsockets, sv_public, sv_public_rejectreason, sys, Sys_CheckParm(), Thread_CreateMutex, and Thread_HasThreads().

Referenced by Host_Init().

◆ NetConn_IsLocalGame()

int NetConn_IsLocalGame ( void )

Definition at line 1696 of file netconn.c.

1697{
1698 if (cls.state == ca_connected && sv.active && cl.maxclients == 1)
1699 return true;
1700 return false;
1701}
client_state_t cl
Definition cl_main.c:117

References server_t::active, ca_connected, cl, cls, client_state_t::maxclients, client_static_t::state, and sv.

Referenced by CL_ParseServerInfo().

◆ NetConn_Open()

netconn_t * NetConn_Open ( lhnetsocket_t * mysocket,
lhnetaddress_t * peeraddress )

Definition at line 1220 of file netconn.c.

1221{
1222 netconn_t *conn;
1223 conn = (netconn_t *)Mem_Alloc(netconn_mempool, sizeof(*conn));
1224 conn->mysocket = mysocket;
1225 conn->peeraddress = *peeraddress;
1227 conn->message.data = conn->messagedata;
1228 conn->message.maxsize = sizeof(conn->messagedata);
1229 conn->message.cursize = 0;
1230 // LadyHavoc: (inspired by ProQuake) use a short connect timeout to
1231 // reduce effectiveness of connection request floods
1233 LHNETADDRESS_ToString(&conn->peeraddress, conn->address, sizeof(conn->address), true);
1234 conn->next = netconn_list;
1235 netconn_list = conn;
1236 return conn;
1237}
double lastMessageTime
Definition netconn.h:154
unsigned char messagedata[NET_MAXMESSAGE]
Definition netconn.h:162
sizebuf_t message
writing buffer to send to peer as the next reliable message can be added to at any time,...
Definition netconn.h:161
#define Mem_Alloc(pool, size)
Definition zone.h:92

References netconn_t::address, sizebuf_t::cursize, sizebuf_t::data, host, netconn_t::lastMessageTime, LHNETADDRESS_ToString(), sizebuf_t::maxsize, Mem_Alloc, netconn_t::message, netconn_t::messagedata, netconn_t::mysocket, net_connecttimeout, netconn_list, netconn_mempool, netconn_t::next, netconn_t::peeraddress, host_static_t::realtime, netconn_t::timeout, and cvar_t::value.

Referenced by NetConn_ConnectionEstablished(), and NetConn_ServerParsePacket().

◆ NetConn_OpenClientPort()

static void NetConn_OpenClientPort ( const char * addressstring,
lhnetaddresstype_t addresstype,
int defaultport )
static

Definition at line 1069 of file netconn.c.

1070{
1071 lhnetaddress_t address;
1072 lhnetsocket_t *s;
1073 int success;
1074 char addressstring2[1024];
1075 if (addressstring && addressstring[0])
1076 success = LHNETADDRESS_FromString(&address, addressstring, defaultport);
1077 else
1078 success = LHNETADDRESS_FromPort(&address, addresstype, defaultport);
1079 if (success)
1080 {
1081 if ((s = LHNET_OpenSocket_Connectionless(&address)))
1082 {
1084 LHNETADDRESS_ToString(LHNET_AddressFromSocket(s), addressstring2, sizeof(addressstring2), true);
1085 if (addresstype != LHNETADDRESSTYPE_LOOP)
1086 Con_Printf("Client opened a socket on address %s\n", addressstring2);
1087 }
1088 else
1089 {
1090 LHNETADDRESS_ToString(&address, addressstring2, sizeof(addressstring2), true);
1091 Con_Printf(CON_ERROR "Client failed to open a socket on address %s\n", addressstring2);
1092 }
1093 }
1094 else
1095 Con_Printf(CON_ERROR "Client unable to parse address %s\n", addressstring);
1096}
int LHNETADDRESS_FromPort(lhnetaddress_t *vaddress, lhnetaddresstype_t addresstype, int port)
Definition lhnet.c:125
lhnetsocket_t * LHNET_OpenSocket_Connectionless(lhnetaddress_t *address)
Definition lhnet.c:832
@ LHNETADDRESSTYPE_LOOP
Definition lhnet.h:13

References cl_numsockets, cl_sockets, CON_ERROR, Con_Printf(), LHNET_AddressFromSocket(), LHNET_OpenSocket_Connectionless(), LHNETADDRESS_FromPort(), LHNETADDRESS_FromString(), LHNETADDRESS_ToString(), and LHNETADDRESSTYPE_LOOP.

Referenced by NetConn_OpenClientPorts().

◆ NetConn_OpenClientPorts()

void NetConn_OpenClientPorts ( void )

Definition at line 1098 of file netconn.c.

1099{
1100 int port;
1102
1103 SV_LockThreadMutex(); // FIXME recursive?
1104 Crypto_LoadKeys(); // client sockets
1106
1107 port = bound(0, cl_netport.integer, 65535);
1108 if (cl_netport.integer != port)
1110 if(port == 0)
1111 Con_Printf("Client using an automatically assigned port\n");
1112 else
1113 Con_Printf("Client using port %i\n", port);
1116#ifndef NOSUPPORTIPV6
1118#endif
1119}
void Crypto_LoadKeys(void)
Definition crypto.c:855
@ LHNETADDRESSTYPE_INET6
Definition lhnet.h:15
@ LHNETADDRESSTYPE_INET4
Definition lhnet.h:14
static void NetConn_OpenClientPort(const char *addressstring, lhnetaddresstype_t addresstype, int defaultport)
Definition netconn.c:1069
#define SV_LockThreadMutex()
Definition server.h:606
#define SV_UnlockThreadMutex()
Definition server.h:607

References bound, cl_netport, Con_Printf(), Crypto_LoadKeys(), Cvar_SetValueQuick(), cvar_t::integer, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, net_address, net_address_ipv6, NetConn_CloseClientPorts(), NetConn_OpenClientPort(), NULL, cvar_t::string, SV_LockThreadMutex, and SV_UnlockThreadMutex.

Referenced by NetConn_CL_UpdateSockets_Callback().

◆ NetConn_OpenServerPort()

static qbool NetConn_OpenServerPort ( const char * addressstring,
lhnetaddresstype_t addresstype,
int defaultport,
int range )
static

Definition at line 1128 of file netconn.c.

1129{
1130 lhnetaddress_t address;
1131 lhnetsocket_t *s;
1132 int port;
1133 char addressstring2[1024];
1134 int success;
1135
1136 for (port = defaultport; port <= defaultport + range; port++)
1137 {
1138 if (addressstring && addressstring[0])
1139 success = LHNETADDRESS_FromString(&address, addressstring, port);
1140 else
1141 success = LHNETADDRESS_FromPort(&address, addresstype, port);
1142 if (success)
1143 {
1144 if ((s = LHNET_OpenSocket_Connectionless(&address)))
1145 {
1147 LHNETADDRESS_ToString(LHNET_AddressFromSocket(s), addressstring2, sizeof(addressstring2), true);
1148 if (addresstype != LHNETADDRESSTYPE_LOOP)
1149 Con_Printf("Server listening on address %s\n", addressstring2);
1150 return true;
1151 }
1152 else
1153 {
1154 LHNETADDRESS_ToString(&address, addressstring2, sizeof(addressstring2), true);
1155 Con_Printf(CON_ERROR "Server failed to open socket on address %s\n", addressstring2);
1156 }
1157 }
1158 else
1159 {
1160 Con_Printf(CON_ERROR "Server unable to parse address %s\n", addressstring);
1161 // if it cant parse one address, it wont be able to parse another for sure
1162 return false;
1163 }
1164 }
1165 return false;
1166}

References CON_ERROR, Con_Printf(), LHNET_AddressFromSocket(), LHNET_OpenSocket_Connectionless(), LHNETADDRESS_FromPort(), LHNETADDRESS_FromString(), LHNETADDRESS_ToString(), LHNETADDRESSTYPE_LOOP, sv_numsockets, and sv_sockets.

Referenced by NetConn_OpenServerPorts().

◆ NetConn_OpenServerPorts()

void NetConn_OpenServerPorts ( int opennetports)

Definition at line 1168 of file netconn.c.

1169{
1170 int port;
1172
1173 SV_LockThreadMutex(); // FIXME recursive?
1174 Crypto_LoadKeys(); // server sockets
1176
1178 port = bound(0, sv_netport.integer, 65535);
1179 if (port == 0)
1180 port = 26000;
1181 if (sv_netport.integer != port)
1183 if (cls.state != ca_dedicated)
1185 if (opennetports)
1186 {
1187#ifndef NOSUPPORTIPV6
1190#else
1192#endif
1193 }
1194 if (sv_numsockets == 0)
1195 Host_Error("NetConn_OpenServerPorts: unable to open any ports!");
1196}
void Host_Error(const char *error,...)
Definition host.c:85
void NetConn_CloseServerPorts(void)
Definition netconn.c:1121
static qbool NetConn_OpenServerPort(const char *addressstring, lhnetaddresstype_t addresstype, int defaultport, int range)
Definition netconn.c:1128

References bound, ca_dedicated, cls, Crypto_LoadKeys(), Cvar_SetValueQuick(), Host_Error(), cvar_t::integer, LHNETADDRESSTYPE_INET4, LHNETADDRESSTYPE_INET6, LHNETADDRESSTYPE_LOOP, net_address, net_address_ipv6, NetConn_CloseServerPorts(), NetConn_OpenServerPort(), NetConn_UpdateSockets(), NULL, client_static_t::state, cvar_t::string, SV_LockThreadMutex, sv_netport, sv_numsockets, and SV_UnlockThreadMutex.

Referenced by Log_DestBuffer_Flush_NoLock(), and SV_SpawnServer().

◆ NetConn_PreventFlood()

static qbool NetConn_PreventFlood ( lhnetaddress_t * peeraddress,
server_floodaddress_t * floodlist,
size_t floodlength,
double floodtime,
qbool renew )
static

Definition at line 2923 of file netconn.c.

2924{
2925 size_t floodslotnum, bestfloodslotnum;
2926 double bestfloodtime;
2927 lhnetaddress_t noportpeeraddress;
2928 // see if this is a connect flood
2929 noportpeeraddress = *peeraddress;
2930 LHNETADDRESS_SetPort(&noportpeeraddress, 0);
2931 bestfloodslotnum = 0;
2932 bestfloodtime = floodlist[bestfloodslotnum].lasttime;
2933 for (floodslotnum = 0;floodslotnum < floodlength;floodslotnum++)
2934 {
2935 if (bestfloodtime >= floodlist[floodslotnum].lasttime)
2936 {
2937 bestfloodtime = floodlist[floodslotnum].lasttime;
2938 bestfloodslotnum = floodslotnum;
2939 }
2940 if (floodlist[floodslotnum].lasttime && LHNETADDRESS_Compare(&noportpeeraddress, &floodlist[floodslotnum].address) == 0)
2941 {
2942 // this address matches an ongoing flood address
2943 if (host.realtime < floodlist[floodslotnum].lasttime + floodtime)
2944 {
2945 if(renew)
2946 {
2947 // renew the ban on this address so it does not expire
2948 // until the flood has subsided
2949 floodlist[floodslotnum].lasttime = host.realtime;
2950 }
2951 //Con_Printf("Flood detected!\n");
2952 return true;
2953 }
2954 // the flood appears to have subsided, so allow this
2955 bestfloodslotnum = floodslotnum; // reuse the same slot
2956 break;
2957 }
2958 }
2959 // begin a new timeout on this address
2960 floodlist[bestfloodslotnum].address = noportpeeraddress;
2961 floodlist[bestfloodslotnum].lasttime = host.realtime;
2962 //Con_Printf("Flood detection initiated!\n");
2963 return false;
2964}

References server_floodaddress_t::address, host, server_floodaddress_t::lasttime, LHNETADDRESS_Compare(), LHNETADDRESS_SetPort(), and host_static_t::realtime.

Referenced by NetConn_ServerParsePacket().

◆ NetConn_Read()

int NetConn_Read ( lhnetsocket_t * mysocket,
void * data,
int maxlength,
lhnetaddress_t * peeraddress )

Definition at line 726 of file netconn.c.

727{
728 int length;
729 unsigned i;
730
733 length = LHNET_Read(mysocket, data, maxlength, peeraddress);
736 if (length == 0)
737 return 0;
739 for (i = 0;i < cl_numsockets;i++)
740 if (cl_sockets[i] == mysocket && (rand() % 100) < net_fakeloss_receive.integer)
741 return 0;
743 {
744 char addressstring[128], addressstring2[128];
745 LHNETADDRESS_ToString(LHNET_AddressFromSocket(mysocket), addressstring, sizeof(addressstring), true);
746 if (length > 0)
747 {
748 LHNETADDRESS_ToString(peeraddress, addressstring2, sizeof(addressstring2), true);
749 Con_Printf("LHNET_Read(%p (%s), %p, %i, %p) = %i from %s:\n", (void *)mysocket, addressstring, (void *)data, maxlength, (void *)peeraddress, length, addressstring2);
750 Com_HexDumpToConsole((unsigned char *)data, length);
751 }
752 else
753 Con_Printf("LHNET_Read(%p (%s), %p, %i, %p) = %i\n", (void *)mysocket, addressstring, (void *)data, maxlength, (void *)peeraddress, length);
754 }
755 return length;
756}
int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, lhnetaddress_t *vaddress)
Definition lhnet.c:1034
lhnetaddress_t address
Definition lhnet.h:45
#define Thread_LockMutex(m)
Definition thread.h:17
#define Thread_UnlockMutex(m)
Definition thread.h:18

References lhnetsocket_t::address, lhnetaddress_t::addresstype, cl_numsockets, cl_sockets, Com_HexDumpToConsole(), Con_Printf(), data, developer_networking, i, cvar_t::integer, length, LHNET_AddressFromSocket(), LHNET_Read(), LHNETADDRESS_ToString(), LHNETADDRESSTYPE_LOOP, net_fakeloss_receive, netconn_mutex, Thread_LockMutex, and Thread_UnlockMutex.

Referenced by NetConn_ClientFrame(), and NetConn_ServerFrame().

◆ NetConn_ReceivedMessage()

static int NetConn_ReceivedMessage ( netconn_t * conn,
const unsigned char * data,
size_t length,
protocolversion_t protocol,
double newtimeout )
static

Definition at line 1331 of file netconn.c.

1332{
1333 int originallength = (int)length;
1334 unsigned char sendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
1335 unsigned char cryptosendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
1336 unsigned char cryptoreadbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
1337 if (length < 8)
1338 return 0;
1339
1340 if (protocol == PROTOCOL_QUAKEWORLD)
1341 {
1342 unsigned int sequence, sequence_ack;
1343 qbool reliable_ack, reliable_message;
1344 int count;
1345 //int qport;
1346
1347 sequence = LittleLong(*((int *)(data + 0)));
1348 sequence_ack = LittleLong(*((int *)(data + 4)));
1349 data += 8;
1350 length -= 8;
1351
1352 if (conn != cls.netcon)
1353 {
1354 // server only
1355 if (length < 2)
1356 return 0;
1357 // TODO: use qport to identify that this client really is who they say they are? (and elsewhere in the code to identify the connection without a port match?)
1358 //qport = LittleShort(*((int *)(data + 8)));
1359 data += 2;
1360 length -= 2;
1361 }
1362
1363 conn->packetsReceived++;
1364 reliable_message = (sequence >> 31) != 0;
1365 reliable_ack = (sequence_ack >> 31) != 0;
1366 sequence &= ~(1u<<31);
1367 sequence_ack &= ~(1u<<31);
1368 if (sequence <= conn->qw.incoming_sequence)
1369 {
1370 //Con_DPrint("Got a stale datagram\n");
1371 return 0;
1372 }
1373 count = sequence - (conn->qw.incoming_sequence + 1);
1374 if (count > 0)
1375 {
1376 conn->droppedDatagrams += count;
1377 //Con_DPrintf("Dropped %u datagram(s)\n", count);
1378 // If too may packets have been dropped, only write the
1379 // last NETGRAPH_PACKETS ones to the netgraph. Why?
1380 // Because there's no point in writing more than
1381 // these as the netgraph is going to be full anyway.
1382 if (count > NETGRAPH_PACKETS)
1384 while (count--)
1385 {
1392 }
1393 }
1397 conn->incoming_netgraph[conn->incoming_packetcounter].unreliablebytes = originallength + 28;
1401
1402 // limit bursts to one packet in size ("dialup mode" emulating old behaviour)
1403 if (net_test.integer)
1404 {
1405 if (conn->cleartime < host.realtime)
1406 conn->cleartime = host.realtime;
1407 }
1408
1409 if (reliable_ack == conn->qw.reliable_sequence)
1410 {
1411 // received, now we will be able to send another reliable message
1412 conn->sendMessageLength = 0;
1414 }
1415 conn->qw.incoming_sequence = sequence;
1416 if (conn == cls.netcon)
1418 conn->qw.incoming_acknowledged = sequence_ack;
1419 conn->qw.incoming_reliable_acknowledged = reliable_ack;
1420 if (reliable_message)
1421 conn->qw.incoming_reliable_sequence ^= 1;
1423 conn->timeout = host.realtime + newtimeout;
1425 if (conn == cls.netcon)
1426 {
1428 SZ_Write(&cl_message, data, (int)length);
1430 }
1431 else
1432 {
1434 SZ_Write(&sv_message, data, (int)length);
1436 }
1437 return 2;
1438 }
1439 else
1440 {
1441 unsigned int count;
1442 unsigned int flags;
1443 unsigned int sequence;
1444 size_t qlength;
1445 const void *sendme;
1446 size_t sendmelen;
1447
1448 originallength = (int)length;
1449 data = (const unsigned char *) Crypto_DecryptPacket(&conn->crypto, data, length, cryptoreadbuffer, &length, sizeof(cryptoreadbuffer));
1450 if(!data)
1451 return 0;
1452 if(length < 8)
1453 return 0;
1454
1455 qlength = (unsigned int)BuffBigLong(data);
1456 flags = qlength & ~NETFLAG_LENGTH_MASK;
1457 qlength &= NETFLAG_LENGTH_MASK;
1458 // control packets were already handled
1459 if (!(flags & NETFLAG_CTL) && qlength == length)
1460 {
1461 sequence = BuffBigLong(data + 4);
1462 conn->packetsReceived++;
1463 data += 8;
1464 length -= 8;
1466 {
1467 if (sequence >= conn->nq.unreliableReceiveSequence)
1468 {
1469 if (sequence > conn->nq.unreliableReceiveSequence)
1470 {
1471 count = sequence - conn->nq.unreliableReceiveSequence;
1472 conn->droppedDatagrams += count;
1473 //Con_DPrintf("Dropped %u datagram(s)\n", count);
1474 // If too may packets have been dropped, only write the
1475 // last NETGRAPH_PACKETS ones to the netgraph. Why?
1476 // Because there's no point in writing more than
1477 // these as the netgraph is going to be full anyway.
1478 if (count > NETGRAPH_PACKETS)
1480 while (count--)
1481 {
1488 }
1489 }
1493 conn->incoming_netgraph[conn->incoming_packetcounter].unreliablebytes = originallength + 28;
1497
1498 conn->nq.unreliableReceiveSequence = sequence + 1;
1500 conn->timeout = host.realtime + newtimeout;
1502 if (length > 0)
1503 {
1504 if (conn == cls.netcon)
1505 {
1507 SZ_Write(&cl_message, data, (int)length);
1509 }
1510 else
1511 {
1513 SZ_Write(&sv_message, data, (int)length);
1515 }
1516 return 2;
1517 }
1518 }
1519 //else
1520 // Con_DPrint("Got a stale datagram\n");
1521 return 1;
1522 }
1523 else if (flags & NETFLAG_ACK)
1524 {
1525 conn->incoming_netgraph[conn->incoming_packetcounter].ackbytes += originallength + 28;
1527
1528 if (sequence == (conn->nq.sendSequence - 1))
1529 {
1530 if (sequence == conn->nq.ackSequence)
1531 {
1532 conn->nq.ackSequence++;
1533 if (conn->nq.ackSequence != conn->nq.sendSequence)
1534 Con_DPrint("ack sequencing error\n");
1536 conn->timeout = host.realtime + newtimeout;
1538 {
1539 unsigned int packetLen;
1540 unsigned int dataLen;
1541 unsigned int eom;
1542
1544 memmove(conn->sendMessage, conn->sendMessage+MAX_PACKETFRAGMENT, conn->sendMessageLength);
1545
1547 {
1548 dataLen = conn->sendMessageLength;
1549 eom = NETFLAG_EOM;
1550 }
1551 else
1552 {
1553 dataLen = MAX_PACKETFRAGMENT;
1554 eom = 0;
1555 }
1556
1557 packetLen = NET_HEADERSIZE + dataLen;
1558
1559 StoreBigLong(sendbuffer, packetLen | (NETFLAG_DATA | eom | NetConn_AddCryptoFlag(&conn->crypto)));
1560 StoreBigLong(sendbuffer + 4, conn->nq.sendSequence);
1561 memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen);
1562
1563 conn->nq.sendSequence++;
1564
1565 sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
1566 if (sendme && NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress) == (int)sendmelen)
1567 {
1568 conn->lastSendTime = host.realtime;
1569 conn->packetsSent++;
1570 }
1571 }
1572 else
1573 conn->sendMessageLength = 0;
1574 }
1575 //else
1576 // Con_DPrint("Duplicate ACK received\n");
1577 }
1578 //else
1579 // Con_DPrint("Stale ACK received\n");
1580 return 1;
1581 }
1582 else if (flags & NETFLAG_DATA)
1583 {
1584 unsigned char temppacket[8];
1585 conn->incoming_netgraph[conn->incoming_packetcounter].reliablebytes += originallength + 28;
1587
1588 conn->outgoing_netgraph[conn->outgoing_packetcounter].ackbytes += 8 + 28;
1589
1590 StoreBigLong(temppacket, 8 | NETFLAG_ACK | NetConn_AddCryptoFlag(&conn->crypto));
1591 StoreBigLong(temppacket + 4, sequence);
1592 sendme = Crypto_EncryptPacket(&conn->crypto, temppacket, 8, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
1593 if(sendme)
1594 NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress);
1595 if (sequence == conn->nq.receiveSequence)
1596 {
1598 conn->timeout = host.realtime + newtimeout;
1599 conn->nq.receiveSequence++;
1600 if( conn->receiveMessageLength + length <= (int)sizeof( conn->receiveMessage ) ) {
1601 memcpy(conn->receiveMessage + conn->receiveMessageLength, data, length);
1603 } else {
1604 Con_Printf( "Reliable message (seq: %i) too big for message buffer!\n"
1605 "Dropping the message!\n", sequence );
1606 conn->receiveMessageLength = 0;
1607 return 1;
1608 }
1609 if (flags & NETFLAG_EOM)
1610 {
1613 conn->receiveMessageLength = 0;
1614 if (length > 0)
1615 {
1616 if (conn == cls.netcon)
1617 {
1621 }
1622 else
1623 {
1627 }
1628 return 2;
1629 }
1630 }
1631 }
1632 else
1633 conn->receivedDuplicateCount++;
1634 return 1;
1635 }
1636 }
1637 }
1638 return 0;
1639}
cvar_t cl_rate_burstsize
Definition cl_cmd.c:34
cvar_t cl_rate
Definition cl_cmd.c:33
#define LittleLong(l)
Definition common.h:92
void Con_DPrint(const char *msg)
A Con_Print that only shows up if the "developer" cvar is set.
Definition console.c:1531
const void * Crypto_EncryptPacket(crypto_t *crypto, const void *data_src, size_t len_src, void *data_dst, size_t *len_dst, size_t len)
Definition crypto.c:1527
const void * Crypto_DecryptPacket(crypto_t *crypto, const void *data_src, size_t len_src, void *data_dst, size_t *len_dst, size_t len)
Definition crypto.c:1584
float flags
GLenum GLenum GLsizei count
Definition glquake.h:656
static void NetConn_UpdateCleartime(double *cleartime, int rate, int burstsize, int len)
Definition netconn.c:806
static int NetConn_AddCryptoFlag(crypto_t *crypto)
Definition netconn.c:823
#define NETFLAG_EOM
Definition netconn.h:39
#define NETFLAG_UNRELIABLE
Definition netconn.h:40
#define NETFLAG_ACK
Definition netconn.h:37
#define NETFLAG_DATA
Definition netconn.h:36
#define NETGRAPH_LOSTPACKET
Definition netconn.h:224
#define MAX_PACKETFRAGMENT
max length of packet fragment
Definition qdefs.h:104
unsigned int qw_incoming_sequence
Definition client.h:644
unsigned int sendSequence
Definition netconn.h:181
unsigned int unreliableReceiveSequence
Definition netconn.h:184
unsigned int ackSequence
Definition netconn.h:180
unsigned int receiveSequence
Definition netconn.h:183
qbool incoming_reliable_sequence
single bit, maintained local
Definition netconn.h:209
unsigned int incoming_acknowledged
Definition netconn.h:206
qbool incoming_reliable_acknowledged
single bit
Definition netconn.h:207
unsigned int incoming_sequence
Definition netconn.h:205
qbool reliable_sequence
single bit
Definition netconn.h:211
int incoming_packetcounter
Definition netconn.h:226
int reliableMessagesReceived
Definition netconn.h:243
netgraphitem_t incoming_netgraph[NETGRAPH_PACKETS]
Definition netconn.h:227
int receiveMessageLength
reliable message that is currently being received (for putting together fragments)
Definition netconn.h:172
int unreliableMessagesReceived
Definition netconn.h:241
double lastSendTime
Definition netconn.h:155
int packetsSent
Definition netconn.h:235
unsigned char receiveMessage[NET_MAXMESSAGE]
Definition netconn.h:173
double incoming_cleartime
Definition netconn.h:218
int sendMessageLength
reliable message that is currently sending (for building fragments)
Definition netconn.h:167
int packetsReceived
Definition netconn.h:237
unsigned char sendMessage[NET_MAXMESSAGE]
Definition netconn.h:168
int droppedDatagrams
Definition netconn.h:239
struct netconn_t::netconn_qw_s qw
int receivedDuplicateCount
Definition netconn.h:238
struct netconn_t::netconn_nq_s nq

References netgraphitem_t::ackbytes, netconn_t::netconn_nq_s::ackSequence, BuffBigLong(), cl_message, cl_rate, cl_rate_burstsize, netconn_t::cleartime, netgraphitem_t::cleartime, cls, Con_DPrint(), Con_Printf(), count, netconn_t::crypto, Crypto_DecryptPacket(), Crypto_EncryptPacket(), CRYPTO_HEADERSIZE, data, netconn_t::droppedDatagrams, flags, host, netconn_t::netconn_qw_s::incoming_acknowledged, netconn_t::incoming_cleartime, netconn_t::incoming_netgraph, netconn_t::incoming_packetcounter, netconn_t::netconn_qw_s::incoming_reliable_acknowledged, netconn_t::netconn_qw_s::incoming_reliable_sequence, netconn_t::netconn_qw_s::incoming_sequence, int(), cvar_t::integer, netconn_t::lastMessageTime, netconn_t::lastSendTime, length, LittleLong, MAX_PACKETFRAGMENT, MSG_BeginReading(), netconn_t::mysocket, NET_HEADERSIZE, NET_MAXMESSAGE, net_test, client_static_t::netcon, NetConn_AddCryptoFlag(), NetConn_UpdateCleartime(), NetConn_Write(), NETFLAG_ACK, NETFLAG_CTL, NETFLAG_DATA, NETFLAG_EOM, NETFLAG_LENGTH_MASK, NETFLAG_UNRELIABLE, NETGRAPH_LOSTPACKET, NETGRAPH_NOPACKET, NETGRAPH_PACKETS, netconn_t::nq, netconn_t::outgoing_netgraph, netconn_t::outgoing_packetcounter, netconn_t::packetsReceived, netconn_t::packetsSent, netconn_t::peeraddress, PROTOCOL_QUAKEWORLD, netconn_t::qw, client_static_t::qw_incoming_sequence, host_static_t::realtime, netconn_t::receivedDuplicateCount, netconn_t::receiveMessage, netconn_t::receiveMessageLength, netconn_t::netconn_nq_s::receiveSequence, netconn_t::netconn_qw_s::reliable_sequence, netgraphitem_t::reliablebytes, netconn_t::reliableMessagesReceived, netconn_t::sendMessage, netconn_t::sendMessageLength, netconn_t::netconn_nq_s::sendSequence, StoreBigLong(), sv_message, SZ_Clear(), SZ_Write(), netgraphitem_t::time, netconn_t::timeout, netgraphitem_t::unreliablebytes, netconn_t::unreliableMessagesReceived, and netconn_t::netconn_nq_s::unreliableReceiveSequence.

Referenced by NetConn_ClientParsePacket(), and NetConn_ServerParsePacket().

◆ NetConn_SendUnreliableMessage()

int NetConn_SendUnreliableMessage ( netconn_t * conn,
sizebuf_t * data,
protocolversion_t protocol,
int rate,
int burstsize,
qbool quakesignon_suppressreliables )

Definition at line 844 of file netconn.c.

845{
846 int totallen = 0;
847 unsigned char sendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
848 unsigned char cryptosendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
849
850 // if this packet was supposedly choked, but we find ourselves sending one
851 // anyway, make sure the size counting starts at zero
852 // (this mostly happens on level changes and disconnects and such)
855
857
858 if (protocol == PROTOCOL_QUAKEWORLD)
859 {
860 int packetLen;
861 qbool sendreliable;
862
863 // note that it is ok to send empty messages to the qw server,
864 // otherwise it won't respond to us at all
865
866 sendreliable = false;
867 // if the remote side dropped the last reliable message, resend it
869 sendreliable = true;
870 // if the reliable transmit buffer is empty, copy the current message out
871 if (!conn->sendMessageLength && conn->message.cursize)
872 {
873 memcpy (conn->sendMessage, conn->message.data, conn->message.cursize);
874 conn->sendMessageLength = conn->message.cursize;
875 SZ_Clear(&conn->message); // clear the message buffer
876 conn->qw.reliable_sequence ^= 1;
877 sendreliable = true;
878 }
879 // outgoing unreliable packet number, and outgoing reliable packet number (0 or 1)
880 StoreLittleLong(sendbuffer, conn->outgoing_unreliable_sequence | (((unsigned int)sendreliable)<<31));
881 // last received unreliable packet number, and last received reliable packet number (0 or 1)
882 StoreLittleLong(sendbuffer + 4, conn->qw.incoming_sequence | (((unsigned int)conn->qw.incoming_reliable_sequence)<<31));
883 packetLen = 8;
885 // client sends qport in every packet
886 if (conn == cls.netcon)
887 {
888 *((short *)(sendbuffer + 8)) = LittleShort(cls.qw_qport);
889 packetLen += 2;
890 // also update cls.qw_outgoing_sequence
892 }
893 if (packetLen + (sendreliable ? conn->sendMessageLength : 0) > 1400)
894 {
895 Con_Printf ("NetConn_SendUnreliableMessage: reliable message too big %u\n", data->cursize);
896 return -1;
897 }
898
899 conn->outgoing_netgraph[conn->outgoing_packetcounter].unreliablebytes += packetLen + 28;
900
901 // add the reliable message if there is one
902 if (sendreliable)
903 {
905 memcpy(sendbuffer + packetLen, conn->sendMessage, conn->sendMessageLength);
906 packetLen += conn->sendMessageLength;
908 }
909
910 // add the unreliable message if possible
911 if (packetLen + data->cursize <= 1400)
912 {
913 conn->outgoing_netgraph[conn->outgoing_packetcounter].unreliablebytes += data->cursize + 28;
914 memcpy(sendbuffer + packetLen, data->data, data->cursize);
915 packetLen += data->cursize;
916 }
917
918 NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress);
919
920 conn->packetsSent++;
922
923 totallen += packetLen + 28;
924 }
925 else
926 {
927 unsigned int packetLen;
928 unsigned int dataLen;
929 unsigned int eom;
930 const void *sendme;
931 size_t sendmelen;
932
933 // if a reliable message fragment has been lost, send it again
934 if (conn->sendMessageLength && (host.realtime - conn->lastSendTime) > 1.0)
935 {
937 {
938 dataLen = conn->sendMessageLength;
939 eom = NETFLAG_EOM;
940 }
941 else
942 {
943 dataLen = MAX_PACKETFRAGMENT;
944 eom = 0;
945 }
946
947 packetLen = NET_HEADERSIZE + dataLen;
948
949 StoreBigLong(sendbuffer, packetLen | (NETFLAG_DATA | eom | NetConn_AddCryptoFlag(&conn->crypto)));
950 StoreBigLong(sendbuffer + 4, conn->nq.sendSequence - 1);
951 memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen);
952
953 conn->outgoing_netgraph[conn->outgoing_packetcounter].reliablebytes += packetLen + 28;
954
955 sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
956 if (sendme && NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress) == (int)sendmelen)
957 {
958 conn->lastSendTime = host.realtime;
959 conn->packetsReSent++;
960 }
961
962 totallen += (int)sendmelen + 28;
963 }
964
965 // if we have a new reliable message to send, do so
966 if (!conn->sendMessageLength && conn->message.cursize && !quakesignon_suppressreliables)
967 {
968 if (conn->message.cursize > (int)sizeof(conn->sendMessage))
969 {
970 Con_Printf("NetConn_SendUnreliableMessage: reliable message too big (%u > %u)\n", conn->message.cursize, (int)sizeof(conn->sendMessage));
971 conn->message.overflowed = true;
972 return -1;
973 }
974
975 if (developer_networking.integer && conn == cls.netcon)
976 {
977 Con_Print("client sending reliable message to server:\n");
979 }
980
981 memcpy(conn->sendMessage, conn->message.data, conn->message.cursize);
982 conn->sendMessageLength = conn->message.cursize;
983 SZ_Clear(&conn->message);
984
986 {
987 dataLen = conn->sendMessageLength;
988 eom = NETFLAG_EOM;
989 }
990 else
991 {
992 dataLen = MAX_PACKETFRAGMENT;
993 eom = 0;
994 }
995
996 packetLen = NET_HEADERSIZE + dataLen;
997
998 StoreBigLong(sendbuffer, packetLen | (NETFLAG_DATA | eom | NetConn_AddCryptoFlag(&conn->crypto)));
999 StoreBigLong(sendbuffer + 4, conn->nq.sendSequence);
1000 memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen);
1001
1002 conn->nq.sendSequence++;
1003
1004 conn->outgoing_netgraph[conn->outgoing_packetcounter].reliablebytes += packetLen + 28;
1005
1006 sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
1007 if(sendme)
1008 NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress);
1009
1010 conn->lastSendTime = host.realtime;
1011 conn->packetsSent++;
1012 conn->reliableMessagesSent++;
1013
1014 totallen += (int)sendmelen + 28;
1015 }
1016
1017 // if we have an unreliable message to send, do so
1018 if (data->cursize)
1019 {
1020 packetLen = NET_HEADERSIZE + data->cursize;
1021
1022 if (packetLen > (int)sizeof(sendbuffer))
1023 {
1024 Con_Printf("NetConn_SendUnreliableMessage: message too big %u\n", data->cursize);
1025 return -1;
1026 }
1027
1028 StoreBigLong(sendbuffer, packetLen | NETFLAG_UNRELIABLE | NetConn_AddCryptoFlag(&conn->crypto));
1029 StoreBigLong(sendbuffer + 4, conn->outgoing_unreliable_sequence);
1030 memcpy(sendbuffer + NET_HEADERSIZE, data->data, data->cursize);
1031
1033
1034 conn->outgoing_netgraph[conn->outgoing_packetcounter].unreliablebytes += packetLen + 28;
1035
1036 sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
1037 if(sendme)
1038 NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress);
1039
1040 conn->packetsSent++;
1041 conn->unreliableMessagesSent++;
1042
1043 totallen += (int)sendmelen + 28;
1044 }
1045 }
1046
1047 NetConn_UpdateCleartime(&conn->cleartime, rate, burstsize, totallen);
1048
1049 return 0;
1050}
void StoreLittleLong(unsigned char *buffer, unsigned int i)
Encode a little endian 32bit int to the given buffer.
Definition com_msg.c:95
void SZ_HexDumpToConsole(const sizebuf_t *buf)
Definition common.c:148
#define LittleShort(l)
Definition common.h:90
unsigned int qw_outgoing_sequence
Definition client.h:645
unsigned int last_reliable_sequence
sequence number of last send
Definition netconn.h:212
int reliableMessagesSent
Definition netconn.h:242
unsigned int outgoing_unreliable_sequence
used by both NQ and QW protocols
Definition netconn.h:176
int unreliableMessagesSent
Definition netconn.h:240
int packetsReSent
Definition netconn.h:236
qbool overflowed
set to true if the buffer size failed
Definition common.h:51

References netconn_t::cleartime, netgraphitem_t::cleartime, cls, Con_Print(), Con_Printf(), netconn_t::crypto, Crypto_EncryptPacket(), CRYPTO_HEADERSIZE, sizebuf_t::cursize, data, sizebuf_t::data, developer_networking, host, netconn_t::netconn_qw_s::incoming_acknowledged, netconn_t::netconn_qw_s::incoming_reliable_acknowledged, netconn_t::netconn_qw_s::incoming_reliable_sequence, netconn_t::netconn_qw_s::incoming_sequence, int(), cvar_t::integer, netconn_t::netconn_qw_s::last_reliable_sequence, netconn_t::lastSendTime, LittleShort, MAX_PACKETFRAGMENT, netconn_t::message, netconn_t::mysocket, NET_HEADERSIZE, NET_MAXMESSAGE, client_static_t::netcon, NetConn_AddCryptoFlag(), NetConn_UpdateCleartime(), NetConn_Write(), NETFLAG_DATA, NETFLAG_EOM, NETFLAG_UNRELIABLE, NETGRAPH_CHOKEDPACKET, NETGRAPH_NOPACKET, netconn_t::nq, netconn_t::outgoing_netgraph, netconn_t::outgoing_packetcounter, netconn_t::outgoing_unreliable_sequence, sizebuf_t::overflowed, netconn_t::packetsReSent, netconn_t::packetsSent, netconn_t::peeraddress, PROTOCOL_QUAKEWORLD, netconn_t::qw, client_static_t::qw_outgoing_sequence, client_static_t::qw_qport, host_static_t::realtime, netconn_t::netconn_qw_s::reliable_sequence, netgraphitem_t::reliablebytes, netconn_t::reliableMessagesSent, netconn_t::sendMessage, netconn_t::sendMessageLength, netconn_t::netconn_nq_s::sendSequence, StoreBigLong(), StoreLittleLong(), SZ_Clear(), SZ_HexDumpToConsole(), netgraphitem_t::unreliablebytes, and netconn_t::unreliableMessagesSent.

Referenced by CL_DisconnectEx(), CL_KeepaliveMessage(), CL_SendMove(), NetConn_ConnectionEstablished(), SV_DropClient(), and SV_SendClientDatagram().

◆ NetConn_ServerFrame()

void NetConn_ServerFrame ( void )

Definition at line 3861 of file netconn.c.

3862{
3863 unsigned i;
3864 int length;
3865 lhnetaddress_t peeraddress;
3866 unsigned char readbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
3867
3868 for (i = 0;i < sv_numsockets;i++)
3869 while (sv_sockets[i] && (length = NetConn_Read(sv_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0)
3870 NetConn_ServerParsePacket(sv_sockets[i], readbuffer, length, &peeraddress);
3871}
static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress)
Definition netconn.c:3193

References i, length, NET_HEADERSIZE, NET_MAXMESSAGE, NetConn_Read(), NetConn_ServerParsePacket(), sv_numsockets, and sv_sockets.

Referenced by SV_Frame(), and SV_ThreadFunc().

◆ NetConn_ServerParsePacket()

static int NetConn_ServerParsePacket ( lhnetsocket_t * mysocket,
unsigned char * data,
int length,
lhnetaddress_t * peeraddress )
static

Definition at line 3193 of file netconn.c.

3194{
3195 int i, ret, clientnum, best;
3196 double besttime;
3197 char *string, response[2800], addressstring2[128];
3198 static char stringbuf[16384]; // server only
3199 qbool islocal = (LHNETADDRESS_GetAddressType(peeraddress) == LHNETADDRESSTYPE_LOOP);
3201 size_t sendlength, response_len;
3202 char infostringvalue[MAX_INPUTLINE];
3203
3204 if (!sv.active)
3205 return false;
3206
3207 // convert the address to a string incase we need it
3208 LHNETADDRESS_ToString(peeraddress, addressstring2, sizeof(addressstring2), true);
3209
3210 // see if we can identify the sender as a local player
3211 // (this is necessary for rcon to send a reliable reply if the client is
3212 // actually on the server, not sending remotely)
3213 for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
3215 break;
3216 if (i == svs.maxclients)
3217 host_client = NULL;
3218
3219 if (length >= 5 && data[0] == 255 && data[1] == 255 && data[2] == 255 && data[3] == 255)
3220 {
3221 // received a command string - strip off the packaging and put it
3222 // into our string buffer with NULL termination
3223 data += 4;
3224 length -= 4;
3225 length = min(length, (int)sizeof(stringbuf) - 1);
3226 memcpy(stringbuf, data, length);
3227 stringbuf[length] = 0;
3228 string = stringbuf;
3229
3231 {
3232 Con_Printf("NetConn_ServerParsePacket: %s sent us a command:\n", addressstring2);
3234 }
3235
3236 sendlength = sizeof(senddata) - 4;
3237 switch(Crypto_ServerParsePacket(string, length, senddata+4, &sendlength, peeraddress))
3238 {
3239 case CRYPTO_NOMATCH:
3240 // nothing to do
3241 break;
3242 case CRYPTO_MATCH:
3243 if(sendlength)
3244 {
3245 memcpy(senddata, "\377\377\377\377", 4);
3246 NetConn_Write(mysocket, senddata, (int)sendlength+4, peeraddress);
3247 }
3248 break;
3249 case CRYPTO_DISCARD:
3250 if(sendlength)
3251 {
3252 memcpy(senddata, "\377\377\377\377", 4);
3253 NetConn_Write(mysocket, senddata, (int)sendlength+4, peeraddress);
3254 }
3255 return true;
3256 break;
3257 case CRYPTO_REPLACE:
3258 string = senddata+4;
3259 length = (int)sendlength;
3260 break;
3261 }
3262
3263 if (length >= 12 && !memcmp(string, "getchallenge", 12) && (islocal || sv_public.integer > -3))
3264 {
3265 for (i = 0, best = 0, besttime = host.realtime;i < MAX_CHALLENGES;i++)
3266 {
3267 if(challenges[i].time > 0)
3268 if (!LHNETADDRESS_Compare(peeraddress, &challenges[i].address))
3269 break;
3270 if (besttime > challenges[i].time)
3271 besttime = challenges[best = i].time;
3272 }
3273 // if we did not find an exact match, choose the oldest and
3274 // update address and string
3275 if (i == MAX_CHALLENGES)
3276 {
3277 i = best;
3278 challenges[i].address = *peeraddress;
3279 NetConn_BuildChallengeString(challenges[i].string, sizeof(challenges[i].string));
3280 }
3281 else
3282 {
3283 // flood control: drop if requesting challenge too often
3285 return true;
3286 }
3288 // send the challenge
3289 memcpy(response, "\377\377\377\377", 4);
3290 dpsnprintf(response+4, sizeof(response)-4, "challenge %s", challenges[i].string);
3291 response_len = strlen(response) + 1;
3292 Crypto_ServerAppendToChallenge(string, length, response, &response_len, sizeof(response));
3293 NetConn_Write(mysocket, response, (int)response_len, peeraddress);
3294 return true;
3295 }
3296 if (length > 8 && !memcmp(string, "connect\\", 8))
3297 {
3298 client_t *client;
3299 crypto_t *crypto = Crypto_ServerGetInstance(peeraddress);
3300 string += 7;
3301 length -= 7;
3302
3303 if(crypto && crypto->authenticated)
3304 {
3305 // no need to check challenge
3307 {
3308 Con_Printf("%s connection to %s is being established: client is %s@%s%.*s, I am %.*s@%s%.*s\n",
3309 crypto->use_aes ? "Encrypted" : "Authenticated",
3310 addressstring2,
3311 crypto->client_idfp[0] ? crypto->client_idfp : "-",
3312 (crypto->client_issigned || !crypto->client_keyfp[0]) ? "" : "~",
3313 crypto_keyfp_recommended_length, crypto->client_keyfp[0] ? crypto->client_keyfp : "-",
3314 crypto_keyfp_recommended_length, crypto->server_idfp[0] ? crypto->server_idfp : "-",
3315 (crypto->server_issigned || !crypto->server_keyfp[0]) ? "" : "~",
3317 );
3318 }
3319 }
3320 else
3321 {
3322 if (InfoString_GetValue(string, "challenge", infostringvalue, sizeof(infostringvalue)))
3323 {
3324 // validate the challenge
3325 for (i = 0;i < MAX_CHALLENGES;i++)
3326 if(challenges[i].time > 0)
3327 if (!LHNETADDRESS_Compare(peeraddress, &challenges[i].address) && !strcmp(challenges[i].string, infostringvalue))
3328 break;
3329 // if the challenge is not recognized, drop the packet
3330 if (i == MAX_CHALLENGES)
3331 return true;
3332 }
3333 }
3334
3335 if(InfoString_GetValue(string, "message", infostringvalue, sizeof(infostringvalue)))
3336 Con_DPrintf("Connecting client %s sent us the message: %s\n", addressstring2, infostringvalue);
3337
3338 if(!(islocal || sv_public.integer > -2))
3339 {
3341 Con_Printf("Datagram_ParseConnectionless: sending \"reject %s\" to %s.\n", sv_public_rejectreason.string, addressstring2);
3342 memcpy(response, "\377\377\377\377", 4);
3343 dpsnprintf(response+4, sizeof(response)-4, "reject %s", sv_public_rejectreason.string);
3344 NetConn_WriteString(mysocket, response, peeraddress);
3345 return true;
3346 }
3347
3348 // check engine protocol
3349 if(!InfoString_GetValue(string, "protocol", infostringvalue, sizeof(infostringvalue)) || strcmp(infostringvalue, "darkplaces 3"))
3350 {
3352 Con_Printf("Datagram_ParseConnectionless: sending \"reject Wrong game protocol.\" to %s.\n", addressstring2);
3353 NetConn_WriteString(mysocket, "\377\377\377\377reject Wrong game protocol.", peeraddress);
3354 return true;
3355 }
3356
3357 // see if this is a duplicate connection request or a disconnected
3358 // client who is rejoining to the same client slot
3359 for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
3360 {
3361 if (client->netconnection && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
3362 {
3363 // this is a known client...
3364 if(crypto && crypto->authenticated)
3365 {
3366 // reject if changing key!
3368 {
3369 if(
3370 strcmp(client->netconnection->crypto.client_idfp, crypto->client_idfp)
3371 ||
3372 strcmp(client->netconnection->crypto.server_idfp, crypto->server_idfp)
3373 ||
3374 strcmp(client->netconnection->crypto.client_keyfp, crypto->client_keyfp)
3375 ||
3376 strcmp(client->netconnection->crypto.server_keyfp, crypto->server_keyfp)
3377 )
3378 {
3380 Con_Printf("Datagram_ParseConnectionless: sending \"reject Attempt to change key of crypto.\" to %s.\n", addressstring2);
3381 NetConn_WriteString(mysocket, "\377\377\377\377reject Attempt to change key of crypto.", peeraddress);
3382 return true;
3383 }
3384 }
3385 }
3386 else
3387 {
3388 // reject if downgrading!
3390 {
3392 Con_Printf("Datagram_ParseConnectionless: sending \"reject Attempt to downgrade crypto.\" to %s.\n", addressstring2);
3393 NetConn_WriteString(mysocket, "\377\377\377\377reject Attempt to downgrade crypto.", peeraddress);
3394 return true;
3395 }
3396 }
3397 if (client->begun)
3398 {
3399 // client crashed and is coming back,
3400 // keep their stuff intact
3402 Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", addressstring2);
3403 NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
3404 if(crypto && crypto->authenticated)
3405 Crypto_FinishInstance(&client->netconnection->crypto, crypto);
3406 SV_SendServerinfo(client);
3407 }
3408 else
3409 {
3410 // client is still trying to connect,
3411 // so we send a duplicate reply
3413 Con_Printf("Datagram_ParseConnectionless: sending duplicate accept to %s.\n", addressstring2);
3414 if(crypto && crypto->authenticated)
3415 Crypto_FinishInstance(&client->netconnection->crypto, crypto);
3416 NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
3417 }
3418 return true;
3419 }
3420 }
3421
3423 return true;
3424
3425 // find an empty client slot for this new client
3426 for (clientnum = 0; clientnum < svs.maxclients; clientnum++)
3427 {
3428 netconn_t *conn;
3429 int offset_clientnum = (net_connect_entnum_ofs.integer > 0)
3431 : clientnum;
3432
3433 if (!svs.clients[offset_clientnum].active && (conn = NetConn_Open(mysocket, peeraddress)))
3434 {
3435 // allocated connection
3437 Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", conn->address);
3438 NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
3439 // now set up the client
3440 if(crypto && crypto->authenticated)
3441 Crypto_FinishInstance(&conn->crypto, crypto);
3442 SV_ConnectClient(offset_clientnum, conn);
3444 return true;
3445 }
3446 }
3447
3448 // no empty slots found - server is full
3450 Con_Printf("Datagram_ParseConnectionless: sending \"reject Server is full.\" to %s.\n", addressstring2);
3451 NetConn_WriteString(mysocket, "\377\377\377\377reject Server is full.", peeraddress);
3452
3453 return true;
3454 }
3455 if (length >= 7 && !memcmp(string, "getinfo", 7) && (islocal || sv_public.integer > -1))
3456 {
3457 const char *challenge = NULL;
3458
3460 return true;
3461
3462 // If there was a challenge in the getinfo message
3463 if (length > 8 && string[7] == ' ')
3464 challenge = string + 8;
3465
3466 if (NetConn_BuildStatusResponse(challenge, response, sizeof(response), false))
3467 {
3469 Con_DPrintf("Sending reply to master %s - %s\n", addressstring2, response);
3470 NetConn_WriteString(mysocket, response, peeraddress);
3471 }
3472 return true;
3473 }
3474 if (length >= 9 && !memcmp(string, "getstatus", 9) && (islocal || sv_public.integer > -1))
3475 {
3476 const char *challenge = NULL;
3477
3479 return true;
3480
3481 // If there was a challenge in the getinfo message
3482 if (length > 10 && string[9] == ' ')
3483 challenge = string + 10;
3484
3485 if (NetConn_BuildStatusResponse(challenge, response, sizeof(response), true))
3486 {
3488 Con_DPrintf("Sending reply to client %s - %s\n", addressstring2, response);
3489 NetConn_WriteString(mysocket, response, peeraddress);
3490 }
3491 return true;
3492 }
3493 if (length >= 37 && !memcmp(string, "srcon HMAC-MD4 TIME ", 20))
3494 {
3495 char *password = string + 20;
3496 char *timeval = string + 37;
3497 char *s = strchr(timeval, ' ');
3498 char *endpos = string + length + 1; // one behind the NUL, so adding strlen+1 will eventually reach it
3499 const char *userlevel;
3500
3501 if(rcon_secure.integer > 1)
3502 return true;
3503
3504 if(!s)
3505 return true; // invalid packet
3506 ++s;
3507
3508 userlevel = RCon_Authenticate(peeraddress, password, s, endpos, hmac_mdfour_time_matching, timeval, endpos - timeval - 1); // not including the appended \0 into the HMAC
3509 RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, false);
3510 return true;
3511 }
3512 if (length >= 42 && !memcmp(string, "srcon HMAC-MD4 CHALLENGE ", 25))
3513 {
3514 char *password = string + 25;
3515 char *challenge = string + 42;
3516 char *s = strchr(challenge, ' ');
3517 char *endpos = string + length + 1; // one behind the NUL, so adding strlen+1 will eventually reach it
3518 const char *userlevel;
3519 if(!s)
3520 return true; // invalid packet
3521 ++s;
3522
3523 userlevel = RCon_Authenticate(peeraddress, password, s, endpos, hmac_mdfour_challenge_matching, challenge, endpos - challenge - 1); // not including the appended \0 into the HMAC
3524 RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, false);
3525 return true;
3526 }
3527 if (length >= 5 && !memcmp(string, "rcon ", 5))
3528 {
3529 int j;
3530 char *s = string + 5;
3531 char *endpos = string + length + 1; // one behind the NUL, so adding strlen+1 will eventually reach it
3532 char password[64];
3533
3534 if(rcon_secure.integer > 0)
3535 return true;
3536
3537 for (j = 0;!ISWHITESPACE(*s);s++)
3538 if (j < (int)sizeof(password) - 1)
3539 password[j++] = *s;
3540 if(ISWHITESPACE(*s) && s != endpos) // skip leading ugly space
3541 ++s;
3542 password[j] = 0;
3543 if (!ISWHITESPACE(password[0]))
3544 {
3545 const char *userlevel = RCon_Authenticate(peeraddress, password, s, endpos, plaintext_matching, NULL, 0);
3546 RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, false);
3547 }
3548 return true;
3549 }
3550 if (!strncmp(string, "extResponse ", 12))
3551 {
3556 dpsnprintf(sv_net_extresponse[sv_net_extresponse_last], sizeof(sv_net_extresponse[sv_net_extresponse_last]), "'%s' %s", addressstring2, string + 12);
3557 return true;
3558 }
3559 if (!strncmp(string, "ping", 4))
3560 {
3562 Con_DPrintf("Received ping from %s, sending ack\n", addressstring2);
3563 NetConn_WriteString(mysocket, "\377\377\377\377ack", peeraddress);
3564 return true;
3565 }
3566 if (!strncmp(string, "ack", 3))
3567 return true;
3568 // we may not have liked the packet, but it was a command packet, so
3569 // we're done processing this packet now
3570 return true;
3571 }
3572 // netquake control packets, supported for compatibility only, and only
3573 // when running game protocols that are normally served via this connection
3574 // protocol
3575 // (this protects more modern protocols against being used for
3576 // Quake packet flood Denial Of Service attacks)
3578 {
3579 int c;
3580 int protocolnumber;
3581 const char *protocolname;
3582 client_t *knownclient;
3583 client_t *newclient;
3584 data += 4;
3585 length -= 4;
3590 switch (c)
3591 {
3592 case CCREQ_CONNECT:
3594 Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_CONNECT from %s.\n", addressstring2);
3595 if(!(islocal || sv_public.integer > -2))
3596 {
3598 Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_REJECT \"%s\" to %s.\n", sv_public_rejectreason.string, addressstring2);
3600 // save space for the header, filled in later
3606 NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
3608 break;
3609 }
3610
3611 protocolname = MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring));
3612 protocolnumber = MSG_ReadByte(&sv_message);
3613 if (strcmp(protocolname, "QUAKE") || protocolnumber != NET_PROTOCOL_VERSION)
3614 {
3616 Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_REJECT \"Incompatible version.\" to %s.\n", addressstring2);
3618 // save space for the header, filled in later
3621 MSG_WriteString(&sv_message, "Incompatible version.\n");
3623 NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
3625 break;
3626 }
3627
3628 // see if this connect request comes from a known client
3629 for (clientnum = 0, knownclient = svs.clients;clientnum < svs.maxclients;clientnum++, knownclient++)
3630 {
3631 if (knownclient->netconnection && LHNETADDRESS_Compare(peeraddress, &knownclient->netconnection->peeraddress) == 0)
3632 {
3633 // this is either a duplicate connection request
3634 // or coming back from a timeout
3635 // (if so, keep their stuff intact)
3636
3637 crypto_t *crypto = Crypto_ServerGetInstance(peeraddress);
3638 if((crypto && crypto->authenticated) || knownclient->netconnection->crypto.authenticated)
3639 {
3641 Con_Printf("Datagram_ParseConnectionless: sending CCREP_REJECT \"Attempt to downgrade crypto.\" to %s.\n", addressstring2);
3643 // save space for the header, filled in later
3646 MSG_WriteString(&sv_message, "Attempt to downgrade crypto.\n");
3648 NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
3650 return true;
3651 }
3652
3653 // send a reply
3655 Con_DPrintf("Datagram_ParseConnectionless: sending duplicate CCREP_ACCEPT to %s.\n", addressstring2);
3657 // save space for the header, filled in later
3662 NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
3664
3665 // if client is already spawned, re-send the
3666 // serverinfo message as they'll need it to play
3667 if (knownclient->begun)
3668 SV_SendServerinfo(knownclient);
3669 return true;
3670 }
3671 }
3672
3673 // this is a new client, check for connection flood
3675 break;
3676
3677 // find a slot for the new client
3678 for (clientnum = 0, newclient = svs.clients;clientnum < svs.maxclients;clientnum++, newclient++)
3679 {
3680 netconn_t *conn;
3681 if (!newclient->active && (newclient->netconnection = conn = NetConn_Open(mysocket, peeraddress)) != NULL)
3682 {
3683 // connect to the client
3684 // everything is allocated, just fill in the details
3685 dp_strlcpy (conn->address, addressstring2, sizeof (conn->address));
3687 Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_ACCEPT to %s.\n", addressstring2);
3688 // send back the info about the server connection
3690 // save space for the header, filled in later
3695 NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
3697 // now set up the client struct
3698 SV_ConnectClient(clientnum, conn);
3700 return true;
3701 }
3702 }
3703
3705 Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_REJECT \"Server is full.\" to %s.\n", addressstring2);
3706 // no room; try to let player know
3708 // save space for the header, filled in later
3711 MSG_WriteString(&sv_message, "Server is full.\n");
3713 NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
3715 break;
3716 case CCREQ_SERVER_INFO:
3718 Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_SERVER_INFO from %s.\n", addressstring2);
3719 if(!(islocal || sv_public.integer > -1))
3720 break;
3721
3723 break;
3724
3725 if (sv.active && !strcmp(MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring)), "QUAKE"))
3726 {
3727 int numclients;
3728 char myaddressstring[128];
3730 Con_DPrintf("Datagram_ParseConnectionless: sending CCREP_SERVER_INFO to %s.\n", addressstring2);
3732 // save space for the header, filled in later
3735 LHNETADDRESS_ToString(LHNET_AddressFromSocket(mysocket), myaddressstring, sizeof(myaddressstring), true);
3736 MSG_WriteString(&sv_message, myaddressstring);
3739 // How many clients are there?
3740 for (i = 0, numclients = 0;i < svs.maxclients;i++)
3741 if (svs.clients[i].active)
3742 numclients++;
3743 MSG_WriteByte(&sv_message, numclients);
3747 NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
3749 }
3750 break;
3751 case CCREQ_PLAYER_INFO:
3753 Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_PLAYER_INFO from %s.\n", addressstring2);
3754 if(!(islocal || sv_public.integer > -1))
3755 break;
3756
3758 break;
3759
3760 if (sv.active)
3761 {
3762 int playerNumber, activeNumber, clientNumber;
3763 client_t *client;
3764
3765 playerNumber = MSG_ReadByte(&sv_message);
3766 activeNumber = -1;
3767 for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++)
3768 if (client->active && ++activeNumber == playerNumber)
3769 break;
3770 if (clientNumber != svs.maxclients)
3771 {
3773 // save space for the header, filled in later
3776 MSG_WriteByte(&sv_message, playerNumber);
3777 MSG_WriteString(&sv_message, client->name);
3778 MSG_WriteLong(&sv_message, client->colors);
3779 MSG_WriteLong(&sv_message, client->frags);
3780 MSG_WriteLong(&sv_message, (int)(host.realtime - client->connecttime));
3782 MSG_WriteString(&sv_message, client->netconnection ? "hidden" : "botclient");
3783 else
3784 MSG_WriteString(&sv_message, client->netconnection ? client->netconnection->address : "botclient");
3786 NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
3788 }
3789 }
3790 break;
3791 case CCREQ_RULE_INFO:
3793 Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_RULE_INFO from %s.\n", addressstring2);
3794 if(!(islocal || sv_public.integer > -1))
3795 break;
3796
3797 // no flood check here, as it only returns one cvar for one cvar and clients may iterate quickly
3798
3799 if (sv.active)
3800 {
3801 char *prevCvarName;
3802 cvar_t *var;
3803
3804 // find the search start location
3805 prevCvarName = MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring));
3806 var = Cvar_FindVarAfter(&cvars_all, prevCvarName, CF_NOTIFY);
3807
3808 // send the response
3810 // save space for the header, filled in later
3813 if (var)
3814 {
3817 }
3819 NetConn_Write(mysocket, sv_message.data, sv_message.cursize, peeraddress);
3821 }
3822 break;
3823 case CCREQ_RCON:
3825 Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_RCON from %s.\n", addressstring2);
3826 if (sv.active && !rcon_secure.integer)
3827 {
3828 char password[2048];
3829 char cmd[2048];
3830 char *s;
3831 char *endpos;
3832 const char *userlevel;
3833 dp_strlcpy(password, MSG_ReadString(&sv_message, sv_readstring, sizeof(sv_readstring)), sizeof(password));
3835 s = cmd;
3836 endpos = cmd + strlen(cmd) + 1; // one behind the NUL, so adding strlen+1 will eventually reach it
3837 userlevel = RCon_Authenticate(peeraddress, password, s, endpos, plaintext_matching, NULL, 0);
3838 RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, true);
3839 return true;
3840 }
3841 break;
3842 default:
3843 break;
3844 }
3846 // we may not have liked the packet, but it was a valid control
3847 // packet, so we're done processing this packet now
3848 return true;
3849 }
3850 if (host_client)
3851 {
3853 {
3855 return ret;
3856 }
3857 }
3858 return 0;
3859}
#define CF_NOTIFY
cvar should trigger a chat notification to all connected clients when changed
Definition cmd.h:55
void MSG_WriteUnterminatedString(sizebuf_t *sb, const char *s)
Definition com_msg.c:181
@ PROTOCOL_DARKPLACES2
various changes
Definition common.h:140
@ PROTOCOL_NEHAHRABJP2
same as NEHAHRABJP but with 16bit soundindex
Definition common.h:147
@ PROTOCOL_NEHAHRABJP
same as QUAKEDP but with 16bit modelindex
Definition common.h:146
@ PROTOCOL_QUAKEDP
darkplaces extended quake protocol (used by TomazQuake and others), backwards compatible as long as n...
Definition common.h:142
@ PROTOCOL_NEHAHRABJP3
same as NEHAHRABJP2 but with some changes
Definition common.h:148
@ PROTOCOL_NEHAHRAMOVIE
Nehahra movie protocol, a big nasty hack dating back to early days of the Quake Standards Group (but ...
Definition common.h:143
@ PROTOCOL_DARKPLACES1
uses EntityFrame entity snapshot encoder/decoder which is a QuakeWorld-like entity snapshot delta com...
Definition common.h:141
crypto_t * Crypto_ServerGetInstance(lhnetaddress_t *peeraddress)
Definition crypto.c:573
cvar_t crypto_developer
Definition crypto.c:30
int Crypto_ServerParsePacket(const char *data_in, size_t len_in, char *data_out, size_t *len_out, lhnetaddress_t *peeraddress)
Definition crypto.c:2036
qbool Crypto_ServerAppendToChallenge(const char *data_in, size_t len_in, char *data_out, size_t *len_out, size_t maxlen_out)
Definition crypto.c:1696
cvar_state_t cvars_all
Definition cvar.c:28
cvar_t * Cvar_FindVarAfter(cvar_state_t *cvars, const char *prev_var_name, unsigned neededflags)
Definition cvar.c:53
int LHNETADDRESS_GetPort(const lhnetaddress_t *address)
Definition lhnet.c:635
void cmd(string command,...)
static void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const char *addressstring2, const char *userlevel, const char *s, const char *endpos, qbool proquakeprotocol)
Definition netconn.c:3152
static qbool NetConn_BuildStatusResponse(const char *challenge, char *out_msg, size_t out_size, qbool fullstatus)
(div0) build the full response only if possible; better a getinfo response than no response at all if...
Definition netconn.c:2757
unsigned sv_net_extresponse_count
Definition netconn.c:165
char sv_net_extresponse[NET_EXTRESPONSE_MAX][1400]
Definition netconn.c:164
static qbool hmac_mdfour_challenge_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
Definition netconn.c:3009
unsigned sv_net_extresponse_last
Definition netconn.c:166
char sv_readstring[MAX_INPUTLINE]
Definition netconn.c:76
static void NetConn_BuildChallengeString(char *buffer, int bufferlength)
Definition netconn.c:2741
cvar_t rcon_secure
Definition console.c:90
static qbool hmac_mdfour_time_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
Definition netconn.c:2988
static qbool NetConn_PreventFlood(lhnetaddress_t *peeraddress, server_floodaddress_t *floodlist, size_t floodlength, double floodtime, qbool renew)
Definition netconn.c:2923
cvar_t sv_status_privacy
Definition sv_ccmds.c:30
static qbool plaintext_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
Definition netconn.c:3043
static const char * RCon_Authenticate(lhnetaddress_t *peeraddress, const char *password, const char *s, const char *endpos, rcon_matchfunc_t comparator, const char *cs, int cslen)
returns a string describing the user level, or NULL for auth failure
Definition netconn.c:3054
#define CCREQ_PLAYER_INFO
Definition netconn.h:121
#define CCREQ_RULE_INFO
Definition netconn.h:122
#define CCREQ_SERVER_INFO
Definition netconn.h:120
#define CCREQ_RCON
Definition netconn.h:123
void SV_ReadClientMessage(void)
Definition sv_user.c:985
void SV_SendServerinfo(client_t *client)
Definition sv_main.c:749
client_t * host_client
Definition sv_main.c:29
void SV_ConnectClient(int clientnum, netconn_t *netconnection)
Definition sv_main.c:936
lhnetaddress_t address
Definition netconn.h:479
qbool begun
false = don't send datagrams
Definition server.h:193
double connecttime
realtime this client connected
Definition server.h:204
Definition cvar.h:66
const char * name
Definition cvar.h:69
server_floodaddress_t getstatusfloodaddresses[MAX_GETSTATUSFLOODADDRESSES]
Definition server.h:141
protocolversion_t protocol
one of the PROTOCOL_ values
Definition server.h:74

References client_t::active, server_t::active, challenge_t::address, netconn_t::address, crypto_t::authenticated, client_t::begun, BuffBigLong(), CCREP_ACCEPT, CCREP_PLAYER_INFO, CCREP_REJECT, CCREP_RULE_INFO, CCREP_SERVER_INFO, CCREQ_CONNECT, CCREQ_PLAYER_INFO, CCREQ_RCON, CCREQ_RULE_INFO, CCREQ_SERVER_INFO, CF_NOTIFY, challenges, crypto_t::client_idfp, crypto_t::client_issigned, crypto_t::client_keyfp, server_static_t::clients, cmd(), client_t::colors, Com_HexDumpToConsole(), Con_DPrintf(), Con_Printf(), server_t::connectfloodaddresses, client_t::connecttime, netconn_t::crypto, crypto_developer, CRYPTO_DISCARD, Crypto_FinishInstance(), CRYPTO_HEADERSIZE, crypto_keyfp_recommended_length, CRYPTO_MATCH, CRYPTO_NOMATCH, CRYPTO_REPLACE, Crypto_ServerAppendToChallenge(), Crypto_ServerGetInstance(), Crypto_ServerParsePacket(), sizebuf_t::cursize, Cvar_FindVarAfter(), cvars_all, data, sizebuf_t::data, developer_extra, dp_strlcpy, dpsnprintf(), ENCRYPTION_REQUIRED, client_t::frags, server_t::getstatusfloodaddresses, hmac_mdfour_challenge_matching(), hmac_mdfour_time_matching(), host, host_client, hostname, i, InfoString_GetValue(), int(), cvar_t::integer, ISWHITESPACE, length, LHNET_AddressFromSocket(), LHNETADDRESS_Compare(), LHNETADDRESS_GetAddressType(), LHNETADDRESS_GetPort(), LHNETADDRESS_ToString(), LHNETADDRESSTYPE_LOOP, MAX_CHALLENGES, MAX_INPUTLINE, server_static_t::maxclients, min, MSG_BeginReading(), MSG_ReadByte, MSG_ReadString(), MSG_WriteByte(), MSG_WriteLong(), MSG_WriteString(), MSG_WriteUnterminatedString(), netconn_t::mysocket, client_t::name, cvar_t::name, net_challengefloodblockingtimeout, net_connect_entnum_ofs, net_connectfloodblockingtimeout, net_connecttimeout, NET_EXTRESPONSE_MAX, net_getstatusfloodblockingtimeout, NET_HEADERSIZE, NET_MAXMESSAGE, net_messagetimeout, NET_PROTOCOL_VERSION, NetConn_BuildChallengeString(), NetConn_BuildStatusResponse(), NetConn_Heartbeat(), NetConn_Open(), NetConn_PreventFlood(), NetConn_ReceivedMessage(), NetConn_Write(), NetConn_WriteString(), client_t::netconnection, NETFLAG_CTL, NETFLAG_LENGTH_MASK, NULL, netconn_t::peeraddress, plaintext_matching(), server_t::protocol, PROTOCOL_DARKPLACES1, PROTOCOL_DARKPLACES2, PROTOCOL_DARKPLACES3, PROTOCOL_NEHAHRABJP, PROTOCOL_NEHAHRABJP2, PROTOCOL_NEHAHRABJP3, PROTOCOL_NEHAHRAMOVIE, PROTOCOL_QUAKE, PROTOCOL_QUAKEDP, RCon_Authenticate(), RCon_Execute(), rcon_secure, host_static_t::realtime, ret, crypto_t::server_idfp, crypto_t::server_issigned, crypto_t::server_keyfp, StoreBigLong(), cvar_t::string, string, strlen(), sv, SV_ConnectClient(), sv_message, sv_net_extresponse, sv_net_extresponse_count, sv_net_extresponse_last, sv_public, sv_public_rejectreason, SV_ReadClientMessage(), sv_readstring, SV_SendServerinfo(), sv_status_privacy, svs, SZ_Clear(), SZ_Write(), challenge_t::time, time, crypto_t::use_aes, cvar_t::value, and server_t::worldbasename.

Referenced by NetConn_ServerFrame().

◆ NetConn_Shutdown()

void NetConn_Shutdown ( void )

Definition at line 4201 of file netconn.c.

4202{
4206 if (netconn_mutex)
4209}
void LHNET_Shutdown(void)
Definition lhnet.c:751
#define Thread_DestroyMutex(m)
Definition thread.h:16

References LHNET_Shutdown(), NetConn_CloseClientPorts(), NetConn_CloseServerPorts(), netconn_mutex, NULL, and Thread_DestroyMutex.

Referenced by Host_Shutdown().

◆ NetConn_sv_netport_Callback()

static void NetConn_sv_netport_Callback ( cvar_t * var)
static

Definition at line 1296 of file netconn.c.

1297{
1298 if (hostport != var->integer)
1299 {
1300 hostport = var->integer;
1301 if (sv.active)
1302 Con_Print("Changing \"port\" will not take effect until \"map\" command is executed.\n");
1303 }
1304}
static int hostport
Definition netconn.c:1293

References server_t::active, Con_Print(), hostport, cvar_t::integer, and sv.

Referenced by NetConn_Init().

◆ NetConn_UpdateCleartime()

static void NetConn_UpdateCleartime ( double * cleartime,
int rate,
int burstsize,
int len )
static

Definition at line 806 of file netconn.c.

807{
808 double bursttime = burstsize / (double)rate;
809
810 // delay later packets to obey rate limit
811 if (*cleartime < host.realtime - bursttime)
812 *cleartime = host.realtime - bursttime;
813 *cleartime = *cleartime + len / (double)rate;
814
815 // limit bursts to one packet in size ("dialup mode" emulating old behaviour)
816 if (net_test.integer)
817 {
818 if (*cleartime < host.realtime)
819 *cleartime = host.realtime;
820 }
821}

References host, cvar_t::integer, net_test, and host_static_t::realtime.

Referenced by NetConn_ReceivedMessage(), and NetConn_SendUnreliableMessage().

◆ NetConn_UpdateSockets()

void NetConn_UpdateSockets ( void )

Definition at line 1306 of file netconn.c.

1307{
1308 int i, j;
1309
1310 // TODO add logic to automatically close sockets if needed
1312
1313 for (j = 0;j < MAX_RCONS;j++)
1314 {
1315 i = (cls.rcon_ringpos + j + 1) % MAX_RCONS;
1316 if(cls.rcon_commands[i][0])
1317 {
1319 {
1320 char s[128];
1321 LHNETADDRESS_ToString(&cls.rcon_addresses[i], s, sizeof(s), true);
1322 Con_Printf("rcon to %s (for command %s) failed: challenge request timed out\n", s, cls.rcon_commands[i]);
1323 cls.rcon_commands[i][0] = 0;
1324 --cls.rcon_trying;
1325 break;
1326 }
1327 }
1328 }
1329}
int LHNET_DefaultDSCP(int dscp)
Definition lhnet.c:739

References cls, Con_Printf(), host, i, cvar_t::integer, LHNET_DefaultDSCP(), LHNETADDRESS_ToString(), MAX_RCONS, net_tos_dscp, client_static_t::rcon_addresses, client_static_t::rcon_commands, client_static_t::rcon_ringpos, client_static_t::rcon_timeout, client_static_t::rcon_trying, and host_static_t::realtime.

Referenced by CL_EstablishConnection(), CL_PlayDemo(), CL_StartVideo(), Host_Frame(), NetConn_ClientFrame(), and NetConn_OpenServerPorts().

◆ NetConn_Write()

int NetConn_Write ( lhnetsocket_t * mysocket,
const void * data,
int length,
const lhnetaddress_t * peeraddress )

Definition at line 758 of file netconn.c.

759{
760 int ret;
761 unsigned i;
762
764 for (i = 0;i < cl_numsockets;i++)
765 if (cl_sockets[i] == mysocket && (rand() % 100) < net_fakeloss_send.integer)
766 return length;
769 ret = LHNET_Write(mysocket, data, length, peeraddress);
773 {
774 char addressstring[128], addressstring2[128];
775 LHNETADDRESS_ToString(LHNET_AddressFromSocket(mysocket), addressstring, sizeof(addressstring), true);
776 LHNETADDRESS_ToString(peeraddress, addressstring2, sizeof(addressstring2), true);
777 Con_Printf("LHNET_Write(%p (%s), %p, %i, %p (%s)) = %i%s\n", (void *)mysocket, addressstring, (void *)data, length, (void *)peeraddress, addressstring2, length, ret == length ? "" : " (ERROR)");
778 Com_HexDumpToConsole((unsigned char *)data, length);
779 }
780 return ret;
781}
int LHNET_Write(lhnetsocket_t *lhnetsocket, const void *content, int contentlength, const lhnetaddress_t *vaddress)
Definition lhnet.c:1135

References lhnetsocket_t::address, lhnetaddress_t::addresstype, cl_numsockets, cl_sockets, Com_HexDumpToConsole(), Con_Printf(), data, developer_networking, i, cvar_t::integer, length, LHNET_AddressFromSocket(), LHNET_Write(), LHNETADDRESS_ToString(), LHNETADDRESSTYPE_LOOP, net_fakeloss_send, netconn_mutex, ret, Thread_LockMutex, and Thread_UnlockMutex.

Referenced by CL_Packet_f(), CL_PQRcon_f(), CL_Rcon_f(), Con_Rcon_Redirect_Flush(), NetConn_ClientFrame(), NetConn_ClientParsePacket(), NetConn_ReceivedMessage(), NetConn_SendUnreliableMessage(), NetConn_ServerParsePacket(), and NetConn_WriteString().

◆ NetConn_WriteString()

int NetConn_WriteString ( lhnetsocket_t * mysocket,
const char * string,
const lhnetaddress_t * peeraddress )

Definition at line 783 of file netconn.c.

784{
785 // note this does not include the trailing NULL because we add that in the parser
786 return NetConn_Write(mysocket, string, (int)strlen(string), peeraddress);
787}

References NetConn_Write(), and strlen().

Referenced by CL_Rcon_f(), Log_DestBuffer_Flush_NoLock(), NetConn_ClientFrame(), NetConn_ClientParsePacket(), NetConn_Heartbeat(), and NetConn_ServerParsePacket().

◆ plaintext_matching()

static qbool plaintext_matching ( lhnetaddress_t * peeraddress,
const char * password,
const char * hash,
const char * s,
int slen )
static

Definition at line 3043 of file netconn.c.

3044{
3045 if (!password[0]) {
3046 Con_Print(CON_ERROR "LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
3047 return false;
3048 }
3049
3050 return !strcmp(password, hash);
3051}

References CON_ERROR, and Con_Print().

Referenced by NetConn_ServerParsePacket().

◆ PrintStats()

static void PrintStats ( netconn_t * conn)
static

Definition at line 4025 of file netconn.c.

4026{
4028 Con_Printf("address=%21s canSend=%u sendSeq=%6u recvSeq=%6u\n", conn->address, !conn->sendMessageLength, conn->outgoing_unreliable_sequence, conn->qw.incoming_sequence);
4029 else
4030 Con_Printf("address=%21s canSend=%u sendSeq=%6u recvSeq=%6u\n", conn->address, !conn->sendMessageLength, conn->nq.sendSequence, conn->nq.receiveSequence);
4031 Con_Printf("unreliable messages sent = %i\n", conn->unreliableMessagesSent);
4032 Con_Printf("unreliable messages recv = %i\n", conn->unreliableMessagesReceived);
4033 Con_Printf("reliable messages sent = %i\n", conn->reliableMessagesSent);
4034 Con_Printf("reliable messages received = %i\n", conn->reliableMessagesReceived);
4035 Con_Printf("packetsSent = %i\n", conn->packetsSent);
4036 Con_Printf("packetsReSent = %i\n", conn->packetsReSent);
4037 Con_Printf("packetsReceived = %i\n", conn->packetsReceived);
4038 Con_Printf("receivedDuplicateCount = %i\n", conn->receivedDuplicateCount);
4039 Con_Printf("droppedDatagrams = %i\n", conn->droppedDatagrams);
4040}

References server_t::active, netconn_t::address, ca_connected, cls, Con_Printf(), netconn_t::droppedDatagrams, netconn_t::netconn_qw_s::incoming_sequence, netconn_t::nq, netconn_t::outgoing_unreliable_sequence, netconn_t::packetsReceived, netconn_t::packetsReSent, netconn_t::packetsSent, client_static_t::protocol, server_t::protocol, PROTOCOL_QUAKEWORLD, netconn_t::qw, netconn_t::receivedDuplicateCount, netconn_t::netconn_nq_s::receiveSequence, netconn_t::reliableMessagesReceived, netconn_t::reliableMessagesSent, netconn_t::sendMessageLength, netconn_t::netconn_nq_s::sendSequence, client_static_t::state, sv, netconn_t::unreliableMessagesReceived, and netconn_t::unreliableMessagesSent.

Referenced by Net_Stats_f().

◆ RCon_Authenticate()

static const char * RCon_Authenticate ( lhnetaddress_t * peeraddress,
const char * password,
const char * s,
const char * endpos,
rcon_matchfunc_t comparator,
const char * cs,
int cslen )
static

returns a string describing the user level, or NULL for auth failure

Definition at line 3054 of file netconn.c.

3055{
3056 const char *text, *userpass_start, *userpass_end, *userpass_startpass;
3057 static char buf[MAX_INPUTLINE];
3058 qbool hasquotes;
3059 qbool restricted = false;
3060 qbool have_usernames = false;
3061 static char vabuf[1024];
3062
3063 userpass_start = rcon_password.string;
3064 while((userpass_end = strchr(userpass_start, ' ')))
3065 {
3066 have_usernames = true;
3067 dp_ustr2stp(buf, sizeof(buf), userpass_start, userpass_end - userpass_start);
3068 if(buf[0]) // Ignore empty entries due to leading/duplicate space.
3069 if(comparator(peeraddress, buf, password, cs, cslen))
3070 goto allow;
3071 userpass_start = userpass_end + 1;
3072 }
3073 if(userpass_start[0]) // Ignore empty trailing entry due to trailing space or password not set.
3074 {
3075 userpass_end = userpass_start + strlen(userpass_start);
3076 if(comparator(peeraddress, userpass_start, password, cs, cslen))
3077 goto allow;
3078 }
3079
3080 restricted = true;
3081 have_usernames = false;
3082 userpass_start = rcon_restricted_password.string;
3083 while((userpass_end = strchr(userpass_start, ' ')))
3084 {
3085 have_usernames = true;
3086 dp_ustr2stp(buf, sizeof(buf), userpass_start, userpass_end - userpass_start);
3087 if(buf[0]) // Ignore empty entries due to leading/duplicate space.
3088 if(comparator(peeraddress, buf, password, cs, cslen))
3089 goto check;
3090 userpass_start = userpass_end + 1;
3091 }
3092 if(userpass_start[0]) // Ignore empty trailing entry due to trailing space or password not set.
3093 {
3094 userpass_end = userpass_start + strlen(userpass_start);
3095 if(comparator(peeraddress, userpass_start, password, cs, cslen))
3096 goto check;
3097 }
3098
3099 return NULL; // DENIED
3100
3101check:
3102 for(text = s; text != endpos; ++text)
3103 if((signed char) *text > 0 && ((signed char) *text < (signed char) ' ' || *text == ';'))
3104 return NULL; // block possible exploits against the parser/alias expansion
3105
3106 while(s != endpos)
3107 {
3108 size_t l = strlen(s);
3109 if(l)
3110 {
3111 hasquotes = (strchr(s, '"') != NULL);
3112 // sorry, we can't allow these substrings in wildcard expressions,
3113 // as they can mess with the argument counts
3115 while(COM_ParseToken_Console(&text))
3116 {
3117 // com_token now contains a pattern to check for...
3118 if(strchr(com_token, '*') || strchr(com_token, '?')) // wildcard expression, * can only match a SINGLE argument
3119 {
3120 if(!hasquotes)
3121 if(matchpattern_with_separator(s, com_token, true, " ", true)) // note how we excluded tab, newline etc. above
3122 goto match;
3123 }
3124 else if(strchr(com_token, ' ')) // multi-arg expression? must match in whole
3125 {
3126 if(!strcmp(com_token, s))
3127 goto match;
3128 }
3129 else // single-arg expression? must match the beginning of the command
3130 {
3131 if(!strcmp(com_token, s))
3132 goto match;
3133 if(!memcmp(va(vabuf, sizeof(vabuf), "%s ", com_token), s, strlen(com_token) + 1))
3134 goto match;
3135 }
3136 }
3137 // if we got here, nothing matched!
3138 return NULL;
3139 }
3140match:
3141 s += l + 1;
3142 }
3143
3144allow:
3145 userpass_startpass = strchr(userpass_start, ':');
3146 if(have_usernames && userpass_startpass && userpass_startpass < userpass_end)
3147 return va(vabuf, sizeof(vabuf), "%srcon (username %.*s)", restricted ? "restricted " : "", (int)(userpass_startpass-userpass_start), userpass_start);
3148
3149 return va(vabuf, sizeof(vabuf), "%srcon", restricted ? "restricted " : "");
3150}
char * dp_ustr2stp(char *dst, size_t dsize, const char *src, size_t slen)
Copies a measured byte sequence (unterminated string) to a null-terminated string.
Definition common.c:1388
char com_token[MAX_INPUTLINE]
Definition common.c:39
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
qbool COM_ParseToken_Console(const char **datapointer)
Definition common.c:819
int matchpattern_with_separator(const char *in, const char *pattern, int caseinsensitive, const char *separators, qbool wildcard_least_one)
Definition filematch.c:23

References buf, COM_ParseToken_Console(), com_token, dp_ustr2stp(), matchpattern_with_separator(), MAX_INPUTLINE, NULL, rcon_password, rcon_restricted_commands, rcon_restricted_password, cvar_t::string, strlen(), and va().

Referenced by NetConn_ServerParsePacket().

◆ RCon_Execute()

static void RCon_Execute ( lhnetsocket_t * mysocket,
lhnetaddress_t * peeraddress,
const char * addressstring2,
const char * userlevel,
const char * s,
const char * endpos,
qbool proquakeprotocol )
static

Definition at line 3152 of file netconn.c.

3153{
3154 if(userlevel)
3155 {
3156 // looks like a legitimate rcon command with the correct password
3157 const char *s_ptr = s;
3158 Con_Printf("server received %s command from %s: ", userlevel, host_client ? host_client->name : addressstring2);
3159 while(s_ptr != endpos)
3160 {
3161 size_t l = strlen(s_ptr);
3162 if(l)
3163 Con_Printf(" %s;", s_ptr);
3164 s_ptr += l + 1;
3165 }
3166 Con_Printf("\n");
3167
3169 Con_Rcon_Redirect_Init(mysocket, peeraddress, proquakeprotocol);
3170 while(s != endpos)
3171 {
3172 size_t l = strlen(s);
3173 if(l)
3174 {
3175 client_t *host_client_save = host_client;
3177 host_client = host_client_save;
3178 // in case it is a command that changes host_client (like restart)
3179 }
3180 s += l + 1;
3181 }
3183 }
3184 else
3185 {
3187 Con_Rcon_Redirect_Init(mysocket, peeraddress, proquakeprotocol);
3188 Con_Printf(CON_ERROR "server denied rcon access to %s\n", host_client ? host_client->name : addressstring2);
3190 }
3191}
cmd_state_t * cmd_local
command interpreter for local commands injected by SVQC, CSQC, MQC, server or client engine code uses...
Definition cmd.c:25
void Cmd_PreprocessAndExecuteString(cmd_state_t *cmd, const char *text, size_t textlen, cmd_source_t src, qbool lockmutex)
Like Cmd_ExecuteString, but with variable expansion.
Definition cmd.c:1323
@ src_local
from the command buffer
Definition cmd.h:75
void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest, qbool proquakeprotocol)
Definition console.c:1004
void Con_Rcon_Redirect_End(void)
Definition console.c:1041

References cmd_local, Cmd_PreprocessAndExecuteString(), CON_ERROR, Con_Printf(), Con_Rcon_Redirect_End(), Con_Rcon_Redirect_Init(), host_client, LHNETADDRESS_GetAddressType(), LHNETADDRESSTYPE_LOOP, client_t::name, client_t::netconnection, netconn_t::peeraddress, src_local, and strlen().

Referenced by NetConn_ServerParsePacket().

Variable Documentation

◆ challenges

◆ cl_message

◆ cl_message_buf

unsigned char cl_message_buf[NET_MAXMESSAGE]
static

Definition at line 73 of file netconn.c.

Referenced by NetConn_Init().

◆ cl_net_extresponse

char cl_net_extresponse[NET_EXTRESPONSE_MAX][1400]

Definition at line 160 of file netconn.c.

Referenced by NetConn_ClientParsePacket(), and VM_CL_getextresponse().

◆ cl_net_extresponse_count

unsigned cl_net_extresponse_count = 0

Definition at line 161 of file netconn.c.

Referenced by NetConn_ClientParsePacket(), and VM_CL_getextresponse().

◆ cl_net_extresponse_last

unsigned cl_net_extresponse_last = 0

Definition at line 162 of file netconn.c.

Referenced by NetConn_ClientParsePacket(), and VM_CL_getextresponse().

◆ cl_netport

cvar_t cl_netport = {CF_CLIENT, "cl_port", "0", "forces client to use chosen port number if not 0"}

Definition at line 155 of file netconn.c.

155{CF_CLIENT, "cl_port", "0", "forces client to use chosen port number if not 0"};

Referenced by CL_DisconnectEx(), CL_Init(), NetConn_Init(), and NetConn_OpenClientPorts().

◆ cl_numsockets

◆ cl_readstring

◆ cl_sockets

◆ clientport

int clientport = -1
static

Definition at line 1268 of file netconn.c.

Referenced by NetConn_CL_UpdateSockets_Callback().

◆ clientport2

int clientport2 = -1
static

Definition at line 1269 of file netconn.c.

Referenced by NetConn_CL_UpdateSockets_Callback().

◆ developer_networking

cvar_t developer_networking = {CF_CLIENT | CF_SERVER, "developer_networking", "0", "prints all received and sent packets (recommended only for debugging)"}

Definition at line 89 of file netconn.c.

89{CF_CLIENT | CF_SERVER, "developer_networking", "0", "prints all received and sent packets (recommended only for debugging)"};

Referenced by Crypto_DecryptPacket(), Crypto_EncryptPacket(), NetConn_ClientParsePacket(), NetConn_Init(), NetConn_Read(), NetConn_SendUnreliableMessage(), NetConn_Write(), and SV_ReadClientMessage().

◆ gameversion

cvar_t gameversion = {CF_SERVER, "gameversion", "0", "version of game data (mod-specific) to be sent to querying clients"}
static

Definition at line 108 of file netconn.c.

108{CF_SERVER, "gameversion", "0", "version of game data (mod-specific) to be sent to querying clients"};

Referenced by NetConn_BuildStatusResponse(), and NetConn_Init().

◆ gameversion_max

cvar_t gameversion_max = {CF_CLIENT | CF_SERVER, "gameversion_max", "-1", "maximum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"}
static

Definition at line 110 of file netconn.c.

110{CF_CLIENT | CF_SERVER, "gameversion_max", "-1", "maximum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"};

Referenced by NetConn_Init().

◆ gameversion_min

cvar_t gameversion_min = {CF_CLIENT | CF_SERVER, "gameversion_min", "-1", "minimum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"}
static

Definition at line 109 of file netconn.c.

109{CF_CLIENT | CF_SERVER, "gameversion_min", "-1", "minimum version of game data (mod-specific), when client and server gameversion mismatch in the server browser the server is shown as incompatible; if -1, gameversion is used alone"};

Referenced by NetConn_Init().

◆ hostname

cvar_t hostname = {CF_SERVER | CF_ARCHIVE, "hostname", "UNNAMED", "server message to show in server browser"}

Definition at line 88 of file netconn.c.

88{CF_SERVER | CF_ARCHIVE, "hostname", "UNNAMED", "server message to show in server browser"};
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53

Referenced by M_GameOptions_Draw(), M_GameOptions_Key(), NetConn_BuildStatusResponse(), NetConn_Init(), NetConn_ServerParsePacket(), SV_Pause_f(), SV_Say(), SV_SpawnServer(), and SV_Tell_f().

◆ hostport

int hostport = -1
static

Definition at line 1293 of file netconn.c.

Referenced by NetConn_sv_netport_Callback().

◆ masterquerycount

unsigned masterquerycount = 0

Definition at line 118 of file netconn.c.

Referenced by M_ServerList_Draw(), and VM_M_getserverliststat().

◆ masterquerytime

double masterquerytime = -1000

Definition at line 117 of file netconn.c.

Referenced by M_ServerList_Draw().

◆ masterreplycount

unsigned masterreplycount = 0

Definition at line 119 of file netconn.c.

Referenced by M_ServerList_Draw(), and VM_M_getserverliststat().

◆ net_address

cvar_t net_address = {CF_CLIENT | CF_SERVER, "net_address", "", "network address to open ipv4 ports on (if empty, use default interfaces)"}

Definition at line 157 of file netconn.c.

157{CF_CLIENT | CF_SERVER, "net_address", "", "network address to open ipv4 ports on (if empty, use default interfaces)"};

Referenced by NetConn_Init(), NetConn_OpenClientPorts(), and NetConn_OpenServerPorts().

◆ net_address_ipv6

cvar_t net_address_ipv6 = {CF_CLIENT | CF_SERVER, "net_address_ipv6", "", "network address to open ipv6 ports on (if empty, use default interfaces)"}

Definition at line 158 of file netconn.c.

158{CF_CLIENT | CF_SERVER, "net_address_ipv6", "", "network address to open ipv6 ports on (if empty, use default interfaces)"};

Referenced by NetConn_Init(), NetConn_OpenClientPorts(), and NetConn_OpenServerPorts().

◆ net_burstreserve

cvar_t net_burstreserve = {CF_SERVER, "net_burstreserve", "0.3", "how much of the burst time to reserve for packet size spikes"}

Definition at line 80 of file netconn.c.

80{CF_SERVER, "net_burstreserve", "0.3", "how much of the burst time to reserve for packet size spikes"};

Referenced by NetConn_Init(), and SV_SendClientDatagram().

◆ net_challengefloodblockingtimeout

cvar_t net_challengefloodblockingtimeout = {CF_SERVER, "net_challengefloodblockingtimeout", "0.5", "when a challenge packet is received, it will block all future challenge packets from that IP address for this many seconds (cuts down on challenge floods). DarkPlaces clients retry once per second, so this should be <= 1. Failure here may lead to connect attempts failing."}

Definition at line 85 of file netconn.c.

85{CF_SERVER, "net_challengefloodblockingtimeout", "0.5", "when a challenge packet is received, it will block all future challenge packets from that IP address for this many seconds (cuts down on challenge floods). DarkPlaces clients retry once per second, so this should be <= 1. Failure here may lead to connect attempts failing."};

Referenced by NetConn_Init(), and NetConn_ServerParsePacket().

◆ net_connect_entnum_ofs

cvar_t net_connect_entnum_ofs = {CF_SERVER, "net_connect_entnum_ofs", "0", "entity number offset of human clients (for developer testing only)"}

Definition at line 83 of file netconn.c.

83{CF_SERVER, "net_connect_entnum_ofs", "0", "entity number offset of human clients (for developer testing only)"};

Referenced by NetConn_Init(), and NetConn_ServerParsePacket().

◆ net_connectfloodblockingtimeout

cvar_t net_connectfloodblockingtimeout = {CF_SERVER, "net_connectfloodblockingtimeout", "5", "when a connection packet is received, it will block all future connect packets from that IP address for this many seconds (cuts down on connect floods). Note that this does not include retries from the same IP; these are handled earlier and let in."}

Definition at line 84 of file netconn.c.

84{CF_SERVER, "net_connectfloodblockingtimeout", "5", "when a connection packet is received, it will block all future connect packets from that IP address for this many seconds (cuts down on connect floods). Note that this does not include retries from the same IP; these are handled earlier and let in."};

Referenced by NetConn_Init(), and NetConn_ServerParsePacket().

◆ net_connecttimeout

cvar_t net_connecttimeout = {CF_CLIENT | CF_SERVER, "net_connecttimeout","15", "after requesting a connection, the client must reply within this many seconds or be dropped (cuts down on connect floods). Must be above 10 seconds."}

Definition at line 82 of file netconn.c.

82{CF_CLIENT | CF_SERVER, "net_connecttimeout","15", "after requesting a connection, the client must reply within this many seconds or be dropped (cuts down on connect floods). Must be above 10 seconds."};

Referenced by NetConn_Init(), NetConn_Open(), NetConn_ServerParsePacket(), and SV_SendServerinfo().

◆ net_fakelag

cvar_t net_fakelag = {CF_CLIENT, "net_fakelag","0", "lags local loopback connection by this much ping time (useful to play more fairly on your own server with people with higher pings)"}

Definition at line 91 of file netconn.c.

91{CF_CLIENT, "net_fakelag","0", "lags local loopback connection by this much ping time (useful to play more fairly on your own server with people with higher pings)"};

Referenced by LHNET_Read(), and NetConn_Init().

◆ net_fakeloss_receive

cvar_t net_fakeloss_receive = {CF_CLIENT, "net_fakeloss_receive","0", "drops this percentage of incoming packets, useful for testing network protocol robustness (jerky movement, effects failing to start, sounds failing to play, etc)"}
static

Definition at line 93 of file netconn.c.

93{CF_CLIENT, "net_fakeloss_receive","0", "drops this percentage of incoming packets, useful for testing network protocol robustness (jerky movement, effects failing to start, sounds failing to play, etc)"};

Referenced by NetConn_Init(), and NetConn_Read().

◆ net_fakeloss_send

cvar_t net_fakeloss_send = {CF_CLIENT, "net_fakeloss_send","0", "drops this percentage of outgoing packets, useful for testing network protocol robustness (jerky movement, prediction errors, etc)"}
static

Definition at line 92 of file netconn.c.

92{CF_CLIENT, "net_fakeloss_send","0", "drops this percentage of outgoing packets, useful for testing network protocol robustness (jerky movement, prediction errors, etc)"};

Referenced by NetConn_Init(), and NetConn_Write().

◆ net_getstatusfloodblockingtimeout

cvar_t net_getstatusfloodblockingtimeout = {CF_SERVER, "net_getstatusfloodblockingtimeout", "1", "when a getstatus packet is received, it will block all future getstatus packets from that IP address for this many seconds (cuts down on getstatus floods). DarkPlaces retries every net_slist_timeout seconds, and qstat retries once per second, so this should be <= 1. Failure here may lead to server not showing up in the server list."}

Definition at line 86 of file netconn.c.

86{CF_SERVER, "net_getstatusfloodblockingtimeout", "1", "when a getstatus packet is received, it will block all future getstatus packets from that IP address for this many seconds (cuts down on getstatus floods). DarkPlaces retries every net_slist_timeout seconds, and qstat retries once per second, so this should be <= 1. Failure here may lead to server not showing up in the server list."};

Referenced by NetConn_Init(), and NetConn_ServerParsePacket().

◆ net_messagetimeout

cvar_t net_messagetimeout = {CF_CLIENT | CF_SERVER, "net_messagetimeout","300", "drops players who have not sent any packets for this many seconds"}

Definition at line 81 of file netconn.c.

81{CF_CLIENT | CF_SERVER, "net_messagetimeout","300", "drops players who have not sent any packets for this many seconds"};

Referenced by NetConn_ClientParsePacket(), NetConn_Init(), and NetConn_ServerParsePacket().

◆ net_sourceaddresscheck

cvar_t net_sourceaddresscheck = {CF_CLIENT, "net_sourceaddresscheck", "1", "compare the source IP address for replies (more secure, may break some bad multihoming setups"}

Definition at line 87 of file netconn.c.

87{CF_CLIENT, "net_sourceaddresscheck", "1", "compare the source IP address for replies (more secure, may break some bad multihoming setups"};

Referenced by Crypto_ClientParsePacket(), NetConn_ClientParsePacket(), and NetConn_Init().

◆ net_test

cvar_t net_test = {CF_CLIENT | CF_SERVER, "net_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"}

Definition at line 78 of file netconn.c.

78{CF_CLIENT | CF_SERVER, "net_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};

Referenced by NetConn_Init(), NetConn_ReceivedMessage(), and NetConn_UpdateCleartime().

◆ net_tos_dscp

cvar_t net_tos_dscp = {CF_CLIENT | CF_ARCHIVE, "net_tos_dscp", "32", "DiffServ Codepoint for network sockets (may need game restart to apply)"}
static

Definition at line 107 of file netconn.c.

107{CF_CLIENT | CF_ARCHIVE, "net_tos_dscp", "32", "DiffServ Codepoint for network sockets (may need game restart to apply)"};

Referenced by NetConn_Init(), and NetConn_UpdateSockets().

◆ net_usesizelimit

cvar_t net_usesizelimit = {CF_SERVER, "net_usesizelimit", "2", "use packet size limiting (0: never, 1: in non-CSQC mode, 2: always)"}

Definition at line 79 of file netconn.c.

79{CF_SERVER, "net_usesizelimit", "2", "use packet size limiting (0: never, 1: in non-CSQC mode, 2: always)"};

Referenced by NetConn_Init(), and SV_SendClientDatagram().

◆ netconn_list

netconn_t* netconn_list = NULL

Definition at line 151 of file netconn.c.

Referenced by Net_Stats_f(), NetConn_Close(), and NetConn_Open().

◆ netconn_mempool

mempool_t* netconn_mempool = NULL

Definition at line 152 of file netconn.c.

Referenced by NetConn_Init(), and NetConn_Open().

◆ netconn_mutex

void* netconn_mutex = NULL

Definition at line 153 of file netconn.c.

Referenced by NetConn_Init(), NetConn_Read(), NetConn_Shutdown(), and NetConn_Write().

◆ nextheartbeattime

double nextheartbeattime = 0
static

Definition at line 69 of file netconn.c.

Referenced by NetConn_Heartbeat().

◆ rcon_restricted_commands

cvar_t rcon_restricted_commands = {CF_SERVER, "rcon_restricted_commands", "", "allowed commands for rcon when the restricted mode password was used"}
static

Definition at line 112 of file netconn.c.

112{CF_SERVER, "rcon_restricted_commands", "", "allowed commands for rcon when the restricted mode password was used"};

Referenced by NetConn_Init(), and RCon_Authenticate().

◆ rcon_restricted_password

cvar_t rcon_restricted_password = {CF_SERVER | CF_PRIVATE, "rcon_restricted_password", "", "password to authenticate rcon commands in restricted mode; may be set to a string of the form user1:pass1 user2:pass2 user3:pass3 to allow multiple user accounts - the client then has to specify ONE of these combinations"}
static

Definition at line 111 of file netconn.c.

111{CF_SERVER | CF_PRIVATE, "rcon_restricted_password", "", "password to authenticate rcon commands in restricted mode; may be set to a string of the form user1:pass1 user2:pass2 user3:pass3 to allow multiple user accounts - the client then has to specify ONE of these combinations"};
#define CF_PRIVATE
cvar should not be $ expanded or sent to the server under any circumstances (rcon_password,...
Definition cmd.h:59

Referenced by NetConn_Init(), and RCon_Authenticate().

◆ rcon_secure

cvar_t rcon_secure
extern

Definition at line 90 of file console.c.

90{CF_CLIENT | CF_SERVER, "rcon_secure", "0", "force secure rcon authentication (1 = time based, 2 = challenge based); NOTE: changing rcon_secure clears rcon_password, so set rcon_secure always before rcon_password"};

Referenced by Con_Init(), and NetConn_ServerParsePacket().

◆ rcon_secure_challengetimeout

cvar_t rcon_secure_challengetimeout
extern

Definition at line 91 of file console.c.

91{CF_CLIENT, "rcon_secure_challengetimeout", "5", "challenge-based secure rcon: time out requests if no challenge came within this time interval"};

Referenced by Con_Init(), and NetConn_ClientParsePacket().

◆ rcon_secure_maxdiff

cvar_t rcon_secure_maxdiff = {CF_SERVER, "rcon_secure_maxdiff", "5", "maximum time difference between rcon request and server system clock (to protect against replay attack)"}
static

Definition at line 113 of file netconn.c.

113{CF_SERVER, "rcon_secure_maxdiff", "5", "maximum time difference between rcon request and server system clock (to protect against replay attack)"};

Referenced by hmac_mdfour_time_matching(), and NetConn_Init().

◆ serverlist_querystage

uint8_t serverlist_querystage = 0

bitfield because in theory we could be doing QW & DP simultaneously

Definition at line 129 of file netconn.c.

Referenced by CL_Frame().

◆ serverquerycount

unsigned serverquerycount = 0

Definition at line 120 of file netconn.c.

Referenced by M_ServerList_Draw(), and VM_M_getserverliststat().

◆ serverreplycount

unsigned serverreplycount = 0

Definition at line 121 of file netconn.c.

Referenced by M_ServerList_Draw(), and VM_M_getserverliststat().

◆ sv_heartbeatperiod

cvar_t sv_heartbeatperiod = {CF_SERVER | CF_ARCHIVE, "sv_heartbeatperiod", "120", "how often to send heartbeat in seconds (only used if sv_public is 1)"}
static

Definition at line 38 of file netconn.c.

38{CF_SERVER | CF_ARCHIVE, "sv_heartbeatperiod", "120", "how often to send heartbeat in seconds (only used if sv_public is 1)"};

Referenced by NetConn_Heartbeat(), and NetConn_Init().

◆ sv_masters

cvar_t sv_masters[]
static
Initial value:
=
{
{CF_CLIENT | CF_SERVER | CF_ARCHIVE, "sv_master1", "", "user-chosen master server 1"},
{CF_CLIENT | CF_SERVER | CF_ARCHIVE, "sv_master2", "", "user-chosen master server 2"},
{CF_CLIENT | CF_SERVER | CF_ARCHIVE, "sv_master3", "", "user-chosen master server 3"},
{CF_CLIENT | CF_SERVER | CF_ARCHIVE, "sv_master4", "", "user-chosen master server 4"},
{CF_CLIENT | CF_SERVER, "sv_masterextra1", "dpmaster.deathmask.net", "dpmaster.deathmask.net - default master server 1 (admin: Willis)"},
{CF_CLIENT | CF_SERVER, "sv_masterextra2", "dpmaster.tchr.no", "dpmaster.tchr.no - default master server 2 (admin: tChr)"},
{CF_CLIENT | CF_SERVER, "sv_masterextra3", "dpm.dpmaster.org:27777", "dpm.dpmaster.org - default master server 3 (admin: gazby/soylent_cow)"},
}

Definition at line 41 of file netconn.c.

42{
43 {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "sv_master1", "", "user-chosen master server 1"},
44 {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "sv_master2", "", "user-chosen master server 2"},
45 {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "sv_master3", "", "user-chosen master server 3"},
46 {CF_CLIENT | CF_SERVER | CF_ARCHIVE, "sv_master4", "", "user-chosen master server 4"},
47 {CF_CLIENT | CF_SERVER, "sv_masterextra1", "dpmaster.deathmask.net", "dpmaster.deathmask.net - default master server 1 (admin: Willis)"},
48 {CF_CLIENT | CF_SERVER, "sv_masterextra2", "dpmaster.tchr.no", "dpmaster.tchr.no - default master server 2 (admin: tChr)"},
49 {CF_CLIENT | CF_SERVER, "sv_masterextra3", "dpm.dpmaster.org:27777", "dpm.dpmaster.org - default master server 3 (admin: gazby/soylent_cow)"},
50};

Referenced by NetConn_Heartbeat(), and NetConn_Init().

◆ sv_message

◆ sv_message_buf

unsigned char sv_message_buf[NET_MAXMESSAGE]
static

Definition at line 74 of file netconn.c.

Referenced by NetConn_Init().

◆ sv_net_extresponse

char sv_net_extresponse[NET_EXTRESPONSE_MAX][1400]

Definition at line 164 of file netconn.c.

Referenced by NetConn_ServerParsePacket(), and VM_SV_getextresponse().

◆ sv_net_extresponse_count

unsigned sv_net_extresponse_count = 0

Definition at line 165 of file netconn.c.

Referenced by NetConn_ServerParsePacket(), and VM_SV_getextresponse().

◆ sv_net_extresponse_last

unsigned sv_net_extresponse_last = 0

Definition at line 166 of file netconn.c.

Referenced by NetConn_ServerParsePacket(), and VM_SV_getextresponse().

◆ sv_netport

cvar_t sv_netport = {CF_SERVER, "port", "26000", "server port for players to connect to"}

Definition at line 156 of file netconn.c.

156{CF_SERVER, "port", "26000", "server port for players to connect to"};

Referenced by CL_Packet_f(), CL_PQRcon_f(), CL_Rcon_f(), M_LanConfig_Key(), NetConn_Init(), NetConn_OpenServerPorts(), and SV_Init().

◆ sv_numsockets

◆ sv_public

cvar_t sv_public = {CF_SERVER, "sv_public", "0", "1: advertises this server on the master server (so that players can find it in the server browser); 0: allow direct queries only; -1: do not respond to direct queries; -2: do not allow anyone to connect; -3: already block at getchallenge level"}

Definition at line 36 of file netconn.c.

36{CF_SERVER, "sv_public", "0", "1: advertises this server on the master server (so that players can find it in the server browser); 0: allow direct queries only; -1: do not respond to direct queries; -2: do not allow anyone to connect; -3: already block at getchallenge level"};

Referenced by Crypto_ServerParsePacket_Internal(), M_GameOptions_Draw(), M_NetStart_Change(), NetConn_Heartbeat(), NetConn_Init(), NetConn_ServerParsePacket(), and SV_ServerOptions().

◆ sv_public_rejectreason

cvar_t sv_public_rejectreason = {CF_SERVER, "sv_public_rejectreason", "The server is closing.", "Rejection reason for connects when sv_public is -2"}

Definition at line 37 of file netconn.c.

37{CF_SERVER, "sv_public_rejectreason", "The server is closing.", "Rejection reason for connects when sv_public is -2"};

Referenced by NetConn_Init(), and NetConn_ServerParsePacket().

◆ sv_readstring

char sv_readstring[MAX_INPUTLINE]

Definition at line 76 of file netconn.c.

Referenced by NetConn_ServerParsePacket(), and SV_ReadClientMessage().

◆ sv_sockets

◆ sv_status_privacy

cvar_t sv_status_privacy
extern

Definition at line 30 of file sv_ccmds.c.

30{CF_SERVER | CF_ARCHIVE, "sv_status_privacy", "0", "do not show IP addresses in 'status' replies to clients"};

Referenced by NetConn_ServerParsePacket(), SV_InitOperatorCommands(), and SV_Status_f().