mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-28 22:52:02 +00:00
Some more ICE polish.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6300 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
5182692590
commit
89fde9c5e4
8 changed files with 176 additions and 51 deletions
|
@ -152,6 +152,7 @@ int NET_LocalAddressForRemote(struct ftenet_connections_s *collection, netadr_
|
||||||
void NET_PrintAddresses(struct ftenet_connections_s *collection);
|
void NET_PrintAddresses(struct ftenet_connections_s *collection);
|
||||||
qboolean NET_AddressSmellsFunny(netadr_t *a);
|
qboolean NET_AddressSmellsFunny(netadr_t *a);
|
||||||
qboolean NET_EnsureRoute(struct ftenet_connections_s *collection, char *routename, char *host, netadr_t *adr);
|
qboolean NET_EnsureRoute(struct ftenet_connections_s *collection, char *routename, char *host, netadr_t *adr);
|
||||||
|
void NET_TerminateRoute(struct ftenet_connections_s *collection, netadr_t *adr);
|
||||||
void NET_PrintConnectionsStatus(struct ftenet_connections_s *collection);
|
void NET_PrintConnectionsStatus(struct ftenet_connections_s *collection);
|
||||||
|
|
||||||
enum addressscope_e
|
enum addressscope_e
|
||||||
|
@ -204,7 +205,8 @@ void NET_DTLS_Timeouts(struct ftenet_connections_s *col);
|
||||||
extern cvar_t dtls_psk_hint, dtls_psk_user, dtls_psk_key;
|
extern cvar_t dtls_psk_hint, dtls_psk_user, dtls_psk_key;
|
||||||
#endif
|
#endif
|
||||||
#ifdef SUPPORT_ICE
|
#ifdef SUPPORT_ICE
|
||||||
neterr_t ICE_SendPacket(struct ftenet_connections_s *col, size_t length, const void *data, netadr_t *to);
|
neterr_t ICE_SendPacket(size_t length, const void *data, netadr_t *to);
|
||||||
|
void ICE_Terminate(netadr_t *to); //if we kicked the client/etc, kill their ICE too.
|
||||||
qboolean ICE_IsEncrypted(netadr_t *to);
|
qboolean ICE_IsEncrypted(netadr_t *to);
|
||||||
void ICE_Init(void);
|
void ICE_Init(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -86,7 +86,11 @@ int net_drop;
|
||||||
cvar_t showpackets = CVAR("showpackets", "0");
|
cvar_t showpackets = CVAR("showpackets", "0");
|
||||||
cvar_t showdrop = CVAR("showdrop", "0");
|
cvar_t showdrop = CVAR("showdrop", "0");
|
||||||
cvar_t qport = CVARF("qport_", "0", CVAR_NOSAVE);
|
cvar_t qport = CVARF("qport_", "0", CVAR_NOSAVE);
|
||||||
|
#ifdef FTE_TARGET_WEB //with webrtc our packets will be layered over sctp(header=28,extras=20ish) over dtls(13),
|
||||||
|
cvar_t net_mtu = CVARD("net_mtu", "1384", "Specifies a maximum udp payload size, above which packets will be fragmented. If routers all worked properly this could be some massive value, and some massive value may work really nicely for lans. Use smaller values than the default if you're connecting through nested tunnels through routers that fail with IP fragmentation.");
|
||||||
|
#else
|
||||||
cvar_t net_mtu = CVARD("net_mtu", "1440", "Specifies a maximum udp payload size, above which packets will be fragmented. If routers all worked properly this could be some massive value, and some massive value may work really nicely for lans. Use smaller values than the default if you're connecting through nested tunnels through routers that fail with IP fragmentation.");
|
cvar_t net_mtu = CVARD("net_mtu", "1440", "Specifies a maximum udp payload size, above which packets will be fragmented. If routers all worked properly this could be some massive value, and some massive value may work really nicely for lans. Use smaller values than the default if you're connecting through nested tunnels through routers that fail with IP fragmentation.");
|
||||||
|
#endif
|
||||||
cvar_t net_compress = CVARD("net_compress", "0", "Enables huffman compression of network packets.");
|
cvar_t net_compress = CVARD("net_compress", "0", "Enables huffman compression of network packets.");
|
||||||
|
|
||||||
cvar_t pext_vrinputs = CVARD("_pext_vrinputs", "0", "RENAME ME WHEN STABLE. Networks player inputs slightly differently, allowing for greater capabilities, particuarly vr controller info.");
|
cvar_t pext_vrinputs = CVARD("_pext_vrinputs", "0", "RENAME ME WHEN STABLE. Networks player inputs slightly differently, allowing for greater capabilities, particuarly vr controller info.");
|
||||||
|
|
|
@ -2068,13 +2068,29 @@ static qboolean QDECL ICE_Set(struct icestate_s *con, const char *prop, const ch
|
||||||
{
|
{
|
||||||
int oldstate = con->state;
|
int oldstate = con->state;
|
||||||
if (!strcmp(value, STRINGIFY(ICE_CONNECTING)))
|
if (!strcmp(value, STRINGIFY(ICE_CONNECTING)))
|
||||||
|
{
|
||||||
con->state = ICE_CONNECTING;
|
con->state = ICE_CONNECTING;
|
||||||
|
if (net_ice_debug.ival >= 1)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: ice state connecting\n", con->friendlyname);
|
||||||
|
}
|
||||||
else if (!strcmp(value, STRINGIFY(ICE_INACTIVE)))
|
else if (!strcmp(value, STRINGIFY(ICE_INACTIVE)))
|
||||||
|
{
|
||||||
con->state = ICE_INACTIVE;
|
con->state = ICE_INACTIVE;
|
||||||
|
if (net_ice_debug.ival >= 1)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: ice state inactive\n", con->friendlyname);
|
||||||
|
}
|
||||||
else if (!strcmp(value, STRINGIFY(ICE_FAILED)))
|
else if (!strcmp(value, STRINGIFY(ICE_FAILED)))
|
||||||
|
{
|
||||||
con->state = ICE_FAILED;
|
con->state = ICE_FAILED;
|
||||||
|
if (net_ice_debug.ival >= 1)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: ice state failed\n", con->friendlyname);
|
||||||
|
}
|
||||||
else if (!strcmp(value, STRINGIFY(ICE_CONNECTED)))
|
else if (!strcmp(value, STRINGIFY(ICE_CONNECTED)))
|
||||||
|
{
|
||||||
con->state = ICE_CONNECTED;
|
con->state = ICE_CONNECTED;
|
||||||
|
if (net_ice_debug.ival >= 1)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: ice state connected\n", con->friendlyname);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Con_Printf("ICE_Set invalid state %s\n", value);
|
Con_Printf("ICE_Set invalid state %s\n", value);
|
||||||
|
@ -2125,12 +2141,60 @@ static qboolean QDECL ICE_Set(struct icestate_s *con, const char *prop, const ch
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldstate != con->state && con->state == ICE_INACTIVE)
|
||||||
|
{ //forget our peer
|
||||||
|
struct icecandidate_s *c;
|
||||||
|
int i;
|
||||||
|
memset(&con->chosenpeer, 0, sizeof(con->chosenpeer));
|
||||||
|
|
||||||
|
#ifdef HAVE_DTLS
|
||||||
|
if (con->sctp)
|
||||||
|
{
|
||||||
|
Z_Free(con->sctp->cookie);
|
||||||
|
Z_Free(con->sctp);
|
||||||
|
con->sctp = NULL;
|
||||||
|
}
|
||||||
|
if (con->dtlsstate)
|
||||||
|
{
|
||||||
|
con->dtlsfuncs->DestroyContext(con->dtlsstate);
|
||||||
|
con->dtlsstate = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while(con->rc)
|
||||||
|
{
|
||||||
|
c = con->rc;
|
||||||
|
con->rc = c->next;
|
||||||
|
Z_Free(c);
|
||||||
|
}
|
||||||
|
while(con->lc)
|
||||||
|
{
|
||||||
|
c = con->lc;
|
||||||
|
con->lc = c->next;
|
||||||
|
Z_Free(c);
|
||||||
|
}
|
||||||
|
for (i = 0; i < con->servers; i++)
|
||||||
|
{
|
||||||
|
struct iceserver_s *s = &con->server[i];
|
||||||
|
if (s->con)
|
||||||
|
{ //make sure we tell the TURN server to release our allocation.
|
||||||
|
s->state = TURN_TERMINATING;
|
||||||
|
ICE_ToStunServer(con, s);
|
||||||
|
|
||||||
|
s->con->Close(s->con);
|
||||||
|
s->con = NULL;
|
||||||
|
}
|
||||||
|
Z_Free(s->nonce);
|
||||||
|
s->nonce = NULL;
|
||||||
|
s->peers = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (oldstate != con->state && con->state == ICE_CONNECTED)
|
if (oldstate != con->state && con->state == ICE_CONNECTED)
|
||||||
{
|
{
|
||||||
if (con->chosenpeer.type == NA_INVALID)
|
if (con->chosenpeer.type == NA_INVALID)
|
||||||
{
|
{
|
||||||
con->state = ICE_FAILED;
|
con->state = ICE_FAILED;
|
||||||
Con_Printf("ICE failed. peer not valid.\n");
|
Con_Printf(CON_WARNING"[%s]: ICE failed. peer not valid.\n", con->friendlyname);
|
||||||
}
|
}
|
||||||
#ifndef CLIENTONLY
|
#ifndef CLIENTONLY
|
||||||
else if (con->proto == ICEP_QWSERVER && con->mode != ICEM_WEBRTC)
|
else if (con->proto == ICEP_QWSERVER && con->mode != ICEM_WEBRTC)
|
||||||
|
@ -2445,7 +2509,7 @@ static qboolean QDECL ICE_Get(struct icestate_s *con, const char *prop, char *va
|
||||||
Q_strncatz(value, "t=0 0\n", valuelen); //start+end times...
|
Q_strncatz(value, "t=0 0\n", valuelen); //start+end times...
|
||||||
Q_strncatz(value, va("a=ice-options:trickle\n"), valuelen);
|
Q_strncatz(value, va("a=ice-options:trickle\n"), valuelen);
|
||||||
|
|
||||||
if ((con->proto == ICEP_QWSERVER || con->proto == ICEP_QWCLIENT) && con->mode == ICEM_WEBRTC)
|
if (con->proto == ICEP_QWSERVER || con->proto == ICEP_QWCLIENT)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DTLS
|
#ifdef HAVE_DTLS
|
||||||
if (con->cred.local.certsize)
|
if (con->cred.local.certsize)
|
||||||
|
@ -2457,10 +2521,20 @@ static qboolean QDECL ICE_Get(struct icestate_s *con, const char *prop, char *va
|
||||||
for (b = 0; b < hash_sha256.digestsize; b++)
|
for (b = 0; b < hash_sha256.digestsize; b++)
|
||||||
Q_strncatz(value, va(b?":%02X":" %02X", fingerprint[b]), valuelen);
|
Q_strncatz(value, va(b?":%02X":" %02X", fingerprint[b]), valuelen);
|
||||||
Q_strncatz(value, "\n", valuelen);
|
Q_strncatz(value, "\n", valuelen);
|
||||||
}
|
|
||||||
|
if (con->mode == ICEM_WEBRTC)
|
||||||
|
{
|
||||||
Q_strncatz(value, "m=application 9 UDP/DTLS/SCTP webrtc-datachannel\n", valuelen);
|
Q_strncatz(value, "m=application 9 UDP/DTLS/SCTP webrtc-datachannel\n", valuelen);
|
||||||
|
if (con->mysctpport)
|
||||||
|
Q_strncatz(value, va("a=sctp-port:%i\n", con->mysctpport), valuelen); //stupid hardcoded thing.
|
||||||
if (con->sctpoptional)
|
if (con->sctpoptional)
|
||||||
Q_strncatz(value, "a=sctp-optional:1\n", valuelen);
|
Q_strncatz(value, "a=sctp-optional:1\n", valuelen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Q_strncatz(value, "m=application 9 UDP/DTLS\n", valuelen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Q_strncatz(value, "m=application 9 UDP\n", valuelen);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// Q_strncatz(value, va("c=IN %s %s\n", sender.type==NA_IPV6?"IP6":"IP4", NET_BaseAdrToString(tmpstr, sizeof(tmpstr), &sender)), valuelen);
|
// Q_strncatz(value, va("c=IN %s %s\n", sender.type==NA_IPV6?"IP6":"IP4", NET_BaseAdrToString(tmpstr, sizeof(tmpstr), &sender)), valuelen);
|
||||||
|
@ -2481,9 +2555,6 @@ static qboolean QDECL ICE_Get(struct icestate_s *con, const char *prop, char *va
|
||||||
else if (!strcmp(prop, "sdpoffer"))
|
else if (!strcmp(prop, "sdpoffer"))
|
||||||
Q_strncatz(value, va("a=setup:actpass\n"), valuelen); //don't care if we're active or passive
|
Q_strncatz(value, va("a=setup:actpass\n"), valuelen); //don't care if we're active or passive
|
||||||
}
|
}
|
||||||
|
|
||||||
if (con->mysctpport)
|
|
||||||
Q_strncatz(value, va("a=sctp-port:%i\n", con->mysctpport), valuelen); //stupid hardcoded thing.
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*fixme: merge the codecs into a single media line*/
|
/*fixme: merge the codecs into a single media line*/
|
||||||
|
@ -2752,6 +2823,8 @@ static void ICE_Destroy(struct icestate_s *con)
|
||||||
{
|
{
|
||||||
struct icecandidate_s *c;
|
struct icecandidate_s *c;
|
||||||
|
|
||||||
|
ICE_Set(con, "state", STRINGIFY(ICE_INACTIVE));
|
||||||
|
|
||||||
#ifdef HAVE_DTLS
|
#ifdef HAVE_DTLS
|
||||||
if (con->sctp)
|
if (con->sctp)
|
||||||
{
|
{
|
||||||
|
@ -2941,8 +3014,6 @@ static void QDECL ICE_Close(struct icestate_s *con)
|
||||||
{
|
{
|
||||||
struct icestate_s **link;
|
struct icestate_s **link;
|
||||||
|
|
||||||
ICE_Set(con, "state", STRINGIFY(ICE_INACTIVE));
|
|
||||||
|
|
||||||
for (link = &icelist; *link; )
|
for (link = &icelist; *link; )
|
||||||
{
|
{
|
||||||
if (con == *link)
|
if (con == *link)
|
||||||
|
@ -3325,7 +3396,7 @@ struct sctp_errorcause_s
|
||||||
quint16_t cause;
|
quint16_t cause;
|
||||||
quint16_t length;
|
quint16_t length;
|
||||||
};
|
};
|
||||||
static void SCTP_ErrorChunk(const char *errortype, struct sctp_errorcause_s *s, size_t totallen)
|
static void SCTP_ErrorChunk(struct icestate_s *peer, const char *errortype, struct sctp_errorcause_s *s, size_t totallen)
|
||||||
{
|
{
|
||||||
quint16_t cc, cl;
|
quint16_t cc, cl;
|
||||||
while(totallen > 0)
|
while(totallen > 0)
|
||||||
|
@ -3337,22 +3408,22 @@ static void SCTP_ErrorChunk(const char *errortype, struct sctp_errorcause_s *s,
|
||||||
if (totallen < cl)
|
if (totallen < cl)
|
||||||
return; //err..
|
return; //err..
|
||||||
|
|
||||||
switch(cc)
|
if (net_ice_debug.ival >= 1) switch(cc)
|
||||||
{
|
{
|
||||||
case 1: Con_Printf("%s: Invalid Stream Identifier\n", errortype); break;
|
case 1: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Invalid Stream Identifier\n", peer->friendlyname, errortype); break;
|
||||||
case 2: Con_Printf("%s: Missing Mandatory Parameter\n", errortype); break;
|
case 2: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Missing Mandatory Parameter\n", peer->friendlyname, errortype); break;
|
||||||
case 3: Con_Printf("%s: Stale Cookie Error\n", errortype); break;
|
case 3: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Stale Cookie Error\n", peer->friendlyname, errortype); break;
|
||||||
case 4: Con_Printf("%s: Out of Resource\n", errortype); break;
|
case 4: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Out of Resource\n", peer->friendlyname, errortype); break;
|
||||||
case 5: Con_Printf("%s: Unresolvable Address\n", errortype); break;
|
case 5: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Unresolvable Address\n", peer->friendlyname, errortype); break;
|
||||||
case 6: Con_Printf("%s: Unrecognized Chunk Type\n", errortype); break;
|
case 6: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Unrecognized Chunk Type\n", peer->friendlyname, errortype); break;
|
||||||
case 7: Con_Printf("%s: Invalid Mandatory Parameter\n", errortype); break;
|
case 7: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Invalid Mandatory Parameter\n", peer->friendlyname, errortype); break;
|
||||||
case 8: Con_Printf("%s: Unrecognized Parameters\n", errortype); break;
|
case 8: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Unrecognized Parameters\n", peer->friendlyname, errortype); break;
|
||||||
case 9: Con_Printf("%s: No User Data\n", errortype); break;
|
case 9: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: No User Data\n", peer->friendlyname, errortype); break;
|
||||||
case 10: Con_Printf("%s: Cookie Received While Shutting Down\n", errortype); break;
|
case 10: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Cookie Received While Shutting Down\n", peer->friendlyname, errortype); break;
|
||||||
case 11: Con_Printf("%s: Restart of an Association with New Addresses\n", errortype); break;
|
case 11: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Restart of an Association with New Addresses\n", peer->friendlyname, errortype); break;
|
||||||
case 12: Con_Printf("%s: User Initiated Abort\n", errortype); break;
|
case 12: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: User Initiated Abort\n", peer->friendlyname, errortype); break;
|
||||||
case 13: Con_Printf("%s: Protocol Violation [%s]\n", errortype, (char*)(s+1)); break;
|
case 13: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Protocol Violation [%s]\n", peer->friendlyname, errortype, (char*)(s+1)); break;
|
||||||
default: Con_Printf("%s: Unknown Reason\n", errortype); break;
|
default: Con_Printf(S_COLOR_GRAY"[%s]: SCTP %s: Unknown Reason\n", peer->friendlyname, errortype); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
totallen -= cl;
|
totallen -= cl;
|
||||||
|
@ -3383,7 +3454,7 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer, ftenet_connection
|
||||||
if (net_message.cursize&3)
|
if (net_message.cursize&3)
|
||||||
{
|
{
|
||||||
if (net_ice_debug.ival >= 2)
|
if (net_ice_debug.ival >= 2)
|
||||||
Con_Printf("SCTP: packet not padded\n");
|
Con_Printf(S_COLOR_GRAY"[%s]: SCTP: packet not padded\n", peer->friendlyname);
|
||||||
return; //mimic chrome, despite it being pointless.
|
return; //mimic chrome, despite it being pointless.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3402,11 +3473,20 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer, ftenet_connection
|
||||||
qint32_t adv = tsn - sctp->i.ctsn;
|
qint32_t adv = tsn - sctp->i.ctsn;
|
||||||
sctp->i.ackneeded++;
|
sctp->i.ackneeded++;
|
||||||
if (adv >= SCTP_RCVSIZE)
|
if (adv >= SCTP_RCVSIZE)
|
||||||
Con_DPrintf("SCTP: Future Packet\n");/*too far in the future. we can't track such things*/
|
{
|
||||||
|
if (net_ice_debug.ival >= 1)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: SCTP: Future Packet\n", peer->friendlyname);/*too far in the future. we can't track such things*/
|
||||||
|
}
|
||||||
else if (adv <= 0)
|
else if (adv <= 0)
|
||||||
Con_DPrintf("SCTP: PreCumulative\n");/*already acked this*/
|
{
|
||||||
|
if (net_ice_debug.ival >= 2)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: SCTP: PreCumulative\n", peer->friendlyname);/*already acked this*/
|
||||||
|
}
|
||||||
else if (sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] & 1<<(tsn&7))
|
else if (sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] & 1<<(tsn&7))
|
||||||
Con_DPrintf("SCTP: Dupe\n");/*already processed it. FIXME: Make a list for the next SACK*/
|
{
|
||||||
|
if (net_ice_debug.ival >= 2)
|
||||||
|
Con_DPrintf(S_COLOR_GRAY"[%s]: SCTP: Dupe\n", peer->friendlyname);/*already processed it. FIXME: Make a list for the next SACK*/
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qboolean err = false;
|
qboolean err = false;
|
||||||
|
@ -3436,7 +3516,8 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer, ftenet_connection
|
||||||
sctp->i.r.tsn++;
|
sctp->i.r.tsn++;
|
||||||
if (sctp->i.r.size + clen-sizeof(*dc) > sizeof(sctp->i.r.buf))
|
if (sctp->i.r.size + clen-sizeof(*dc) > sizeof(sctp->i.r.buf))
|
||||||
{
|
{
|
||||||
Con_DPrintf("SCTP: Oversized\n");
|
if (net_ice_debug.ival >= 2)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: SCTP: Oversized\n", peer->friendlyname);
|
||||||
sctp->i.r.toobig = true; //reassembled packet was too large, just corrupt it.
|
sctp->i.r.toobig = true; //reassembled packet was too large, just corrupt it.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3516,7 +3597,8 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer, ftenet_connection
|
||||||
sctp->peerhasfwdtsn = true;
|
sctp->peerhasfwdtsn = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Con_DPrintf("SCTP: Found unknown init parameter %i||%#x\n", ptype, ptype);
|
if (net_ice_debug.ival >= 2)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: SCTP: Found unknown init parameter %i||%#x\n", peer->friendlyname, ptype, ptype);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
p = (void*)((qbyte*)p + ((plen+3)&~3));
|
p = (void*)((qbyte*)p + ((plen+3)&~3));
|
||||||
|
@ -3607,16 +3689,17 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer, ftenet_connection
|
||||||
// case SCTP_TYPE_PONG: //we don't send pings
|
// case SCTP_TYPE_PONG: //we don't send pings
|
||||||
case SCTP_TYPE_ABORT:
|
case SCTP_TYPE_ABORT:
|
||||||
ICE_Set(peer, "state", STRINGIFY(ICE_FAILED));
|
ICE_Set(peer, "state", STRINGIFY(ICE_FAILED));
|
||||||
SCTP_ErrorChunk("Abort", (struct sctp_errorcause_s*)(c+1), clen-sizeof(*c));
|
SCTP_ErrorChunk(peer, "Abort", (struct sctp_errorcause_s*)(c+1), clen-sizeof(*c));
|
||||||
break;
|
break;
|
||||||
case SCTP_TYPE_SHUTDOWN: //FIXME. we should send an ack...
|
case SCTP_TYPE_SHUTDOWN: //FIXME. we should send an ack...
|
||||||
ICE_Set(peer, "state", STRINGIFY(ICE_FAILED));
|
ICE_Set(peer, "state", STRINGIFY(ICE_FAILED));
|
||||||
Con_DPrintf(CON_ERROR"SCTP: Shutdown\n");
|
if (net_ice_debug.ival >= 1)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: SCTP: Shutdown\n", peer->friendlyname);
|
||||||
break;
|
break;
|
||||||
// case SCTP_TYPE_SHUTDOWNACK: //we don't send shutdowns, cos we're lame like that...
|
// case SCTP_TYPE_SHUTDOWNACK: //we don't send shutdowns, cos we're lame like that...
|
||||||
case SCTP_TYPE_ERROR:
|
case SCTP_TYPE_ERROR:
|
||||||
//not fatal...
|
//not fatal...
|
||||||
SCTP_ErrorChunk("Error", (struct sctp_errorcause_s*)(c+1), clen-sizeof(*c));
|
SCTP_ErrorChunk(peer, "Error", (struct sctp_errorcause_s*)(c+1), clen-sizeof(*c));
|
||||||
break;
|
break;
|
||||||
case SCTP_TYPE_COOKIEECHO:
|
case SCTP_TYPE_COOKIEECHO:
|
||||||
if (clen >= sizeof(struct sctp_chunk_s))
|
if (clen >= sizeof(struct sctp_chunk_s))
|
||||||
|
@ -3666,7 +3749,8 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer, ftenet_connection
|
||||||
// case SCTP_TYPE_SHUTDOWNDONE:
|
// case SCTP_TYPE_SHUTDOWNDONE:
|
||||||
safedefault:
|
safedefault:
|
||||||
//no idea what this chunk is, just ignore it...
|
//no idea what this chunk is, just ignore it...
|
||||||
Con_DPrintf("SCTP: Unsupported chunk %i\n", c->type);
|
if (net_ice_debug.ival >= 1)
|
||||||
|
Con_Printf(S_COLOR_GRAY"[%s]: SCTP: Unsupported chunk %i\n", peer->friendlyname, c->type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = (struct sctp_chunk_s*)((qbyte*)c + ((clen+3)&~3)); //next chunk is 4-byte aligned.
|
c = (struct sctp_chunk_s*)((qbyte*)c + ((clen+3)&~3)); //next chunk is 4-byte aligned.
|
||||||
|
@ -4666,7 +4750,19 @@ qboolean ICE_IsEncrypted(netadr_t *to)
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
neterr_t ICE_SendPacket(ftenet_connections_t *col, size_t length, const void *data, netadr_t *to)
|
void ICE_Terminate(netadr_t *to)
|
||||||
|
{
|
||||||
|
struct icestate_s *con;
|
||||||
|
for (con = icelist; con; con = con->next)
|
||||||
|
{
|
||||||
|
if (NET_CompareAdr(to, &con->qadr))
|
||||||
|
{
|
||||||
|
ICE_Set(con, "state", STRINGIFY(ICE_INACTIVE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
neterr_t ICE_SendPacket(size_t length, const void *data, netadr_t *to)
|
||||||
{
|
{
|
||||||
struct icestate_s *con;
|
struct icestate_s *con;
|
||||||
for (con = icelist; con; con = con->next)
|
for (con = icelist; con; con = con->next)
|
||||||
|
|
|
@ -545,11 +545,6 @@ static int QDECL SSL_CheckFingerprint(gnutls_session_t session)
|
||||||
file->peerhashfunc->process(ctx, certlist[j].data, certlist[j].size);
|
file->peerhashfunc->process(ctx, certlist[j].data, certlist[j].size);
|
||||||
file->peerhashfunc->terminate(digest, ctx);
|
file->peerhashfunc->terminate(digest, ctx);
|
||||||
|
|
||||||
{
|
|
||||||
vfsfile_t *f = FS_OpenVFS("/tmp/cert", "wb", FS_SYSTEM);
|
|
||||||
VFS_WRITE(f, certlist[0].data, certlist[0].size);
|
|
||||||
VFS_CLOSE(f);
|
|
||||||
}
|
|
||||||
if (!memcmp(digest, file->peerdigest, file->peerhashfunc->digestsize))
|
if (!memcmp(digest, file->peerdigest, file->peerhashfunc->digestsize))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -640,7 +635,7 @@ static int QDECL SSL_Read(struct vfsfile_s *f, void *buffer, int bytestoread)
|
||||||
return 0; //caller is expected to try again later, no real need to loop here, just in case it repeats (eg E_AGAIN)
|
return 0; //caller is expected to try again later, no real need to loop here, just in case it repeats (eg E_AGAIN)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Con_Printf("TLS Read Warning %i (bufsize %i)\n", read, bytestoread);
|
Con_Printf("GNUTLS Read Warning %i (bufsize %i)\n", read, bytestoread);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -667,7 +662,7 @@ static int QDECL SSL_Write(struct vfsfile_s *f, const void *buffer, int bytestow
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Con_DPrintf("TLS Send Error %i (%i bytes)\n", written, bytestowrite);
|
Con_DPrintf("GNUTLS Send Error %i (%i bytes)\n", written, bytestowrite);
|
||||||
return VFS_ERROR_UNSPECIFIED;
|
return VFS_ERROR_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -999,7 +994,9 @@ static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred)
|
||||||
if (priv.size && pub.size)
|
if (priv.size && pub.size)
|
||||||
{ //submit them to gnutls
|
{ //submit them to gnutls
|
||||||
ret = qgnutls_certificate_set_x509_key_mem(cred, &pub, &priv, GNUTLS_X509_FMT_PEM);
|
ret = qgnutls_certificate_set_x509_key_mem(cred, &pub, &priv, GNUTLS_X509_FMT_PEM);
|
||||||
if (ret < 0)
|
if (ret == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
|
||||||
|
Con_Printf(CON_ERROR"gnutls_certificate_set_x509_key_mem failed: GNUTLS_E_CERTIFICATE_KEY_MISMATCH\n");
|
||||||
|
else if (ret < 0)
|
||||||
Con_Printf(CON_ERROR"gnutls_certificate_set_x509_key_mem failed: %i\n", ret);
|
Con_Printf(CON_ERROR"gnutls_certificate_set_x509_key_mem failed: %i\n", ret);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1632,7 +1629,7 @@ static qboolean GNUDTLS_GenTempCertificate(const char *subject, struct dtlslocal
|
||||||
{
|
{
|
||||||
qbyte tmp[16];
|
qbyte tmp[16];
|
||||||
Sys_RandomBytes(tmp, sizeof(tmp));
|
Sys_RandomBytes(tmp, sizeof(tmp));
|
||||||
randomsub[Base16_EncodeBlock(tmp, sizeof(tmp), randomsub, sizeof(randomsub))] = 0;
|
randomsub[Base16_EncodeBlock(tmp, sizeof(tmp), randomsub, sizeof(randomsub)-1)] = 0;
|
||||||
subject = randomsub;
|
subject = randomsub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1687,7 +1684,7 @@ static const dtlsfuncs_t *GNUDTLS_InitServer(void)
|
||||||
{
|
{
|
||||||
if (!SSL_InitGlobal(true))
|
if (!SSL_InitGlobal(true))
|
||||||
return NULL; //unable to init a server certificate. don't allow dtls to init.
|
return NULL; //unable to init a server certificate. don't allow dtls to init.
|
||||||
if (servercertfail && !*dtls_psk_user.string)
|
if (servercertfail && !*dtls_psk_user.string) //FIXME: with ICE connections we'll be using temporary certs anyway.
|
||||||
return NULL;
|
return NULL;
|
||||||
return &dtlsfuncs_gnutls;
|
return &dtlsfuncs_gnutls;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8199,7 +8199,7 @@ neterr_t NET_SendPacket (ftenet_connections_t *collection, int length, const voi
|
||||||
|
|
||||||
#ifdef SUPPORT_ICE
|
#ifdef SUPPORT_ICE
|
||||||
if (to->type == NA_ICE)
|
if (to->type == NA_ICE)
|
||||||
return ICE_SendPacket(collection, length, data, to);
|
return ICE_SendPacket(length, data, to);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_DTLS
|
#ifdef HAVE_DTLS
|
||||||
if (to->prot == NP_DTLS)
|
if (to->prot == NP_DTLS)
|
||||||
|
@ -8256,6 +8256,24 @@ qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
void NET_TerminateRoute(ftenet_connections_t *collection, netadr_t *adr)
|
||||||
|
{
|
||||||
|
switch(adr->prot)
|
||||||
|
{
|
||||||
|
case NP_DTLS:
|
||||||
|
#ifdef HAVE_DTLS
|
||||||
|
NET_DTLS_Disconnect(collection, adr);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SUPPORT_ICE
|
||||||
|
if (adr->type == NA_ICE)
|
||||||
|
ICE_Terminate(adr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int NET_EnumerateAddresses(ftenet_connections_t *collection, struct ftenet_generic_connection_s **con, unsigned int *adrflags, netadr_t *addresses, const char **adrparams, int maxaddresses)
|
int NET_EnumerateAddresses(ftenet_connections_t *collection, struct ftenet_generic_connection_s **con, unsigned int *adrflags, netadr_t *addresses, const char **adrparams, int maxaddresses)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1124,7 +1124,7 @@ qboolean GLBE_BeginShadowMap(int id, int w, int h, uploadfmt_t encoding, int *re
|
||||||
{
|
{
|
||||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||||
qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
|
//qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
|
||||||
}
|
}
|
||||||
tex->status = TEX_LOADED;
|
tex->status = TEX_LOADED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5020,11 +5020,19 @@ void SV_CheckTimeouts (void)
|
||||||
SV_BroadcastTPrintf (PRINT_HIGH, "Client %s timed out\n", cl->name);
|
SV_BroadcastTPrintf (PRINT_HIGH, "Client %s timed out\n", cl->name);
|
||||||
SV_DropClient (cl);
|
SV_DropClient (cl);
|
||||||
cl->state = cs_free; // don't bother with zombie state for local player.
|
cl->state = cs_free; // don't bother with zombie state for local player.
|
||||||
|
if (cl->netchan.remote_address.type != NA_INVALID)
|
||||||
|
NET_TerminateRoute(svs.sockets, &cl->netchan.remote_address);
|
||||||
|
cl->netchan.remote_address.type = NA_INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cl->state == cs_zombie && realtime - cl->connection_started > zombietime.value)
|
if (cl->state == cs_zombie && realtime - cl->connection_started > zombietime.value)
|
||||||
|
{
|
||||||
cl->state = cs_free; // can now be reused
|
cl->state = cs_free; // can now be reused
|
||||||
|
if (cl->netchan.remote_address.type != NA_INVALID)
|
||||||
|
NET_TerminateRoute(svs.sockets, &cl->netchan.remote_address);
|
||||||
|
cl->netchan.remote_address.type = NA_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
if (cl->state == cs_loadzombie && realtime - cl->connection_started > zombietime.value)
|
if (cl->state == cs_loadzombie && realtime - cl->connection_started > zombietime.value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -770,7 +770,7 @@ static void *OSSL_CreateContext(const dtlscred_t *cred, void *cbctx, neterr_t(*p
|
||||||
SSL_CTX_set_session_cache_mode(n->ctx, SSL_SESS_CACHE_OFF);
|
SSL_CTX_set_session_cache_mode(n->ctx, SSL_SESS_CACHE_OFF);
|
||||||
|
|
||||||
SSL_CTX_set_verify(n->ctx, SSL_VERIFY_PEER|(n->cert.hash?SSL_VERIFY_FAIL_IF_NO_PEER_CERT:0), OSSL_Verify_Peer);
|
SSL_CTX_set_verify(n->ctx, SSL_VERIFY_PEER|(n->cert.hash?SSL_VERIFY_FAIL_IF_NO_PEER_CERT:0), OSSL_Verify_Peer);
|
||||||
SSL_CTX_set_verify_depth(n->ctx, 5);
|
SSL_CTX_set_verify_depth(n->ctx, 10);
|
||||||
SSL_CTX_set_options(n->ctx, SSL_OP_NO_COMPRESSION| //compression allows guessing the contents of the stream somehow.
|
SSL_CTX_set_options(n->ctx, SSL_OP_NO_COMPRESSION| //compression allows guessing the contents of the stream somehow.
|
||||||
SSL_OP_NO_RENEGOTIATION);
|
SSL_OP_NO_RENEGOTIATION);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue