From 0a1fd09459d5e95d5a3a73e4b243a02f9534cda7 Mon Sep 17 00:00:00 2001
From: Our Air Quality <info@ourairquality.org>
Date: Fri, 8 Sep 2017 10:48:44 +1000
Subject: [PATCH] lwip: revise ooseq handling.

Modified for lwip backwards compatibility based on upstream feedback.
---
 lwip/esp_interface.c    | 23 ++++++++++++++++-----
 lwip/include/arch/cc.h  |  5 +++--
 lwip/include/lwipopts.h | 45 +++++++++++++++++++++++++++++++++--------
 lwip/lwip               |  2 +-
 4 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/lwip/esp_interface.c b/lwip/esp_interface.c
index d241db4..8157c8b 100644
--- a/lwip/esp_interface.c
+++ b/lwip/esp_interface.c
@@ -47,6 +47,7 @@
 #include <lwip/snmp.h>
 #include "lwip/ip.h"
 #include "lwip/ethip6.h"
+#include "lwip/priv/tcp_priv.h"
 #include "netif/etharp.h"
 #include "sysparam.h"
 #include "netif/ppp/pppoe.h"
@@ -143,7 +144,7 @@ low_level_output(struct netif *netif, struct pbuf *p)
  * Keep account of the number the PP RX pool buffers being used in lwip,
  * to help make decision about the number of OOSEQ buffers to maintain etc.
  */
-uint32_t pp_rx_pool_usage;
+volatile uint32_t pp_rx_pool_usage;
 
 /* Support for recycling a pbuf from the sdk rx pool, and accounting for the
  * number of these used in lwip. */
@@ -165,11 +166,17 @@ void pp_recycle_rx_pbuf(struct pbuf *p)
 
 /* Return the number of ooseq bytes that can be retained given the current
  * size 'n'. */
-size_t ooseq_max_bytes(size_t n)
+size_t ooseq_bytes_limit(struct tcp_seg *ooseq)
 {
 #if COPY_PP_RX_PBUFS
+    size_t ooseq_blen = 0;
+    for (; ooseq != NULL; ooseq = ooseq->next) {
+        struct pbuf *p = ooseq->p;
+        ooseq_blen += p->tot_len;
+    }
+
     size_t free = xPortGetFreeHeapSize();
-    ssize_t target = ((ssize_t)free - 8000) + n;
+    ssize_t target = ((ssize_t)free - 8000) + ooseq_blen;
 
     if (target < 0) {
         target = 0;
@@ -185,8 +192,14 @@ size_t ooseq_max_bytes(size_t n)
 
 /* Return the number of ooseq pbufs that can be retained given the current
  * size 'n'. */
-size_t ooseq_max_pbufs(size_t n)
+size_t ooseq_pbufs_limit(struct tcp_seg *ooseq)
 {
+    size_t ooseq_qlen = 0;
+    for (; ooseq != NULL; ooseq = ooseq->next) {
+        struct pbuf *p = ooseq->p;
+        ooseq_qlen += pbuf_clen(p);
+    }
+
 #if COPY_PP_RX_PBUFS
     /* More likely memory limited, but set some limit. */
     ssize_t limit = 10;
@@ -196,7 +209,7 @@ size_t ooseq_max_pbufs(size_t n)
 #endif
 
     size_t usage = pp_rx_pool_usage;
-    ssize_t target = limit - ((ssize_t)usage - n);
+    ssize_t target = limit - ((ssize_t)usage - ooseq_qlen);
 
     if (target < 0) {
         target = 0;
diff --git a/lwip/include/arch/cc.h b/lwip/include/arch/cc.h
index ce40e64..ed169ea 100644
--- a/lwip/include/arch/cc.h
+++ b/lwip/include/arch/cc.h
@@ -48,8 +48,9 @@ void sdk_system_pp_recycle_rx_pkt(struct esf_buf *);
 struct pbuf;
 void pp_recycle_rx_pbuf(struct pbuf *);
 
-size_t ooseq_max_bytes(size_t n);
-size_t ooseq_max_pbufs(size_t n);
+struct tcp_seg;
+size_t ooseq_bytes_limit(struct tcp_seg *ooseq);
+size_t ooseq_pbufs_limit(struct tcp_seg *ooseq);
 
 /* Define generic types used in lwIP */
 typedef uint8_t    u8_t;
diff --git a/lwip/include/lwipopts.h b/lwip/include/lwipopts.h
index 7869d85..4d69eda 100644
--- a/lwip/include/lwipopts.h
+++ b/lwip/include/lwipopts.h
@@ -125,6 +125,19 @@
  */
 #define MEM_ALIGNMENT           4
 
+/**
+ * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable
+ * amount of bytes before and after each memp element in every pool and fills
+ * it with a prominent default value.
+ *    MEMP_OVERFLOW_CHECK == 0 no checking
+ *    MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed
+ *    MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time
+ *      memp_malloc() or memp_free() is called (useful but slow!)
+ */
+#ifndef MEMP_OVERFLOW_CHECK
+#define MEMP_OVERFLOW_CHECK             0
+#endif
+
 /*
    ------------------------------------------------
    ---------- Internal Memory Pool Sizes ----------
@@ -326,21 +339,37 @@
 #endif
 
 /**
- * TCP_OOSEQ_MAX_BYTES(n):
- * Return the maximum number of bytes to be queued on ooseq per pcb, given the
- * current number queued on a pcb.  Only valid for TCP_QUEUE_OOSEQ==1.
+ * TCP_OOSEQ_MAX_BYTES: The default maximum number of bytes queued on ooseq per
+ * pcb if TCP_OOSEQ_BYTES_LIMIT is not defined. Default is 0 (no limit).
+ * Only valid for TCP_QUEUE_OOSEQ==1.
  */
 #ifndef TCP_OOSEQ_MAX_BYTES
-#define TCP_OOSEQ_MAX_BYTES(n)           ooseq_max_bytes(n)
+#define TCP_OOSEQ_MAX_BYTES             (2 * TCP_MSS)
 #endif
 
 /**
- * TCP_OOSEQ_MAX_PBUFS(n):
- * Return the maximum number of pbufs to be queued on ooseq per pcb, given the
- * current number queued on a pcb.  Only valid for TCP_QUEUE_OOSEQ==1.
+ * TCP_OOSEQ_BYTES_LIMIT(ooseq): Return the maximum number of bytes to be queued
+ * on ooseq per pcb, given the pcb.  Only valid for TCP_QUEUE_OOSEQ==1.
+ */
+#if !defined TCP_OOSEQ_BYTES_LIMIT
+#define TCP_OOSEQ_BYTES_LIMIT(ooseq)    ooseq_bytes_limit(ooseq)
+#endif
+
+/**
+ * TCP_OOSEQ_MAX_PBUFS: The default maximum number of pbufs queued on ooseq per
+ * pcb if TCP_OOSEQ_BYTES_LIMIT is not defined. Default is 0 (no limit).
+ * Only valid for TCP_QUEUE_OOSEQ==1.
  */
 #ifndef TCP_OOSEQ_MAX_PBUFS
-#define TCP_OOSEQ_MAX_PBUFS(n)          ooseq_max_pbufs(n)
+#define TCP_OOSEQ_MAX_PBUFS             2
+#endif
+
+/**
+ * TCP_OOSEQ_PBUFS_LIMIT(ooseq): Return the maximum number of pbufs to be queued
+ * on ooseq per pcb, given the pcb.  Only valid for TCP_QUEUE_OOSEQ==1.
+ */
+#ifndef TCP_OOSEQ_PBUFS_LIMIT
+#define TCP_OOSEQ_PBUFS_LIMIT(ooseq)        ooseq_pbufs_limit(ooseq)
 #endif
 
 /**
diff --git a/lwip/lwip b/lwip/lwip
index bb66be5..ecafdf0 160000
--- a/lwip/lwip
+++ b/lwip/lwip
@@ -1 +1 @@
-Subproject commit bb66be5a47e47faa4d3aa572299ceaac216de000
+Subproject commit ecafdf0e5d399c610f5c2f777949d2b5fec8d0ca