]> granicus.if.org Git - transmission/commitdiff
Add patch from #5002 (r13646) to fix crash in libutp for CMake-based builds
authorMike Gelfand <mikedld@mikedld.com>
Sun, 29 Mar 2015 20:48:06 +0000 (20:48 +0000)
committerMike Gelfand <mikedld@mikedld.com>
Sun, 29 Mar 2015 20:48:06 +0000 (20:48 +0000)
CMakeLists.txt
third-party/utp-01-ticket-5002.patch [new file with mode: 0644]

index d37019e4f2650ac4db72b1585564943f89ff596f..1e7d4ececbdeb131386cdd2833042a3f55cfa543 100644 (file)
@@ -270,7 +270,8 @@ tr_add_external_auto_library(DHT dht
 if(ENABLE_UTP)
     tr_add_external_auto_library(UTP utp
         PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${THIRD_PARTY_DIR}/utp.cmake" "<SOURCE_DIR>/CMakeLists.txt"
-              COMMAND "${CMAKE_COMMAND}" -E copy "${THIRD_PARTY_DIR}/utp_config.h" "<SOURCE_DIR>/utp_config.h")
+              COMMAND "${CMAKE_COMMAND}" -E copy "${THIRD_PARTY_DIR}/utp_config.h" "<SOURCE_DIR>/utp_config.h"
+              COMMAND "${CMAKE_COMMAND}" -E chdir "<SOURCE_DIR>" patch -p1 --binary -i "${THIRD_PARTY_DIR}/utp-01-ticket-5002.patch")
 endif()
 
 tr_add_external_auto_library(B64 b64
diff --git a/third-party/utp-01-ticket-5002.patch b/third-party/utp-01-ticket-5002.patch
new file mode 100644 (file)
index 0000000..330cbc7
--- /dev/null
@@ -0,0 +1,52 @@
+diff --git a/utp.cpp b/utp.cpp
+--- a/utp.cpp
++++ b/utp.cpp
+@@ -1487,6 +1487,8 @@
+       return acked_bytes;\r
+ }\r
\r
++enum { MAX_EACK = 128 };\r
++\r
+ void UTPSocket::selective_ack(uint base, const byte *mask, byte len)\r
+ {\r
+       if (cur_window_packets == 0) return;\r
+@@ -1499,7 +1501,7 @@
+       // resends is a stack of sequence numbers we need to resend. Since we\r
+       // iterate in reverse over the acked packets, at the end, the top packets\r
+       // are the ones we want to resend\r
+-      int resends[32];\r
++      int resends[MAX_EACK];\r
+       int nr = 0;\r
\r
+       LOG_UTPV("0x%08x: Got EACK [%032b] base:%u", this, *(uint32*)mask, base);\r
+@@ -1572,6 +1574,12 @@
+               if (((v - fast_resend_seq_nr) & ACK_NR_MASK) <= OUTGOING_BUFFER_MAX_SIZE &&\r
+                       count >= DUPLICATE_ACKS_BEFORE_RESEND &&\r
+                       duplicate_ack < DUPLICATE_ACKS_BEFORE_RESEND) {\r
++                      // resends is a stack, and we're mostly interested in the top of it\r
++                      // if we're full, just throw away the lower half\r
++                      if (nr >= MAX_EACK - 2) {\r
++                              memmove(resends, &resends[MAX_EACK/2], MAX_EACK/2 * sizeof(resends[0]));\r
++                              nr -= MAX_EACK / 2;\r
++                      }\r
+                       resends[nr++] = v;\r
+                       LOG_UTPV("0x%08x: no ack for %u", this, v);\r
+               } else {\r
+@@ -1580,13 +1588,12 @@
+               }\r
+       } while (--bits >= -1);\r
\r
+-      if (((base - 1 - fast_resend_seq_nr) & ACK_NR_MASK) < 256 &&\r
+-              count >= DUPLICATE_ACKS_BEFORE_RESEND &&\r
+-              duplicate_ack < DUPLICATE_ACKS_BEFORE_RESEND) {\r
++      if (((base - 1 - fast_resend_seq_nr) & ACK_NR_MASK) <= OUTGOING_BUFFER_MAX_SIZE &&\r
++              count >= DUPLICATE_ACKS_BEFORE_RESEND) {\r
+               // if we get enough duplicate acks to start\r
+               // resending, the first packet we should resend\r
+               // is base-1\r
+-              resends[nr++] = base - 1;\r
++              resends[nr++] = (base - 1) & ACK_NR_MASK;\r
+       } else {\r
+               LOG_UTPV("0x%08x: not resending %u count:%d dup_ack:%u fast_resend_seq_nr:%u",\r
+                                this, base - 1, count, duplicate_ack, fast_resend_seq_nr);\r
+\r