mirror of
https://github.com/transmission/transmission
synced 2024-12-23 00:04:06 +00:00
(trunk, libutp) #5002 'crash in UTP_ProcessIncoming()' -- patch ef69847aaa from upstream
This commit is contained in:
parent
0933fa11cc
commit
285107dbca
1 changed files with 12 additions and 5 deletions
17
third-party/libutp/utp.cpp
vendored
17
third-party/libutp/utp.cpp
vendored
|
@ -1487,6 +1487,8 @@ size_t UTPSocket::selective_ack_bytes(uint base, const byte* mask, byte len, int
|
||||||
return acked_bytes;
|
return acked_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum { MAX_EACK = 128 };
|
||||||
|
|
||||||
void UTPSocket::selective_ack(uint base, const byte *mask, byte len)
|
void UTPSocket::selective_ack(uint base, const byte *mask, byte len)
|
||||||
{
|
{
|
||||||
if (cur_window_packets == 0) return;
|
if (cur_window_packets == 0) return;
|
||||||
|
@ -1499,7 +1501,7 @@ void UTPSocket::selective_ack(uint base, const byte *mask, byte len)
|
||||||
// resends is a stack of sequence numbers we need to resend. Since we
|
// resends is a stack of sequence numbers we need to resend. Since we
|
||||||
// iterate in reverse over the acked packets, at the end, the top packets
|
// iterate in reverse over the acked packets, at the end, the top packets
|
||||||
// are the ones we want to resend
|
// are the ones we want to resend
|
||||||
int resends[32];
|
int resends[MAX_EACK];
|
||||||
int nr = 0;
|
int nr = 0;
|
||||||
|
|
||||||
LOG_UTPV("0x%08x: Got EACK [%032b] base:%u", this, *(uint32*)mask, base);
|
LOG_UTPV("0x%08x: Got EACK [%032b] base:%u", this, *(uint32*)mask, base);
|
||||||
|
@ -1572,6 +1574,12 @@ void UTPSocket::selective_ack(uint base, const byte *mask, byte len)
|
||||||
if (((v - fast_resend_seq_nr) & ACK_NR_MASK) <= OUTGOING_BUFFER_MAX_SIZE &&
|
if (((v - fast_resend_seq_nr) & ACK_NR_MASK) <= OUTGOING_BUFFER_MAX_SIZE &&
|
||||||
count >= DUPLICATE_ACKS_BEFORE_RESEND &&
|
count >= DUPLICATE_ACKS_BEFORE_RESEND &&
|
||||||
duplicate_ack < DUPLICATE_ACKS_BEFORE_RESEND) {
|
duplicate_ack < DUPLICATE_ACKS_BEFORE_RESEND) {
|
||||||
|
// resends is a stack, and we're mostly interested in the top of it
|
||||||
|
// if we're full, just throw away the lower half
|
||||||
|
if (nr >= MAX_EACK - 2) {
|
||||||
|
memmove(resends, &resends[MAX_EACK/2], MAX_EACK/2 * sizeof(resends[0]));
|
||||||
|
nr -= MAX_EACK / 2;
|
||||||
|
}
|
||||||
resends[nr++] = v;
|
resends[nr++] = v;
|
||||||
LOG_UTPV("0x%08x: no ack for %u", this, v);
|
LOG_UTPV("0x%08x: no ack for %u", this, v);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1580,13 +1588,12 @@ void UTPSocket::selective_ack(uint base, const byte *mask, byte len)
|
||||||
}
|
}
|
||||||
} while (--bits >= -1);
|
} while (--bits >= -1);
|
||||||
|
|
||||||
if (((base - 1 - fast_resend_seq_nr) & ACK_NR_MASK) < 256 &&
|
if (((base - 1 - fast_resend_seq_nr) & ACK_NR_MASK) <= OUTGOING_BUFFER_MAX_SIZE &&
|
||||||
count >= DUPLICATE_ACKS_BEFORE_RESEND &&
|
count >= DUPLICATE_ACKS_BEFORE_RESEND) {
|
||||||
duplicate_ack < DUPLICATE_ACKS_BEFORE_RESEND) {
|
|
||||||
// if we get enough duplicate acks to start
|
// if we get enough duplicate acks to start
|
||||||
// resending, the first packet we should resend
|
// resending, the first packet we should resend
|
||||||
// is base-1
|
// is base-1
|
||||||
resends[nr++] = base - 1;
|
resends[nr++] = (base - 1) & ACK_NR_MASK;
|
||||||
} else {
|
} else {
|
||||||
LOG_UTPV("0x%08x: not resending %u count:%d dup_ack:%u fast_resend_seq_nr:%u",
|
LOG_UTPV("0x%08x: not resending %u count:%d dup_ack:%u fast_resend_seq_nr:%u",
|
||||||
this, base - 1, count, duplicate_ack, fast_resend_seq_nr);
|
this, base - 1, count, duplicate_ack, fast_resend_seq_nr);
|
||||||
|
|
Loading…
Reference in a new issue