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:
Spoike 2022-01-08 10:01:05 +00:00
parent 310bf64d83
commit bf44769b4d
7 changed files with 221 additions and 54 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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,

View File

@ -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,

View File

@ -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;
}

View File

@ -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...

View File

@ -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,