mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 03:51:32 +00:00
Improve webrtc compat.
This commit is contained in:
parent
5bc9626dd6
commit
d99bc0b22a
8 changed files with 154 additions and 66 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,10 +2429,13 @@ 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);
|
||||||
|
|
||||||
Con_Printf(CON_WARNING"[%s]: %s\n", con->friendlyname, string);
|
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);
|
||||||
return ICE_Set(con, "state", STRINGIFY(ICE_FAILED)); //does the disconnection stuff.
|
return ICE_Set(con, "state", STRINGIFY(ICE_FAILED)); //does the disconnection stuff.
|
||||||
}
|
}
|
||||||
static char *ICE_CandidateToSDP(struct icecandidate_s *can, char *value, size_t valuelen)
|
static char *ICE_CandidateToSDP(struct icecandidate_s *can, char *value, size_t valuelen)
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue