]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - netconn.c
Just in case, make QW sequence numbers unsigned too.
[xonotic/darkplaces.git] / netconn.c
index 84439332b04196771a863769067efcfb07f4032f..9db3a473c311baab53a27840c628c8a2712d0d50 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -45,14 +45,16 @@ static cvar_t sv_masters [] =
        {CVAR_SAVE, "sv_master3", "", "user-chosen master server 3"},
        {CVAR_SAVE, "sv_master4", "", "user-chosen master server 4"},
        {0, "sv_masterextra1", "69.59.212.88", "ghdigital.com - default master server 1 (admin: LordHavoc)"}, // admin: LordHavoc
-       {0, "sv_masterextra2", "64.22.107.125", "dpmaster.deathmask.net - default master server 2 (admin: Willis)"}, // admin: Willis
+       {0, "sv_masterextra2", "107.161.23.68", "dpmaster.deathmask.net - default master server 2 (admin: Willis)"}, // admin: Willis
        {0, "sv_masterextra3", "92.62.40.73", "dpmaster.tchr.no - default master server 3 (admin: tChr)"}, // admin: tChr
 #ifdef SUPPORTIPV6
        {0, "sv_masterextra4", "[2a03:4000:2:225::51:334d]:27950", "dpmaster.sudo.rm-f.org - default master server 4 (admin: divVerent)"}, // admin: divVerent
+       {0, "sv_masterextra5", "[2604:180::4ac:98c1]:27950", "dpmaster.deathmask.net - default master server 5 ipv6 address of dpmaster.deathmask.net (admin: Willis)"}, // admin: Willis
 #endif
        {0, NULL, NULL, NULL}
 };
 
+#ifdef CONFIG_MENU
 static cvar_t sv_qwmasters [] =
 {
        {CVAR_SAVE, "sv_qwmaster1", "", "user-chosen qwmaster server 1"},
@@ -66,6 +68,7 @@ static cvar_t sv_qwmasters [] =
        {0, "sv_qwmasterextra5", "qwmaster.fodquake.net:27000", "Global master server. (admin: unknown)"},
        {0, NULL, NULL, NULL}
 };
+#endif
 
 static double nextheartbeattime = 0;
 
@@ -114,6 +117,7 @@ int serverreplycount = 0;
 
 challenge_t challenge[MAX_CHALLENGES];
 
+#ifdef CONFIG_MENU
 /// this is only false if there are still servers left to query
 static qboolean serverlist_querysleep = true;
 static qboolean serverlist_paused = false;
@@ -121,6 +125,7 @@ static qboolean serverlist_paused = false;
 /// reply is received, to avoid issuing queries while master replies are still
 /// flooding in (which would make a mess of the ping times)
 static double serverlist_querywaittime = 0;
+#endif
 
 static int cl_numsockets;
 static lhnetsocket_t *cl_sockets[16];
@@ -144,6 +149,7 @@ char sv_net_extresponse[NET_EXTRESPONSE_MAX][1400];
 int sv_net_extresponse_count = 0;
 int sv_net_extresponse_last = 0;
 
+#ifdef CONFIG_MENU
 // ServerList interface
 serverlist_mask_t serverlist_andmasks[SERVERLIST_ANDMASKCOUNT];
 serverlist_mask_t serverlist_ormasks[SERVERLIST_ORMASKCOUNT];
@@ -218,12 +224,19 @@ static qboolean _ServerList_Entry_Compare( serverlist_entry_t *A, serverlist_ent
 {
        int result = 0; // > 0 if for numbers A > B and for text if A < B
 
-       if( serverlist_sortflags & SLSF_FAVORITESFIRST )
+       if( serverlist_sortflags & SLSF_CATEGORIES )
+       {
+               result = A->info.category - B->info.category;
+               if (result != 0)
+                       return result < 0;
+       }
+
+       if( serverlist_sortflags & SLSF_FAVORITES )
        {
                if(A->info.isfavorite != B->info.isfavorite)
                        return A->info.isfavorite;
        }
-
+       
        switch( serverlist_sortbyfield ) {
                case SLIF_PING:
                        result = A->info.ping - B->info.ping;
@@ -264,6 +277,9 @@ static qboolean _ServerList_Entry_Compare( serverlist_entry_t *A, serverlist_ent
                case SLIF_QCSTATUS:
                        result = strcasecmp( B->info.qcstatus, A->info.qcstatus ); // not really THAT useful, though
                        break;
+               case SLIF_CATEGORY:
+                       result = A->info.category - B->info.category;
+                       break;
                case SLIF_ISFAVORITE:
                        result = !!B->info.isfavorite - !!A->info.isfavorite;
                        break;
@@ -391,6 +407,8 @@ static qboolean _ServerList_Entry_Mask( serverlist_mask_t *mask, serverlist_info
        if( *mask->info.players
                && !_ServerList_CompareStr( info->players, mask->tests[SLIF_PLAYERS], mask->info.players ) )
                return false;
+       if( !_ServerList_CompareInt( info->category, mask->tests[SLIF_CATEGORY], mask->info.category ) )
+               return false;
        if( !_ServerList_CompareInt( info->isfavorite, mask->tests[SLIF_ISFAVORITE], mask->info.isfavorite ))
                return false;
        return true;
@@ -427,7 +445,7 @@ static void ServerList_ViewList_Insert( serverlist_entry_t *entry )
                                break;
                        }
                }
-               if(Crypto_RetrieveHostKey(&addr, 0, NULL, 0, idfp, sizeof(idfp), NULL))
+               if(Crypto_RetrieveHostKey(&addr, 0, NULL, 0, idfp, sizeof(idfp), NULL, NULL))
                {
                        for(i = 0; i < nFavorites_idfp; ++i)
                        {
@@ -440,6 +458,9 @@ static void ServerList_ViewList_Insert( serverlist_entry_t *entry )
                }
        }
 
+       // refresh the "category"
+       entry->info.category = MR_GetServerListEntryCategory(entry);
+
        // FIXME: change this to be more readable (...)
        // now check whether it passes through the masks
        for( start = 0 ; start < SERVERLIST_ANDMASKCOUNT && serverlist_andmasks[start].active; start++ )
@@ -587,6 +608,7 @@ void ServerList_QueryList(qboolean resetcache, qboolean querydp, qboolean queryq
 
        NetConn_QueryMasters(querydp, queryqw);
 }
+#endif
 
 // rest
 
@@ -668,7 +690,7 @@ qboolean NetConn_CanSend(netconn_t *conn)
        }
 }
 
-void NetConn_UpdateCleartime(double *cleartime, int rate, int burstsize, int len)
+static void NetConn_UpdateCleartime(double *cleartime, int rate, int burstsize, int len)
 {
        double bursttime = burstsize / (double)rate;
 
@@ -685,6 +707,27 @@ void NetConn_UpdateCleartime(double *cleartime, int rate, int burstsize, int len
        }
 }
 
+static int NetConn_AddCryptoFlag(crypto_t *crypto)
+{
+       // HACK: if an encrypted connection is used, randomly set some unused
+       // flags. When AES encryption is enabled, that will make resends differ
+       // from the original, so that e.g. substring filters in a router/IPS
+       // are unlikely to match a second time. See also "startkeylogger".
+       int flag = 0;
+       if (crypto->authenticated)
+       {
+               // Let's always set at least one of the bits.
+               int r = rand() % 7 + 1;
+               if (r & 1)
+                       flag |= NETFLAG_CRYPTO0;
+               if (r & 2)
+                       flag |= NETFLAG_CRYPTO1;
+               if (r & 4)
+                       flag |= NETFLAG_CRYPTO2;
+       }
+       return flag;
+}
+
 int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolversion_t protocol, int rate, int burstsize, qboolean quakesignon_suppressreliables)
 {
        int totallen = 0;
@@ -721,9 +764,9 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
                        sendreliable = true;
                }
                // outgoing unreliable packet number, and outgoing reliable packet number (0 or 1)
-               StoreLittleLong(sendbuffer, (unsigned int)conn->outgoing_unreliable_sequence | ((unsigned int)sendreliable<<31));
+               StoreLittleLong(sendbuffer, conn->outgoing_unreliable_sequence | (((unsigned int)sendreliable)<<31));
                // last received unreliable packet number, and last received reliable packet number (0 or 1)
-               StoreLittleLong(sendbuffer + 4, (unsigned int)conn->qw.incoming_sequence | ((unsigned int)conn->qw.incoming_reliable_sequence<<31));
+               StoreLittleLong(sendbuffer + 4, conn->qw.incoming_sequence | (((unsigned int)conn->qw.incoming_reliable_sequence)<<31));
                packetLen = 8;
                conn->outgoing_unreliable_sequence++;
                // client sends qport in every packet
@@ -790,20 +833,20 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
 
                        packetLen = NET_HEADERSIZE + dataLen;
 
-                       StoreBigLong(sendbuffer, packetLen | (NETFLAG_DATA | eom));
+                       StoreBigLong(sendbuffer, packetLen | (NETFLAG_DATA | eom | NetConn_AddCryptoFlag(&conn->crypto)));
                        StoreBigLong(sendbuffer + 4, conn->nq.sendSequence - 1);
                        memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen);
 
                        conn->outgoing_netgraph[conn->outgoing_packetcounter].reliablebytes += packetLen + 28;
 
                        sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
-                       if (sendme && NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress) == (int)sendmelen)
+                       if (sendme && NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress) == (int)sendmelen)
                        {
                                conn->lastSendTime = realtime;
                                conn->packetsReSent++;
                        }
 
-                       totallen += sendmelen + 28;
+                       totallen += (int)sendmelen + 28;
                }
 
                // if we have a new reliable message to send, do so
@@ -839,7 +882,7 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
 
                        packetLen = NET_HEADERSIZE + dataLen;
 
-                       StoreBigLong(sendbuffer, packetLen | (NETFLAG_DATA | eom));
+                       StoreBigLong(sendbuffer, packetLen | (NETFLAG_DATA | eom | NetConn_AddCryptoFlag(&conn->crypto)));
                        StoreBigLong(sendbuffer + 4, conn->nq.sendSequence);
                        memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen);
 
@@ -849,13 +892,13 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
 
                        sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
                        if(sendme)
-                               NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress);
+                               NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress);
 
                        conn->lastSendTime = realtime;
                        conn->packetsSent++;
                        conn->reliableMessagesSent++;
 
-                       totallen += sendmelen + 28;
+                       totallen += (int)sendmelen + 28;
                }
 
                // if we have an unreliable message to send, do so
@@ -869,7 +912,7 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
                                return -1;
                        }
 
-                       StoreBigLong(sendbuffer, packetLen | NETFLAG_UNRELIABLE);
+                       StoreBigLong(sendbuffer, packetLen | NETFLAG_UNRELIABLE | NetConn_AddCryptoFlag(&conn->crypto));
                        StoreBigLong(sendbuffer + 4, conn->outgoing_unreliable_sequence);
                        memcpy(sendbuffer + NET_HEADERSIZE, data->data, data->cursize);
 
@@ -879,16 +922,16 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers
 
                        sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
                        if(sendme)
-                               NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress);
+                               NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress);
 
                        conn->packetsSent++;
                        conn->unreliableMessagesSent++;
 
-                       totallen += sendmelen + 28;
+                       totallen += (int)sendmelen + 28;
                }
        }
 
-       NetConn_UpdateCleartime(&conn->cleartime, cl_rate.integer, cl_rate_burstsize.integer, totallen);
+       NetConn_UpdateCleartime(&conn->cleartime, rate, burstsize, totallen);
 
        return 0;
 }
@@ -1160,7 +1203,7 @@ void NetConn_UpdateSockets(void)
 
 static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, size_t length, protocolversion_t protocol, double newtimeout)
 {
-       int originallength = length;
+       int originallength = (int)length;
        unsigned char sendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE];
        unsigned char cryptosendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
        unsigned char cryptoreadbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
@@ -1169,7 +1212,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
 
        if (protocol == PROTOCOL_QUAKEWORLD)
        {
-               int sequence, sequence_ack;
+               unsigned int sequence, sequence_ack;
                int reliable_ack, reliable_message;
                int count;
                //int qport;
@@ -1205,6 +1248,12 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                {
                        conn->droppedDatagrams += count;
                        //Con_DPrintf("Dropped %u datagram(s)\n", count);
+                       // If too may packets have been dropped, only write the
+                       // last NETGRAPH_PACKETS ones to the netgraph. Why?
+                       // Because there's no point in writing more than
+                       // these as the netgraph is going to be full anyway.
+                       if (count > NETGRAPH_PACKETS)
+                               count = NETGRAPH_PACKETS;
                        while (count--)
                        {
                                conn->incoming_packetcounter = (conn->incoming_packetcounter + 1) % NETGRAPH_PACKETS;
@@ -1249,13 +1298,13 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                if (conn == cls.netcon)
                {
                        SZ_Clear(&cl_message);
-                       SZ_Write(&cl_message, data, length);
+                       SZ_Write(&cl_message, data, (int)length);
                        MSG_BeginReading(&cl_message);
                }
                else
                {
                        SZ_Clear(&sv_message);
-                       SZ_Write(&sv_message, data, length);
+                       SZ_Write(&sv_message, data, (int)length);
                        MSG_BeginReading(&sv_message);
                }
                return 2;
@@ -1269,7 +1318,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                const void *sendme;
                size_t sendmelen;
 
-               originallength = length;
+               originallength = (int)length;
                data = (const unsigned char *) Crypto_DecryptPacket(&conn->crypto, data, length, cryptoreadbuffer, &length, sizeof(cryptoreadbuffer));
                if(!data)
                        return 0;
@@ -1295,6 +1344,12 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                                                count = sequence - conn->nq.unreliableReceiveSequence;
                                                conn->droppedDatagrams += count;
                                                //Con_DPrintf("Dropped %u datagram(s)\n", count);
+                                               // If too may packets have been dropped, only write the
+                                               // last NETGRAPH_PACKETS ones to the netgraph. Why?
+                                               // Because there's no point in writing more than
+                                               // these as the netgraph is going to be full anyway.
+                                               if (count > NETGRAPH_PACKETS)
+                                                       count = NETGRAPH_PACKETS;
                                                while (count--)
                                                {
                                                        conn->incoming_packetcounter = (conn->incoming_packetcounter + 1) % NETGRAPH_PACKETS;
@@ -1322,13 +1377,13 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                                                if (conn == cls.netcon)
                                                {
                                                        SZ_Clear(&cl_message);
-                                                       SZ_Write(&cl_message, data, length);
+                                                       SZ_Write(&cl_message, data, (int)length);
                                                        MSG_BeginReading(&cl_message);
                                                }
                                                else
                                                {
                                                        SZ_Clear(&sv_message);
-                                                       SZ_Write(&sv_message, data, length);
+                                                       SZ_Write(&sv_message, data, (int)length);
                                                        MSG_BeginReading(&sv_message);
                                                }
                                                return 2;
@@ -1374,14 +1429,14 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
 
                                                        packetLen = NET_HEADERSIZE + dataLen;
 
-                                                       StoreBigLong(sendbuffer, packetLen | (NETFLAG_DATA | eom));
+                                                       StoreBigLong(sendbuffer, packetLen | (NETFLAG_DATA | eom | NetConn_AddCryptoFlag(&conn->crypto)));
                                                        StoreBigLong(sendbuffer + 4, conn->nq.sendSequence);
                                                        memcpy(sendbuffer + NET_HEADERSIZE, conn->sendMessage, dataLen);
 
                                                        conn->nq.sendSequence++;
 
                                                        sendme = Crypto_EncryptPacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
-                                                       if (sendme && NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress) == (int)sendmelen)
+                                                       if (sendme && NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress) == (int)sendmelen)
                                                        {
                                                                conn->lastSendTime = realtime;
                                                                conn->packetsSent++;
@@ -1405,11 +1460,11 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
 
                                conn->outgoing_netgraph[conn->outgoing_packetcounter].ackbytes        += 8 + 28;
 
-                               StoreBigLong(temppacket, 8 | NETFLAG_ACK);
+                               StoreBigLong(temppacket, 8 | NETFLAG_ACK | NetConn_AddCryptoFlag(&conn->crypto));
                                StoreBigLong(temppacket + 4, sequence);
                                sendme = Crypto_EncryptPacket(&conn->crypto, temppacket, 8, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer));
                                if(sendme)
-                                       NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress);
+                                       NetConn_Write(conn->mysocket, sendme, (int)sendmelen, &conn->peeraddress);
                                if (sequence == conn->nq.receiveSequence)
                                {
                                        conn->lastMessageTime = realtime;
@@ -1417,7 +1472,7 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                                        conn->nq.receiveSequence++;
                                        if( conn->receiveMessageLength + length <= (int)sizeof( conn->receiveMessage ) ) {
                                                memcpy(conn->receiveMessage + conn->receiveMessageLength, data, length);
-                                               conn->receiveMessageLength += length;
+                                               conn->receiveMessageLength += (int)length;
                                        } else {
                                                Con_Printf( "Reliable message (seq: %i) too big for message buffer!\n"
                                                                        "Dropping the message!\n", sequence );
@@ -1434,13 +1489,13 @@ static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, s
                                                        if (conn == cls.netcon)
                                                        {
                                                                SZ_Clear(&cl_message);
-                                                               SZ_Write(&cl_message, conn->receiveMessage, length);
+                                                               SZ_Write(&cl_message, conn->receiveMessage, (int)length);
                                                                MSG_BeginReading(&cl_message);
                                                        }
                                                        else
                                                        {
                                                                SZ_Clear(&sv_message);
-                                                               SZ_Write(&sv_message, conn->receiveMessage, length);
+                                                               SZ_Write(&sv_message, conn->receiveMessage, (int)length);
                                                                MSG_BeginReading(&sv_message);
                                                        }
                                                        return 2;
@@ -1474,16 +1529,18 @@ static void NetConn_ConnectionEstablished(lhnetsocket_t *mysocket, lhnetaddress_
        }
        // allocate a net connection to keep track of things
        cls.netcon = NetConn_Open(mysocket, peeraddress);
-       crypto = &cls.crypto;
-       if(crypto && crypto->authenticated)
+       crypto = &cls.netcon->crypto;
+       if(cls.crypto.authenticated)
        {
-               Crypto_ServerFinishInstance(&cls.netcon->crypto, crypto);
-               Con_Printf("%s connection to %s has been established: server is %s@%.*s, I am %.*s@%.*s\n",
+               Crypto_FinishInstance(crypto, &cls.crypto);
+               Con_Printf("%s connection to %s has been established: server is %s@%s%.*s, I am %.*s@%s%.*s\n",
                                crypto->use_aes ? "Encrypted" : "Authenticated",
                                cls.netcon->address,
                                crypto->server_idfp[0] ? crypto->server_idfp : "-",
+                               (crypto->server_issigned || !crypto->server_keyfp[0]) ? "" : "~",
                                crypto_keyfp_recommended_length, crypto->server_keyfp[0] ? crypto->server_keyfp : "-",
                                crypto_keyfp_recommended_length, crypto->client_idfp[0] ? crypto->client_idfp : "-",
+                               (crypto->client_issigned || !crypto->client_keyfp[0]) ? "" : "~",
                                crypto_keyfp_recommended_length, crypto->client_keyfp[0] ? crypto->client_keyfp : "-"
                                );
        }
@@ -1521,6 +1578,7 @@ int NetConn_IsLocalGame(void)
        return false;
 }
 
+#ifdef CONFIG_MENU
 static int NetConn_ClientParsePacket_ServerList_ProcessReply(const char *addressstring)
 {
        int n;
@@ -1729,17 +1787,21 @@ static void NetConn_ClientParsePacket_ServerList_ParseDPList(lhnetaddress_t *sen
        serverlist_querysleep = false;
        serverlist_querywaittime = realtime + 3;
 }
+#endif
 
 static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *data, int length, lhnetaddress_t *peeraddress)
 {
        qboolean fromserver;
        int ret, c;
-       const char *s;
-       char *string, addressstring2[128], ipstring[32];
+       char *string, addressstring2[128];
        char stringbuf[16384];
        char senddata[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE];
        size_t sendlength;
+#ifdef CONFIG_MENU
        char infostringvalue[MAX_INPUTLINE];
+       char ipstring[32];
+       const char *s;
+#endif
        char vabuf[1024];
 
        // quakeworld ingame packet
@@ -1775,20 +1837,20 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                if(sendlength)
                                {
                                        memcpy(senddata, "\377\377\377\377", 4);
-                                       NetConn_Write(mysocket, senddata, sendlength+4, peeraddress);
+                                       NetConn_Write(mysocket, senddata, (int)sendlength+4, peeraddress);
                                }
                                break;
                        case CRYPTO_DISCARD:
                                if(sendlength)
                                {
                                        memcpy(senddata, "\377\377\377\377", 4);
-                                       NetConn_Write(mysocket, senddata, sendlength+4, peeraddress);
+                                       NetConn_Write(mysocket, senddata, (int)sendlength+4, peeraddress);
                                }
                                return true;
                                break;
                        case CRYPTO_REPLACE:
                                string = senddata+4;
-                               length = sendlength;
+                               length = (int)sendlength;
                                break;
                }
 
@@ -1815,12 +1877,12 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                e = strchr(rcon_password.string, ' ');
                                n = e ? e-rcon_password.string : (int)strlen(rcon_password.string);
 
-                               if(HMAC_MDFOUR_16BYTES((unsigned char *) (buf + 29), (unsigned char *) argbuf, strlen(argbuf), (unsigned char *) rcon_password.string, n))
+                               if(HMAC_MDFOUR_16BYTES((unsigned char *) (buf + 29), (unsigned char *) argbuf, (int)strlen(argbuf), (unsigned char *) rcon_password.string, n))
                                {
                                        int k;
                                        buf[45] = ' ';
                                        strlcpy(buf + 46, argbuf, sizeof(buf) - 46);
-                                       NetConn_Write(mysocket, buf, 46 + strlen(buf + 46), peeraddress);
+                                       NetConn_Write(mysocket, buf, 46 + (int)strlen(buf + 46), peeraddress);
                                        cls.rcon_commands[i][0] = 0;
                                        --cls.rcon_trying;
 
@@ -1880,6 +1942,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
 #endif
                        return true;
                }
+#ifdef CONFIG_MENU
                if (length >= 15 && !memcmp(string, "statusResponse\x0A", 15))
                {
                        serverlist_info_t *info;
@@ -2016,6 +2079,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        serverlist_querywaittime = realtime + 3;
                        return true;
                }
+#endif
                if (!strncmp(string, "extResponse ", 12))
                {
                        ++cl_net_extresponse_count;
@@ -2059,6 +2123,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                }
                if (length > 2 && !memcmp(string, "n\\", 2))
                {
+#ifdef CONFIG_MENU
                        serverlist_info_t *info;
                        int n;
 
@@ -2102,7 +2167,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        }
 
                        NetConn_ClientParsePacket_ServerList_UpdateCache(n);
-
+#endif
                        return true;
                }
                if (string[0] == 'n')
@@ -2124,8 +2189,10 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
        // netquake control packets, supported for compatibility only
        if (length >= 5 && BuffBigLong(data) == ((int)NETFLAG_CTL | length) && !ENCRYPTION_REQUIRED)
        {
+#ifdef CONFIG_MENU
                int n;
                serverlist_info_t *info;
+#endif
 
                data += 4;
                length -= 4;
@@ -2177,6 +2244,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                case CCREP_SERVER_INFO:
                        if (developer_extra.integer)
                                Con_DPrintf("Datagram_ParseConnectionless: received CCREP_SERVER_INFO from %s.\n", addressstring2);
+#ifdef CONFIG_MENU
                        // LordHavoc: because the quake server may report weird addresses
                        // we just ignore it and keep the real address
                        MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
@@ -2195,7 +2263,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        info->protocol = MSG_ReadByte(&cl_message);
 
                        NetConn_ClientParsePacket_ServerList_UpdateCache(n);
-
+#endif
                        break;
                case CCREP_RCON: // RocketGuy: ProQuake rcon support
                        if (developer_extra.integer)
@@ -2227,6 +2295,7 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
        return ret;
 }
 
+#ifdef CONFIG_MENU
 void NetConn_QueryQueueFrame(void)
 {
        int index;
@@ -2315,6 +2384,7 @@ void NetConn_QueryQueueFrame(void)
                }
        }
 }
+#endif
 
 void NetConn_ClientFrame(void)
 {
@@ -2369,7 +2439,9 @@ void NetConn_ClientFrame(void)
 //                     R_TimeReport("clientparsepacket");
                }
        }
+#ifdef CONFIG_MENU
        NetConn_QueryQueueFrame();
+#endif
        if (cls.netcon && realtime > cls.netcon->timeout && !sv.active)
        {
                Con_Print("Connection timed out\n");
@@ -2637,7 +2709,7 @@ static qboolean hmac_mdfour_time_matching(lhnetaddress_t *peeraddress, const cha
        if(abs(t1 - t2) > rcon_secure_maxdiff.integer)
                return false;
 
-       if(!HMAC_MDFOUR_16BYTES((unsigned char *) mdfourbuf, (unsigned char *) s, slen, (unsigned char *) password, strlen(password)))
+       if(!HMAC_MDFOUR_16BYTES((unsigned char *) mdfourbuf, (unsigned char *) s, slen, (unsigned char *) password, (int)strlen(password)))
                return false;
 
        return !memcmp(mdfourbuf, hash, 16);
@@ -2660,7 +2732,7 @@ static qboolean hmac_mdfour_challenge_matching(lhnetaddress_t *peeraddress, cons
        if (i == MAX_CHALLENGES)
                return false;
 
-       if(!HMAC_MDFOUR_16BYTES((unsigned char *) mdfourbuf, (unsigned char *) s, slen, (unsigned char *) password, strlen(password)))
+       if(!HMAC_MDFOUR_16BYTES((unsigned char *) mdfourbuf, (unsigned char *) s, slen, (unsigned char *) password, (int)strlen(password)))
                return false;
 
        if(memcmp(mdfourbuf, hash, 16))
@@ -2685,7 +2757,7 @@ static const char *RCon_Authenticate(lhnetaddress_t *peeraddress, const char *pa
        qboolean hasquotes;
        qboolean restricted = false;
        qboolean have_usernames = false;
-       char vabuf[1024];
+       static char vabuf[1024];
 
        userpass_start = rcon_password.string;
        while((userpass_end = strchr(userpass_start, ' ')))
@@ -2869,20 +2941,20 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                if(sendlength)
                                {
                                        memcpy(senddata, "\377\377\377\377", 4);
-                                       NetConn_Write(mysocket, senddata, sendlength+4, peeraddress);
+                                       NetConn_Write(mysocket, senddata, (int)sendlength+4, peeraddress);
                                }
                                break;
                        case CRYPTO_DISCARD:
                                if(sendlength)
                                {
                                        memcpy(senddata, "\377\377\377\377", 4);
-                                       NetConn_Write(mysocket, senddata, sendlength+4, peeraddress);
+                                       NetConn_Write(mysocket, senddata, (int)sendlength+4, peeraddress);
                                }
                                return true;
                                break;
                        case CRYPTO_REPLACE:
                                string = senddata+4;
-                               length = sendlength;
+                               length = (int)sendlength;
                                break;
                }
 
@@ -2915,7 +2987,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        dpsnprintf(response, sizeof(response), "\377\377\377\377challenge %s", challenge[i].string);
                        response_len = strlen(response) + 1;
                        Crypto_ServerAppendToChallenge(string, length, response, &response_len, sizeof(response));
-                       NetConn_Write(mysocket, response, response_len, peeraddress);
+                       NetConn_Write(mysocket, response, (int)response_len, peeraddress);
                        return true;
                }
                if (length > 8 && !memcmp(string, "connect\\", 8))
@@ -2929,12 +3001,14 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                // no need to check challenge
                                if(crypto_developer.integer)
                                {
-                                       Con_Printf("%s connection to %s is being established: client is %s@%.*s, I am %.*s@%.*s\n",
+                                       Con_Printf("%s connection to %s is being established: client is %s@%s%.*s, I am %.*s@%s%.*s\n",
                                                        crypto->use_aes ? "Encrypted" : "Authenticated",
                                                        addressstring2,
                                                        crypto->client_idfp[0] ? crypto->client_idfp : "-",
+                                                       (crypto->client_issigned || !crypto->client_keyfp[0]) ? "" : "~",
                                                        crypto_keyfp_recommended_length, crypto->client_keyfp[0] ? crypto->client_keyfp : "-",
                                                        crypto_keyfp_recommended_length, crypto->server_idfp[0] ? crypto->server_idfp : "-",
+                                                       (crypto->server_issigned || !crypto->server_keyfp[0]) ? "" : "~",
                                                        crypto_keyfp_recommended_length, crypto->server_keyfp[0] ? crypto->server_keyfp : "-"
                                                  );
                                }
@@ -3022,7 +3096,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                                        Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", addressstring2);
                                                NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
                                                if(crypto && crypto->authenticated)
-                                                       Crypto_ServerFinishInstance(&client->netconnection->crypto, crypto);
+                                                       Crypto_FinishInstance(&client->netconnection->crypto, crypto);
                                                SV_SendServerinfo(client);
                                        }
                                        else
@@ -3032,7 +3106,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                                if (developer_extra.integer)
                                                        Con_Printf("Datagram_ParseConnectionless: sending duplicate accept to %s.\n", addressstring2);
                                                if(crypto && crypto->authenticated)
-                                                       Crypto_ServerFinishInstance(&client->netconnection->crypto, crypto);
+                                                       Crypto_FinishInstance(&client->netconnection->crypto, crypto);
                                                NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
                                        }
                                        return true;
@@ -3054,7 +3128,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                        NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
                                        // now set up the client
                                        if(crypto && crypto->authenticated)
-                                               Crypto_ServerFinishInstance(&conn->crypto, crypto);
+                                               Crypto_FinishInstance(&conn->crypto, crypto);
                                        SV_ConnectClient(clientnum, conn);
                                        NetConn_Heartbeat(1);
                                        return true;
@@ -3495,6 +3569,7 @@ void NetConn_SleepMicroseconds(int microseconds)
        LHNET_SleepUntilPacket_Microseconds(microseconds);
 }
 
+#ifdef CONFIG_MENU
 void NetConn_QueryMasters(qboolean querydp, qboolean queryqw)
 {
        int i, j;
@@ -3597,16 +3672,12 @@ void NetConn_QueryMasters(qboolean querydp, qboolean queryqw)
                                {
                                        if (sv_qwmasters[masternum].string && LHNETADDRESS_FromString(&masteraddress, sv_qwmasters[masternum].string, QWMASTER_PORT) && LHNETADDRESS_GetAddressType(&masteraddress) == LHNETADDRESS_GetAddressType(LHNET_AddressFromSocket(cl_sockets[i])))
                                        {
-#ifdef CONFIG_MENU
                                                if (m_state != m_slist)
                                                {
-#endif
                                                        char lookupstring[128];
                                                        LHNETADDRESS_ToString(&masteraddress, lookupstring, sizeof(lookupstring), true);
                                                        Con_Printf("Querying master %s (resolved from %s)\n", lookupstring, sv_qwmasters[masternum].string);
-#ifdef CONFIG_MENU
                                                }
-#endif
                                                masterquerycount++;
                                                NetConn_Write(cl_sockets[i], request, (int)strlen(request) + 1, &masteraddress);
                                        }
@@ -3630,11 +3701,10 @@ void NetConn_QueryMasters(qboolean querydp, qboolean queryqw)
        if (!masterquerycount)
        {
                Con_Print("Unable to query master servers, no suitable network sockets active.\n");
-#ifdef CONFIG_MENU
                M_Update_Return_Reason("No network");
-#endif
        }
 }
+#endif
 
 void NetConn_Heartbeat(int priority)
 {
@@ -3700,18 +3770,15 @@ void Net_Stats_f(void)
                PrintStats(conn);
 }
 
+#ifdef CONFIG_MENU
 void Net_Refresh_f(void)
 {
-#ifdef CONFIG_MENU
        if (m_state != m_slist) {
-#endif
                Con_Print("Sending new requests to master servers\n");
                ServerList_QueryList(false, true, false, true);
                Con_Print("Listening for replies...\n");
-#ifdef CONFIG_MENU
        } else
                ServerList_QueryList(false, true, false, false);
-#endif
 }
 
 void Net_Slist_f(void)
@@ -3719,16 +3786,12 @@ void Net_Slist_f(void)
        ServerList_ResetMasks();
        serverlist_sortbyfield = SLIF_PING;
        serverlist_sortflags = 0;
-#ifdef CONFIG_MENU
     if (m_state != m_slist) {
-#endif
                Con_Print("Sending requests to master servers\n");
                ServerList_QueryList(true, true, false, true);
                Con_Print("Listening for replies...\n");
-#ifdef CONFIG_MENU
        } else
                ServerList_QueryList(true, true, false, false);
-#endif
 }
 
 void Net_SlistQW_f(void)
@@ -3736,18 +3799,15 @@ void Net_SlistQW_f(void)
        ServerList_ResetMasks();
        serverlist_sortbyfield = SLIF_PING;
        serverlist_sortflags = 0;
-#ifdef CONFIG_MENU
     if (m_state != m_slist) {
-#endif
                Con_Print("Sending requests to master servers\n");
                ServerList_QueryList(true, false, true, true);
                serverlist_consoleoutput = true;
                Con_Print("Listening for replies...\n");
-#ifdef CONFIG_MENU
        } else
                ServerList_QueryList(true, false, true, false);
-#endif
 }
+#endif
 
 void NetConn_Init(void)
 {
@@ -3755,9 +3815,11 @@ void NetConn_Init(void)
        lhnetaddress_t tempaddress;
        netconn_mempool = Mem_AllocPool("network connections", 0, NULL);
        Cmd_AddCommand("net_stats", Net_Stats_f, "print network statistics");
+#ifdef CONFIG_MENU
        Cmd_AddCommand("net_slist", Net_Slist_f, "query dp master servers and print all server information");
        Cmd_AddCommand("net_slistqw", Net_SlistQW_f, "query qw master servers and print all server information");
        Cmd_AddCommand("net_refresh", Net_Refresh_f, "query dp master servers and refresh all server information");
+#endif
        Cmd_AddCommand("heartbeat", Net_Heartbeat_f, "send a heartbeat to the master server (updates your server information)");
        Cvar_RegisterVariable(&net_test);
        Cvar_RegisterVariable(&net_usesizelimit);