mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 06:32:00 +00:00
Add support for 'connect dtls://foo' without needing extra upgrading stuff first. This change allows for QEx to establish a dtls connection to our server, though the reverse still doesn't work.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6156 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
310bf64d83
commit
bf44769b4d
7 changed files with 221 additions and 54 deletions
|
@ -294,6 +294,13 @@ ELSEIF(${UNIX} AND NOT FTE_USE_SDL) #linux(ish)
|
|||
IF(NOT GNUTLS_FOUND)
|
||||
MESSAGE(WARNING "gnutls library NOT available. HTTPS/DTLS will not be available.")
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_GNUTLS)
|
||||
ELSE()
|
||||
SET(GNUTLS_STATIC false CACHE BOOL "Link gnutls statically.") #usually as an .so though. :/
|
||||
IF(GNUTLS_STATIC)
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};GNUTLS_STATIC)
|
||||
SET(FTE_LIBS ${FTE_LIBS} ${GNUTLS_LIBRARY})
|
||||
SET(FTESV_LIBS ${FTESV_LIBS} ${GNUTLS_LIBRARY})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
#linux-only packages
|
||||
|
@ -1207,7 +1214,7 @@ IF(FTE_PLUG_MPQ)
|
|||
ENDIF()
|
||||
|
||||
#vpk package format plugin (halflife2)
|
||||
SET(FTE_PLUG_HL2 false CACHE BOOL "Compile support for hl2 file formats.")
|
||||
SET(FTE_PLUG_HL2 true CACHE BOOL "Compile support for hl2 file formats.")
|
||||
IF(FTE_PLUG_HL2)
|
||||
ADD_LIBRARY(plug_hl2 MODULE
|
||||
plugins/plugin.c
|
||||
|
|
|
@ -1200,7 +1200,7 @@ void CL_CheckForResend (void)
|
|||
if (!connectinfo.clogged)
|
||||
connectinfo.time = realtime+t2-t1; // for retransmit requests
|
||||
|
||||
to = &connectinfo.adr[connectinfo.nextadr++%connectinfo.numadr];
|
||||
to = &connectinfo.adr[connectinfo.nextadr%connectinfo.numadr];
|
||||
if (!NET_IsClientLegal(to))
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("Illegal server address"));
|
||||
|
@ -1225,7 +1225,7 @@ void CL_CheckForResend (void)
|
|||
Con_TPrintf ("Connecting to %s...\n", cls.servername);
|
||||
}
|
||||
|
||||
if (connectinfo.tries == 0 && to == &connectinfo.adr[0])
|
||||
if (connectinfo.tries == 0 && connectinfo.nextadr < connectinfo.numadr)
|
||||
if (!NET_EnsureRoute(cls.sockets, "conn", cls.servername, to))
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("Unable to establish connection to %s\n", cls.servername));
|
||||
|
@ -1235,8 +1235,10 @@ void CL_CheckForResend (void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (to->prot == NP_DGRAM)
|
||||
connectinfo.nextadr++; //cycle hosts with each ping (if we got multiple).
|
||||
|
||||
contype |= 1; /*always try qw type connections*/
|
||||
// if ((connect_tries&3)==3) || (connect_defaultport==26000))
|
||||
#ifdef VM_UI
|
||||
if (!UI_IsRunning()) //don't try to connect to nq servers when running a q3ui. I was getting annoying error messages from q3 servers due to this.
|
||||
#endif
|
||||
|
@ -1304,10 +1306,15 @@ void CL_CheckForResend (void)
|
|||
|
||||
if (!keeptrying)
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("No route to \"%s\", giving up\n", cls.servername));
|
||||
Con_TPrintf ("No route to host, giving up\n");
|
||||
connectinfo.trying = false;
|
||||
SCR_EndLoadingPlaque();
|
||||
if (to->prot != NP_DGRAM && connectinfo.nextadr+1 < connectinfo.numadr)
|
||||
connectinfo.nextadr++; //cycle hosts with each ping (if we got multiple).
|
||||
else
|
||||
{
|
||||
Cvar_Set(&cl_disconnectreason, va("No route to \"%s\", giving up\n", cls.servername));
|
||||
Con_TPrintf ("No route to host, giving up\n");
|
||||
connectinfo.trying = false;
|
||||
SCR_EndLoadingPlaque();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1324,8 +1331,8 @@ void CL_BeginServerConnect(const char *host, int port, qboolean noproxy)
|
|||
if (!port)
|
||||
port = cl_defaultport.value;
|
||||
#ifdef HAVE_DTLS
|
||||
if (connectinfo.numadr)
|
||||
NET_DTLS_Disconnect(cls.sockets, &connectinfo.adr[0]);
|
||||
while (connectinfo.numadr)
|
||||
NET_DTLS_Disconnect(cls.sockets, &connectinfo.adr[--connectinfo.numadr]);
|
||||
#endif
|
||||
memset(&connectinfo, 0, sizeof(connectinfo));
|
||||
if (*cl_disconnectreason.string)
|
||||
|
@ -1358,6 +1365,7 @@ void CL_BeginServerReconnect(void)
|
|||
connectinfo.istransfer = false;
|
||||
connectinfo.time = 0;
|
||||
connectinfo.tries = 0; //re-ensure routes.
|
||||
connectinfo.nextadr = 0; //should at least be consistent, other than packetloss. yay. :\
|
||||
|
||||
NET_InitClient(false);
|
||||
}
|
||||
|
|
|
@ -141,6 +141,8 @@ typedef int (VARGS gnutls_certificate_verify_function)(gnutls_session_t session)
|
|||
|
||||
static int (VARGS *qgnutls_bye)(gnutls_session_t session, gnutls_close_request_t how);
|
||||
static void (VARGS *qgnutls_perror)(int error);
|
||||
static gnutls_alert_description_t (VARGS *qgnutls_alert_get)(gnutls_session_t session);
|
||||
static const char *(VARGS *qgnutls_alert_get_name)(gnutls_alert_description_t alert);
|
||||
static int (VARGS *qgnutls_handshake)(gnutls_session_t session);
|
||||
static void (VARGS *qgnutls_transport_set_ptr)(gnutls_session_t session, gnutls_transport_ptr_t ptr);
|
||||
static void (VARGS *qgnutls_transport_set_push_function)(gnutls_session_t session, gnutls_push_func push_func);
|
||||
|
@ -190,6 +192,9 @@ static int (VARGS *qgnutls_dtls_cookie_verify)(gnutls_datum_t * key, void *clien
|
|||
static int (VARGS *qgnutls_dtls_cookie_send)(gnutls_datum_t * key, void *client_data, size_t client_data_size, gnutls_dtls_prestate_st * prestate, gnutls_transport_ptr_t ptr, gnutls_push_func push_func);
|
||||
static void (VARGS *qgnutls_dtls_prestate_set)(gnutls_session_t session, gnutls_dtls_prestate_st * prestate);
|
||||
static void (VARGS *qgnutls_dtls_set_mtu)(gnutls_session_t session, unsigned int mtu);
|
||||
|
||||
//static int (VARGS *qgnutls_psk_allocate_client_credentials)(gnutls_psk_client_credentials_t *sc);
|
||||
//static int (VARGS *qgnutls_psk_set_client_credentials)(gnutls_psk_client_credentials_t res, const char *username, const gnutls_datum_t * key, gnutls_psk_key_flags flags);
|
||||
#endif
|
||||
|
||||
static unsigned int (VARGS *qgnutls_sec_param_to_pk_bits)(gnutls_pk_algorithm_t algo, gnutls_sec_param_t param);
|
||||
|
@ -231,7 +236,8 @@ static qboolean Init_GNUTLS(void)
|
|||
#ifdef GNUTLS_HAVE_VERIFY3
|
||||
#define GNUTLS_VERIFYFUNCS \
|
||||
GNUTLS_FUNC(gnutls_certificate_verify_peers3) \
|
||||
GNUTLS_FUNC(gnutls_certificate_verification_status_print)
|
||||
GNUTLS_FUNC(gnutls_certificate_verification_status_print) \
|
||||
GNUTLS_FUNC(gnutls_certificate_get_peers)
|
||||
#else
|
||||
#define GNUTLS_VERIFYFUNCS \
|
||||
GNUTLS_FUNC(gnutls_certificate_verify_peers2) \
|
||||
|
@ -249,6 +255,8 @@ static qboolean Init_GNUTLS(void)
|
|||
GNUTLS_FUNC(gnutls_dtls_cookie_send) \
|
||||
GNUTLS_FUNC(gnutls_dtls_prestate_set) \
|
||||
GNUTLS_FUNC(gnutls_dtls_set_mtu)
|
||||
// GNUTLS_FUNC(gnutls_psk_allocate_client_credentials)
|
||||
// GNUTLS_FUNC(gnutls_psk_set_client_credentials)
|
||||
#else
|
||||
#define GNUTLS_DTLS_STUFF
|
||||
#endif
|
||||
|
@ -303,7 +311,8 @@ static qboolean Init_GNUTLS(void)
|
|||
GNUTLS_FUNC(gnutls_certificate_set_x509_key_file) \
|
||||
GNUTLS_VERIFYFUNCS \
|
||||
GNUTLS_FUNC(gnutls_certificate_type_get) \
|
||||
GNUTLS_FUNC(gnutls_free) \
|
||||
GNUTLS_FUNCPTR(gnutls_malloc) \
|
||||
GNUTLS_FUNCPTR(gnutls_free) \
|
||||
GNUTLS_FUNC(gnutls_server_name_set) \
|
||||
GNUTLS_DTLS_STUFF \
|
||||
GNUTLS_X509_STUFF
|
||||
|
@ -318,6 +327,8 @@ static qboolean Init_GNUTLS(void)
|
|||
//#undef GNUTLS_FUNC
|
||||
{(void**)&qgnutls_bye, "gnutls_bye"},
|
||||
{(void**)&qgnutls_perror, "gnutls_perror"},
|
||||
{(void**)&qgnutls_alert_get, "gnutls_alert_get"},
|
||||
{(void**)&qgnutls_alert_get_name, "gnutls_alert_get_name"},
|
||||
{(void**)&qgnutls_handshake, "gnutls_handshake"},
|
||||
{(void**)&qgnutls_transport_set_ptr, "gnutls_transport_set_ptr"},
|
||||
{(void**)&qgnutls_transport_set_push_function, "gnutls_transport_set_push_function"},
|
||||
|
@ -367,6 +378,8 @@ static qboolean Init_GNUTLS(void)
|
|||
{(void**)&qgnutls_dtls_cookie_send, "gnutls_dtls_cookie_send"},
|
||||
{(void**)&qgnutls_dtls_prestate_set, "gnutls_dtls_prestate_set"},
|
||||
{(void**)&qgnutls_dtls_set_mtu, "gnutls_dtls_set_mtu"},
|
||||
// {(void**)&qgnutls_psk_allocate_client_credentials, "gnutls_psk_allocate_client_credentials"},
|
||||
// {(void**)&qgnutls_psk_set_client_credentials, "gnutls_psk_set_client_credentials"},
|
||||
#endif
|
||||
|
||||
{(void**)&qgnutls_sec_param_to_pk_bits, "gnutls_sec_param_to_pk_bits"},
|
||||
|
@ -413,8 +426,10 @@ static qboolean Init_GNUTLS(void)
|
|||
return false;
|
||||
#else
|
||||
#define GNUTLS_FUNC(name) q##name = name;
|
||||
#define GNUTLS_FUNCPTR(name) q##name = &name;
|
||||
GNUTLS_FUNCS
|
||||
#undef GNUTLS_FUNC
|
||||
#undef GNUTLS_FUNCPTR
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -673,7 +688,10 @@ static int SSL_DoHandshake(gnutlsfile_t *file)
|
|||
if (developer.ival)
|
||||
{
|
||||
if (err == GNUTLS_E_FATAL_ALERT_RECEIVED)
|
||||
; //peer doesn't like us.
|
||||
{ //peer doesn't like us.
|
||||
gnutls_alert_description_t desc = qgnutls_alert_get(file->session);
|
||||
Con_Printf(CON_ERROR"GNU%sTLS: %s: %s(%i)\n", file->datagram?"D":"", file->certname, qgnutls_alert_get_name(desc), desc);
|
||||
}
|
||||
else
|
||||
//we didn't like the peer.
|
||||
qgnutls_perror (err);
|
||||
|
@ -683,6 +701,7 @@ static int SSL_DoHandshake(gnutlsfile_t *file)
|
|||
|
||||
switch(err)
|
||||
{
|
||||
case GNUTLS_E_INSUFFICIENT_CREDENTIALS:
|
||||
case GNUTLS_E_CERTIFICATE_ERROR: err = VFS_ERROR_UNTRUSTED; break;
|
||||
case GNUTLS_E_PREMATURE_TERMINATION: err = VFS_ERROR_EOF; break;
|
||||
case GNUTLS_E_PUSH_ERROR: err = file->pusherror; break;
|
||||
|
@ -839,6 +858,9 @@ static ssize_t DTLS_Push(gnutls_transport_ptr_t p, const void *data, size_t size
|
|||
|
||||
// Sys_Printf("DTLS_Push: %u, err=%i\n", (unsigned)size, (int)ne);
|
||||
|
||||
if (!file->session)
|
||||
return ne?-1:size;
|
||||
|
||||
switch(ne)
|
||||
{
|
||||
case NETERR_CLOGGED:
|
||||
|
@ -1180,6 +1202,15 @@ qboolean SSL_InitGlobal(qboolean isserver)
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
#if 0
|
||||
static int GetPSKForUser(gnutls_session_t sess, const char *username, gnutls_datum_t * key)
|
||||
{
|
||||
Con_Printf("GetPSKForUser: %s\n", username);
|
||||
key->size = 0;
|
||||
key->data = key->size?gnutls_malloc(key->size):0;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
static qboolean SSL_InitConnection(gnutlsfile_t *newf, qboolean isserver, qboolean datagram)
|
||||
{
|
||||
// Initialize TLS session
|
||||
|
@ -1187,28 +1218,42 @@ static qboolean SSL_InitConnection(gnutlsfile_t *newf, qboolean isserver, qboole
|
|||
|
||||
if (!isserver)
|
||||
qgnutls_server_name_set(newf->session, GNUTLS_NAME_DNS, newf->certname, strlen(newf->certname));
|
||||
/*else
|
||||
{
|
||||
size_t size = sizeof(newf->certname);
|
||||
unsigned int type = GNUTLS_NAME_DNS;
|
||||
int err;
|
||||
err=qgnutls_server_name_get(newf->session, newf->certname, &size, &type, 0);
|
||||
if (err!=GNUTLS_E_SUCCESS)
|
||||
*newf->certname = 0;
|
||||
}*/
|
||||
|
||||
qgnutls_session_set_ptr(newf->session, newf);
|
||||
|
||||
#ifdef USE_ANON
|
||||
//qgnutls_kx_set_priority (newf->session, kx_prio);
|
||||
qgnutls_credentials_set (newf->session, GNUTLS_CRD_ANON, anoncred[isserver]);
|
||||
#else
|
||||
//#if GNUTLS_VERSION_MAJOR >= 3
|
||||
//gnutls_priority_set_direct();
|
||||
//#else
|
||||
//qgnutls_certificate_type_set_priority (newf->session, cert_type_priority);
|
||||
//#endif
|
||||
qgnutls_credentials_set (newf->session, GNUTLS_CRD_CERTIFICATE, xcred[isserver]);
|
||||
#if 0//def HAVE_DTLS
|
||||
if (datagram)
|
||||
{ //use some arbitrary PSK for dtls clients.
|
||||
if (isserver)
|
||||
{
|
||||
gnutls_psk_server_credentials_t pskcred;
|
||||
qgnutls_psk_allocate_server_credentials(&pskcred);
|
||||
qgnutls_psk_set_server_credentials_function(pskcred, GetPSKForUser);
|
||||
qgnutls_psk_set_server_credentials_hint(pskcred, "id-quake-ex-dtls");
|
||||
qgnutls_credentials_set(newf->session, GNUTLS_CRD_PSK, pskcred);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_CLIENT
|
||||
extern cvar_t name;
|
||||
const char *namestr = name.string;
|
||||
#else
|
||||
const char *namestr = "Anonymous";
|
||||
#endif
|
||||
gnutls_psk_client_credentials_t pskcred;
|
||||
const gnutls_datum_t key = { (void *) "deadbeef", 0 };
|
||||
qgnutls_psk_allocate_client_credentials(&pskcred);
|
||||
qgnutls_psk_set_client_credentials(pskcred, namestr, &key, GNUTLS_PSK_KEY_HEX);
|
||||
|
||||
qgnutls_credentials_set(newf->session, GNUTLS_CRD_PSK, pskcred);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
qgnutls_credentials_set (newf->session, GNUTLS_CRD_CERTIFICATE, xcred[isserver]);
|
||||
#endif
|
||||
// Use default priorities
|
||||
qgnutls_set_default_priority (newf->session);
|
||||
|
@ -1223,9 +1268,6 @@ static qboolean SSL_InitConnection(gnutlsfile_t *newf, qboolean isserver, qboole
|
|||
qgnutls_transport_set_pull_timeout_function(newf->session, DTLS_Pull_Timeout);
|
||||
#endif
|
||||
|
||||
// if (isserver) //don't bother to auth any client certs
|
||||
// qgnutls_certificate_server_set_request(newf->session, GNUTLS_CERT_IGNORE);
|
||||
|
||||
newf->handshaking = true;
|
||||
|
||||
return true;
|
||||
|
@ -1406,8 +1448,6 @@ static neterr_t GNUDTLS_Transmit(void *ctx, const qbyte *data, size_t datasize)
|
|||
{
|
||||
int ret;
|
||||
gnutlsfile_t *f = (gnutlsfile_t *)ctx;
|
||||
// Sys_Printf("DTLS_Transmit: %u\n", datasize);
|
||||
// Sys_Printf("%su\n", data);
|
||||
|
||||
if (f->challenging)
|
||||
return NETERR_CLOGGED;
|
||||
|
@ -1425,7 +1465,6 @@ static neterr_t GNUDTLS_Transmit(void *ctx, const qbyte *data, size_t datasize)
|
|||
{
|
||||
if (ret == GNUTLS_E_LARGE_PACKET)
|
||||
return NETERR_MTU;
|
||||
//Sys_Error("qgnutls_record_send returned %i\n", ret);
|
||||
|
||||
if (qgnutls_error_is_fatal(ret))
|
||||
return NETERR_DISCONNECTED;
|
||||
|
@ -1436,14 +1475,12 @@ static neterr_t GNUDTLS_Transmit(void *ctx, const qbyte *data, size_t datasize)
|
|||
|
||||
static neterr_t GNUDTLS_Received(void *ctx, sizebuf_t *message)
|
||||
{
|
||||
int cli_addr = 0xdeadbeef;
|
||||
int ret;
|
||||
gnutlsfile_t *f = (gnutlsfile_t *)ctx;
|
||||
|
||||
//Sys_Printf("DTLS_Received: %u\n", datasize);
|
||||
|
||||
if (f->challenging)
|
||||
{
|
||||
int cli_addr = 0xdeadbeef; //FIXME: replace with client's IP:port.
|
||||
memset(&f->prestate, 0, sizeof(f->prestate));
|
||||
ret = qgnutls_dtls_cookie_verify(&cookie_key,
|
||||
&cli_addr, sizeof(cli_addr),
|
||||
|
@ -1452,21 +1489,17 @@ static neterr_t GNUDTLS_Received(void *ctx, sizebuf_t *message)
|
|||
|
||||
if (ret < 0)
|
||||
{
|
||||
//Sys_Printf("Sending cookie\n");
|
||||
qgnutls_dtls_cookie_send(&cookie_key,
|
||||
&cli_addr, sizeof(cli_addr),
|
||||
&f->prestate,
|
||||
(gnutls_transport_ptr_t)f, DTLS_Push);
|
||||
return NETERR_CLOGGED;
|
||||
}
|
||||
//Sys_Printf("Got correct cookie\n");
|
||||
f->challenging = false;
|
||||
|
||||
qgnutls_dtls_prestate_set(f->session, &f->prestate);
|
||||
qgnutls_dtls_set_mtu(f->session, 1440);
|
||||
|
||||
// qgnutls_transport_set_push_function(f->session, DTLS_Push);
|
||||
// qgnutls_transport_set_pull_function(f->session, DTLS_Pull);
|
||||
f->handshaking = true;
|
||||
}
|
||||
|
||||
|
@ -1508,6 +1541,59 @@ static neterr_t GNUDTLS_Received(void *ctx, sizebuf_t *message)
|
|||
return NETERR_SENT;
|
||||
}
|
||||
|
||||
static qboolean GNUDTLS_CheckConnection(void *cbctx, void *peeraddr, size_t peeraddrsize, void *indata, size_t insize, neterr_t(*push)(void *cbctx, const qbyte *data, size_t datasize), void (*EstablishTrueContext)(void **cbctx, void *state))
|
||||
{ //called when we got a possibly-dtls packet out of the blue.
|
||||
gnutlsfile_t *f;
|
||||
int ret;
|
||||
gnutls_dtls_prestate_st prestate;
|
||||
|
||||
memset(&prestate, 0, sizeof(prestate));
|
||||
ret = qgnutls_dtls_cookie_verify(&cookie_key,
|
||||
peeraddr, peeraddrsize,
|
||||
indata, insize,
|
||||
&prestate);
|
||||
|
||||
if (ret == GNUTLS_E_BAD_COOKIE)
|
||||
{ //some sort of handshake with a bad/unknown cookie. send them a real one.
|
||||
gnutlsfile_t f;
|
||||
f.cbctx = cbctx;
|
||||
f.cbpush = push;
|
||||
f.session = NULL;
|
||||
|
||||
qgnutls_dtls_cookie_send(&cookie_key,
|
||||
peeraddr, peeraddrsize,
|
||||
&prestate,
|
||||
(gnutls_transport_ptr_t)&f, DTLS_Push);
|
||||
return true;
|
||||
}
|
||||
else if (ret < 0)
|
||||
return false; //dunno... might still be dtls but doesn't seem to be needed... oh well...
|
||||
|
||||
//allocate our context
|
||||
f = GNUDTLS_CreateContext(NULL, cbctx, push, true);
|
||||
if (!f)
|
||||
{
|
||||
Con_Printf("GNUDTLS_CreateContext: failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//tell caller that this is an actual valid connection
|
||||
EstablishTrueContext(&f->cbctx, f);
|
||||
if (!f->cbctx)
|
||||
return true;
|
||||
|
||||
//we're done with the challenge stuff
|
||||
f->challenging = false;
|
||||
|
||||
//and this is the result...
|
||||
qgnutls_dtls_prestate_set(f->session, &prestate);
|
||||
qgnutls_dtls_set_mtu(f->session, 1440);
|
||||
|
||||
//still need to do the whole certificate thing though.
|
||||
f->handshaking = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static neterr_t GNUDTLS_Timeouts(void *ctx)
|
||||
{
|
||||
gnutlsfile_t *f = (gnutlsfile_t *)ctx;
|
||||
|
@ -1532,6 +1618,7 @@ static neterr_t GNUDTLS_Timeouts(void *ctx)
|
|||
static const dtlsfuncs_t dtlsfuncs_gnutls =
|
||||
{
|
||||
GNUDTLS_CreateContext,
|
||||
GNUDTLS_CheckConnection,
|
||||
GNUDTLS_DestroyContext,
|
||||
GNUDTLS_Transmit,
|
||||
GNUDTLS_Received,
|
||||
|
|
|
@ -1231,6 +1231,7 @@ static neterr_t SSPI_DTLS_Timeouts(void *ctx)
|
|||
static const dtlsfuncs_t dtlsfuncs_schannel =
|
||||
{
|
||||
SSPI_DTLS_CreateContext,
|
||||
NULL,
|
||||
SSPI_DTLS_DestroyContext,
|
||||
SSPI_DTLS_Transmit,
|
||||
SSPI_DTLS_Received,
|
||||
|
|
|
@ -3025,10 +3025,10 @@ qboolean NET_DTLS_Create(ftenet_connections_t *col, netadr_t *to)
|
|||
peer->timeout = realtime+timeout.value;
|
||||
if (peer->dtlsstate)
|
||||
{
|
||||
if (peer->next)
|
||||
peer->next->link = &peer->next;
|
||||
peer->link = &col->dtls;
|
||||
peer->next = col->dtls;
|
||||
if (peer->next)
|
||||
peer->next->link = &peer->next;
|
||||
col->dtls = peer;
|
||||
}
|
||||
else
|
||||
|
@ -3039,10 +3039,54 @@ qboolean NET_DTLS_Create(ftenet_connections_t *col, netadr_t *to)
|
|||
}
|
||||
return peer!=NULL;
|
||||
}
|
||||
#ifdef HAVE_SERVER
|
||||
static void FTENET_DTLS_Established(void **ctx, void *state)
|
||||
{
|
||||
ftenet_connections_t *col;
|
||||
struct dtlspeer_s *peer = Z_Malloc(sizeof(*peer));
|
||||
memcpy(peer, *ctx, sizeof(*peer));
|
||||
*ctx = peer;
|
||||
col = peer->col;
|
||||
|
||||
peer->dtlsstate = state;
|
||||
|
||||
peer->timeout = realtime+timeout.value;
|
||||
peer->link = &col->dtls;
|
||||
peer->next = col->dtls;
|
||||
if (peer->next)
|
||||
peer->next->link = &peer->next;
|
||||
col->dtls = peer;
|
||||
}
|
||||
qboolean NET_DTLS_CheckInbound(ftenet_connections_t *col)
|
||||
{
|
||||
extern cvar_t timeout, net_enable_dtls;
|
||||
struct dtlspeer_s *peer;
|
||||
netadr_t *from = &net_from;
|
||||
if (from->prot != NP_DGRAM || !net_enable_dtls.ival || !col->dtlsfuncs)
|
||||
return false;
|
||||
for (peer = col->dtls; peer; peer = peer->next)
|
||||
{
|
||||
if (NET_CompareAdr(&peer->addr, from))
|
||||
break;
|
||||
}
|
||||
if (!peer)
|
||||
{
|
||||
if (col->dtlsfuncs->CheckConnection)
|
||||
{
|
||||
struct dtlspeer_s peer;
|
||||
//fill it with preliminary info
|
||||
peer.addr = *from;
|
||||
peer.col = col;
|
||||
peer.funcs = col->dtlsfuncs;
|
||||
return col->dtlsfuncs->CheckConnection(&peer, from, sizeof(*from), net_message.data, net_message.cursize, FTENET_DTLS_DoSendPacket, FTENET_DTLS_Established);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
static void NET_DTLS_DisconnectPeer(ftenet_connections_t *col, struct dtlspeer_s *peer)
|
||||
{
|
||||
// Sys_Printf("Destroy %p\n", peer->dtlsstate);
|
||||
|
||||
if (peer->next)
|
||||
peer->next->link = peer->link;
|
||||
*peer->link = peer->next;
|
||||
|
@ -3095,8 +3139,8 @@ qboolean NET_DTLS_Decode(ftenet_connections_t *col)
|
|||
switch(peer->funcs->Received(peer->dtlsstate, &net_message))
|
||||
{
|
||||
case NETERR_DISCONNECTED:
|
||||
Sys_Printf("disconnected %p\n", peer->dtlsstate);
|
||||
NET_DTLS_DisconnectPeer(col, peer);
|
||||
net_message.cursize = 0;
|
||||
break;
|
||||
case NETERR_NOROUTE:
|
||||
return false; //not a valid dtls packet.
|
||||
|
@ -7964,6 +8008,14 @@ qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char
|
|||
return false;
|
||||
break;
|
||||
case NP_DTLS:
|
||||
adr->prot = NP_DGRAM;
|
||||
NET_EnsureRoute(collection, routename, host, adr);
|
||||
if (NET_DTLS_Create(collection, adr))
|
||||
{
|
||||
adr->prot = NP_DTLS;
|
||||
return true;
|
||||
}
|
||||
adr->prot = NP_DTLS;
|
||||
break;
|
||||
case NP_WS:
|
||||
case NP_WSS:
|
||||
|
@ -8038,7 +8090,7 @@ static enum addressscope_e NET_ClassifyAddressipv4(int ip, const char **outdesc)
|
|||
else if ((ip&BigLong(0xffc00000)) == BigLong(0x64400000)) //100.64.x.x/10
|
||||
scope = ASCOPE_LAN, desc = localtext("CGNAT");
|
||||
else if (ip == BigLong(0x00000000)) //0.0.0.0/32
|
||||
scope = ASCOPE_LAN, desc = "any";
|
||||
scope = ASCOPE_HOST, desc = "any";
|
||||
|
||||
*outdesc = desc;
|
||||
return scope;
|
||||
|
@ -8066,7 +8118,7 @@ enum addressscope_e NET_ClassifyAddress(netadr_t *adr, const char **outdesc)
|
|||
else if (memcmp(adr->address.ip6, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", 16) == 0) //::1
|
||||
scope = ASCOPE_HOST, desc = "localhost";
|
||||
else if (memcmp(adr->address.ip6, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0) //::
|
||||
scope = ASCOPE_NET, desc = "any";
|
||||
scope = ASCOPE_HOST, desc = "any";
|
||||
else if (memcmp(adr->address.ip6, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12) == 0) //::ffff:x.y.z.w
|
||||
{
|
||||
scope = NET_ClassifyAddressipv4(*(int*)(adr->address.ip6+12), &desc);
|
||||
|
@ -8690,6 +8742,11 @@ qboolean NET_WasSpecialPacket(ftenet_connections_t *collection)
|
|||
return true;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DTLS) && defined(HAVE_SERVER)
|
||||
if (collection->islisten && NET_DTLS_CheckInbound(collection))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -349,6 +349,7 @@ struct dtlsfuncs_s;
|
|||
typedef struct dtlsfuncs_s
|
||||
{
|
||||
void *(*CreateContext)(const char *remotehost, void *cbctx, neterr_t(*push)(void *cbctx, const qbyte *data, size_t datasize), qboolean isserver); //if remotehost is null then their certificate will not be validated.
|
||||
qboolean (*CheckConnection)(void *cbctx, void *peeraddr, size_t peeraddrsize, void *indata, size_t insize, neterr_t(*push)(void *cbctx, const qbyte *data, size_t datasize), void (*EstablishTrueContext)(void **cbctx, void *state));
|
||||
void (*DestroyContext)(void *ctx);
|
||||
neterr_t (*Transmit)(void *ctx, const qbyte *data, size_t datasize);
|
||||
neterr_t (*Received)(void *ctx, sizebuf_t *message); //operates in-place...
|
||||
|
|
|
@ -125,7 +125,7 @@ static int QDECL OSSL_FRead (struct vfsfile_s *file, void *buffer, int bytestore
|
|||
case BIO_RR_ACCEPT:
|
||||
case BIO_RR_CONNECT:
|
||||
return -1; //should never happen
|
||||
};
|
||||
}
|
||||
}
|
||||
if (BIO_should_retry(o->bio))
|
||||
return 0;
|
||||
|
@ -665,11 +665,16 @@ static neterr_t OSSL_Received(void *ctx, sizebuf_t *message)
|
|||
ossldtls_t *o = (ossldtls_t*)ctx;
|
||||
int r;
|
||||
|
||||
o->pending = message->data;
|
||||
o->pendingsize = message->cursize;
|
||||
r = BIO_read(o->bio, message->data, message->maxsize);
|
||||
o->pending = NULL;
|
||||
o->pendingsize = 0;
|
||||
if (!message)
|
||||
r = 0;
|
||||
else
|
||||
{
|
||||
o->pending = message->data;
|
||||
o->pendingsize = message->cursize;
|
||||
r = BIO_read(o->bio, message->data, message->maxsize);
|
||||
o->pending = NULL;
|
||||
o->pendingsize = 0;
|
||||
}
|
||||
|
||||
if (r > 0)
|
||||
{
|
||||
|
@ -704,6 +709,7 @@ static neterr_t OSSL_Timeouts(void *ctx)
|
|||
static dtlsfuncs_t ossl_dtlsfuncs =
|
||||
{
|
||||
OSSL_CreateContext,
|
||||
NULL,
|
||||
OSSL_DestroyContext,
|
||||
OSSL_Transmit,
|
||||
OSSL_Received,
|
||||
|
|
Loading…
Reference in a new issue