|
|
@@ -229,7 +229,7 @@ tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length,
|
|
|
LWIP_UNUSED_ARG(apiflags);
|
|
|
LWIP_UNUSED_ARG(first_seg);
|
|
|
/* always create MSS-sized pbufs */
|
|
|
- alloc = pcb->mss;
|
|
|
+ alloc = max_length;
|
|
|
#else /* LWIP_NETIF_TX_SINGLE_PBUF */
|
|
|
if (length < max_length) {
|
|
|
/* Should we allocate an oversized pbuf, or just the minimum
|
|
|
@@ -369,6 +369,8 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|
|
u16_t concat_chksummed = 0;
|
|
|
#endif /* TCP_CHECKSUM_ON_COPY */
|
|
|
err_t err;
|
|
|
+ /* don't allocate segments bigger than half the maximum window we ever received */
|
|
|
+ u16_t mss_local = LWIP_MIN(pcb->mss, pcb->snd_wnd_max/2);
|
|
|
|
|
|
#if LWIP_NETIF_TX_SINGLE_PBUF
|
|
|
/* Always copy to try to create single pbufs for TX */
|
|
|
@@ -427,7 +429,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|
|
|
|
|
/* Usable space at the end of the last unsent segment */
|
|
|
unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags);
|
|
|
- space = pcb->mss - (last_unsent->len + unsent_optlen);
|
|
|
+ space = mss_local - (last_unsent->len + unsent_optlen);
|
|
|
|
|
|
/*
|
|
|
* Phase 1: Copy data directly into an oversized pbuf.
|
|
|
@@ -520,7 +522,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|
|
while (pos < len) {
|
|
|
struct pbuf *p;
|
|
|
u16_t left = len - pos;
|
|
|
- u16_t max_len = pcb->mss - optlen;
|
|
|
+ u16_t max_len = mss_local - optlen;
|
|
|
u16_t seglen = left > max_len ? max_len : left;
|
|
|
#if TCP_CHECKSUM_ON_COPY
|
|
|
u16_t chksum = 0;
|
|
|
@@ -530,7 +532,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|
|
if (apiflags & TCP_WRITE_FLAG_COPY) {
|
|
|
/* If copy is set, memory should be allocated and data copied
|
|
|
* into pbuf */
|
|
|
- if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, pcb->mss, &oversize, pcb, apiflags, queue == NULL)) == NULL) {
|
|
|
+ if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) {
|
|
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
|
|
|
goto memerr;
|
|
|
}
|
|
|
@@ -1062,7 +1064,6 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
|
|
|
|
|
/* Add any requested options. NB MSS option is only set on SYN
|
|
|
packets, so ignore it here */
|
|
|
- //LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
|
|
|
opts = (u32_t *)(void *)(seg->tcphdr + 1);
|
|
|
if (seg->flags & TF_SEG_OPTS_MSS) {
|
|
|
*opts = TCP_BUILD_MSS_OPTION(pcb->mss);
|