Improve webrtc compat.

This commit is contained in:
Shpoike 2024-05-30 14:00:38 +01:00
parent 5bc9626dd6
commit d99bc0b22a
8 changed files with 154 additions and 66 deletions

View file

@ -650,8 +650,10 @@ void SV_Master_Heartbeat (void)
{ {
const char *s = net_ice_broker.string; const char *s = net_ice_broker.string;
struct thr_res *work = Z_Malloc(sizeof(*work) + strlen(s)); struct thr_res *work = Z_Malloc(sizeof(*work) + strlen(s));
if (!strncmp(s, "tls://", 6) || !strncmp(s, "tcp://", 6)) if (!strncmp(s, "tls://", 6) || !strncmp(s, "tcp://", 6) || !strncmp(s, "wss://", 6))
s+=6; //ignore weird prefixes here s+=6; //ignore weird prefixes here
else if (!strncmp(s, "ws://", 5))
s+=5; //ignore dumb prefixes here
strcpy(work->str, s); strcpy(work->str, s);
COM_AddWork(WG_MAIN, SV_Master_Worker_Resolve, NULL, work, ~(size_t)0, 0); COM_AddWork(WG_MAIN, SV_Master_Worker_Resolve, NULL, work, ~(size_t)0, 0);
} }

View file

@ -1020,9 +1020,22 @@ static qboolean ICE_SendSpam(struct icestate_s *con)
break; break;
case NETERR_CLOGGED: //oh well... we retry anyway. case NETERR_CLOGGED: //oh well... we retry anyway.
break; break;
case NETERR_NOROUTE:
if (net_ice_debug.ival >= 2)
Con_Printf(S_COLOR_GRAY"ICE NETERR_NOROUTE to %s:%i(%s)\n", bestpeer->info.addr, bestpeer->info.port, candtype);
break;
case NETERR_DISCONNECTED:
if (net_ice_debug.ival >= 2)
Con_Printf(S_COLOR_GRAY"ICE NETERR_DISCONNECTED to %s:%i(%s)\n", bestpeer->info.addr, bestpeer->info.port, candtype);
break;
case NETERR_MTU:
if (net_ice_debug.ival >= 2)
Con_Printf(S_COLOR_GRAY"ICE NETERR_MTU to %s:%i(%s) (%i bytes)\n", bestpeer->info.addr, bestpeer->info.port, candtype, buf.cursize);
break;
default: default:
if (net_ice_debug.ival >= 2) if (net_ice_debug.ival >= 2)
Con_Printf("ICE send error to %s:%i(%s)\n", bestpeer->info.addr, bestpeer->info.port, candtype); Con_Printf(S_COLOR_GRAY"ICE send error(%i) to %s:%i(%s)\n", err, bestpeer->info.addr, bestpeer->info.port, candtype);
break; break;
} }
return true; return true;
@ -1548,6 +1561,8 @@ static void MDNS_ProcessPacket(qbyte *inmsg, size_t inmsgsize, netadr_t *source)
((struct sockaddr_in*)&dest)->sin_addr.s_addr = inet_addr("224.0.0.251"); ((struct sockaddr_in*)&dest)->sin_addr.s_addr = inet_addr("224.0.0.251");
} }
sendto(mdns_socket, resp, o-resp, 0, (struct sockaddr*)&dest, sz); sendto(mdns_socket, resp, o-resp, 0, (struct sockaddr*)&dest, sz);
if (net_ice_debug.ival)
Con_Printf(S_COLOR_GRAY"%s: Answering mdns (%s)\n", NET_AdrToString(resp, sizeof(resp), source), a.name);
} }
} }
} }
@ -2414,9 +2429,12 @@ static qboolean ICE_SetFailed(struct icestate_s *con, const char *reasonfmt, ...
char string[256]; char string[256];
va_start (argptr, reasonfmt); va_start (argptr, reasonfmt);
Q_vsnprintf (string,sizeof(string)-1, reasonfmt,argptr); Q_vsnprintfz (string,sizeof(string)-1, reasonfmt,argptr);
va_end (argptr); va_end (argptr);
if (con->state == ICE_FAILED)
Con_Printf(S_COLOR_GRAY"[%s]: %s\n", con->friendlyname, string); //we were probably already expecting this. don't show it as a warning.
else
Con_Printf(CON_WARNING"[%s]: %s\n", con->friendlyname, string); Con_Printf(CON_WARNING"[%s]: %s\n", con->friendlyname, string);
return ICE_Set(con, "state", STRINGIFY(ICE_FAILED)); //does the disconnection stuff. return ICE_Set(con, "state", STRINGIFY(ICE_FAILED)); //does the disconnection stuff.
} }
@ -2443,6 +2461,8 @@ static char *ICE_CandidateToSDP(struct icecandidate_s *can, char *value, size_t
{ {
if (*can->info.reladdr) if (*can->info.reladdr)
Q_strncatz(value, va(" raddr %s", can->info.reladdr), valuelen); Q_strncatz(value, va(" raddr %s", can->info.reladdr), valuelen);
else
Q_strncatz(value, " raddr 0.0.0.0", valuelen);
Q_strncatz(value, va(" rport %i", can->info.relport), valuelen); Q_strncatz(value, va(" rport %i", can->info.relport), valuelen);
} }
} }
@ -2615,6 +2635,8 @@ static qboolean QDECL ICE_Get(struct icestate_s *con, const char *prop, char *va
for (can = con->lc; can; can = can->next) for (can = con->lc; can; can = can->next)
{ {
char canline[256]; char canline[256];
if (ICE_LCandidateIsPrivate(can))
continue; //ignore it.
can->dirty = false; //doesn't matter now. can->dirty = false; //doesn't matter now.
ICE_CandidateToSDP(can, canline, sizeof(canline)); ICE_CandidateToSDP(can, canline, sizeof(canline));
Q_strncatz(value, canline, valuelen); Q_strncatz(value, canline, valuelen);
@ -4210,7 +4232,9 @@ qboolean ICE_WasStun(ftenet_connections_t *col)
for (i = 0; i < con->servers; i++) for (i = 0; i < con->servers; i++)
{ {
s = &con->server[i]; s = &con->server[i];
if (NET_CompareAdr(&net_from, &s->addr)) if (NET_CompareAdr(&net_from, &s->addr) && s->stunrnd[0] == stun->transactid[0] &&
s->stunrnd[1] == stun->transactid[1] &&
s->stunrnd[2] == stun->transactid[2])
{ //check to see if this is a new server-reflexive address, which happens when the peer is behind a nat. { //check to see if this is a new server-reflexive address, which happens when the peer is behind a nat.
for (rc = con->lc; rc; rc = rc->next) for (rc = con->lc; rc; rc = rc->next)
{ {
@ -4610,6 +4634,8 @@ qboolean ICE_WasStun(ftenet_connections_t *col)
len = sizeof(errmsg)-1; len = sizeof(errmsg)-1;
memcpy(errmsg, &((qbyte*)attr)[8], len); memcpy(errmsg, &((qbyte*)attr)[8], len);
errmsg[len] = 0; errmsg[len] = 0;
if (!len)
Q_strncpyz(errmsg, "<no description>", len);
if (err==0) if (err==0)
err = (((qbyte*)attr)[6]*100) + (((qbyte*)attr)[7]%100); err = (((qbyte*)attr)[6]*100) + (((qbyte*)attr)[7]%100);
} }
@ -5051,7 +5077,7 @@ qboolean ICE_WasStun(ftenet_connections_t *col)
case NETERR_NOROUTE: case NETERR_NOROUTE:
return false; //not a dtls packet at all. don't de-ICE it when we're meant to be using ICE. return false; //not a dtls packet at all. don't de-ICE it when we're meant to be using ICE.
case NETERR_DISCONNECTED: //dtls failure. ICE failed. case NETERR_DISCONNECTED: //dtls failure. ICE failed.
ICE_SetFailed(con, "DTLS Failure"); ICE_SetFailed(con, "DTLS Terminated");
return true; return true;
default: //some kind of failure decoding the dtls packet. drop it. default: //some kind of failure decoding the dtls packet. drop it.
return true; return true;
@ -5271,13 +5297,45 @@ static void FTENET_ICE_Heartbeat(ftenet_ice_connection_t *b)
} }
*info = 0; *info = 0;
Info_SetValueForKey(info, "protocol", SV_GetProtocolVersionString(), sizeof(info));
Info_SetValueForKey(info, "maxclients", maxclients.string, sizeof(info)); //first line contains the serverinfo, or some form of it
Info_SetValueForKey(info, "clients", va("%i", numclients), sizeof(info)); {
Info_SetValueForKey(info, "hostname", hostname.string, sizeof(info)); char *resp = info;
Info_SetValueForKey(info, "modname", FS_GetGamedir(true), sizeof(info)); const char *ignorekeys[] = {
Info_SetValueForKey(info, "mapname", InfoBuf_ValueForKey(&svs.info, "map"), sizeof(info)); "maxclients", "map", "*gamedir", "*z_ext", //this is a DP protocol query, so some QW fields are not needed
Info_SetValueForKey(info, "needpass", InfoBuf_ValueForKey(&svs.info, "needpass"), sizeof(info)); "gamename", "modname", "protocol", "clients", "sv_maxclients", "mapname", "qcstatus", "challenge", NULL}; //and we need to add some
const char *prioritykeys[] = {"hostname", NULL}; //make sure we include these before we start overflowing
char protocolname[64];
const char *gamestatus;
COM_ParseOut(com_protocolname.string, protocolname, sizeof(protocolname)); //we can only report one, so report the first.
if (svprogfuncs)
{
eval_t *v = PR_FindGlobal(svprogfuncs, "worldstatus", PR_ANY, NULL);
if (v)
gamestatus = PR_GetString(svprogfuncs, v->string);
else
gamestatus = "";
}
else
gamestatus = "";
Info_SetValueForKey(resp, "gamename", protocolname, sizeof(info) - (resp-info));//distinguishes it from other types of games
Info_SetValueForKey(resp, "protocol", SV_GetProtocolVersionString(), sizeof(info) - (resp-info));
Info_SetValueForKey(resp, "modname", FS_GetGamedir(true), sizeof(info) - (resp-info));
Info_SetValueForKey(resp, "clients", va("%d", numclients), sizeof(info) - (resp-info));
Info_SetValueForKey(resp, "sv_maxclients", maxclients.string, sizeof(info) - (resp-info));
Info_SetValueForKey(resp, "mapname", InfoBuf_ValueForKey(&svs.info, "map"), sizeof(info) - (resp-info));
resp += strlen(resp);
//now include the full/regular serverinfo
resp += InfoBuf_ToString(&svs.info, resp, sizeof(info) - (resp-info), prioritykeys, ignorekeys, NULL, NULL, NULL);
*resp = 0;
//and any possibly-long qc status string
if (*gamestatus)
Info_SetValueForKey(resp, "qcstatus", gamestatus, sizeof(info) - (resp-info));
resp += strlen(resp);
*resp++ = 0;
}
FTENET_ICE_SplurgeCmd(b, ICEMSG_SERVERINFO, -1, info); FTENET_ICE_SplurgeCmd(b, ICEMSG_SERVERINFO, -1, info);
} }
@ -5354,9 +5412,11 @@ static void FTENET_ICE_Refresh(ftenet_ice_connection_t *b, int cl, struct icesta
} }
static qboolean FTENET_ICE_GetPacket(ftenet_generic_connection_t *gcon) static qboolean FTENET_ICE_GetPacket(ftenet_generic_connection_t *gcon)
{ {
json_t *json;
ftenet_ice_connection_t *b = (void*)gcon; ftenet_ice_connection_t *b = (void*)gcon;
int ctrl, len, cmd, cl, ofs; int ctrl, len, cmd, cl, ofs;
char *data, n; const char *data;
char n;
if (!b->broker) if (!b->broker)
{ {
@ -5568,18 +5628,10 @@ handleerror:
} }
break; break;
case ICEMSG_OFFER: //we received an offer from a client case ICEMSG_OFFER: //we received an offer from a client
if (!strncmp(data, "{\"type\":\"offer\",\"sdp\":\"", 23)) json = JSON_Parse(data);
{ if (json)
data += 22; //should probably also verify the type.
COM_ParseCString(data, com_token, sizeof(com_token), NULL); data = JSON_GetString(json, "sdp", com_token,sizeof(com_token), NULL);
data = com_token;
}
else if (!strncmp(data, "{\"type\":\"answer\",\"sdp\":\"", 24))
{
data += 23;
COM_ParseCString(data, com_token, sizeof(com_token), NULL);
data = com_token;
}
if (b->generic.islisten) if (b->generic.islisten)
{ {
if (cl >= 0 && cl < b->numclients && b->clients[cl].ice) if (cl >= 0 && cl < b->numclients && b->clients[cl].ice)
@ -5590,10 +5642,8 @@ handleerror:
iceapi.Set(b->clients[cl].ice, "state", STRINGIFY(ICE_CONNECTING)); iceapi.Set(b->clients[cl].ice, "state", STRINGIFY(ICE_CONNECTING));
FTENET_ICE_SendOffer(b, cl, b->clients[cl].ice, "sdpanswer"); FTENET_ICE_SendOffer(b, cl, b->clients[cl].ice, "sdpanswer");
break;
} }
else if (net_ice_debug.ival)
if (net_ice_debug.ival)
Con_Printf(S_COLOR_GRAY"[%s]: Got bad offer/answer:\n%s\n", b->clients[cl].ice?b->clients[cl].ice->friendlyname:"?", data); Con_Printf(S_COLOR_GRAY"[%s]: Got bad offer/answer:\n%s\n", b->clients[cl].ice?b->clients[cl].ice->friendlyname:"?", data);
} }
else else
@ -5604,21 +5654,21 @@ handleerror:
Con_Printf(S_COLOR_GRAY"[%s]: Got answer:\n%s\n", b->ice?b->ice->friendlyname:"?", data); Con_Printf(S_COLOR_GRAY"[%s]: Got answer:\n%s\n", b->ice?b->ice->friendlyname:"?", data);
iceapi.Set(b->ice, "sdpanswer", data); iceapi.Set(b->ice, "sdpanswer", data);
iceapi.Set(b->ice, "state", STRINGIFY(ICE_CONNECTING)); iceapi.Set(b->ice, "state", STRINGIFY(ICE_CONNECTING));
break;
} }
else if (net_ice_debug.ival)
if (net_ice_debug.ival)
Con_Printf(S_COLOR_GRAY"[%s]: Got bad offer/answer:\n%s\n", b->ice?b->ice->friendlyname:"?", data); Con_Printf(S_COLOR_GRAY"[%s]: Got bad offer/answer:\n%s\n", b->ice?b->ice->friendlyname:"?", data);
} }
JSON_Destroy(json);
break; break;
case ICEMSG_CANDIDATE: case ICEMSG_CANDIDATE:
if (!strncmp(data, "{\"candidate\":\"", 14)) json = JSON_Parse(data);
if (json)
{ {
data += 13; data = com_token;
com_token[0]='a'; com_token[0]='a';
com_token[1]='='; com_token[1]='=';
COM_ParseCString(data, com_token+2, sizeof(com_token)-2, NULL); com_token[2]=0;
data = com_token; JSON_GetString(json, "candidate", com_token+2,sizeof(com_token)-2, NULL);
} }
// Con_Printf("Candidate update: %s\n", data); // Con_Printf("Candidate update: %s\n", data);
if (b->generic.islisten) if (b->generic.islisten)
@ -5639,6 +5689,7 @@ handleerror:
iceapi.Set(b->ice, "sdp", data); iceapi.Set(b->ice, "sdp", data);
} }
} }
JSON_Destroy(json);
break; break;
default: default:
if (net_ice_debug.ival) if (net_ice_debug.ival)
@ -5796,12 +5847,13 @@ void SVC_ICE_Offer(void)
extern cvar_t net_ice_servers; extern cvar_t net_ice_servers;
struct icestate_s *ice; struct icestate_s *ice;
static float throttletimer; static float throttletimer;
char *sdp, *s; const char *sdp, *s;
char buf[1400]; char buf[1400];
int sz; int sz;
char *clientaddr = Cmd_Argv(1); //so we can do ip bans on the client's srflx address char *clientaddr = Cmd_Argv(1); //so we can do ip bans on the client's srflx address
char *brokerid = Cmd_Argv(2); //specific id to identify the pairing on the broker. char *brokerid = Cmd_Argv(2); //specific id to identify the pairing on the broker.
netadr_t adr; netadr_t adr;
json_t *json;
if (!sv.state) if (!sv.state)
return; //err..? return; //err..?
if (net_from.prot != NP_DTLS && net_from.prot != NP_WSS && net_from.prot != NP_TLS) if (net_from.prot != NP_DTLS && net_from.prot != NP_WSS && net_from.prot != NP_TLS)
@ -5833,12 +5885,9 @@ void SVC_ICE_Offer(void)
iceapi.Set(ice, "server", com_token); iceapi.Set(ice, "server", com_token);
sdp = MSG_ReadString(); sdp = MSG_ReadString();
if (!strncmp(sdp, "{\"type\":\"offer\",\"sdp\":\"", 23)) json = JSON_Parse(sdp); //browsers are poo
{ //browsers are poo if (json)
sdp += 22; sdp = JSON_GetString(json, "sdp", buf,sizeof(buf), "");
COM_ParseCString(sdp, buf, sizeof(buf), NULL);
sdp = buf;
}
if (iceapi.Set(ice, "sdpoffer", sdp)) if (iceapi.Set(ice, "sdpoffer", sdp))
{ {
@ -5853,14 +5902,16 @@ void SVC_ICE_Offer(void)
NET_SendPacket(svs.sockets, sz, buf, &net_from); NET_SendPacket(svs.sockets, sz, buf, &net_from);
} }
} }
JSON_Destroy(json);
//and because we won't have access to its broker, disconnect it from any persistent state to let it time out. //and because we won't have access to its broker, disconnect it from any persistent state to let it time out.
iceapi.Close(ice, false); iceapi.Close(ice, false);
} }
void SVC_ICE_Candidate(void) void SVC_ICE_Candidate(void)
{ { //handles an 'ice_ccand' udp message from a broker
struct icestate_s *ice; struct icestate_s *ice;
char *sdp; json_t *json;
const char *sdp;
char buf[1400]; char buf[1400];
char *brokerid = Cmd_Argv(1); //specific id to identify the pairing on the broker. char *brokerid = Cmd_Argv(1); //specific id to identify the pairing on the broker.
unsigned int seq = atoi(Cmd_Argv(2)); //their seq, to ack and prevent dupes unsigned int seq = atoi(Cmd_Argv(2)); //their seq, to ack and prevent dupes
@ -5882,15 +5933,17 @@ void SVC_ICE_Candidate(void)
if (seq++ < ice->u.inseq) if (seq++ < ice->u.inseq)
continue; continue;
ice->u.inseq++; ice->u.inseq++;
if (!strncmp(sdp, "{\"candidate\":\"", 14)) json = JSON_Parse(sdp);
{ //dewebify if (json)
sdp += 13; {
sdp = buf;
buf[0]='a'; buf[0]='a';
buf[1]='='; buf[1]='=';
COM_ParseCString(sdp, buf+2, sizeof(buf)-2, NULL); buf[2]=0;
sdp = buf; JSON_GetString(json, "candidate", buf+2,sizeof(buf)-2, NULL);
} }
iceapi.Set(ice, "sdp", sdp); iceapi.Set(ice, "sdp", sdp);
JSON_Destroy(json);
} }
while (ack > ice->u.outseq) while (ack > ice->u.outseq)
@ -5911,7 +5964,10 @@ void SVC_ICE_Candidate(void)
//check for new candidates to include //check for new candidates to include
while (iceapi.GetLCandidateSDP(ice, buf, sizeof(buf))) while (iceapi.GetLCandidateSDP(ice, buf, sizeof(buf)))
{
Z_StrCat(&ice->u.text, buf); Z_StrCat(&ice->u.text, buf);
Z_StrCat(&ice->u.text, "\n");
}
Q_snprintfz(buf, sizeof(buf), "\xff\xff\xff\xff""ice_scand %s %u %u\n%s", brokerid, ice->u.outseq, ice->u.inseq, ice->u.text?ice->u.text:""); Q_snprintfz(buf, sizeof(buf), "\xff\xff\xff\xff""ice_scand %s %u %u\n%s", brokerid, ice->u.outseq, ice->u.inseq, ice->u.text?ice->u.text:"");
NET_SendPacket(svs.sockets, strlen(buf), buf, &net_from); NET_SendPacket(svs.sockets, strlen(buf), buf, &net_from);

View file

@ -134,7 +134,7 @@
GNUTLS_FUNC(gnutls_bye,int,(gnutls_session_t session, gnutls_close_request_t how)) \ GNUTLS_FUNC(gnutls_bye,int,(gnutls_session_t session, gnutls_close_request_t how)) \
GNUTLS_FUNC(gnutls_alert_get,gnutls_alert_description_t,(gnutls_session_t session)) \ GNUTLS_FUNC(gnutls_alert_get,gnutls_alert_description_t,(gnutls_session_t session)) \
GNUTLS_FUNC(gnutls_alert_get_name,const char *,(gnutls_alert_description_t alert)) \ GNUTLS_FUNC(gnutls_alert_get_name,const char *,(gnutls_alert_description_t alert)) \
GNUTLS_FUNC(gnutls_perror,void,(int error)) \ GNUTLS_FUNC(gnutls_strerror,const char *,(int error)) \
GNUTLS_FUNC(gnutls_handshake,int,(gnutls_session_t session)) \ GNUTLS_FUNC(gnutls_handshake,int,(gnutls_session_t session)) \
GNUTLS_FUNC(gnutls_transport_set_ptr,void,(gnutls_session_t session, gnutls_transport_ptr_t ptr)) \ GNUTLS_FUNC(gnutls_transport_set_ptr,void,(gnutls_session_t session, gnutls_transport_ptr_t ptr)) \
GNUTLS_FUNC(gnutls_transport_set_push_function,void,(gnutls_session_t session, gnutls_push_func push_func)) \ GNUTLS_FUNC(gnutls_transport_set_push_function,void,(gnutls_session_t session, gnutls_push_func push_func)) \
@ -585,8 +585,10 @@ static int SSL_DoHandshake(gnutlsfile_t *file)
Con_Printf(CON_ERROR"GNU%sTLS: %s: %s(%i)\n", file->datagram?"D":"", file->certname, qgnutls_alert_get_name(desc), desc); Con_Printf(CON_ERROR"GNU%sTLS: %s: %s(%i)\n", file->datagram?"D":"", file->certname, qgnutls_alert_get_name(desc), desc);
} }
else else
{
//we didn't like the peer. //we didn't like the peer.
qgnutls_perror (err); Con_Printf(CON_ERROR"GNU%sTLS: %s: %s(%i)\n", file->datagram?"D":"", file->certname, qgnutls_strerror(err), err);
}
} }
// Con_Printf("%s: abort\n", file->certname); // Con_Printf("%s: abort\n", file->certname);
@ -1579,9 +1581,14 @@ static neterr_t GNUDTLS_Received(void *ctx, sizebuf_t *message)
} }
if (qgnutls_error_is_fatal(ret)) if (qgnutls_error_is_fatal(ret))
{ {
// Sys_Printf("DTLS_Received fail error\n"); if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
Con_DPrintf(CON_ERROR"GNUDTLS_Received: fatal alert %s\n", qgnutls_alert_get_name(qgnutls_alert_get(f->session)));
else
Con_DPrintf(CON_ERROR"GNUDTLS_Received fatal error %s\n", qgnutls_strerror(ret));
return NETERR_DISCONNECTED; return NETERR_DISCONNECTED;
} }
if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED)
Con_DPrintf(CON_WARNING"GNUDTLS_Received: alert %s\n", qgnutls_alert_get_name(qgnutls_alert_get(f->session)));
// Sys_Printf("DTLS_Received temp error\n"); // Sys_Printf("DTLS_Received temp error\n");
return NETERR_CLOGGED; return NETERR_CLOGGED;
} }

View file

@ -7232,6 +7232,7 @@ restart: //gotos are evil. I am evil. live with it.
SVM_AddBrokerGame(st->webrtc.resource, st->inbuffer+payoffs+3); SVM_AddBrokerGame(st->webrtc.resource, st->inbuffer+payoffs+3);
st->inbuffer[payoffs+paylen] = old; st->inbuffer[payoffs+paylen] = old;
#endif #endif
net_message.cursize = 0;
} }
else if ((st->clienttype == TCPC_WEBRTC_CLIENT || st->clienttype == TCPC_WEBRTC_HOST) && paylen >= 3) else if ((st->clienttype == TCPC_WEBRTC_CLIENT || st->clienttype == TCPC_WEBRTC_HOST) && paylen >= 3)
{ //we're brokering a client+server. all messages should be unicasts between a client and its host, matched by resource. { //we're brokering a client+server. all messages should be unicasts between a client and its host, matched by resource.
@ -7258,6 +7259,8 @@ restart: //gotos are evil. I am evil. live with it.
ftenet_tcp_stream_t *o; ftenet_tcp_stream_t *o;
int clnum = (st->inbuffer[payoffs+1]<<0)|(st->inbuffer[payoffs+2]<<8); int clnum = (st->inbuffer[payoffs+1]<<0)|(st->inbuffer[payoffs+2]<<8);
int type = (st->clienttype != TCPC_WEBRTC_CLIENT)?TCPC_WEBRTC_CLIENT:TCPC_WEBRTC_HOST; int type = (st->clienttype != TCPC_WEBRTC_CLIENT)?TCPC_WEBRTC_CLIENT:TCPC_WEBRTC_HOST;
if (clnum == 0xffff)
clnum = -1;
for (o = con->tcpstreams; o; o = o->next) for (o = con->tcpstreams; o; o = o->next)
{ {
if (o->clienttype == type && clnum == o->webrtc.clientnum && !strcmp(o->webrtc.resource, st->webrtc.resource)) if (o->clienttype == type && clnum == o->webrtc.clientnum && !strcmp(o->webrtc.resource, st->webrtc.resource))
@ -9076,15 +9079,19 @@ static qboolean FTENET_WebRTC_GetPacket(ftenet_generic_connection_t *gcon)
break; break;
case ICEMSG_CANDIDATE: case ICEMSG_CANDIDATE:
s = MSG_ReadString(); //either json or raw sdp s = MSG_ReadString(); //either json or raw sdp
if (s[0] == 'a' && s[1] == '=')
s+=2;
if (wsc->generic.islisten) if (wsc->generic.islisten)
{ {
if (cl < wsc->numclients && wsc->clients[cl].datasock != INVALID_SOCKET) if (cl < wsc->numclients && wsc->clients[cl].datasock != INVALID_SOCKET)
emscriptenfte_rtc_candidate(wsc->clients[cl].datasock, s); if (emscriptenfte_rtc_candidate(wsc->clients[cl].datasock, s) < 0)
Con_Printf("ICEMSG_CANDIDATE(%s): error\n", s);
} }
else else
{ {
if (wsc->datasock != INVALID_SOCKET) if (wsc->datasock != INVALID_SOCKET)
emscriptenfte_rtc_candidate(wsc->datasock, s); if (emscriptenfte_rtc_candidate(wsc->datasock, s) < 0)
Con_Printf("ICEMSG_CANDIDATE(%s): error\n", s);
} }
break; break;
} }

View file

@ -132,13 +132,10 @@ static void sha2trunc_init (void *context)
hd->count = 0; hd->count = 0;
} }
#if defined(__GNUC__) && (__GNUC__==10)
__attribute__((optimize("no-tree-bit-ccp"))) //gcc (Debian 10.2.1-6) 10.2.1 20210110 miscompiles without this (eg: test webrtc compat with a browser)
#endif
fte_inlinestatic u64 fte_inlinestatic u64
ROTR (u64 x, u64 n) ROTR (u64 x, u64 n)
{ {
return ((x >> n) | (x << (64 - n))); return ((x >> n) | (x << (sizeof(u64)*8 - n)));
} }
fte_inlinestatic u64 fte_inlinestatic u64
@ -531,6 +528,24 @@ hashfunc_t hash_sha2_256 =
sha2_write, sha2_write,
sha256_finish sha256_finish
}; };
/*#if defined(HAVE_SERVER) && !defined(HAVE_CLIENT)
__attribute__((constructor)) void sha2_256_unit_test(void)
{
qbyte digest[256/8];
qbyte need[sizeof(digest)];
CalcHash(&hash_sha2_256, digest, sizeof(digest), (qbyte*)(volatile qbyte*)"", 0);
Base16_DecodeBlock("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", need, sizeof(need));
if (memcmp(digest, need, sizeof(digest)))
printf("%s %i fail\n", __func__, __LINE__), abort();
CalcHash(&hash_sha2_256, digest, sizeof(digest), (qbyte*)(volatile qbyte*)"abc", 3);
Base16_DecodeBlock("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", need, sizeof(need));
if (memcmp(digest, need, sizeof(digest)))
printf("%s %i fail\n", __func__, __LINE__), abort();
}
#endif*/
#endif #endif
#if SHA2==512 #if SHA2==512
static void sha384_finish (qbyte *digest, void *context) static void sha384_finish (qbyte *digest, void *context)

View file

@ -28,7 +28,7 @@ int emscriptenfte_ws_recv(int sockid, void *data, int len); //receive data fr
int emscriptenfte_rtc_create(int clientside, void *ctxp, int ctxi, void(*cb)(void *ctxp, int ctxi, int type, const char *data), const char *json_config); //open a webrtc connection to a specific broker url int emscriptenfte_rtc_create(int clientside, void *ctxp, int ctxi, void(*cb)(void *ctxp, int ctxi, int type, const char *data), const char *json_config); //open a webrtc connection to a specific broker url
void emscriptenfte_rtc_offer(int sock, const char *offer, const char *sdptype);//sets the remote sdp. void emscriptenfte_rtc_offer(int sock, const char *offer, const char *sdptype);//sets the remote sdp.
void emscriptenfte_rtc_candidate(int sock, const char *offer); //adds a remote candidate. int emscriptenfte_rtc_candidate(int sock, const char *offer); //adds a remote candidate.
//misc stuff for printf replacements //misc stuff for printf replacements
void emscriptenfte_alert(const char *msg); void emscriptenfte_alert(const char *msg);

View file

@ -553,13 +553,13 @@ mergeInto(LibraryManager.library,
if (b.lastframe != p) if (b.lastframe != p)
{ //cache it to avoid spam { //cache it to avoid spam
b.lastframe = p; b.lastframe = p;
console.log("jbutton dev:" + idx + " btn:"+j+" dn:"+p+" mapping:"+gp.mapping); //console.log("jbutton dev:" + idx + " btn:"+j+" dn:"+p+" mapping:"+gp.mapping);
{{{makeDynCall('viiii','FTEC.evcb.jbutton')}}}(idx, j, p, gp.mapping=="standard"); {{{makeDynCall('viiii','FTEC.evcb.jbutton')}}}(idx, j, p, gp.mapping=="standard");
} }
} }
for (let j = 0; j < gp.axes.length; j+=1) for (let j = 0; j < gp.axes.length; j+=1)
{ {
console.log("jaxis dev:" + idx + " axis:"+j+" val:"+gp.axes[j]+" mapping:"+gp.mapping); //console.log("jaxis dev:" + idx + " axis:"+j+" val:"+gp.axes[j]+" mapping:"+gp.mapping);
{{{makeDynCall('viifi','FTEC.evcb.jaxis')}}}(idx, j, gp.axes[j], gp.mapping=="standard"); {{{makeDynCall('viifi','FTEC.evcb.jaxis')}}}(idx, j, gp.axes[j], gp.mapping=="standard");
} }
} }
@ -1485,6 +1485,7 @@ console.log("jaxis dev:" + idx + " axis:"+j+" val:"+gp.axes[j]+" mapping:"+gp.ma
} }
s.pc.addIceCandidate(desc); s.pc.addIceCandidate(desc);
} catch(err) { console.log(err); } } catch(err) { console.log(err); }
return 0;
}, },
emscriptenfte_async_wget_data2 : function(url, ctx, onload, onerror, onprogress) emscriptenfte_async_wget_data2 : function(url, ctx, onload, onerror, onprogress)

View file

@ -83,7 +83,7 @@ static long OSSL_Bio_FCtrl(BIO *h, int cmd, long arg1, void *arg2)
VFS_FLUSH(f); VFS_FLUSH(f);
return 1; return 1;
default: default:
Con_Printf("OSSL_Bio_FCtrl: unknown cmd %i\n", cmd); // Con_Printf("OSSL_Bio_FCtrl: unknown cmd %i\n", cmd);
case BIO_CTRL_PUSH: case BIO_CTRL_PUSH:
case BIO_CTRL_POP: case BIO_CTRL_POP:
return 0; return 0;
@ -95,7 +95,7 @@ static long OSSL_Bio_FOtherCtrl(BIO *h, int cmd, BIO_info_cb *cb)
switch(cmd) switch(cmd)
{ {
default: default:
Con_Printf("OSSL_Bio_FOtherCtrl unknown cmd %i\n", cmd); // Con_Printf("OSSL_Bio_FOtherCtrl unknown cmd %i\n", cmd);
return 0; return 0;
} }
return 0; //failure return 0; //failure
@ -664,7 +664,7 @@ static long OSSL_Bio_DCtrl(BIO *h, int cmd, long arg1, void *arg2)
default: default:
Con_Printf("OSSL_Bio_DCtrl: unknown cmd %i\n", cmd); // Con_Printf("OSSL_Bio_DCtrl: unknown cmd %i\n", cmd);
case BIO_CTRL_PUSH: case BIO_CTRL_PUSH:
case BIO_CTRL_POP: case BIO_CTRL_POP:
return 0; return 0;
@ -676,7 +676,7 @@ static long OSSL_Bio_DOtherCtrl(BIO *h, int cmd, BIO_info_cb *cb)
switch(cmd) switch(cmd)
{ {
default: default:
Con_Printf("OSSL_Bio_DOtherCtrl unknown cmd %i\n", cmd); // Con_Printf("OSSL_Bio_DOtherCtrl unknown cmd %i\n", cmd);
return 0; return 0;
} }
return 0; //failure return 0; //failure