diff --git a/src/core/pbuf.c b/src/core/pbuf.c index b596b3d7..405673f2 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -617,7 +617,6 @@ pbuf_clen(struct pbuf *p) } /** - * * Increment the reference count of the pbuf. * * @param p pbuf to increase reference counter of @@ -636,20 +635,16 @@ pbuf_ref(struct pbuf *p) } /** - * - * Chain two pbufs (or pbuf chains) together. They must belong to the same packet. - * - * @param h head pbuf (chain) - * @param t tail pbuf (chain) - * @note May not be called on a packet queue. - * - * The ->tot_len fields of all pbufs of the head chain are adjusted. - * The ->next field of the last pbuf of the head chain is adjusted. - * The ->ref field of the first pbuf of the tail chain is adjusted. - * + * Concatenate two pbufs (each may be a pbuf chain) and take over + * the reference of the tail pbuf. + * + * @note The caller MAY NOT reference the tail pbuf afterwards. + * + * @see pbuf_chain() */ + void -pbuf_chain(struct pbuf *h, struct pbuf *t) +pbuf_cat(struct pbuf *h, struct pbuf *t) { struct pbuf *p; @@ -670,9 +665,29 @@ pbuf_chain(struct pbuf *h, struct pbuf *t) p->tot_len += t->tot_len; /* chain last pbuf of head (p) with first of tail (t) */ p->next = t; +} + +/** + * Chain two pbufs (or pbuf chains) together. They must belong to the same packet. + * It's the same as pbuf_cat with the addition that it increases the reference count + * of the tail. + * + * @param h head pbuf (chain) + * @param t tail pbuf (chain) + * @note May not be called on a packet queue. + * + * The ->tot_len fields of all pbufs of the head chain are adjusted. + * The ->next field of the last pbuf of the head chain is adjusted. + * The ->ref field of the first pbuf of the tail chain is adjusted. + * + */ +void +pbuf_chain(struct pbuf *h, struct pbuf *t) +{ + pbuf_cat(h, t); /* t is now referenced to one more time */ pbuf_ref(t); - LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)p, (void *)t)); + LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); } /* For packet queueing. Note that queued packets must be dequeued first diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 741e6156..bb025e68 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -1013,8 +1013,7 @@ tcp_receive(struct tcp_pcb *pcb) /* Chain this pbuf onto the pbuf that we will pass to the application. */ if (recv_data) { - pbuf_chain(recv_data, cseg->p); - pbuf_free(cseg->p); + pbuf_cat(recv_data, cseg->p); } else { recv_data = cseg->p; } diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index 0ba851ed..f8f4b9c1 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -210,9 +210,8 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, } ++queuelen; - /* Chain the headers and data pbufs together. */ - pbuf_chain(seg->p, p); - pbuf_free(p); + /* Concatenate the headers and data pbufs together. */ + pbuf_cat(seg->p, p); p = NULL; } @@ -286,11 +285,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, useg->len + queue->len <= pcb->mss) { /* Remove TCP header from first segment. */ pbuf_header(queue->p, -TCP_HLEN); - pbuf_chain(useg->p, queue->p); - /* Free buffer which was merged. Note that the previous pbuf_chain call - * will have incremented the ref count, so here the ref count will still - * be 1 for the 1 pointer still being used on this buffer. */ - pbuf_free(queue->p); + pbuf_cat(useg->p, queue->p); useg->len += queue->len; useg->next = queue->next; diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h index 3c755f7e..24685025 100644 --- a/src/include/lwip/pbuf.h +++ b/src/include/lwip/pbuf.h @@ -108,6 +108,7 @@ void pbuf_ref(struct pbuf *p); void pbuf_ref_chain(struct pbuf *p); u8_t pbuf_free(struct pbuf *p); u8_t pbuf_clen(struct pbuf *p); +void pbuf_cat(struct pbuf *h, struct pbuf *t); void pbuf_chain(struct pbuf *h, struct pbuf *t); struct pbuf *pbuf_take(struct pbuf *f); struct pbuf *pbuf_dechain(struct pbuf *p); diff --git a/src/netif/ppp/ppp.c b/src/netif/ppp/ppp.c index 263e8fb2..d94e54ee 100644 --- a/src/netif/ppp/ppp.c +++ b/src/netif/ppp/ppp.c @@ -1480,14 +1480,12 @@ static void pppInProc(int pd, u_char *s, int l) pc->inTail->tot_len = pc->inTail->len; if (pc->inTail != pc->inHead) { - pbuf_chain(pc->inHead, pc->inTail); - pbuf_free(pc->inTail); + pbuf_cat(pc->inHead, pc->inTail); } } else { pc->inTail->tot_len = pc->inTail->len; if (pc->inTail != pc->inHead) { - pbuf_chain(pc->inHead, pc->inTail); - pbuf_free(pc->inTail); + pbuf_cat(pc->inHead, pc->inTail); } pbuf_realloc(pc->inHead, pc->inHead->tot_len - 2); @@ -1583,8 +1581,7 @@ static void pppInProc(int pd, u_char *s, int l) if(pc->inTail) { pc->inTail->tot_len = pc->inTail->len; if (pc->inTail != pc->inHead) { - pbuf_chain(pc->inHead, pc->inTail); - pbuf_free(pc->inTail); + pbuf_cat(pc->inHead, pc->inTail); } } /* If we haven't started a packet, we need a packet header. */ diff --git a/src/netif/ppp/vj.c b/src/netif/ppp/vj.c index 15c77af0..7615bb5b 100644 --- a/src/netif/ppp/vj.c +++ b/src/netif/ppp/vj.c @@ -611,8 +611,7 @@ int vj_uncompress_tcp( *nb = NULL; goto bad; } - pbuf_chain(np, n0); - pbuf_free(n0); + pbuf_cat(np, n0); n0 = np; } LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen); diff --git a/src/netif/slipif.c b/src/netif/slipif.c index 53c20237..97618517 100644 --- a/src/netif/slipif.c +++ b/src/netif/slipif.c @@ -145,8 +145,7 @@ slipif_input( struct netif * netif ) } if (q != NULL) { - pbuf_chain(q, p); - pbuf_free(p); + pbuf_cat(q, p); } else { q = p; }