try to fix chrome's disconnection issues.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6178 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2022-01-30 11:44:37 +00:00
parent 98c60de572
commit 711bd8a990
2 changed files with 49 additions and 39 deletions

View file

@ -930,6 +930,7 @@ static qboolean QDECL ICE_Set(struct icestate_s *con, const char *prop, const ch
con->sctp = Z_Malloc(sizeof(*con->sctp)); con->sctp = Z_Malloc(sizeof(*con->sctp));
con->sctp->myport = htons(con->mysctpport); con->sctp->myport = htons(con->mysctpport);
con->sctp->peerport = htons(con->peersctpport); con->sctp->peerport = htons(con->peersctpport);
con->sctp->o.tsn = rand() ^ (rand()<<16);
Sys_RandomBytes((void*)&con->sctp->o.verifycode, sizeof(con->sctp->o.verifycode)); Sys_RandomBytes((void*)&con->sctp->o.verifycode, sizeof(con->sctp->o.verifycode));
Sys_RandomBytes((void*)&con->sctp->i.verifycode, sizeof(con->sctp->i.verifycode)); Sys_RandomBytes((void*)&con->sctp->i.verifycode, sizeof(con->sctp->i.verifycode));
} }
@ -1130,7 +1131,10 @@ static qboolean QDECL ICE_Get(struct icestate_s *con, const char *prop, char *va
const char *params[countof(addr)]; const char *params[countof(addr)];
if (!NET_EnumerateAddresses(ICE_PickConnection(con), gcon, flags, addr, params, countof(addr))) if (!NET_EnumerateAddresses(ICE_PickConnection(con), gcon, flags, addr, params, countof(addr)))
{
sender.type = NA_INVALID; sender.type = NA_INVALID;
sender.port = 0;
}
else else
sender = *addr; sender = *addr;
} }
@ -1588,11 +1592,11 @@ struct sctp_chunk_fwdtsn_s
{ {
struct sctp_chunk_s chunk; struct sctp_chunk_s chunk;
quint32_t tsn; quint32_t tsn;
struct /*struct
{ {
quint16_t sid; quint16_t sid;
quint16_t seq; quint16_t seq;
} streams[1];//... } streams[];*/
}; };
static neterr_t SCTP_PeerSendPacket(struct icestate_s *peer, int length, const void *data) static neterr_t SCTP_PeerSendPacket(struct icestate_s *peer, int length, const void *data)
@ -1639,6 +1643,18 @@ static neterr_t SCTP_Transmit(sctp_t *sctp, struct icestate_s *peer, const void
h->verifycode = sctp->o.verifycode; h->verifycode = sctp->o.verifycode;
pktlen += sizeof(*h); pktlen += sizeof(*h);
//advance our ctsn if we're received the relevant packets
while(sctp->i.htsn)
{
quint32_t tsn = sctp->i.ctsn+1;
if (!(sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] & 1<<(tsn&7)))
break;
//advance our cumulative ack.
sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] &= ~(1<<(tsn&7));
sctp->i.ctsn = tsn;
sctp->i.htsn--;
}
if (!sctp->o.writable) if (!sctp->o.writable)
{ {
double time = Sys_DoubleTime(); double time = Sys_DoubleTime();
@ -1688,15 +1704,17 @@ static neterr_t SCTP_Transmit(sctp_t *sctp, struct icestate_s *peer, const void
return NETERR_CLOGGED; //nope, not ready yet return NETERR_CLOGGED; //nope, not ready yet
} }
if (sctp->peerhasfwdtsn && sctp->o.ctsn < sctp->o.tsn && sctp->o.losttsn) if (sctp->peerhasfwdtsn && (int)(sctp->o.ctsn-sctp->o.tsn) < -5 && sctp->o.losttsn)
{ {
fwd = (struct sctp_chunk_fwdtsn_s*)&pkt[pktlen]; fwd = (struct sctp_chunk_fwdtsn_s*)&pkt[pktlen];
fwd->chunk.type = SCTP_TYPE_FORWARDTSN; fwd->chunk.type = SCTP_TYPE_FORWARDTSN;
fwd->chunk.flags = 0; fwd->chunk.flags = 0;
fwd->chunk.length = BigShort(sizeof(*fwd)); fwd->chunk.length = BigShort(sizeof(*fwd));
fwd->tsn = BigLong(sctp->o.tsn-1); fwd->tsn = BigLong(sctp->o.tsn-1);
fwd->streams[0].sid = sctp->qstreamid;
fwd->streams[0].seq = BigShort(0); //we only send unordered unreliables, so this stream stuff here is irrelevant.
// fwd->streams[0].sid = sctp->qstreamid;
// fwd->streams[0].seq = BigShort(0);
pktlen += sizeof(*fwd); pktlen += sizeof(*fwd);
} }
@ -1870,10 +1888,9 @@ static void SCTP_ErrorChunk(const char *errortype, struct sctp_errorcause_s *s,
} }
} }
static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer) static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer, ftenet_connections_t *col)
{ {
qbyte resp[4096]; qbyte resp[4096];
qboolean finished = false;
qbyte *msg = net_message.data; qbyte *msg = net_message.data;
qbyte *msgend = net_message.data+net_message.cursize; qbyte *msgend = net_message.data+net_message.cursize;
@ -1915,7 +1932,7 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer)
else if (adv <= 0) else if (adv <= 0)
Con_DPrintf("SCTP: PreCumulative\n");/*already acked this*/ Con_DPrintf("SCTP: PreCumulative\n");/*already acked this*/
else if (sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] & 1<<(tsn&7)) else if (sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] & 1<<(tsn&7))
Con_DPrintf("SCTP: Dupe\n");/*already processed it*/ Con_DPrintf("SCTP: Dupe\n");/*already processed it. FIXME: Make a list for the next SACK*/
else else
{ {
qboolean err = false; qboolean err = false;
@ -1929,9 +1946,6 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer)
sctp->i.r.sid = dc->sid; sctp->i.r.sid = dc->sid;
sctp->i.r.seq = dc->seq; sctp->i.r.seq = dc->seq;
sctp->i.r.toobig = false; sctp->i.r.toobig = false;
if (finished)
Con_Printf("SCTP: Multiple data chunks\n");
finished = false;
} }
else else
{ {
@ -1966,7 +1980,16 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer)
if (sctp->i.r.toobig) if (sctp->i.r.toobig)
;/*ignore it when it cannot be handled*/ ;/*ignore it when it cannot be handled*/
else if (sctp->i.r.ppid == BigLong(SCTP_PPID_DATA)) else if (sctp->i.r.ppid == BigLong(SCTP_PPID_DATA))
finished = true; //FIXME: handle multiple small packets {
memmove(net_message.data, sctp->i.r.buf, sctp->i.r.size);
net_message.cursize = sctp->i.r.size;
col->ReadGamePacket();
if (net_message.cursize != sctp->i.r.size)
{
net_message.cursize = 0;
return; //something weird happened...
}
}
else if (sctp->i.r.ppid == BigLong(SCTP_PPID_DCEP)) else if (sctp->i.r.ppid == BigLong(SCTP_PPID_DCEP))
SCTP_DecodeDCEP(sctp, peer, resp); SCTP_DecodeDCEP(sctp, peer, resp);
} }
@ -1979,17 +2002,6 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer)
// Con_Printf("\tStream Id %i\n", BigShort(dc->sid)); // Con_Printf("\tStream Id %i\n", BigShort(dc->sid));
// Con_Printf("\tStream Seq %i\n", BigShort(dc->seq)); // Con_Printf("\tStream Seq %i\n", BigShort(dc->seq));
// Con_Printf("\tPPID %i\n", BigLong(dc->ppid)); // Con_Printf("\tPPID %i\n", BigLong(dc->ppid));
while(sctp->i.htsn)
{
tsn = sctp->i.ctsn+1;
if (!(sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] & 1<<(tsn&7)))
break;
//advance our cumulative ack.
sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] &= ~(1<<(tsn&7));
sctp->i.ctsn = tsn;
sctp->i.htsn--;
}
} }
} }
break; break;
@ -2173,6 +2185,7 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer)
sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] &= ~(1<<(tsn&7)); sctp->i.received[(tsn>>3)%sizeof(sctp->i.received)] &= ~(1<<(tsn&7));
if (sctp->i.htsn) if (sctp->i.htsn)
sctp->i.htsn--; sctp->i.htsn--;
sctp->i.ackneeded++; //flag for a sack if we actually completed something here.
} }
} }
break; break;
@ -2188,14 +2201,8 @@ static void SCTP_Decode(sctp_t *sctp, struct icestate_s *peer)
if (sctp->i.ackneeded >= 5) if (sctp->i.ackneeded >= 5)
SCTP_Transmit(sctp, peer, NULL, 0); //make sure we send acks occasionally even if we have nothing else to say. SCTP_Transmit(sctp, peer, NULL, 0); //make sure we send acks occasionally even if we have nothing else to say.
//if we read something, spew it out and return to caller. //we already made sense of it all.
if (finished) net_message.cursize = 0;
{
memmove(net_message.data, sctp->i.r.buf, sctp->i.r.size);
net_message.cursize = sctp->i.r.size;
}
else
net_message.cursize = 0; //nothing to read.
} }
//======================================== //========================================
@ -2709,7 +2716,7 @@ qboolean ICE_WasStun(ftenet_connections_t *col)
net_from = con->qadr; net_from = con->qadr;
#ifdef HAVE_DTLS #ifdef HAVE_DTLS
if (con->sctp) if (con->sctp)
SCTP_Decode(con->sctp, con); SCTP_Decode(con->sctp, con, col);
#endif #endif
if (net_message.cursize) if (net_message.cursize)
col->ReadGamePacket(); col->ReadGamePacket();

View file

@ -1001,13 +1001,16 @@ void SVM_GenChallenge(char *out, size_t outsize, netadr_t *foradr)
char digest[256]; char digest[256];
void *ctx = alloca(hash_sha1.contextsize); void *ctx = alloca(hash_sha1.contextsize);
if (!*randumb) while (!*randumb)
{ {
int i; if (!Sys_RandomBytes(randumb, sizeof(randumb)))
srand(time(NULL)); //lame {
for (i = 0; i < sizeof(randumb)-1; i++) int i;
while (!randumb[i]) srand(time(NULL)); //lame
randumb[i] = rand(); for (i = 0; i < sizeof(randumb)-1; i++)
while (!randumb[i])
randumb[i] = rand();
}
} }
NET_AdrToString(adr, sizeof(adr), foradr); NET_AdrToString(adr, sizeof(adr), foradr);