Should at least build for android again.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6177 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2022-01-30 07:18:34 +00:00
parent 42430d4712
commit 98c60de572
4 changed files with 55 additions and 27 deletions

View file

@ -425,7 +425,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#if defined(HAVE_GNUTLS) || defined(HAVE_WINSSPI) #if defined(HAVE_GNUTLS) || defined(HAVE_WINSSPI)
#define HAVE_SSL #define HAVE_SSL
#endif #endif
#if defined(HAVE_GNUTLS) || defined(HAVE_WINSSPI) #if defined(HAVE_GNUTLS) || defined(HAVE_WINSSPI) || defined(HAVE_PLUGINS)
//FIXME: HAVE_WINSSPI does not work as a server. //FIXME: HAVE_WINSSPI does not work as a server.
//FIXME: advertising dtls without a valid certificate will probably bug out if a client tries to auto-upgrade. //FIXME: advertising dtls without a valid certificate will probably bug out if a client tries to auto-upgrade.
//FIXME: we don't cache server certs //FIXME: we don't cache server certs

View file

@ -75,9 +75,6 @@ struct icestate_s
netadr_t qadr; //address reported to the rest of the engine (packets from our peer get remapped to this) netadr_t qadr; //address reported to the rest of the engine (packets from our peer get remapped to this)
netadr_t chosenpeer; //address we're sending our data to. netadr_t chosenpeer; //address we're sending our data to.
void *dtlsstate;
struct sctp_s *sctp; //ffs! extra processing needed.
netadr_t pubstunserver; netadr_t pubstunserver;
unsigned int stunretry; //once a second, extended to once a minite on reply unsigned int stunretry; //once a second, extended to once a minite on reply
char *stunserver;//where to get our public ip from. char *stunserver;//where to get our public ip from.
@ -111,11 +108,16 @@ struct icestate_s
int foundation; int foundation;
qboolean blockcandidates; //don't send candidates yet. qboolean blockcandidates; //don't send candidates yet.
#ifdef HAVE_DTLS
void *dtlsstate;
struct sctp_s *sctp; //ffs! extra processing needed.
const dtlsfuncs_t *dtlsfuncs; const dtlsfuncs_t *dtlsfuncs;
qboolean dtlspassive; //true=server, false=client (separate from ice controller and whether we're hosting. yay...) qboolean dtlspassive; //true=server, false=client (separate from ice controller and whether we're hosting. yay...)
dtlscred_t cred; //credentials info for dtls (both peer and local info) dtlscred_t cred; //credentials info for dtls (both peer and local info)
quint16_t mysctpport; quint16_t mysctpport;
quint16_t peersctpport; quint16_t peersctpport;
#endif
ftenet_connections_t *connections; //used only for PRIVATE sockets. ftenet_connections_t *connections; //used only for PRIVATE sockets.
@ -166,7 +168,9 @@ typedef struct sctp_s
} i; } i;
unsigned short qstreamid; //in network endian. unsigned short qstreamid; //in network endian.
} sctp_t; } sctp_t;
#ifdef HAVE_DTLS
static neterr_t SCTP_Transmit(sctp_t *sctp, struct icestate_s *peer, const void *data, size_t length); static neterr_t SCTP_Transmit(sctp_t *sctp, struct icestate_s *peer, const void *data, size_t length);
#endif
static struct icestate_s *icelist; static struct icestate_s *icelist;
@ -334,6 +338,10 @@ static struct icestate_s *QDECL ICE_Create(void *module, const char *conname, co
//only allow modes that we actually support. //only allow modes that we actually support.
if (mode != ICEM_RAW && mode != ICEM_ICE && mode != ICEM_WEBRTC) if (mode != ICEM_RAW && mode != ICEM_ICE && mode != ICEM_WEBRTC)
return NULL; return NULL;
#ifndef HAVE_DTLS
if (mode == ICEM_WEBRTC)
return NULL;
#endif
//only allow protocols that we actually support. //only allow protocols that we actually support.
switch(proto) switch(proto)
@ -395,6 +403,8 @@ static struct icestate_s *QDECL ICE_Create(void *module, const char *conname, co
con->mode = mode; con->mode = mode;
con->blockcandidates = true; //until offers/answers are sent. con->blockcandidates = true; //until offers/answers are sent.
#ifdef HAVE_DTLS
con->dtlspassive = (proto == ICEP_QWSERVER); //note: may change later. con->dtlspassive = (proto == ICEP_QWSERVER); //note: may change later.
if (mode == ICEM_WEBRTC) if (mode == ICEM_WEBRTC)
@ -416,9 +426,10 @@ static struct icestate_s *QDECL ICE_Create(void *module, const char *conname, co
con->mysctpport = 27500; con->mysctpport = 27500;
} }
con->qadr.port = con->mysctpport;
#endif
con->qadr.type = NA_ICE; con->qadr.type = NA_ICE;
con->qadr.prot = NP_DGRAM; con->qadr.prot = NP_DGRAM;
con->qadr.port = con->mysctpport;
Q_strncpyz(con->qadr.address.icename, con->friendlyname, sizeof(con->qadr.address.icename)); Q_strncpyz(con->qadr.address.icename, con->friendlyname, sizeof(con->qadr.address.icename));
con->next = icelist; con->next = icelist;
@ -723,6 +734,7 @@ static void ICE_ParseSDPLine(struct icestate_s *con, const char *value)
ICE_Set(con, "rpwd", value+10); ICE_Set(con, "rpwd", value+10);
else if (!strncmp(value, "a=ice-ufrag:", 12)) else if (!strncmp(value, "a=ice-ufrag:", 12))
ICE_Set(con, "rufrag", value+12); ICE_Set(con, "rufrag", value+12);
#ifdef HAVE_DTLS
else if (!strncmp(value, "a=setup:", 8)) else if (!strncmp(value, "a=setup:", 8))
{ //this is their state, so we want the opposite. { //this is their state, so we want the opposite.
if (!strncmp(value+8, "passive", 7)) if (!strncmp(value+8, "passive", 7))
@ -730,21 +742,6 @@ static void ICE_ParseSDPLine(struct icestate_s *con, const char *value)
else if (!strncmp(value+8, "active", 6)) else if (!strncmp(value+8, "active", 6))
con->dtlspassive = true; con->dtlspassive = true;
} }
else if (!strncmp(value, "a=rtpmap:", 9))
{
char name[64];
int codec;
char *sl;
value += 9;
codec = strtoul(value, (char**)&value, 0);
if (*value == ' ') value++;
COM_ParseOut(value, name, sizeof(name));
sl = strchr(name, '/');
if (sl)
*sl = '@';
ICE_Set(con, va("codec%i", codec), name);
}
else if (!strncmp(value, "a=fingerprint:", 14)) else if (!strncmp(value, "a=fingerprint:", 14))
{ {
char name[64]; char name[64];
@ -799,6 +796,22 @@ static void ICE_ParseSDPLine(struct icestate_s *con, const char *value)
} }
else if (!strncmp(value, "a=sctp-port:", 12)) else if (!strncmp(value, "a=sctp-port:", 12))
con->peersctpport = atoi(value+12); con->peersctpport = atoi(value+12);
#endif
else if (!strncmp(value, "a=rtpmap:", 9))
{
char name[64];
int codec;
char *sl;
value += 9;
codec = strtoul(value, (char**)&value, 0);
if (*value == ' ') value++;
COM_ParseOut(value, name, sizeof(name));
sl = strchr(name, '/');
if (sl)
*sl = '@';
ICE_Set(con, va("codec%i", codec), name);
}
else if (!strncmp(value, "a=candidate:", 12)) else if (!strncmp(value, "a=candidate:", 12))
{ {
struct icecandinfo_s n; struct icecandinfo_s n;
@ -905,6 +918,7 @@ static qboolean QDECL ICE_Set(struct icestate_s *con, const char *prop, const ch
if (con->state >= ICE_CONNECTING) if (con->state >= ICE_CONNECTING)
{ {
#ifdef HAVE_DTLS
if (con->mode == ICEM_WEBRTC) if (con->mode == ICEM_WEBRTC)
{ {
if (!con->dtlsstate && con->dtlsfuncs) if (!con->dtlsstate && con->dtlsfuncs)
@ -920,6 +934,7 @@ static qboolean QDECL ICE_Set(struct icestate_s *con, const char *prop, const ch
Sys_RandomBytes((void*)&con->sctp->i.verifycode, sizeof(con->sctp->i.verifycode)); Sys_RandomBytes((void*)&con->sctp->i.verifycode, sizeof(con->sctp->i.verifycode));
} }
} }
#endif
} }
if (oldstate != con->state && con->state == ICE_CONNECTED) if (oldstate != con->state && con->state == ICE_CONNECTED)
@ -1147,6 +1162,7 @@ static qboolean QDECL ICE_Get(struct icestate_s *con, const char *prop, char *va
Q_strncatz(value, va("a=ice-pwd:%s\n", con->lpwd), valuelen); Q_strncatz(value, va("a=ice-pwd:%s\n", con->lpwd), valuelen);
Q_strncatz(value, va("a=ice-ufrag:%s\n", con->lufrag), valuelen); Q_strncatz(value, va("a=ice-ufrag:%s\n", con->lufrag), valuelen);
#ifdef HAVE_DTLS
if (con->dtlsfuncs) if (con->dtlsfuncs)
{ {
if (!strcmp(prop, "sdpanswer")) if (!strcmp(prop, "sdpanswer"))
@ -1162,6 +1178,7 @@ static qboolean QDECL ICE_Get(struct icestate_s *con, const char *prop, char *va
if (con->mysctpport) if (con->mysctpport)
Q_strncatz(value, va("a=sctp-port:%i\n", con->mysctpport), valuelen); //stupid hardcoded thing. Q_strncatz(value, va("a=sctp-port:%i\n", con->mysctpport), valuelen); //stupid hardcoded thing.
#endif
/*fixme: merge the codecs into a single media line*/ /*fixme: merge the codecs into a single media line*/
for (i = 0; i < countof(con->codecslot); i++) for (i = 0; i < countof(con->codecslot); i++)
@ -1335,6 +1352,7 @@ static void ICE_Destroy(struct icestate_s *con)
{ {
struct icecandidate_s *c; struct icecandidate_s *c;
#ifdef HAVE_DTLS
if (con->sctp) if (con->sctp)
{ {
Z_Free(con->sctp->cookie); Z_Free(con->sctp->cookie);
@ -1342,12 +1360,13 @@ static void ICE_Destroy(struct icestate_s *con)
} }
if (con->dtlsstate) if (con->dtlsstate)
con->dtlsfuncs->DestroyContext(con->dtlsstate); con->dtlsfuncs->DestroyContext(con->dtlsstate);
if (con->connections)
FTENET_CloseCollection(con->connections);
if (con->cred.local.cert) if (con->cred.local.cert)
Z_Free(con->cred.local.cert); Z_Free(con->cred.local.cert);
if (con->cred.local.key) if (con->cred.local.key)
Z_Free(con->cred.local.key); Z_Free(con->cred.local.key);
#endif
if (con->connections)
FTENET_CloseCollection(con->connections);
while(con->rc) while(con->rc)
{ {
c = con->rc; c = con->rc;
@ -1436,10 +1455,12 @@ void ICE_Tick(void)
} }
else if (con->state == ICE_CONNECTED) else if (con->state == ICE_CONNECTED)
{ {
#ifdef HAVE_DTLS
if (con->sctp) if (con->sctp)
SCTP_Transmit(con->sctp, con, NULL,0); //try to keep it ticking... SCTP_Transmit(con->sctp, con, NULL,0); //try to keep it ticking...
if (con->dtlsstate) if (con->dtlsstate)
con->dtlsfuncs->Timeouts(con->dtlsstate); con->dtlsfuncs->Timeouts(con->dtlsstate);
#endif
//FIXME: We should be sending a stun binding indication every 15 secs with a fingerprint attribute //FIXME: We should be sending a stun binding indication every 15 secs with a fingerprint attribute
} }
@ -1497,10 +1518,11 @@ icefuncs_t iceapi =
#if defined(SUPPORT_ICE) #if defined(SUPPORT_ICE) && defined(HAVE_DTLS)
//======================================== //========================================
//WebRTC's interpretation of SCTP. its annoying, but hey its only 28 wasted bytes... along with the dtls overhead too. most of this is redundant. //WebRTC's interpretation of SCTP. its annoying, but hey its only 28 wasted bytes... along with the dtls overhead too. most of this is redundant.
//we only send unreliably. //we only send unreliably.
//there's no point in this code without full webrtc code.
struct sctp_header_s struct sctp_header_s
{ {
@ -2667,6 +2689,7 @@ qboolean ICE_WasStun(ftenet_connections_t *col)
con->timeout = Sys_Milliseconds() + 32; //not dead yet... con->timeout = Sys_Milliseconds() + 32; //not dead yet...
#ifdef HAVE_DTLS
if (con->dtlsstate) if (con->dtlsstate)
{ {
switch(con->dtlsfuncs->Received(con->dtlsstate, &net_message)) switch(con->dtlsfuncs->Received(con->dtlsstate, &net_message))
@ -2682,9 +2705,12 @@ qboolean ICE_WasStun(ftenet_connections_t *col)
return true; return true;
} }
} }
#endif
net_from = con->qadr; net_from = con->qadr;
#ifdef HAVE_DTLS
if (con->sctp) if (con->sctp)
SCTP_Decode(con->sctp, con); SCTP_Decode(con->sctp, con);
#endif
if (net_message.cursize) if (net_message.cursize)
col->ReadGamePacket(); col->ReadGamePacket();
return true; return true;
@ -2704,12 +2730,14 @@ neterr_t ICE_SendPacket(ftenet_connections_t *col, size_t length, const void *da
{ {
if (NET_CompareAdr(to, &con->qadr)) if (NET_CompareAdr(to, &con->qadr))
{ {
#ifdef HAVE_DTLS
if (con->sctp) if (con->sctp)
return SCTP_Transmit(con->sctp, con, data, length); return SCTP_Transmit(con->sctp, con, data, length);
if (con->dtlsstate) if (con->dtlsstate)
return SCTP_PeerSendPacket(con, length, data); return SCTP_PeerSendPacket(con, length, data);
#endif
if (con->chosenpeer.type != NA_INVALID) if (con->chosenpeer.type != NA_INVALID)
return NET_SendPacket(col, length, data, &con->chosenpeer); return ICE_Transmit(con, data, length);
if (con->state < ICE_CONNECTING) if (con->state < ICE_CONNECTING)
return NETERR_DISCONNECTED; return NETERR_DISCONNECTED;
return NETERR_CLOGGED; //still pending return NETERR_CLOGGED; //still pending

View file

@ -436,7 +436,7 @@ static qboolean QDECL SSL_CloseFile(vfsfile_t *vfs)
static int SSL_CheckUserTrust(gnutls_session_t session, gnutlsfile_t *file, int gcertcode) static int SSL_CheckUserTrust(gnutls_session_t session, gnutlsfile_t *file, int gcertcode)
{ {
int ret = gcertcode?GNUTLS_E_CERTIFICATE_ERROR:GNUTLS_E_SUCCESS; int ret = gcertcode?GNUTLS_E_CERTIFICATE_ERROR:GNUTLS_E_SUCCESS;
#ifdef HAVE_CLIENT #if defined(HAVE_CLIENT) && defined(HAVE_DTLS)
unsigned int ferrcode; unsigned int ferrcode;
//when using dtls, we expect self-signed certs and persistent trust. //when using dtls, we expect self-signed certs and persistent trust.
if (file->datagram) if (file->datagram)

View file

@ -346,7 +346,6 @@ enum hashvalidation_e
VH_CORRECT //all is well. VH_CORRECT //all is well.
}; };
struct dtlsfuncs_s; struct dtlsfuncs_s;
#ifdef HAVE_DTLS
typedef struct dtlscred_s typedef struct dtlscred_s
{ {
struct dtlslocalcred_s struct dtlslocalcred_s
@ -375,6 +374,7 @@ typedef struct dtlsfuncs_s
void (*GetPeerCertificate)(void *ctx); void (*GetPeerCertificate)(void *ctx);
qboolean (*GenTempCertificate)(const char *subject, struct dtlslocalcred_s *cred); qboolean (*GenTempCertificate)(const char *subject, struct dtlslocalcred_s *cred);
} dtlsfuncs_t; } dtlsfuncs_t;
#ifdef HAVE_DTLS
const dtlsfuncs_t *DTLS_InitServer(void); const dtlsfuncs_t *DTLS_InitServer(void);
const dtlsfuncs_t *DTLS_InitClient(void); const dtlsfuncs_t *DTLS_InitClient(void);
#endif #endif