Advertisement
Guest User

Untitled

a guest
Nov 16th, 2017
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
LDIF 74.47 KB | None | 0 0
  1. diff --git a/README b/README
  2. index 34ea77e7d..9afabaf80 100644
  3. --- a/README
  4. +++ b/README
  5. @@ -100,6 +100,17 @@ plugins to build large scale web applications.
  6.      libcurl4-openssl-dev (optional, required for e.g.: traffic_top)
  7.      flex (optional, required for e.g. WCCP)
  8.  
  9. +  Alpine Linux
  10. +    build-base
  11. +    libexecinfo-dev
  12. +    pcre-dev
  13. +    libressl-dev
  14. +    autoconf
  15. +    automake
  16. +    libtool
  17. +    tcl-dev
  18. +    linux-headers
  19. +  
  20.    OSX (we recommend HomeBrew):
  21.      autoconf
  22.      automake
  23. diff --git a/configure.ac b/configure.ac
  24. index 0dbdd1c29..4495d0c24 100644
  25. --- a/configure.ac
  26. +++ b/configure.ac
  27. @@ -444,12 +444,6 @@ AC_ARG_WITH([max-threads-per-type],
  28.  )
  29.  AC_SUBST(max_threads_per_type)
  30.  
  31. -# Check Brotli
  32. -AC_CHECK_HEADERS([brotli/encode.h], [has_brotli=1],[has_brotli=0])
  33. -AC_CHECK_LIB([brotlienc],[BrotliEncoderCreateInstance],[AC_SUBST([LIB_BROTLIENC],["-lbrotlienc"])],[has_brotli=0])
  34. -AC_SUBST(has_brotli)
  35. -AM_CONDITIONAL([HAS_BROTLI], [ test "x${has_brotli}" = "x1" ])
  36. -
  37.  #
  38.  # Experimental plugins
  39.  #
  40. @@ -1226,8 +1220,14 @@ if test "x${enable_pcre}" != "xyes"; then
  41.    AC_MSG_ERROR([Cannot find pcre library. Configure --with-pcre=DIR])
  42.  fi
  43.  
  44. -has_backtrace=0
  45. +# Check Brotli
  46. +AC_CHECK_HEADERS([brotli/encode.h], [has_brotli=1],[has_brotli=0])
  47. +AC_CHECK_LIB([brotlienc],[BrotliEncoderCreateInstance],[AC_SUBST([LIB_BROTLIENC],["-lbrotlienc"])],[has_brotli=0])
  48. +AC_SUBST(has_brotli)
  49. +AM_CONDITIONAL([HAS_BROTLI], [ test "x${has_brotli}" = "x1" ])
  50. +
  51.  # Check for backtrace() support
  52. +has_backtrace=0
  53.  AC_CHECK_HEADERS([execinfo.h], [has_backtrace=1],[])
  54.  if test "${has_backtrace}" = "1"; then
  55.    # FreeBSD requires '/usr/ports/devel/libexecinfo' for gdb style backtrace() support
  56. diff --git a/doc/developer-guide/api/types/TSHttpStatus.en.rst b/doc/developer-guide/api/types/TSHttpStatus.en.rst
  57. index 9cfe9fe1a..78d2453e7 100644
  58. --- a/doc/developer-guide/api/types/TSHttpStatus.en.rst
  59. +++ b/doc/developer-guide/api/types/TSHttpStatus.en.rst
  60. @@ -45,6 +45,8 @@ Enumeration Members
  61.  
  62.  .. c:member:: TSHttpStatus TS_HTTP_STATUS_SWITCHING_PROTOCOL
  63.  
  64. +.. c:member:: TSHttpStatus TS_HTTP_STATUS_EARLY_HINTS
  65. +
  66.  .. c:member:: TSHttpStatus TS_HTTP_STATUS_OK
  67.  
  68.  .. c:member:: TSHttpStatus TS_HTTP_STATUS_CREATED
  69. diff --git a/example/thread-pool/psi.c b/example/thread-pool/psi.c
  70. index 970259756..a690c037c 100644
  71. --- a/example/thread-pool/psi.c
  72. +++ b/example/thread-pool/psi.c
  73. @@ -49,6 +49,7 @@
  74.  #include <stdlib.h>
  75.  #include <limits.h>
  76.  #include <string.h>
  77. +#include <sys/param.h>
  78.  
  79.  #include "ts/ts.h"
  80.  #include "thread.h"
  81. diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc
  82. index 9e4263e4a..e0b633980 100644
  83. --- a/iocore/cache/Cache.cc
  84. +++ b/iocore/cache/Cache.cc
  85. @@ -3407,7 +3407,7 @@ HTTPInfo_v21::copy_and_upgrade_unmarshalled_to_v23(char *&dst, char *&src, size_
  86.    // Extra data is fragment table - set that if we have it.
  87.    if (n_frags) {
  88.      static size_t const IFT_SIZE = HTTPCacheAlt_v23::N_INTEGRAL_FRAG_OFFSETS * sizeof(FragOffset);
  89. -    size_t ift_actual            = min(n_frags, HTTPCacheAlt_v23::N_INTEGRAL_FRAG_OFFSETS) * sizeof(FragOffset);
  90. +    size_t ift_actual            = std::min(n_frags, HTTPCacheAlt_v23::N_INTEGRAL_FRAG_OFFSETS) * sizeof(FragOffset);
  91.  
  92.      if (length < (HTTP_ALT_MARSHAL_SIZE + n_frags * sizeof(FragOffset) - IFT_SIZE))
  93.        return false; // can't place fragment table.
  94. diff --git a/iocore/cache/Store.cc b/iocore/cache/Store.cc
  95. index e922d3bdf..06068adca 100644
  96. --- a/iocore/cache/Store.cc
  97. +++ b/iocore/cache/Store.cc
  98. @@ -561,7 +561,7 @@ Span::init(const char *path, int64_t size)
  99.  
  100.    // The actual size of a span always trumps the configured size.
  101.    if (size > 0 && this->size() != size) {
  102. -    int64_t newsz = MIN(size, this->size());
  103. +    int64_t newsz = std::min(size, this->size());
  104.  
  105.      Note("cache %s '%s' is %" PRId64 " bytes, but the configured size is %" PRId64 " bytes, using the minimum",
  106.           span_file_typename(sbuf.st_mode), path, this->size(), size);
  107. diff --git a/iocore/cluster/ClusterHandlerBase.cc b/iocore/cluster/ClusterHandlerBase.cc
  108. index 16d42a86f..36011d634 100644
  109. --- a/iocore/cluster/ClusterHandlerBase.cc
  110. +++ b/iocore/cluster/ClusterHandlerBase.cc
  111. @@ -1144,7 +1144,7 @@ ClusterHandler::startClusterEvent(int event, Event *e)
  112.        //  external_incoming_control.
  113.  
  114.        int procs_online    = ink_number_of_processors();
  115. -      int total_callbacks = min(procs_online, MAX_COMPLETION_CALLBACK_EVENTS);
  116. +      int total_callbacks = std::min(procs_online, MAX_COMPLETION_CALLBACK_EVENTS);
  117.        for (int n = 0; n < total_callbacks; ++n) {
  118.          callout_cont[n]   = new ClusterCalloutContinuation(this);
  119.          callout_events[n] = eventProcessor.schedule_every(callout_cont[n], COMPLETION_CALLBACK_PERIOD, ET_NET);
  120. diff --git a/iocore/dns/DNS.cc b/iocore/dns/DNS.cc
  121. index 5c1522add..0c0c4ae14 100644
  122. --- a/iocore/dns/DNS.cc
  123. +++ b/iocore/dns/DNS.cc
  124. @@ -509,7 +509,7 @@ DNSHandler::startEvent(int /* event ATS_UNUSED */, Event *e)
  125.        open_con(nullptr); // use current target address.
  126.        n_con = 1;
  127.      }
  128. -    e->ethread->schedule_every(this, DNS_PERIOD);
  129. +    e->ethread->schedule_every(this, -DNS_PERIOD);
  130.  
  131.      return EVENT_CONT;
  132.    } else {
  133. @@ -532,7 +532,7 @@ DNSHandler::startEvent_sdns(int /* event ATS_UNUSED */, Event *e)
  134.    open_con(&ip.sa, false, n_con);
  135.    ++n_con; // TODO should n_con be zeroed?
  136.  
  137. -  e->schedule_every(DNS_PERIOD);
  138. +  e->schedule_every(-DNS_PERIOD);
  139.    return EVENT_CONT;
  140.  }
  141.  
  142. @@ -645,6 +645,8 @@ DNSHandler::failover()
  143.      switch_named(name_server);
  144.    } else {
  145.      ip_text_buffer buff;
  146. +    con[name_server].eio.stop();
  147. +    con[name_server].close();
  148.      Warning("failover: connection to DNS server %s lost, retrying", ats_ip_ntop(&ip.sa, buff, sizeof(buff)));
  149.    }
  150.  }
  151. @@ -1235,7 +1237,7 @@ Lretry:
  152.    e->retries    = 0;
  153.    if (e->timeout)
  154.      e->timeout->cancel();
  155. -  e->timeout = h->mutex->thread_holding->schedule_in(e, DNS_PERIOD);
  156. +  e->timeout = h->mutex->thread_holding->schedule_in(e, MUTEX_RETRY_DELAY);
  157.  }
  158.  
  159.  int
  160. diff --git a/iocore/dns/P_DNSProcessor.h b/iocore/dns/P_DNSProcessor.h
  161. index 8fead49d5..be22b014f 100644
  162. --- a/iocore/dns/P_DNSProcessor.h
  163. +++ b/iocore/dns/P_DNSProcessor.h
  164. @@ -62,7 +62,7 @@ extern unsigned int dns_sequence_number;
  165.  // Constants
  166.  //
  167.  
  168. -#define DNS_PERIOD HRTIME_MSECONDS(-100)
  169. +#define DNS_PERIOD HRTIME_MSECONDS(100)
  170.  #define DNS_DELAY_PERIOD HRTIME_MSECONDS(10)
  171.  #define DNS_SEQUENCE_NUMBER_RESTART_OFFSET 4000
  172.  #define DNS_PRIMARY_RETRY_PERIOD HRTIME_SECONDS(5)
  173. diff --git a/iocore/eventsystem/P_UnixSocketManager.h b/iocore/eventsystem/P_UnixSocketManager.h
  174. index b023a8de9..b45f74562 100644
  175. --- a/iocore/eventsystem/P_UnixSocketManager.h
  176. +++ b/iocore/eventsystem/P_UnixSocketManager.h
  177. @@ -118,7 +118,7 @@ SocketManager::vector_io(int fd, struct iovec *vector, size_t count, int read_re
  178.    int64_t current_request_bytes;
  179.  
  180.    for (n_vec = 0; n_vec < (int)count; n_vec += max_iovecs_per_request) {
  181. -    current_count = min(max_iovecs_per_request, ((int)(count - n_vec)));
  182. +    current_count = std::min(max_iovecs_per_request, ((int)(count - n_vec)));
  183.      do {
  184.        // coverity[tainted_data_argument]
  185.        r = read_request ? ::readv(fd, &vector[n_vec], current_count) : ::writev(fd, &vector[n_vec], current_count);
  186. diff --git a/iocore/net/Connection.cc b/iocore/net/Connection.cc
  187. index e52af10b6..78f5a6a69 100644
  188. --- a/iocore/net/Connection.cc
  189. +++ b/iocore/net/Connection.cc
  190. @@ -45,7 +45,7 @@ get_listen_backlog()
  191.    int listen_backlog;
  192.  
  193.    REC_ReadConfigInteger(listen_backlog, "proxy.config.net.listen_backlog");
  194. -  return listen_backlog >= 0 ? listen_backlog : ats_tcp_somaxconn();
  195. +  return (0 < listen_backlog && listen_backlog <= 65535) ? listen_backlog : ats_tcp_somaxconn();
  196.  }
  197.  
  198.  //
  199. diff --git a/iocore/net/NetVCTest.cc b/iocore/net/NetVCTest.cc
  200. index 17401d58c..07d7c6b8c 100644
  201. --- a/iocore/net/NetVCTest.cc
  202. +++ b/iocore/net/NetVCTest.cc
  203. @@ -308,7 +308,7 @@ NetVCTest::write_handler(int event)
  204.      if (write_vio->ndone < bytes_to_send) {
  205.        int left_to_send = bytes_to_send - actual_bytes_sent;
  206.        ink_assert(left_to_send >= 0);
  207. -      int to_fill = MIN(left_to_send, write_bytes_to_add_per);
  208. +      int to_fill = std::min(left_to_send, write_bytes_to_add_per);
  209.        actual_bytes_sent += fill_buffer(write_buffer, &write_seed, to_fill);
  210.        write_vio->reenable();
  211.      }
  212. diff --git a/iocore/net/P_InkBulkIO.h b/iocore/net/P_InkBulkIO.h
  213. index 46df82b82..f24b95a8f 100644
  214. --- a/iocore/net/P_InkBulkIO.h
  215. +++ b/iocore/net/P_InkBulkIO.h
  216. @@ -141,7 +141,7 @@ struct InkBulkIORequest {
  217.   */
  218.  #define INKBIO_MAX_PKTS_PER_REQ_BLOCK                                                              \
  219.    ((INKBIO_PKT_SIZE_WO_UDPHDR - (sizeof(struct InkBulkIORequest) + sizeof(struct InkBulkIOPkt))) / \
  220. -   MAX((sizeof(struct InkBulkIORequest)), (sizeof(struct InkBulkIOPkt))))
  221. +   std::max((sizeof(struct InkBulkIORequest)), (sizeof(struct InkBulkIOPkt))))
  222.  
  223.  /*
  224.   * Requests are just block-ids---the block id points to the inkbio-block
  225. diff --git a/iocore/net/UnixUDPNet.cc b/iocore/net/UnixUDPNet.cc
  226. index da5a8780b..e9fadb144 100644
  227. --- a/iocore/net/UnixUDPNet.cc
  228. +++ b/iocore/net/UnixUDPNet.cc
  229. @@ -668,10 +668,10 @@ UDPQueue::service(UDPNetHandler *nh)
  230.        // insert into our queue.
  231.        Debug("udp-send", "Adding %p", p);
  232.        if (p->conn->lastPktStartTime == 0) {
  233. -        pktSendStartTime = MAX(now, p->delivery_time);
  234. +        pktSendStartTime = std::max(now, p->delivery_time);
  235.        } else {
  236.          pktSendTime      = p->delivery_time;
  237. -        pktSendStartTime = MAX(MAX(now, pktSendTime), p->delivery_time);
  238. +        pktSendStartTime = std::max(std::max(now, pktSendTime), p->delivery_time);
  239.        }
  240.        p->conn->lastPktStartTime = pktSendStartTime;
  241.        p->delivery_time          = pktSendStartTime;
  242. diff --git a/lib/cppapi/include/atscppapi/HttpStatus.h b/lib/cppapi/include/atscppapi/HttpStatus.h
  243. index 5c2e3732d..071aef1a3 100644
  244. --- a/lib/cppapi/include/atscppapi/HttpStatus.h
  245. +++ b/lib/cppapi/include/atscppapi/HttpStatus.h
  246. @@ -37,6 +37,7 @@ enum HttpStatus {
  247.  
  248.    HTTP_STATUS_CONTINUE           = 100,
  249.    HTTP_STATUS_SWITCHING_PROTOCOL = 101,
  250. +  HTTP_STATUS_EARLY_HINTS        = 103,
  251.  
  252.    HTTP_STATUS_OK                            = 200,
  253.    HTTP_STATUS_CREATED                       = 201,
  254. diff --git a/lib/records/RecHttp.cc b/lib/records/RecHttp.cc
  255. index 29ea1fa48..99f56b7af 100644
  256. --- a/lib/records/RecHttp.cc
  257. +++ b/lib/records/RecHttp.cc
  258. @@ -600,7 +600,7 @@ HttpProxyPort::print(char *out, size_t n)
  259.      }
  260.    }
  261.  
  262. -  return min(zret, n);
  263. +  return std::min(zret, n);
  264.  }
  265.  
  266.  void
  267. diff --git a/lib/ts/Makefile.am b/lib/ts/Makefile.am
  268. index 2e09e151f..146c06fe6 100644
  269. --- a/lib/ts/Makefile.am
  270. +++ b/lib/ts/Makefile.am
  271. @@ -244,6 +244,7 @@ test_tslib_CPPFLAGS = $(AM_CPPFLAGS)\
  272.     -I$(abs_top_srcdir)/tests/include
  273.  
  274.  # add you catch based test file here for tslib
  275. +test_tslib_CXXFLAGS = -Wno-array-bounds $(AM_CXXFLAGS)
  276.  test_tslib_LDADD = libtsutil.la
  277.  test_tslib_SOURCES = \
  278.     unit-tests/main.cpp \
  279. diff --git a/lib/ts/apidefs.h.in b/lib/ts/apidefs.h.in
  280. index 4f0ada31f..7efe01967 100644
  281. --- a/lib/ts/apidefs.h.in
  282. +++ b/lib/ts/apidefs.h.in
  283. @@ -155,6 +155,7 @@ typedef enum {
  284.    TS_HTTP_STATUS_NONE                            = 0,
  285.    TS_HTTP_STATUS_CONTINUE                        = 100,
  286.    TS_HTTP_STATUS_SWITCHING_PROTOCOL              = 101,
  287. +  TS_HTTP_STATUS_EARLY_HINTS                     = 103,
  288.    TS_HTTP_STATUS_OK                              = 200,
  289.    TS_HTTP_STATUS_CREATED                         = 201,
  290.    TS_HTTP_STATUS_ACCEPTED                        = 202,
  291. diff --git a/lib/ts/ink_defs.h b/lib/ts/ink_defs.h
  292. index 0f80a8152..f85589d3a 100644
  293. --- a/lib/ts/ink_defs.h
  294. +++ b/lib/ts/ink_defs.h
  295. @@ -88,33 +88,6 @@ countof(const T (&)[N])
  296.  #define ABS(x) (((x) < 0) ? (-(x)) : (x))
  297.  #endif
  298.  
  299. -#ifndef MAX
  300. -#define MAX(x, y) (((x) >= (y)) ? (x) : (y))
  301. -#endif
  302. -
  303. -#ifndef MIN
  304. -#define MIN(x, y) (((x) <= (y)) ? (x) : (y))
  305. -#endif
  306. -
  307. -#ifdef __cplusplus
  308. -// We can't use #define for min and max because it will conflict with
  309. -// other declarations of min and max functions.  This conflict
  310. -// occurs with STL
  311. -template <class T>
  312. -T
  313. -min(const T a, const T b)
  314. -{
  315. -  return a < b ? a : b;
  316. -}
  317. -
  318. -template <class T>
  319. -T
  320. -max(const T a, const T b)
  321. -{
  322. -  return a > b ? a : b;
  323. -}
  324. -#endif
  325. -
  326.  #define ATS_UNUSED __attribute__((unused))
  327.  #define ATS_WARN_IF_UNUSED __attribute__((warn_unused_result))
  328.  #define ATS_UNUSED_RETURN(x) \
  329. diff --git a/lib/ts/ink_inet.cc b/lib/ts/ink_inet.cc
  330. index 01c2127bf..10d9b282c 100644
  331. --- a/lib/ts/ink_inet.cc
  332. +++ b/lib/ts/ink_inet.cc
  333. @@ -675,18 +675,17 @@ REGRESSION_TEST(Ink_Inet)(RegressionTest *t, int /* atype */, int *pstatus)
  334.  int
  335.  ats_tcp_somaxconn()
  336.  {
  337. -  int fd;
  338.    int value = 0;
  339.  
  340.  /* Darwin version ... */
  341.  #if HAVE_SYSCTLBYNAME
  342.    size_t value_size = sizeof(value);
  343. -  if (sysctlbyname("kern.ipc.somaxconn", &value, &value_size, nullptr, 0) == 0) {
  344. -    return value;
  345. +  if (sysctlbyname("kern.ipc.somaxconn", &value, &value_size, nullptr, 0) < 0) {
  346. +    value = 0;
  347.    }
  348. -#endif
  349. -
  350. -  fd = open("/proc/sys/net/ipv4/tcp_max_syn_backlog", O_RDONLY);
  351. +#else
  352. +  int fd;
  353. +  fd = open("/proc/sys/net/core/somaxconn", O_RDONLY);
  354.    if (fd != -1) {
  355.      textBuffer text(0);
  356.      text.slurp(fd);
  357. @@ -695,11 +694,12 @@ ats_tcp_somaxconn()
  358.      }
  359.      close(fd);
  360.    }
  361. +#endif
  362.  
  363.    // Default to the compatible value we used before detection. SOMAXCONN is the right
  364.    // macro to use, but most systems set this to 128, which is just too small.
  365. -  if (value <= 0) {
  366. -    return 1024;
  367. +  if (value <= 0 || value > 65535) {
  368. +    value = 1024;
  369.    }
  370.  
  371.    return value;
  372. diff --git a/lib/ts/ink_sys_control.cc b/lib/ts/ink_sys_control.cc
  373. index 8cdc824dc..e1d3e715c 100644
  374. --- a/lib/ts/ink_sys_control.cc
  375. +++ b/lib/ts/ink_sys_control.cc
  376. @@ -30,7 +30,7 @@ ink_max_out_rlimit(int which, bool max_it, bool unlim_it)
  377.  {
  378.    struct rlimit rl;
  379.  
  380. -#if defined(linux)
  381. +#if defined(__GLIBC__)
  382.  #define MAGIC_CAST(x) (enum __rlimit_resource)(x)
  383.  #else
  384.  #define MAGIC_CAST(x) x
  385. diff --git a/lib/ts/mkdfa.c b/lib/ts/mkdfa.c
  386. index 3767b0c1b..9dcc89083 100644
  387. --- a/lib/ts/mkdfa.c
  388. +++ b/lib/ts/mkdfa.c
  389. @@ -138,6 +138,7 @@ info_t methods[] = {
  390.  info_t statuses[] = {
  391.    {"100", "HTTP_STATUS_CONTINUE", -1},
  392.    {"101", "HTTP_STATUS_SWITCHING_PROTOCOL", -1},
  393. +  {"103", "HTTP_STATUS_EARLY_HINTS", -1},
  394.    {"200", "HTTP_STATUS_OK", -1},
  395.    {"201", "HTTP_STATUS_CREATED", -1},
  396.    {"202", "HTTP_STATUS_ACCEPTED", -1},
  397. diff --git a/mgmt/cluster/ClusterCom.cc b/mgmt/cluster/ClusterCom.cc
  398. index 496def120..263069d01 100644
  399. --- a/mgmt/cluster/ClusterCom.cc
  400. +++ b/mgmt/cluster/ClusterCom.cc
  401. @@ -658,7 +658,7 @@ ClusterCom::generateClusterDelta()
  402.  
  403.      // is the node alive?
  404.      if (tmp->num_virt_addrs != -1) {
  405. -      highest_delta = max(highest_delta, tmp->delta);
  406. +      highest_delta = std::max(highest_delta, tmp->delta);
  407.      }
  408.    }
  409.    ink_mutex_release(&(mutex));
  410. diff --git a/proxy/InkAPITest.cc b/proxy/InkAPITest.cc
  411. index 486c343b5..5f67c697e 100644
  412. --- a/proxy/InkAPITest.cc
  413. +++ b/proxy/InkAPITest.cc
  414. @@ -3272,7 +3272,7 @@ REGRESSION_TEST(SDK_API_TSHttpHdr)(RegressionTest *test, int /* atype ATS_UNUSED
  415.    }
  416.  
  417.    if (strcmp("Not Modified", TSHttpHdrReasonLookup(TS_HTTP_STATUS_NOT_MODIFIED)) != 0) {
  418. -    SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase2", TC_FAIL, "TSHttpHdrReasonLookup returns Value's mismatch");
  419. +    SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase4", TC_FAIL, "TSHttpHdrReasonLookup returns Value's mismatch");
  420.      if (test_passed_Http_Hdr_Reason_Lookup == true) {
  421.        test_passed_Http_Hdr_Reason_Lookup = false;
  422.      }
  423. @@ -3280,6 +3280,15 @@ REGRESSION_TEST(SDK_API_TSHttpHdr)(RegressionTest *test, int /* atype ATS_UNUSED
  424.      SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase4", TC_PASS, "ok");
  425.    }
  426.  
  427. +  if (strcmp("Early Hints", TSHttpHdrReasonLookup(TS_HTTP_STATUS_EARLY_HINTS)) != 0) {
  428. +    SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase5", TC_FAIL, "TSHttpHdrReasonLookup returns Value's mismatch");
  429. +    if (test_passed_Http_Hdr_Reason_Lookup == true) {
  430. +      test_passed_Http_Hdr_Reason_Lookup = false;
  431. +    }
  432. +  } else {
  433. +    SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase5", TC_PASS, "ok");
  434. +  }
  435. +
  436.    // Copy
  437.    if (test_passed_Http_Hdr_Create == true) {
  438.      if (TSHttpHdrCopy(bufp3, hdr_loc3, bufp1, hdr_loc1) == TS_ERROR) {
  439. @@ -5488,6 +5497,7 @@ typedef enum {
  440.  
  441.    ORIG_TS_HTTP_STATUS_CONTINUE           = 100,
  442.    ORIG_TS_HTTP_STATUS_SWITCHING_PROTOCOL = 101,
  443. +  ORIG_TS_HTTP_STATUS_EARLY_HINTS        = 103,
  444.  
  445.    ORIG_TS_HTTP_STATUS_OK                            = 200,
  446.    ORIG_TS_HTTP_STATUS_CREATED                       = 201,
  447. @@ -5657,6 +5667,8 @@ REGRESSION_TEST(SDK_API_TSConstant)(RegressionTest *test, int /* atype ATS_UNUSE
  448.    PRINT_DIFF(TS_HTTP_STATUS_NONE);
  449.    PRINT_DIFF(TS_HTTP_STATUS_CONTINUE);
  450.    PRINT_DIFF(TS_HTTP_STATUS_SWITCHING_PROTOCOL);
  451. +  PRINT_DIFF(TS_HTTP_STATUS_EARLY_HINTS);
  452. +
  453.    PRINT_DIFF(TS_HTTP_STATUS_OK);
  454.    PRINT_DIFF(TS_HTTP_STATUS_CREATED);
  455.  
  456. diff --git a/proxy/InkAPITestTool.cc b/proxy/InkAPITestTool.cc
  457. index dd814b1ce..fc3392a68 100644
  458. --- a/proxy/InkAPITestTool.cc
  459. +++ b/proxy/InkAPITestTool.cc
  460. @@ -667,7 +667,7 @@ synclient_txn_write_request(TSCont contp)
  461.    while (ntodo > 0) {
  462.      block     = TSIOBufferStart(txn->req_buffer);
  463.      ptr_block = TSIOBufferBlockWriteStart(block, &avail);
  464. -    towrite   = MIN(ntodo, avail);
  465. +    towrite   = std::min(ntodo, avail);
  466.      memcpy(ptr_block, txn->request + ndone, towrite);
  467.      TSIOBufferProduce(txn->req_buffer, towrite);
  468.      ntodo -= towrite;
  469. @@ -962,7 +962,7 @@ synserver_txn_write_response(TSCont contp)
  470.    while (ntodo > 0) {
  471.      block     = TSIOBufferStart(txn->resp_buffer);
  472.      ptr_block = TSIOBufferBlockWriteStart(block, &avail);
  473. -    towrite   = MIN(ntodo, avail);
  474. +    towrite   = std::min(ntodo, avail);
  475.      memcpy(ptr_block, response + ndone, towrite);
  476.      TSIOBufferProduce(txn->resp_buffer, towrite);
  477.      ntodo -= towrite;
  478. diff --git a/proxy/PluginVC.cc b/proxy/PluginVC.cc
  479. index 7a377e723..e2e221712 100644
  480. --- a/proxy/PluginVC.cc
  481. +++ b/proxy/PluginVC.cc
  482. @@ -432,7 +432,7 @@ PluginVC::transfer_bytes(MIOBuffer *transfer_to, IOBufferReader *transfer_from,
  483.  
  484.    while (act_on > 0) {
  485.      int64_t block_read_avail = transfer_from->block_read_avail();
  486. -    int64_t to_move          = MIN(act_on, block_read_avail);
  487. +    int64_t to_move          = std::min(act_on, block_read_avail);
  488.      int64_t moved            = 0;
  489.  
  490.      if (to_move <= 0) {
  491. @@ -507,7 +507,7 @@ PluginVC::process_write_side(bool other_side_call)
  492.  
  493.    IOBufferReader *reader = write_state.vio.get_reader();
  494.    int64_t bytes_avail    = reader->read_avail();
  495. -  int64_t act_on         = MIN(bytes_avail, ntodo);
  496. +  int64_t act_on         = std::min(bytes_avail, ntodo);
  497.  
  498.    Debug("pvc", "[%u] %s: process_write_side; act_on %" PRId64 "", core_obj->id, PVC_TYPE, act_on);
  499.  
  500. @@ -532,7 +532,7 @@ PluginVC::process_write_side(bool other_side_call)
  501.      Debug("pvc", "[%u] %s: process_write_side no buffer space", core_obj->id, PVC_TYPE);
  502.      return;
  503.    }
  504. -  act_on = MIN(act_on, buf_space);
  505. +  act_on = std::min(act_on, buf_space);
  506.  
  507.    int64_t added = transfer_bytes(core_buffer, reader, act_on);
  508.    if (added < 0) {
  509. @@ -625,7 +625,7 @@ PluginVC::process_read_side(bool other_side_call)
  510.    }
  511.  
  512.    int64_t bytes_avail = core_reader->read_avail();
  513. -  int64_t act_on      = MIN(bytes_avail, ntodo);
  514. +  int64_t act_on      = std::min(bytes_avail, ntodo);
  515.  
  516.    Debug("pvc", "[%u] %s: process_read_side; act_on %" PRId64 "", core_obj->id, PVC_TYPE, act_on);
  517.  
  518. @@ -641,13 +641,13 @@ PluginVC::process_read_side(bool other_side_call)
  519.    MIOBuffer *output_buffer = read_state.vio.get_writer();
  520.  
  521.    int64_t water_mark = output_buffer->water_mark;
  522. -  water_mark         = MAX(water_mark, PVC_DEFAULT_MAX_BYTES);
  523. +  water_mark         = std::max(water_mark, static_cast<int64_t>(PVC_DEFAULT_MAX_BYTES));
  524.    int64_t buf_space  = water_mark - output_buffer->max_read_avail();
  525.    if (buf_space <= 0) {
  526.      Debug("pvc", "[%u] %s: process_read_side no buffer space", core_obj->id, PVC_TYPE);
  527.      return;
  528.    }
  529. -  act_on = MIN(act_on, buf_space);
  530. +  act_on = std::min(act_on, buf_space);
  531.  
  532.    int64_t added = transfer_bytes(output_buffer, core_reader, act_on);
  533.    if (added <= 0) {
  534. diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc
  535. index 3be7064da..c265e1293 100644
  536. --- a/proxy/hdrs/HTTP.cc
  537. +++ b/proxy/hdrs/HTTP.cc
  538. @@ -756,6 +756,7 @@ http_hdr_reason_lookup(unsigned status)
  539.      HTTP_STATUS_ENTRY(100, Continue);            // [RFC2616]
  540.      HTTP_STATUS_ENTRY(101, Switching Protocols); // [RFC2616]
  541.      HTTP_STATUS_ENTRY(102, Processing);          // [RFC2518]
  542. +    HTTP_STATUS_ENTRY(103, Early Hints);         // TODO: add RFC number
  543.      // 103-199 Unassigned
  544.      HTTP_STATUS_ENTRY(200, OK);                              // [RFC2616]
  545.      HTTP_STATUS_ENTRY(201, Created);                         // [RFC2616]
  546. @@ -1815,6 +1816,8 @@ ClassAllocator<HTTPCacheAlt> httpCacheAltAllocator("httpCacheAltAllocator");
  547.  
  548.  /*-------------------------------------------------------------------------
  549.    -------------------------------------------------------------------------*/
  550. +int constexpr HTTPCacheAlt::N_INTEGRAL_FRAG_OFFSETS;
  551. +
  552.  HTTPCacheAlt::HTTPCacheAlt()
  553.    : m_magic(CACHE_ALT_MAGIC_ALIVE),
  554.      m_writeable(1),
  555. diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h
  556. index 5891834dc..3cd61a31f 100644
  557. --- a/proxy/hdrs/HTTP.h
  558. +++ b/proxy/hdrs/HTTP.h
  559. @@ -43,6 +43,7 @@ enum HTTPStatus {
  560.  
  561.    HTTP_STATUS_CONTINUE           = 100,
  562.    HTTP_STATUS_SWITCHING_PROTOCOL = 101,
  563. +  HTTP_STATUS_EARLY_HINTS        = 103,
  564.  
  565.    HTTP_STATUS_OK                            = 200,
  566.    HTTP_STATUS_CREATED                       = 201,
  567. @@ -1352,7 +1353,7 @@ struct HTTPCacheAlt {
  568.    /// for the last fragment.
  569.    FragOffset *m_frag_offsets;
  570.    /// # of fragment offsets built in to object.
  571. -  static int const N_INTEGRAL_FRAG_OFFSETS = 4;
  572. +  static int constexpr N_INTEGRAL_FRAG_OFFSETS = 4;
  573.    /// Integral fragment offset table.
  574.    FragOffset m_integral_frag_offsets[N_INTEGRAL_FRAG_OFFSETS];
  575.  
  576. diff --git a/proxy/hdrs/HttpCompat.cc b/proxy/hdrs/HttpCompat.cc
  577. index 6f69758b6..89eaa634a 100644
  578. --- a/proxy/hdrs/HttpCompat.cc
  579. +++ b/proxy/hdrs/HttpCompat.cc
  580. @@ -851,7 +851,7 @@ HttpCompat::determine_set_by_language(RawHashTable *table_of_sets, StrList *acpt
  581.        // index, preferring values earlier in Accept-Language list.   //
  582.        /////////////////////////////////////////////////////////////////
  583.  
  584. -      Q = min(Ql, Qc);
  585. +      Q = std::min(Ql, Qc);
  586.  
  587.        //////////////////////////////////////////////////////////
  588.        // normally the Q for default pages should be slightly  //
  589. diff --git a/proxy/hdrs/MIME.cc b/proxy/hdrs/MIME.cc
  590. index 418c34a67..e2b0c1bd5 100644
  591. --- a/proxy/hdrs/MIME.cc
  592. +++ b/proxy/hdrs/MIME.cc
  593. @@ -2802,7 +2802,7 @@ mime_mem_print(const char *src_d, int src_l, char *buf_start, int buf_length, in
  594.      }
  595.    }
  596.  
  597. -  copy_l = min(buf_length - *buf_index_inout, src_l);
  598. +  copy_l = std::min(buf_length - *buf_index_inout, src_l);
  599.    if (copy_l > 0) {
  600.      memcpy(buf_start + *buf_index_inout, src_d, copy_l);
  601.      *buf_index_inout += copy_l;
  602. diff --git a/proxy/http/HttpConfig.cc b/proxy/http/HttpConfig.cc
  603. index 258d1d843..a7d3371cf 100644
  604. --- a/proxy/http/HttpConfig.cc
  605. +++ b/proxy/http/HttpConfig.cc
  606. @@ -1304,7 +1304,7 @@ HttpConfig::reconfigure()
  607.  
  608.    params->oride.cache_heuristic_min_lifetime = m_master.oride.cache_heuristic_min_lifetime;
  609.    params->oride.cache_heuristic_max_lifetime = m_master.oride.cache_heuristic_max_lifetime;
  610. -  params->oride.cache_heuristic_lm_factor    = min(max(m_master.oride.cache_heuristic_lm_factor, 0.0f), 1.0f);
  611. +  params->oride.cache_heuristic_lm_factor    = std::min(std::max(m_master.oride.cache_heuristic_lm_factor, 0.0f), 1.0f);
  612.  
  613.    params->oride.cache_guaranteed_min_lifetime = m_master.oride.cache_guaranteed_min_lifetime;
  614.    params->oride.cache_guaranteed_max_lifetime = m_master.oride.cache_guaranteed_max_lifetime;
  615. diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
  616. index 29f492e74..411c6316e 100644
  617. --- a/proxy/http/HttpTransact.cc
  618. +++ b/proxy/http/HttpTransact.cc
  619. @@ -2411,8 +2411,8 @@ HttpTransact::HandleCacheOpenReadHitFreshness(State *s)
  620.    // for it. this is just to deal with the effects
  621.    // of the skew by setting minimum and maximum times
  622.    // so that ages are not negative, etc.
  623. -  s->request_sent_time      = min(s->client_request_time, s->request_sent_time);
  624. -  s->response_received_time = min(s->client_request_time, s->response_received_time);
  625. +  s->request_sent_time      = std::min(s->client_request_time, s->request_sent_time);
  626. +  s->response_received_time = std::min(s->client_request_time, s->response_received_time);
  627.  
  628.    ink_assert(s->request_sent_time <= s->response_received_time);
  629.  
  630. @@ -4071,7 +4071,8 @@ HttpTransact::handle_forward_server_connection_open(State *s)
  631.      // dont update the hostdb. let us try again with what we currently think.
  632.    }
  633.  
  634. -  if (s->hdr_info.server_response.status_get() == HTTP_STATUS_CONTINUE) {
  635. +  if (s->hdr_info.server_response.status_get() == HTTP_STATUS_CONTINUE ||
  636. +      s->hdr_info.server_response.status_get() == HTTP_STATUS_EARLY_HINTS) {
  637.      handle_100_continue_response(s);
  638.      return;
  639.    }
  640. @@ -4840,7 +4841,7 @@ HttpTransact::merge_and_update_headers_for_cache_update(State *s)
  641.      // If the cached response has an Age: we should update it
  642.      // We could use calculate_document_age but my guess is it's overkill
  643.      // Just use 'now' - 304's Date: + Age: (response's Age: if there)
  644. -    date_value = max(s->current.now - date_value, (ink_time_t)0);
  645. +    date_value = std::max(s->current.now - date_value, (ink_time_t)0);
  646.      if (s->hdr_info.server_response.presence(MIME_PRESENCE_AGE)) {
  647.        time_t new_age = s->hdr_info.server_response.get_age();
  648.  
  649. @@ -7267,7 +7268,7 @@ HttpTransact::calculate_document_freshness_limit(State *s, HTTPHdr *response, ti
  650.        freshness_limit = (int)response->get_cooked_cc_max_age();
  651.        DebugTxn("http_match", "calculate_document_freshness_limit --- max_age set, freshness_limit = %d", freshness_limit);
  652.      }
  653. -    freshness_limit = min(max(0, freshness_limit), (int)s->txn_conf->cache_guaranteed_max_lifetime);
  654. +    freshness_limit = std::min(std::max(0, freshness_limit), (int)s->txn_conf->cache_guaranteed_max_lifetime);
  655.    } else {
  656.      date_set = last_modified_set = false;
  657.  
  658. @@ -7304,7 +7305,7 @@ HttpTransact::calculate_document_freshness_limit(State *s, HTTPHdr *response, ti
  659.        DebugTxn("http_match", "calculate_document_freshness_limit --- Expires: %" PRId64 ", Date: %" PRId64 ", freshness_limit = %d",
  660.                 (int64_t)expires_value, (int64_t)date_value, freshness_limit);
  661.  
  662. -      freshness_limit = min(max(0, freshness_limit), (int)s->txn_conf->cache_guaranteed_max_lifetime);
  663. +      freshness_limit = std::min(std::max(0, freshness_limit), (int)s->txn_conf->cache_guaranteed_max_lifetime);
  664.      } else {
  665.        last_modified_value = 0;
  666.        if (response->presence(MIME_PRESENCE_LAST_MODIFIED)) {
  667. @@ -7328,7 +7329,7 @@ HttpTransact::calculate_document_freshness_limit(State *s, HTTPHdr *response, ti
  668.          ink_assert((f >= 0.0) && (f <= 1.0));
  669.          ink_time_t time_since_last_modify = date_value - last_modified_value;
  670.          int h_freshness                   = (int)(time_since_last_modify * f);
  671. -        freshness_limit                   = max(h_freshness, 0);
  672. +        freshness_limit                   = std::max(h_freshness, 0);
  673.          DebugTxn("http_match", "calculate_document_freshness_limit --- heuristic: date=%" PRId64 ", lm=%" PRId64
  674.                                 ", time_since_last_modify=%" PRId64 ", f=%g, freshness_limit = %d",
  675.                   (int64_t)date_value, (int64_t)last_modified_value, (int64_t)time_since_last_modify, f, freshness_limit);
  676. @@ -7340,13 +7341,13 @@ HttpTransact::calculate_document_freshness_limit(State *s, HTTPHdr *response, ti
  677.    }
  678.  
  679.    // The freshness limit must always fall within the min and max guaranteed bounds.
  680. -  min_freshness_bounds = max((MgmtInt)0, s->txn_conf->cache_guaranteed_min_lifetime);
  681. +  min_freshness_bounds = std::max((MgmtInt)0, s->txn_conf->cache_guaranteed_min_lifetime);
  682.    max_freshness_bounds = s->txn_conf->cache_guaranteed_max_lifetime;
  683.  
  684.    // Heuristic freshness can be more strict.
  685.    if (*heuristic) {
  686. -    min_freshness_bounds = max(min_freshness_bounds, s->txn_conf->cache_heuristic_min_lifetime);
  687. -    max_freshness_bounds = min(max_freshness_bounds, s->txn_conf->cache_heuristic_max_lifetime);
  688. +    min_freshness_bounds = std::max(min_freshness_bounds, s->txn_conf->cache_heuristic_min_lifetime);
  689. +    max_freshness_bounds = std::min(max_freshness_bounds, s->txn_conf->cache_heuristic_max_lifetime);
  690.    }
  691.    // Now clip the freshness limit.
  692.    if (freshness_limit > max_freshness_bounds) {
  693. @@ -7387,12 +7388,12 @@ HttpTransact::calculate_freshness_fuzz(State *s, int fresh_limit)
  694.      if (s->txn_conf->freshness_fuzz_min_time > 0) {
  695.        // Complicated calculations to try to find a reasonable fuzz time between fuzz_min_time and fuzz_time
  696.        int fresh_small = (int)rint((double)s->txn_conf->freshness_fuzz_min_time *
  697. -                                  pow(2, min((double)fresh_limit / (double)s->txn_conf->freshness_fuzz_time,
  698. -                                             sqrt((double)s->txn_conf->freshness_fuzz_time))));
  699. -      int fresh_large = max((int)s->txn_conf->freshness_fuzz_min_time,
  700. -                            (int)rint(s->txn_conf->freshness_fuzz_time *
  701. -                                      log10((double)(fresh_limit - s->txn_conf->freshness_fuzz_min_time) / LOG_YEAR)));
  702. -      result = min(fresh_small, fresh_large);
  703. +                                  pow(2, std::min((double)fresh_limit / (double)s->txn_conf->freshness_fuzz_time,
  704. +                                                  sqrt((double)s->txn_conf->freshness_fuzz_time))));
  705. +      int fresh_large = std::max((int)s->txn_conf->freshness_fuzz_min_time,
  706. +                                 (int)rint(s->txn_conf->freshness_fuzz_time *
  707. +                                           log10((double)(fresh_limit - s->txn_conf->freshness_fuzz_min_time) / LOG_YEAR)));
  708. +      result = std::min(fresh_small, fresh_large);
  709.        DebugTxn("http_match", "calculate_freshness_fuzz using min/max --- freshness fuzz = %d", result);
  710.      } else {
  711.        result = s->txn_conf->freshness_fuzz_time;
  712. @@ -7472,8 +7473,8 @@ HttpTransact::what_is_document_freshness(State *s, HTTPHdr *client_request, HTTP
  713.    //  documents at the same time
  714.    if ((s->txn_conf->freshness_fuzz_time > 0) && (s->txn_conf->freshness_fuzz_prob > 0.0)) {
  715.      fresh_limit = fresh_limit - calculate_freshness_fuzz(s, fresh_limit);
  716. -    fresh_limit = max(0, fresh_limit);
  717. -    fresh_limit = min((int)s->txn_conf->cache_guaranteed_max_lifetime, fresh_limit);
  718. +    fresh_limit = std::max(0, fresh_limit);
  719. +    fresh_limit = std::min((int)s->txn_conf->cache_guaranteed_max_lifetime, fresh_limit);
  720.    }
  721.  
  722.    current_age = HttpTransactHeaders::calculate_document_age(s->request_sent_time, s->response_received_time, cached_obj_response,
  723. @@ -7483,7 +7484,7 @@ HttpTransact::what_is_document_freshness(State *s, HTTPHdr *client_request, HTTP
  724.    if (current_age < 0) {
  725.      current_age = s->txn_conf->cache_guaranteed_max_lifetime;
  726.    } else {
  727. -    current_age = min((time_t)s->txn_conf->cache_guaranteed_max_lifetime, current_age);
  728. +    current_age = std::min((time_t)s->txn_conf->cache_guaranteed_max_lifetime, current_age);
  729.    }
  730.  
  731.    DebugTxn("http_match", "[what_is_document_freshness] fresh_limit:  %d  current_age: %" PRId64, fresh_limit, (int64_t)current_age);
  732. @@ -7560,7 +7561,7 @@ HttpTransact::what_is_document_freshness(State *s, HTTPHdr *client_request, HTTP
  733.      // if min-fresh set, constrain the freshness limit //
  734.      /////////////////////////////////////////////////////
  735.      if (cooked_cc_mask & MIME_COOKED_MASK_CC_MIN_FRESH) {
  736. -      age_limit = min(age_limit, fresh_limit - client_request->get_cooked_cc_min_fresh());
  737. +      age_limit = std::min(age_limit, fresh_limit - client_request->get_cooked_cc_min_fresh());
  738.        DebugTxn("http_match", "[..._document_freshness] min_fresh set, age limit: %d", age_limit);
  739.      }
  740.      ///////////////////////////////////////////////////
  741. @@ -7571,7 +7572,7 @@ HttpTransact::what_is_document_freshness(State *s, HTTPHdr *client_request, HTTP
  742.        if (age_val == 0) {
  743.          do_revalidate = true;
  744.        }
  745. -      age_limit = min(age_limit, age_val);
  746. +      age_limit = std::min(age_limit, age_val);
  747.        DebugTxn("http_match", "[..._document_freshness] min_fresh set, age limit: %d", age_limit);
  748.      }
  749.    }
  750. @@ -8870,7 +8871,7 @@ HttpTransact::update_size_and_time_stats(State *s, ink_hrtime total_time, ink_hr
  751.    switch (s->state_machine->background_fill) {
  752.    case BACKGROUND_FILL_COMPLETED: {
  753.      int64_t bg_size = origin_server_response_body_size - user_agent_response_body_size;
  754. -    bg_size         = max((int64_t)0, bg_size);
  755. +    bg_size         = std::max((int64_t)0, bg_size);
  756.      HTTP_SUM_DYN_STAT(http_background_fill_bytes_completed_stat, bg_size);
  757.      break;
  758.    }
  759. diff --git a/proxy/http/HttpTransactHeaders.cc b/proxy/http/HttpTransactHeaders.cc
  760. index d3844c7a9..eba47c207 100644
  761. --- a/proxy/http/HttpTransactHeaders.cc
  762. +++ b/proxy/http/HttpTransactHeaders.cc
  763. @@ -409,7 +409,7 @@ HttpTransactHeaders::calculate_document_age(ink_time_t request_time, ink_time_t
  764.    // Deal with clock skew. Sigh.
  765.    //
  766.    // TODO solve this global clock problem
  767. -  now_value = max(now, response_time);
  768. +  now_value = std::max(now, response_time);
  769.  
  770.    ink_assert(response_time >= 0);
  771.    ink_assert(request_time >= 0);
  772. @@ -417,12 +417,12 @@ HttpTransactHeaders::calculate_document_age(ink_time_t request_time, ink_time_t
  773.    ink_assert(now_value >= response_time);
  774.  
  775.    if (date_value > 0) {
  776. -    apparent_age = max((time_t)0, (response_time - date_value));
  777. +    apparent_age = std::max((time_t)0, (response_time - date_value));
  778.    }
  779.    if (age_value < 0) {
  780.      current_age = -1; // Overflow from Age: header
  781.    } else {
  782. -    corrected_received_age = max(apparent_age, age_value);
  783. +    corrected_received_age = std::max(apparent_age, age_value);
  784.      response_delay         = response_time - request_time;
  785.      corrected_initial_age  = corrected_received_age + response_delay;
  786.      resident_time          = now_value - response_time;
  787. diff --git a/proxy/http/HttpTunnel.cc b/proxy/http/HttpTunnel.cc
  788. index d9fc59d18..d21e79dc7 100644
  789. --- a/proxy/http/HttpTunnel.cc
  790. +++ b/proxy/http/HttpTunnel.cc
  791. @@ -233,7 +233,7 @@ ChunkedHandler::transfer_bytes()
  792.  
  793.    // Handle the case where we are doing chunked passthrough.
  794.    if (!dechunked_buffer) {
  795. -    moved = MIN(bytes_left, chunked_reader->read_avail());
  796. +    moved = std::min(bytes_left, chunked_reader->read_avail());
  797.      chunked_reader->consume(moved);
  798.      bytes_left = bytes_left - moved;
  799.      return moved;
  800. @@ -242,7 +242,7 @@ ChunkedHandler::transfer_bytes()
  801.    while (bytes_left > 0) {
  802.      block_read_avail = chunked_reader->block_read_avail();
  803.  
  804. -    to_move = MIN(bytes_left, block_read_avail);
  805. +    to_move = std::min(bytes_left, block_read_avail);
  806.      if (to_move <= 0) {
  807.        break;
  808.      }
  809. @@ -374,7 +374,7 @@ ChunkedHandler::generate_chunked_content()
  810.    }
  811.  
  812.    while ((r_avail = dechunked_reader->read_avail()) > 0 && state != CHUNK_WRITE_DONE) {
  813. -    int64_t write_val = MIN(max_chunk_size, r_avail);
  814. +    int64_t write_val = std::min(max_chunk_size, r_avail);
  815.  
  816.      state = CHUNK_WRITE_CHUNK;
  817.      Debug("http_chunk", "creating a chunk of size %" PRId64 " bytes", write_val);
  818. diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc
  819. index 67af7b695..85c10b5c8 100644
  820. --- a/proxy/http2/HTTP2.cc
  821. +++ b/proxy/http2/HTTP2.cc
  822. @@ -586,7 +586,7 @@ http2_encode_header_blocks(HTTPHdr *in, uint8_t *out, uint32_t out_len, uint32_t
  823.                             int32_t maximum_table_size)
  824.  {
  825.    // Limit the maximum table size to 64kB, which is the size advertised by major clients
  826. -  maximum_table_size = min(maximum_table_size, HTTP2_MAX_TABLE_SIZE_LIMIT);
  827. +  maximum_table_size = std::min(maximum_table_size, HTTP2_MAX_TABLE_SIZE_LIMIT);
  828.    // Set maximum table size only if it is different from current maximum size
  829.    if (maximum_table_size == hpack_get_maximum_table_size(handle)) {
  830.      maximum_table_size = -1;
  831. @@ -661,7 +661,11 @@ http2_decode_header_blocks(HTTPHdr *hdr, const uint8_t *buf_start, const uint32_
  832.  
  833.    // rfc7540,sec8.1.2.2: Any message containing connection-specific header
  834.    // fields MUST be treated as malformed
  835. -  if (hdr->field_find(MIME_FIELD_CONNECTION, MIME_LEN_CONNECTION) != nullptr) {
  836. +  if (hdr->field_find(MIME_FIELD_CONNECTION, MIME_LEN_CONNECTION) != nullptr ||
  837. +      hdr->field_find(MIME_FIELD_KEEP_ALIVE, MIME_LEN_KEEP_ALIVE) != nullptr ||
  838. +      hdr->field_find(MIME_FIELD_PROXY_CONNECTION, MIME_LEN_PROXY_CONNECTION) != nullptr ||
  839. +      hdr->field_find(MIME_FIELD_TRANSFER_ENCODING, MIME_LEN_TRANSFER_ENCODING) != nullptr ||
  840. +      hdr->field_find(MIME_FIELD_UPGRADE, MIME_LEN_UPGRADE) != nullptr) {
  841.      return Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR;
  842.    }
  843.  
  844. diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc
  845. index 2e684c490..c38c919ba 100644
  846. --- a/proxy/http2/Http2ConnectionState.cc
  847. +++ b/proxy/http2/Http2ConnectionState.cc
  848. @@ -30,7 +30,7 @@
  849.  #define DebugHttp2Con(ua_session, fmt, ...) \
  850.    DebugSsn(ua_session, "http2_con", "[%" PRId64 "] " fmt, ua_session->connection_id(), ##__VA_ARGS__);
  851.  
  852. -#define DebugHttp2Stream(ua_session, stream_id, fmt, ...) \
  853. +#define Http2StreamDebug(ua_session, stream_id, fmt, ...) \
  854.    DebugSsn(ua_session, "http2_con", "[%" PRId64 "] [%u] " fmt, ua_session->connection_id(), stream_id, ##__VA_ARGS__);
  855.  
  856.  using http2_frame_dispatch = Http2Error (*)(Http2ConnectionState &, const Http2Frame &);
  857. @@ -71,7 +71,7 @@ rcv_data_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  858.    uint8_t pad_length            = 0;
  859.    const uint32_t payload_length = frame.header().length;
  860.  
  861. -  DebugHttp2Stream(cstate.ua_session, id, "Received DATA frame");
  862. +  Http2StreamDebug(cstate.ua_session, id, "Received DATA frame");
  863.  
  864.    // If a DATA frame is received whose stream identifier field is 0x0, the
  865.    // recipient MUST
  866. @@ -167,7 +167,7 @@ rcv_data_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  867.    myreader->writer()->dealloc_reader(myreader);
  868.  
  869.    uint32_t initial_rwnd = cstate.server_settings.get(HTTP2_SETTINGS_INITIAL_WINDOW_SIZE);
  870. -  uint32_t min_rwnd     = min(initial_rwnd, cstate.server_settings.get(HTTP2_SETTINGS_MAX_FRAME_SIZE));
  871. +  uint32_t min_rwnd     = std::min(initial_rwnd, cstate.server_settings.get(HTTP2_SETTINGS_MAX_FRAME_SIZE));
  872.    // Connection level WINDOW UPDATE
  873.    if (cstate.server_rwnd <= min_rwnd) {
  874.      Http2WindowSize diff_size = initial_rwnd - cstate.server_rwnd;
  875. @@ -199,7 +199,7 @@ rcv_headers_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  876.    const Http2StreamId stream_id = frame.header().streamid;
  877.    const uint32_t payload_length = frame.header().length;
  878.  
  879. -  DebugHttp2Stream(cstate.ua_session, stream_id, "Received HEADERS frame");
  880. +  Http2StreamDebug(cstate.ua_session, stream_id, "Received HEADERS frame");
  881.  
  882.    if (!http2_is_client_streamid(stream_id)) {
  883.      return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR,
  884. @@ -284,7 +284,7 @@ rcv_headers_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  885.        stream->priority_node = node;
  886.        node->t               = stream;
  887.      } else {
  888. -      DebugHttp2Stream(cstate.ua_session, stream_id, "PRIORITY - dep: %d, weight: %d, excl: %d, tree size: %d",
  889. +      Http2StreamDebug(cstate.ua_session, stream_id, "HEADER PRIORITY - dep: %d, weight: %d, excl: %d, tree size: %d",
  890.                         params.priority.stream_dependency, params.priority.weight, params.priority.exclusive_flag,
  891.                         cstate.dependency_tree->size());
  892.  
  893. @@ -343,7 +343,7 @@ rcv_headers_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  894.    } else {
  895.      // NOTE: Expect CONTINUATION Frame. Do NOT change state of stream or decode
  896.      // Header Blocks.
  897. -    DebugHttp2Stream(cstate.ua_session, stream_id, "No END_HEADERS flag, expecting CONTINUATION frame");
  898. +    Http2StreamDebug(cstate.ua_session, stream_id, "No END_HEADERS flag, expecting CONTINUATION frame");
  899.      cstate.set_continued_stream_id(stream_id);
  900.    }
  901.  
  902. @@ -360,7 +360,7 @@ rcv_priority_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  903.    const Http2StreamId stream_id = frame.header().streamid;
  904.    const uint32_t payload_length = frame.header().length;
  905.  
  906. -  DebugHttp2Stream(cstate.ua_session, stream_id, "Received PRIORITY frame");
  907. +  Http2StreamDebug(cstate.ua_session, stream_id, "Received PRIORITY frame");
  908.  
  909.    // If a PRIORITY frame is received with a stream identifier of 0x0, the
  910.    // recipient MUST respond with a connection error of type PROTOCOL_ERROR.
  911. @@ -395,14 +395,14 @@ rcv_priority_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  912.                        "PRIORITY frame depends on itself");
  913.    }
  914.  
  915. -  DebugHttp2Stream(cstate.ua_session, stream_id, "PRIORITY - dep: %d, weight: %d, excl: %d, tree size: %d",
  916. +  Http2StreamDebug(cstate.ua_session, stream_id, "PRIORITY - dep: %d, weight: %d, excl: %d, tree size: %d",
  917.                     priority.stream_dependency, priority.weight, priority.exclusive_flag, cstate.dependency_tree->size());
  918.  
  919.    Http2DependencyTree::Node *node = cstate.dependency_tree->find(stream_id);
  920.  
  921.    if (node != nullptr) {
  922.      // [RFC 7540] 5.3.3 Reprioritization
  923. -    DebugHttp2Stream(cstate.ua_session, stream_id, "Reprioritize");
  924. +    Http2StreamDebug(cstate.ua_session, stream_id, "Reprioritize");
  925.      cstate.dependency_tree->reprioritize(node, priority.stream_dependency, priority.exclusive_flag);
  926.    } else {
  927.      // PRIORITY frame is received before HEADERS frame.
  928. @@ -425,7 +425,7 @@ rcv_rst_stream_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  929.    char *end;
  930.    const Http2StreamId stream_id = frame.header().streamid;
  931.  
  932. -  DebugHttp2Stream(cstate.ua_session, frame.header().streamid, "Received RST_STREAM frame");
  933. +  Http2StreamDebug(cstate.ua_session, frame.header().streamid, "Received RST_STREAM frame");
  934.  
  935.    // RST_STREAM frames MUST be associated with a stream.  If a RST_STREAM
  936.    // frame is received with a stream identifier of 0x0, the recipient MUST
  937. @@ -468,7 +468,7 @@ rcv_rst_stream_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  938.    }
  939.  
  940.    if (stream != nullptr) {
  941. -    DebugHttp2Stream(cstate.ua_session, stream_id, "RST_STREAM: Error Code: %u", rst_stream.error_code);
  942. +    Http2StreamDebug(cstate.ua_session, stream_id, "RST_STREAM: Error Code: %u", rst_stream.error_code);
  943.  
  944.      cstate.delete_stream(stream);
  945.    }
  946. @@ -484,7 +484,7 @@ rcv_settings_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  947.    unsigned nbytes               = 0;
  948.    const Http2StreamId stream_id = frame.header().streamid;
  949.  
  950. -  DebugHttp2Stream(cstate.ua_session, stream_id, "Received SETTINGS frame");
  951. +  Http2StreamDebug(cstate.ua_session, stream_id, "Received SETTINGS frame");
  952.  
  953.    // [RFC 7540] 6.5. The stream identifier for a SETTINGS frame MUST be zero.
  954.    // If an endpoint receives a SETTINGS frame whose stream identifier field is
  955. @@ -533,7 +533,7 @@ rcv_settings_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  956.        }
  957.      }
  958.  
  959. -    DebugHttp2Stream(cstate.ua_session, stream_id, "   %s : %u", Http2DebugNames::get_settings_param_name(param.id), param.value);
  960. +    Http2StreamDebug(cstate.ua_session, stream_id, "   %s : %u", Http2DebugNames::get_settings_param_name(param.id), param.value);
  961.  
  962.      // [RFC 7540] 6.9.2. When the value of SETTINGS_INITIAL_WINDOW_SIZE
  963.      // changes, a receiver MUST adjust the size of all stream flow control
  964. @@ -557,7 +557,7 @@ rcv_settings_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  965.  static Http2Error
  966.  rcv_push_promise_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  967.  {
  968. -  DebugHttp2Stream(cstate.ua_session, frame.header().streamid, "Received PUSH_PROMISE frame");
  969. +  Http2StreamDebug(cstate.ua_session, frame.header().streamid, "Received PUSH_PROMISE frame");
  970.  
  971.    // [RFC 7540] 8.2. A client cannot push. Thus, servers MUST treat the receipt of a
  972.    // PUSH_PROMISE frame as a connection error of type PROTOCOL_ERROR.
  973. @@ -571,7 +571,7 @@ rcv_ping_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  974.    uint8_t opaque_data[HTTP2_PING_LEN];
  975.    const Http2StreamId stream_id = frame.header().streamid;
  976.  
  977. -  DebugHttp2Stream(cstate.ua_session, stream_id, "Received PING frame");
  978. +  Http2StreamDebug(cstate.ua_session, stream_id, "Received PING frame");
  979.  
  980.    //  If a PING frame is received with a stream identifier field value other
  981.    //  than 0x0, the recipient MUST respond with a connection error of type
  982. @@ -608,7 +608,7 @@ rcv_goaway_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  983.    unsigned nbytes               = 0;
  984.    const Http2StreamId stream_id = frame.header().streamid;
  985.  
  986. -  DebugHttp2Stream(cstate.ua_session, stream_id, "Received GOAWAY frame");
  987. +  Http2StreamDebug(cstate.ua_session, stream_id, "Received GOAWAY frame");
  988.  
  989.    // An endpoint MUST treat a GOAWAY frame with a stream identifier other
  990.    // than 0x0 as a connection error of type PROTOCOL_ERROR.
  991. @@ -626,7 +626,7 @@ rcv_goaway_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  992.      }
  993.    }
  994.  
  995. -  DebugHttp2Stream(cstate.ua_session, stream_id, "GOAWAY: last stream id=%d, error code=%d", goaway.last_streamid,
  996. +  Http2StreamDebug(cstate.ua_session, stream_id, "GOAWAY: last stream id=%d, error code=%d", goaway.last_streamid,
  997.                     static_cast<int>(goaway.error_code));
  998.  
  999.    cstate.handleEvent(HTTP2_SESSION_EVENT_FINI, nullptr);
  1000. @@ -645,7 +645,7 @@ rcv_window_update_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  1001.    //  A WINDOW_UPDATE frame with a length other than 4 octets MUST be
  1002.    //  treated as a connection error of type FRAME_SIZE_ERROR.
  1003.    if (frame.header().length != HTTP2_WINDOW_UPDATE_LEN) {
  1004. -    DebugHttp2Stream(cstate.ua_session, stream_id, "Received WINDOW_UPDATE frame - length incorrect");
  1005. +    Http2StreamDebug(cstate.ua_session, stream_id, "Received WINDOW_UPDATE frame - length incorrect");
  1006.      return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_FRAME_SIZE_ERROR,
  1007.                        "window update bad length");
  1008.    }
  1009. @@ -667,7 +667,7 @@ rcv_window_update_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  1010.  
  1011.    if (stream_id == 0) {
  1012.      // Connection level window update
  1013. -    DebugHttp2Stream(cstate.ua_session, stream_id, "Received WINDOW_UPDATE frame - updated to: %zd delta: %u",
  1014. +    Http2StreamDebug(cstate.ua_session, stream_id, "Received WINDOW_UPDATE frame - updated to: %zd delta: %u",
  1015.                       (cstate.client_rwnd + size), size);
  1016.  
  1017.      // A sender MUST NOT allow a flow-control window to exceed 2^31-1
  1018. @@ -697,7 +697,7 @@ rcv_window_update_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  1019.        }
  1020.      }
  1021.  
  1022. -    DebugHttp2Stream(cstate.ua_session, stream_id, "Received WINDOW_UPDATE frame - updated to: %zd delta: %u",
  1023. +    Http2StreamDebug(cstate.ua_session, stream_id, "Received WINDOW_UPDATE frame - updated to: %zd delta: %u",
  1024.                       (stream->client_rwnd + size), size);
  1025.  
  1026.      // A sender MUST NOT allow a flow-control window to exceed 2^31-1
  1027. @@ -713,7 +713,7 @@ rcv_window_update_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  1028.      }
  1029.  
  1030.      stream->client_rwnd += size;
  1031. -    ssize_t wnd = min(cstate.client_rwnd, stream->client_rwnd);
  1032. +    ssize_t wnd = std::min(cstate.client_rwnd, stream->client_rwnd);
  1033.  
  1034.      if (!stream->is_closed() && stream->get_state() == Http2StreamState::HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE && wnd > 0) {
  1035.        stream->send_response_body();
  1036. @@ -736,7 +736,7 @@ rcv_continuation_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  1037.    const Http2StreamId stream_id = frame.header().streamid;
  1038.    const uint32_t payload_length = frame.header().length;
  1039.  
  1040. -  DebugHttp2Stream(cstate.ua_session, stream_id, "Received CONTINUATION frame");
  1041. +  Http2StreamDebug(cstate.ua_session, stream_id, "Received CONTINUATION frame");
  1042.  
  1043.    if (!http2_is_client_streamid(stream_id)) {
  1044.      return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_PROTOCOL_ERROR,
  1045. @@ -814,7 +814,7 @@ rcv_continuation_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
  1046.      stream->send_request(cstate);
  1047.    } else {
  1048.      // NOTE: Expect another CONTINUATION Frame. Do nothing.
  1049. -    DebugHttp2Stream(cstate.ua_session, stream_id, "No END_HEADERS flag, expecting CONTINUATION frame");
  1050. +    Http2StreamDebug(cstate.ua_session, stream_id, "No END_HEADERS flag, expecting CONTINUATION frame");
  1051.    }
  1052.  
  1053.    return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_NONE);
  1054. @@ -890,7 +890,7 @@ Http2ConnectionState::main_event_handler(int event, void *edata)
  1055.      // [RFC 7540] 5.5. Extending HTTP/2
  1056.      //   Implementations MUST discard frames that have unknown or unsupported types.
  1057.      if (frame->header().type >= HTTP2_FRAME_TYPE_MAX) {
  1058. -      DebugHttp2Stream(ua_session, stream_id, "Discard a frame which has unknown type, type=%x", frame->header().type);
  1059. +      Http2StreamDebug(ua_session, stream_id, "Discard a frame which has unknown type, type=%x", frame->header().type);
  1060.        break;
  1061.      }
  1062.  
  1063. @@ -1067,7 +1067,7 @@ Http2ConnectionState::restart_streams()
  1064.        s = next;
  1065.      }
  1066.      if (!s->is_closed() && s->get_state() == Http2StreamState::HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE &&
  1067. -        min(this->client_rwnd, s->client_rwnd) > 0) {
  1068. +        std::min(this->client_rwnd, s->client_rwnd) > 0) {
  1069.        s->send_response_body();
  1070.      }
  1071.  
  1072. @@ -1100,13 +1100,14 @@ bool
  1073.  Http2ConnectionState::delete_stream(Http2Stream *stream)
  1074.  {
  1075.    ink_assert(nullptr != stream);
  1076. +  SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
  1077.  
  1078.    // If stream has already been removed from the list, just go on
  1079.    if (!stream_list.in(stream)) {
  1080.      return false;
  1081.    }
  1082.  
  1083. -  DebugHttp2Stream(ua_session, stream->get_id(), "Delete stream");
  1084. +  Http2StreamDebug(ua_session, stream->get_id(), "Delete stream");
  1085.  
  1086.    if (Http2::stream_priority_enabled) {
  1087.      Http2DependencyTree::Node *node = stream->priority_node;
  1088. @@ -1115,10 +1116,12 @@ Http2ConnectionState::delete_stream(Http2Stream *stream)
  1089.          dependency_tree->deactivate(node, 0);
  1090.        }
  1091.        dependency_tree->remove(node);
  1092. +      // ink_release_assert(dependency_tree->find(stream->get_id()) == nullptr);
  1093.      }
  1094. +    stream->priority_node = nullptr;
  1095.    }
  1096.  
  1097. -  if (stream->get_state() == Http2StreamState::HTTP2_STREAM_STATE_HALF_CLOSED_LOCAL) {
  1098. +  if (stream->get_state() != Http2StreamState::HTTP2_STREAM_STATE_CLOSED) {
  1099.      send_rst_stream_frame(stream->get_id(), Http2ErrorCode::HTTP2_ERROR_NO_ERROR);
  1100.    }
  1101.  
  1102. @@ -1141,7 +1144,6 @@ Http2ConnectionState::release_stream(Http2Stream *stream)
  1103.        ink_assert(client_streams_out_count > 0);
  1104.        --client_streams_out_count;
  1105.      }
  1106. -    stream_list.remove(stream);
  1107.    }
  1108.  
  1109.    if (ua_session) {
  1110. @@ -1177,7 +1179,7 @@ Http2ConnectionState::update_initial_rwnd(Http2WindowSize new_size)
  1111.  void
  1112.  Http2ConnectionState::schedule_stream(Http2Stream *stream)
  1113.  {
  1114. -  DebugHttp2Stream(ua_session, stream->get_id(), "Scheduled");
  1115. +  Http2StreamDebug(ua_session, stream->get_id(), "Scheduled");
  1116.  
  1117.    Http2DependencyTree::Node *node = stream->priority_node;
  1118.    ink_release_assert(node != nullptr);
  1119. @@ -1205,13 +1207,13 @@ Http2ConnectionState::send_data_frames_depends_on_priority()
  1120.  
  1121.    Http2Stream *stream = static_cast<Http2Stream *>(node->t);
  1122.    ink_release_assert(stream != nullptr);
  1123. -  DebugHttp2Stream(ua_session, stream->get_id(), "top node, point=%d", node->point);
  1124. +  Http2StreamDebug(ua_session, stream->get_id(), "top node, point=%d", node->point);
  1125.  
  1126. -  size_t len                       = 0;
  1127. -  Http2SendADataFrameResult result = send_a_data_frame(stream, len);
  1128. +  size_t len                      = 0;
  1129. +  Http2SendDataFrameResult result = send_a_data_frame(stream, len);
  1130.  
  1131.    switch (result) {
  1132. -  case HTTP2_SEND_A_DATA_FRAME_NO_ERROR: {
  1133. +  case Http2SendDataFrameResult::NO_ERROR: {
  1134.      // No response body to send
  1135.      if (len == 0 && !stream->is_body_done()) {
  1136.        dependency_tree->deactivate(node, len);
  1137. @@ -1220,7 +1222,7 @@ Http2ConnectionState::send_data_frames_depends_on_priority()
  1138.      }
  1139.      break;
  1140.    }
  1141. -  case HTTP2_SEND_A_DATA_FRAME_DONE: {
  1142. +  case Http2SendDataFrameResult::DONE: {
  1143.      dependency_tree->deactivate(node, len);
  1144.      delete_stream(stream);
  1145.      break;
  1146. @@ -1235,12 +1237,12 @@ Http2ConnectionState::send_data_frames_depends_on_priority()
  1147.    return;
  1148.  }
  1149.  
  1150. -Http2SendADataFrameResult
  1151. +Http2SendDataFrameResult
  1152.  Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_length)
  1153.  {
  1154. -  const ssize_t window_size         = min(this->client_rwnd, stream->client_rwnd);
  1155. +  const ssize_t window_size         = std::min(this->client_rwnd, stream->client_rwnd);
  1156.    const size_t buf_len              = BUFFER_SIZE_FOR_INDEX(buffer_size_index[HTTP2_FRAME_TYPE_DATA]);
  1157. -  const size_t write_available_size = min(buf_len, static_cast<size_t>(window_size));
  1158. +  const size_t write_available_size = std::min(buf_len, static_cast<size_t>(window_size));
  1159.    size_t read_available_size        = 0;
  1160.  
  1161.    uint8_t flags = 0x00;
  1162. @@ -1257,7 +1259,7 @@ Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_len
  1163.    if (read_available_size > 0) {
  1164.      // We only need to check for window size when there is a payload
  1165.      if (window_size <= 0) {
  1166. -      return HTTP2_SEND_A_DATA_FRAME_NO_WINDOW;
  1167. +      return Http2SendDataFrameResult::NO_WINDOW;
  1168.      }
  1169.      // Copy into the payload buffer. Seems like we should be able to skip this copy step
  1170.      payload_length = current_reader->read(payload_buffer, write_available_size);
  1171. @@ -1269,7 +1271,7 @@ Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_len
  1172.    // If we return here, we never send the END_STREAM in the case of a early terminating OS.
  1173.    // OK if there is no body yet. Otherwise continue on to send a DATA frame and delete the stream
  1174.    if (!stream->is_body_done() && payload_length == 0) {
  1175. -    return HTTP2_SEND_A_DATA_FRAME_NO_PAYLOAD;
  1176. +    return Http2SendDataFrameResult::NO_PAYLOAD;
  1177.    }
  1178.  
  1179.    if (stream->is_body_done() && read_available_size <= write_available_size) {
  1180. @@ -1281,7 +1283,7 @@ Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_len
  1181.    stream->client_rwnd -= payload_length;
  1182.  
  1183.    // Create frame
  1184. -  DebugHttp2Stream(ua_session, stream->get_id(), "Send a DATA frame - client window con: %zd stream: %zd payload: %zd", client_rwnd,
  1185. +  Http2StreamDebug(ua_session, stream->get_id(), "Send a DATA frame - client window con: %zd stream: %zd payload: %zd", client_rwnd,
  1186.                     stream->client_rwnd, payload_length);
  1187.  
  1188.    Http2Frame data(HTTP2_FRAME_TYPE_DATA, stream->get_id(), flags);
  1189. @@ -1296,47 +1298,45 @@ Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_len
  1190.    this->ua_session->handleEvent(HTTP2_SESSION_EVENT_XMIT, &data);
  1191.  
  1192.    if (flags & HTTP2_FLAGS_DATA_END_STREAM) {
  1193. -    DebugHttp2Stream(ua_session, stream->get_id(), "End of DATA frame");
  1194. +    Http2StreamDebug(ua_session, stream->get_id(), "End of DATA frame");
  1195.      stream->send_end_stream = true;
  1196.      // Setting to the same state shouldn't be erroneous
  1197.      stream->change_state(data.header().type, data.header().flags);
  1198.  
  1199. -    return HTTP2_SEND_A_DATA_FRAME_DONE;
  1200. +    return Http2SendDataFrameResult::DONE;
  1201.    }
  1202.  
  1203. -  return HTTP2_SEND_A_DATA_FRAME_NO_ERROR;
  1204. +  return Http2SendDataFrameResult::NO_ERROR;
  1205.  }
  1206.  
  1207. -void
  1208. +Http2SendDataFrameResult
  1209.  Http2ConnectionState::send_data_frames(Http2Stream *stream)
  1210.  {
  1211.    // To follow RFC 7540 must not send more frames other than priority on
  1212.    // a closed stream.  So we return without sending
  1213.    if (stream->get_state() == Http2StreamState::HTTP2_STREAM_STATE_HALF_CLOSED_LOCAL ||
  1214.        stream->get_state() == Http2StreamState::HTTP2_STREAM_STATE_CLOSED) {
  1215. -    DebugSsn(this->ua_session, "http2_cs", "Shutdown half closed local stream %d", stream->get_id());
  1216. +    Http2StreamDebug(this->ua_session, stream->get_id(), "Shutdown half closed local stream");
  1217.      this->delete_stream(stream);
  1218. -    return;
  1219. +    return Http2SendDataFrameResult::NO_ERROR;
  1220.    }
  1221.  
  1222. -  size_t len = 0;
  1223. -  while (true) {
  1224. -    Http2SendADataFrameResult result = send_a_data_frame(stream, len);
  1225. +  size_t len                      = 0;
  1226. +  Http2SendDataFrameResult result = Http2SendDataFrameResult::NO_ERROR;
  1227. +  while (result == Http2SendDataFrameResult::NO_ERROR) {
  1228. +    result = send_a_data_frame(stream, len);
  1229.  
  1230. -    if (result == HTTP2_SEND_A_DATA_FRAME_DONE) {
  1231. +    if (result == Http2SendDataFrameResult::DONE) {
  1232.        // Delete a stream immediately
  1233.        // TODO its should not be deleted for a several time to handling
  1234.        // RST_STREAM and WINDOW_UPDATE.
  1235.        // See 'closed' state written at [RFC 7540] 5.1.
  1236. -      DebugSsn(this->ua_session, "http2_cs", "Shutdown stream %d", stream->get_id());
  1237. +      Http2StreamDebug(this->ua_session, stream->get_id(), "Shutdown stream");
  1238.        this->delete_stream(stream);
  1239. -      break;
  1240. -    } else if (result == HTTP2_SEND_A_DATA_FRAME_NO_ERROR) {
  1241. -      continue;
  1242. -    } else {
  1243. -      break;
  1244.      }
  1245.    }
  1246. +
  1247. +  return result;
  1248.  }
  1249.  
  1250.  void
  1251. @@ -1351,7 +1351,7 @@ Http2ConnectionState::send_headers_frame(Http2Stream *stream)
  1252.  
  1253.    HTTPHdr *resp_header = &stream->response_header;
  1254.  
  1255. -  DebugHttp2Stream(ua_session, stream->get_id(), "Send HEADERS frame");
  1256. +  Http2StreamDebug(ua_session, stream->get_id(), "Send HEADERS frame");
  1257.  
  1258.    HTTPHdr h2_hdr;
  1259.    http2_generate_h2_header_from_1_1(resp_header, &h2_hdr);
  1260. @@ -1405,9 +1405,9 @@ Http2ConnectionState::send_headers_frame(Http2Stream *stream)
  1261.    // Send CONTINUATION frames
  1262.    flags = 0;
  1263.    while (sent < header_blocks_size) {
  1264. -    DebugHttp2Stream(ua_session, stream->get_id(), "Send CONTINUATION frame");
  1265. -    payload_length = MIN(static_cast<uint32_t>(BUFFER_SIZE_FOR_INDEX(buffer_size_index[HTTP2_FRAME_TYPE_CONTINUATION])),
  1266. -                         header_blocks_size - sent);
  1267. +    Http2StreamDebug(ua_session, stream->get_id(), "Send CONTINUATION frame");
  1268. +    payload_length = std::min(static_cast<uint32_t>(BUFFER_SIZE_FOR_INDEX(buffer_size_index[HTTP2_FRAME_TYPE_CONTINUATION])),
  1269. +                              static_cast<uint32_t>(header_blocks_size - sent));
  1270.      if (sent + payload_length == header_blocks_size) {
  1271.        flags |= HTTP2_FLAGS_CONTINUATION_END_HEADERS;
  1272.      }
  1273. @@ -1441,7 +1441,7 @@ Http2ConnectionState::send_push_promise_frame(Http2Stream *stream, URL &url)
  1274.      return;
  1275.    }
  1276.  
  1277. -  DebugHttp2Stream(ua_session, stream->get_id(), "Send PUSH_PROMISE frame");
  1278. +  Http2StreamDebug(ua_session, stream->get_id(), "Send PUSH_PROMISE frame");
  1279.  
  1280.    h1_hdr.create(HTTP_TYPE_REQUEST);
  1281.    h1_hdr.url_set(&url);
  1282. @@ -1487,9 +1487,9 @@ Http2ConnectionState::send_push_promise_frame(Http2Stream *stream, URL &url)
  1283.    // Send CONTINUATION frames
  1284.    flags = 0;
  1285.    while (sent < header_blocks_size) {
  1286. -    DebugHttp2Stream(ua_session, stream->get_id(), "Send CONTINUATION frame");
  1287. -    payload_length = MIN(static_cast<uint32_t>(BUFFER_SIZE_FOR_INDEX(buffer_size_index[HTTP2_FRAME_TYPE_CONTINUATION])),
  1288. -                         header_blocks_size - sent);
  1289. +    Http2StreamDebug(ua_session, stream->get_id(), "Send CONTINUATION frame");
  1290. +    payload_length = std::min(static_cast<uint32_t>(BUFFER_SIZE_FOR_INDEX(buffer_size_index[HTTP2_FRAME_TYPE_CONTINUATION])),
  1291. +                              static_cast<uint32_t>(header_blocks_size - sent));
  1292.      if (sent + payload_length == header_blocks_size) {
  1293.        flags |= HTTP2_FLAGS_CONTINUATION_END_HEADERS;
  1294.      }
  1295. @@ -1515,7 +1515,7 @@ Http2ConnectionState::send_push_promise_frame(Http2Stream *stream, URL &url)
  1296.      if (node != nullptr) {
  1297.        stream->priority_node = node;
  1298.      } else {
  1299. -      DebugHttp2Stream(this->ua_session, id, "PRIORITY - dep: %d, weight: %d, excl: %d, tree size: %d",
  1300. +      Http2StreamDebug(this->ua_session, id, "PRIORITY - dep: %d, weight: %d, excl: %d, tree size: %d",
  1301.                         HTTP2_PRIORITY_DEFAULT_STREAM_DEPENDENCY, HTTP2_PRIORITY_DEFAULT_WEIGHT, false,
  1302.                         this->dependency_tree->size());
  1303.  
  1304. @@ -1534,7 +1534,7 @@ Http2ConnectionState::send_push_promise_frame(Http2Stream *stream, URL &url)
  1305.  void
  1306.  Http2ConnectionState::send_rst_stream_frame(Http2StreamId id, Http2ErrorCode ec)
  1307.  {
  1308. -  DebugHttp2Stream(ua_session, id, "Send RST_STREAM frame");
  1309. +  Http2StreamDebug(ua_session, id, "Send RST_STREAM frame");
  1310.  
  1311.    if (ec != Http2ErrorCode::HTTP2_ERROR_NO_ERROR) {
  1312.      HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_STREAM_ERRORS_COUNT, this_ethread());
  1313. @@ -1568,7 +1568,7 @@ Http2ConnectionState::send_settings_frame(const Http2ConnectionSettings &new_set
  1314.  {
  1315.    const Http2StreamId stream_id = 0;
  1316.  
  1317. -  DebugHttp2Stream(ua_session, stream_id, "Send SETTINGS frame");
  1318. +  Http2StreamDebug(ua_session, stream_id, "Send SETTINGS frame");
  1319.  
  1320.    Http2Frame settings(HTTP2_FRAME_TYPE_SETTINGS, stream_id, 0);
  1321.    settings.alloc(buffer_size_index[HTTP2_FRAME_TYPE_SETTINGS]);
  1322. @@ -1599,7 +1599,7 @@ Http2ConnectionState::send_settings_frame(const Http2ConnectionSettings &new_set
  1323.        // Update current settings
  1324.        server_settings.set(id, new_settings.get(id));
  1325.  
  1326. -      DebugHttp2Stream(ua_session, stream_id, "  %s : %u", Http2DebugNames::get_settings_param_name(param.id), param.value);
  1327. +      Http2StreamDebug(ua_session, stream_id, "  %s : %u", Http2DebugNames::get_settings_param_name(param.id), param.value);
  1328.      }
  1329.    }
  1330.  
  1331. @@ -1611,7 +1611,7 @@ Http2ConnectionState::send_settings_frame(const Http2ConnectionSettings &new_set
  1332.  void
  1333.  Http2ConnectionState::send_ping_frame(Http2StreamId id, uint8_t flag, const uint8_t *opaque_data)
  1334.  {
  1335. -  DebugHttp2Stream(ua_session, id, "Send PING frame");
  1336. +  Http2StreamDebug(ua_session, id, "Send PING frame");
  1337.  
  1338.    Http2Frame ping(HTTP2_FRAME_TYPE_PING, id, flag);
  1339.  
  1340. @@ -1655,7 +1655,7 @@ Http2ConnectionState::send_goaway_frame(Http2StreamId id, Http2ErrorCode ec)
  1341.  void
  1342.  Http2ConnectionState::send_window_update_frame(Http2StreamId id, uint32_t size)
  1343.  {
  1344. -  DebugHttp2Stream(ua_session, id, "Send WINDOW_UPDATE frame");
  1345. +  Http2StreamDebug(ua_session, id, "Send WINDOW_UPDATE frame");
  1346.  
  1347.    // Create WINDOW_UPDATE frame
  1348.    Http2Frame window_update(HTTP2_FRAME_TYPE_WINDOW_UPDATE, id, 0x0);
  1349. diff --git a/proxy/http2/Http2ConnectionState.h b/proxy/http2/Http2ConnectionState.h
  1350. index ceabb1de6..2bd63a76f 100644
  1351. --- a/proxy/http2/Http2ConnectionState.h
  1352. +++ b/proxy/http2/Http2ConnectionState.h
  1353. @@ -31,11 +31,11 @@
  1354.  
  1355.  class Http2ClientSession;
  1356.  
  1357. -enum Http2SendADataFrameResult {
  1358. -  HTTP2_SEND_A_DATA_FRAME_NO_ERROR   = 0,
  1359. -  HTTP2_SEND_A_DATA_FRAME_NO_WINDOW  = 1,
  1360. -  HTTP2_SEND_A_DATA_FRAME_NO_PAYLOAD = 2,
  1361. -  HTTP2_SEND_A_DATA_FRAME_DONE       = 3,
  1362. +enum class Http2SendDataFrameResult {
  1363. +  NO_ERROR   = 0,
  1364. +  NO_WINDOW  = 1,
  1365. +  NO_PAYLOAD = 2,
  1366. +  DONE       = 3,
  1367.  };
  1368.  
  1369.  class Http2ConnectionSettings
  1370. @@ -234,8 +234,8 @@ public:
  1371.    // HTTP/2 frame sender
  1372.    void schedule_stream(Http2Stream *stream);
  1373.    void send_data_frames_depends_on_priority();
  1374. -  void send_data_frames(Http2Stream *stream);
  1375. -  Http2SendADataFrameResult send_a_data_frame(Http2Stream *stream, size_t &payload_length);
  1376. +  Http2SendDataFrameResult send_data_frames(Http2Stream *stream);
  1377. +  Http2SendDataFrameResult send_a_data_frame(Http2Stream *stream, size_t &payload_length);
  1378.    void send_headers_frame(Http2Stream *stream);
  1379.    void send_push_promise_frame(Http2Stream *stream, URL &url);
  1380.    void send_rst_stream_frame(Http2StreamId id, Http2ErrorCode ec);
  1381. diff --git a/proxy/http2/Http2DependencyTree.h b/proxy/http2/Http2DependencyTree.h
  1382. index f0a569257..39b21659c 100644
  1383. --- a/proxy/http2/Http2DependencyTree.h
  1384. +++ b/proxy/http2/Http2DependencyTree.h
  1385. @@ -118,6 +118,7 @@ public:
  1386.    void activate(Node *node);
  1387.    void deactivate(Node *node, uint32_t sent);
  1388.    void update(Node *node, uint32_t sent);
  1389. +  bool in(Node *current, Node *node);
  1390.    uint32_t size() const;
  1391.  
  1392.  private:
  1393. @@ -201,6 +202,7 @@ Tree<T>::add(uint32_t parent_id, uint32_t id, uint32_t weight, bool exclusive, T
  1394.  
  1395.    parent->children.push(node);
  1396.    if (!node->queue->empty()) {
  1397. +    ink_release_assert(!node->queued);
  1398.      parent->queue->push(node->entry);
  1399.      node->queued = true;
  1400.    }
  1401. @@ -210,6 +212,27 @@ Tree<T>::add(uint32_t parent_id, uint32_t id, uint32_t weight, bool exclusive, T
  1402.  }
  1403.  
  1404.  template <typename T>
  1405. +bool
  1406. +Tree<T>::in(Node *current, Node *node)
  1407. +{
  1408. +  bool retval = false;
  1409. +  if (current == nullptr)
  1410. +    current = _root;
  1411. +  if (current->queue->in(node->entry)) {
  1412. +    return true;
  1413. +  } else {
  1414. +    Node *child = current->children.head;
  1415. +    while (child) {
  1416. +      if (in(child, node)) {
  1417. +        return true;
  1418. +      }
  1419. +      child = child->link.next;
  1420. +    }
  1421. +  }
  1422. +  return retval;
  1423. +}
  1424. +
  1425. +template <typename T>
  1426.  void
  1427.  Tree<T>::remove(Node *node)
  1428.  {
  1429. @@ -241,6 +264,8 @@ Tree<T>::remove(Node *node)
  1430.      remove(parent);
  1431.    }
  1432.  
  1433. +  // ink_release_assert(!this->in(nullptr, node));
  1434. +
  1435.    --_node_count;
  1436.    delete node;
  1437.  }
  1438. diff --git a/proxy/http2/Http2Stream.cc b/proxy/http2/Http2Stream.cc
  1439. index dc30e7800..7b5ed4a21 100644
  1440. --- a/proxy/http2/Http2Stream.cc
  1441. +++ b/proxy/http2/Http2Stream.cc
  1442. @@ -26,6 +26,9 @@
  1443.  #include "Http2ClientSession.h"
  1444.  #include "../http/HttpSM.h"
  1445.  
  1446. +#define Http2StreamDebug(fmt, ...) \
  1447. +  DebugSsn(parent, "http2_stream", "[%" PRId64 "] [%u] " fmt, parent->connection_id(), this->get_id(), ##__VA_ARGS__);
  1448. +
  1449.  ClassAllocator<Http2Stream> http2StreamAllocator("http2StreamAllocator");
  1450.  
  1451.  int
  1452. @@ -123,9 +126,7 @@ Http2Stream::main_event_handler(int event, void *edata)
  1453.    }
  1454.    reentrancy_count--;
  1455.    // Clean stream up if the terminate flag is set and we are at the bottom of the handler stack
  1456. -  if (terminate_stream && reentrancy_count == 0) {
  1457. -    destroy();
  1458. -  }
  1459. +  terminate_if_possible();
  1460.  
  1461.    return 0;
  1462.  }
  1463. @@ -263,7 +264,7 @@ Http2Stream::change_state(uint8_t type, uint8_t flags)
  1464.      return false;
  1465.    }
  1466.  
  1467. -  Debug("http2_stream", "%s", Http2DebugNames::get_state_name(_state));
  1468. +  Http2StreamDebug("%s", Http2DebugNames::get_state_name(_state));
  1469.  
  1470.    return true;
  1471.  }
  1472. @@ -314,26 +315,32 @@ void
  1473.  Http2Stream::do_io_close(int /* flags */)
  1474.  {
  1475.    SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
  1476. -  super::release(nullptr);
  1477. +
  1478.    if (!closed) {
  1479. -    Debug("http2_stream", "do_io_close stream %d", this->get_id());
  1480. +    if (parent && this->is_client_state_writeable()) {
  1481. +      // Make sure any trailing end of stream frames are sent
  1482. +      // Wee will be removed at send_data_frames or closing connection phase
  1483. +      Http2SendDataFrameResult result = static_cast<Http2ClientSession *>(parent)->connection_state.send_data_frames(this);
  1484. +      if (result == Http2SendDataFrameResult::NO_WINDOW) {
  1485. +        Http2StreamDebug("cancel closing");
  1486. +        return;
  1487. +      } else {
  1488. +        Http2StreamDebug("continue closing");
  1489. +      }
  1490. +    }
  1491.  
  1492.      // When we get here, the SM has initiated the shutdown.  Either it received a WRITE_COMPLETE, or it is shutting down.  Any
  1493.      // remaining IO operations back to client should be abandoned.  The SM-side buffers backing these operations will be deleted
  1494.      // by the time this is called from transaction_done.
  1495.      closed = true;
  1496.  
  1497. -    if (parent && this->is_client_state_writeable()) {
  1498. -      // Make sure any trailing end of stream frames are sent
  1499. -      // Wee will be removed at send_data_frames or closing connection phase
  1500. -      static_cast<Http2ClientSession *>(parent)->connection_state.send_data_frames(this);
  1501. -    }
  1502. -
  1503.      clear_timers();
  1504.      clear_io_events();
  1505.  
  1506.      // Wait until transaction_done is called from HttpSM to signal that the TXN_CLOSE hook has been executed
  1507.    }
  1508. +
  1509. +  super::release(nullptr);
  1510.  }
  1511.  
  1512.  /*
  1513. @@ -358,9 +365,18 @@ Http2Stream::transaction_done()
  1514.      ink_assert(cross_thread_event == nullptr);
  1515.      // Schedule the destroy to occur after we unwind here.  IF we call directly, may delete with reference on the stack.
  1516.      terminate_stream = true;
  1517. -    if (terminate_stream && reentrancy_count == 0) {
  1518. -      destroy();
  1519. -    }
  1520. +    terminate_if_possible();
  1521. +  }
  1522. +}
  1523. +
  1524. +void
  1525. +Http2Stream::terminate_if_possible()
  1526. +{
  1527. +  if (terminate_stream && reentrancy_count == 0) {
  1528. +    Http2ClientSession *h2_parent = static_cast<Http2ClientSession *>(parent);
  1529. +    SCOPED_MUTEX_LOCK(lock, h2_parent->connection_state.mutex, this_ethread());
  1530. +    h2_parent->connection_state.delete_stream(this);
  1531. +    destroy();
  1532.    }
  1533.  }
  1534.  
  1535. @@ -370,7 +386,7 @@ Http2Stream::initiating_close()
  1536.  {
  1537.    if (!closed) {
  1538.      SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
  1539. -    Debug("http2_stream", "initiating_close stream %d", this->get_id());
  1540. +    Http2StreamDebug("initiating_close");
  1541.  
  1542.      // Set the state of the connection to closed
  1543.      // TODO - these states should be combined
  1544. @@ -398,11 +414,11 @@ Http2Stream::initiating_close()
  1545.          SCOPED_MUTEX_LOCK(lock, write_vio.mutex, this_ethread());
  1546.          // Are we done?
  1547.          if (write_vio.nbytes == write_vio.ndone) {
  1548. -          Debug("http2_stream", "handle write from destroy stream=%d event=%d", this->_id, VC_EVENT_WRITE_COMPLETE);
  1549. +          Http2StreamDebug("handle write from destroy (event=%d)", VC_EVENT_WRITE_COMPLETE);
  1550.            write_event = send_tracked_event(write_event, VC_EVENT_WRITE_COMPLETE, &write_vio);
  1551.          } else {
  1552.            write_event = send_tracked_event(write_event, VC_EVENT_EOS, &write_vio);
  1553. -          Debug("http2_stream", "handle write from destroy stream=%d event=%d", this->_id, VC_EVENT_EOS);
  1554. +          Http2StreamDebug("handle write from destroy (event=%d)", VC_EVENT_EOS);
  1555.          }
  1556.          sent_write_complete = true;
  1557.        }
  1558. @@ -412,7 +428,7 @@ Http2Stream::initiating_close()
  1559.        // Only bother with the EOS if we haven't sent the write complete
  1560.        if (!sent_write_complete) {
  1561.          SCOPED_MUTEX_LOCK(lock, read_vio.mutex, this_ethread());
  1562. -        Debug("http2_stream", "send EOS to read cont stream=%d", this->_id);
  1563. +        Http2StreamDebug("send EOS to read cont");
  1564.          read_event = send_tracked_event(read_event, VC_EVENT_EOS, &read_vio);
  1565.        }
  1566.      } else if (current_reader) {
  1567. @@ -607,7 +623,7 @@ Http2Stream::update_write_request(IOBufferReader *buf_reader, int64_t write_len,
  1568.        }
  1569.      }
  1570.  
  1571. -    Debug("http2_stream", "write update stream_id=%d event=%d", this->get_id(), send_event);
  1572. +    Http2StreamDebug("write update (event=%d)", send_event);
  1573.    }
  1574.  
  1575.    return retval;
  1576. @@ -651,7 +667,7 @@ Http2Stream::reenable(VIO *vio)
  1577.  void
  1578.  Http2Stream::destroy()
  1579.  {
  1580. -  Debug("http2_stream", "Destroy stream %d, sent %" PRIu64 " bytes", this->_id, this->bytes_sent);
  1581. +  Http2StreamDebug("Destroy stream, sent %" PRIu64 " bytes", this->bytes_sent);
  1582.    SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
  1583.    // Clean up after yourself if this was an EOS
  1584.    ink_release_assert(this->closed);
  1585. @@ -659,21 +675,14 @@ Http2Stream::destroy()
  1586.  
  1587.    // Safe to initiate SSN_CLOSE if this is the last stream
  1588.    if (parent) {
  1589. -    // release_stream and delete_stream indirectly call each other and seem to have a lot of commonality
  1590. -    // Should get resolved at somepoint.
  1591.      Http2ClientSession *h2_parent = static_cast<Http2ClientSession *>(parent);
  1592.      SCOPED_MUTEX_LOCK(lock, h2_parent->connection_state.mutex, this_ethread());
  1593. -    h2_parent->connection_state.release_stream(this);
  1594. +    // Make sure the stream is removed from the stream list and priority tree
  1595. +    // In many cases, this has been called earlier, so this call is a no-op
  1596. +    h2_parent->connection_state.delete_stream(this);
  1597.  
  1598. -    // Current Http2ConnectionState implementation uses a memory pool for instantiating streams and DLL<> stream_list for storing
  1599. -    // active streams. Destroying a stream before deleting it from stream_list and then creating a new one + reusing the same chunk
  1600. -    // from the memory pool right away always leads to destroying the DLL structure (deadlocks, inconsistencies).
  1601. -    // The following is meant as a safety net since the consequences are disastrous. Until the design/implementation changes it
  1602. -    // seems
  1603. -    // less error prone to (double) delete before destroying (noop if already deleted).
  1604. -    if (h2_parent->connection_state.delete_stream(this)) {
  1605. -      Warning("Http2Stream was about to be deallocated without removing it from the active stream list");
  1606. -    }
  1607. +    // Update session's stream counts, so it accurately goes into keep-alive state
  1608. +    h2_parent->connection_state.release_stream(this);
  1609.    }
  1610.  
  1611.    // Clean up the write VIO in case of inactivity timeout
  1612. @@ -731,7 +740,7 @@ Http2Stream::response_initialize_data_handling(bool &is_done)
  1613.    int chunked_index = response_header.value_get_index(name, strlen(name), value, strlen(value));
  1614.    // -1 means this value was not found for this field
  1615.    if (chunked_index >= 0) {
  1616. -    Debug("http2_stream", "Response is chunked");
  1617. +    Http2StreamDebug("Response is chunked");
  1618.      chunked = true;
  1619.      this->chunked_handler.init_by_action(this->response_reader, ChunkedHandler::ACTION_DECHUNK);
  1620.      this->chunked_handler.state            = ChunkedHandler::CHUNK_READ_SIZE;
  1621. diff --git a/proxy/http2/Http2Stream.h b/proxy/http2/Http2Stream.h
  1622. index ed28b545c..2261377c6 100644
  1623. --- a/proxy/http2/Http2Stream.h
  1624. +++ b/proxy/http2/Http2Stream.h
  1625. @@ -168,6 +168,7 @@ public:
  1626.    VIO *do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *abuffer, bool owner = false);
  1627.    void do_io_close(int lerrno = -1);
  1628.    void initiating_close();
  1629. +  void terminate_if_possible();
  1630.    void do_io_shutdown(ShutdownHowTo_t) {}
  1631.    void update_read_request(int64_t read_len, bool send_update);
  1632.    bool update_write_request(IOBufferReader *buf_reader, int64_t write_len, bool send_update);
  1633. diff --git a/tools/jtest/jtest.cc b/tools/jtest/jtest.cc
  1634. index 774a6ddff..730a88176 100644
  1635. --- a/tools/jtest/jtest.cc
  1636. +++ b/tools/jtest/jtest.cc
  1637. @@ -516,7 +516,7 @@ max_limit_fd()
  1638.    if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
  1639.  #ifdef OPEN_MAX
  1640.      // Darwin
  1641. -    rl.rlim_cur = MIN(OPEN_MAX, rl.rlim_max);
  1642. +    rl.rlim_cur = std::min(static_cast<rlim_t>(OPEN_MAX), rl.rlim_max);
  1643.  #else
  1644.      rl.rlim_cur = rl.rlim_max;
  1645.  #endif
  1646. @@ -1962,7 +1962,7 @@ compose_all_urls(const char *tag, char *buf, char *start, char *end, int buflen,
  1647.    char old;
  1648.    while ((start = find_href_start(tag, end, buflen - (end - buf)))) {
  1649.      char newurl[512];
  1650. -    end = (char *)find_href_end(start, MIN(buflen - (start - buf), 512 - 10));
  1651. +    end = (char *)find_href_end(start, std::min(static_cast<int>(buflen - (start - buf)), 512 - 10));
  1652.      if (!end) {
  1653.        end = start + strlen(tag);
  1654.        continue;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement