mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
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:
parent
42430d4712
commit
98c60de572
4 changed files with 55 additions and 27 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue