Split pbuf flags in pbuf type and flgs.

Improved lwip_recvfrom(). TCP push now propagated.
This commit is contained in:
marcbou 2007-08-16 20:22:15 +00:00
parent 75935ad251
commit 4236699052
5 changed files with 80 additions and 50 deletions

View File

@ -387,15 +387,18 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
{ {
struct lwip_socket *sock; struct lwip_socket *sock;
struct netbuf *buf; struct netbuf *buf;
u16_t buflen, copylen; u16_t buflen, copylen, off = 0;
struct ip_addr *addr; struct ip_addr *addr;
u16_t port; u16_t port;
u8_t done = 0;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags)); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags));
sock = get_socket(s); sock = get_socket(s);
if (!sock) if (!sock)
return -1; return -1;
while ( !done ) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata));
/* Check if there is data left from the last recv operation. */ /* Check if there is data left from the last recv operation. */
if (sock->lastdata) { if (sock->lastdata) {
buf = sock->lastdata; buf = sock->lastdata;
@ -410,6 +413,7 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
/* No data was left from the previous operation, so we try to get /* No data was left from the previous operation, so we try to get
some from the network. */ some from the network. */
sock->lastdata = buf = netconn_recv(sock->conn); sock->lastdata = buf = netconn_recv(sock->conn);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv netbuf=%p\n", buf));
if (!buf) { if (!buf) {
/* We should really do some error checking here. */ /* We should really do some error checking here. */
@ -420,6 +424,7 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
} }
buflen = netbuf_len(buf); buflen = netbuf_len(buf);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%d len=%d off=%d sock->lastoffset=%d\n", buflen, len, off, sock->lastoffset));
buflen -= sock->lastoffset; buflen -= sock->lastoffset;
@ -431,7 +436,36 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
/* copy the contents of the received buffer into /* copy the contents of the received buffer into
the supplied memory pointer mem */ the supplied memory pointer mem */
netbuf_copy_partial(buf, mem, copylen, sock->lastoffset); netbuf_copy_partial(buf, (u8_t*)mem + off, copylen - off, sock->lastoffset);
off += copylen;
if (netconn_type(sock->conn) == NETCONN_TCP) {
len -= copylen;
if ( (len <= 0) || (buf->p->flgs & PBUF_FLAG_PUSH) )
done = 1;
}
else
done = 1;
/* If we don't peek the incoming message... */
if ((flags & MSG_PEEK)==0) {
/* If this is a TCP socket, check if there is data left in the
buffer. If so, it should be saved in the sock structure for next
time around. */
if ((sock->conn->type == NETCONN_TCP) && (buflen - copylen > 0)) {
sock->lastdata = buf;
sock->lastoffset += copylen;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf));
} else {
sock->lastdata = NULL;
sock->lastoffset = 0;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf));
netbuf_delete(buf);
}
} else
done = 1;
} /* while ( !done ) */
/* Check to see from where the data was.*/ /* Check to see from where the data was.*/
if (from && fromlen) { if (from && fromlen) {
@ -453,7 +487,7 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
ip_addr_debug_print(SOCKETS_DEBUG, addr); ip_addr_debug_print(SOCKETS_DEBUG, addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen)); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off));
} else { } else {
#if SOCKETS_DEBUG #if SOCKETS_DEBUG
addr = netbuf_fromaddr(buf); addr = netbuf_fromaddr(buf);
@ -461,27 +495,12 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
ip_addr_debug_print(SOCKETS_DEBUG, addr); ip_addr_debug_print(SOCKETS_DEBUG, addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen)); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off));
#endif #endif
} }
/* If we don't peek the incoming message... */
if ((flags & MSG_PEEK)==0) {
/* If this is a TCP socket, check if there is data left in the
buffer. If so, it should be saved in the sock structure for next
time around. */
if ((sock->conn->type == NETCONN_TCP) && (buflen - copylen > 0)) {
sock->lastdata = buf;
sock->lastoffset += copylen;
} else {
sock->lastdata = NULL;
sock->lastoffset = 0;
netbuf_delete(buf);
}
}
sock_set_errno(sock, 0); sock_set_errno(sock, 0);
return copylen; return off;
} }
int int

View File

@ -146,7 +146,8 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
if (p == NULL) { if (p == NULL) {
return NULL; return NULL;
} }
p->flags = PBUF_FLAG_POOL; p->type = PBUF_TYPE_POOL;
p->flgs = 0;
p->next = NULL; p->next = NULL;
/* make the payload pointer point 'offset' bytes into pbuf data memory */ /* make the payload pointer point 'offset' bytes into pbuf data memory */
@ -179,7 +180,8 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
/* bail out unsuccesfully */ /* bail out unsuccesfully */
return NULL; return NULL;
} }
q->flags = PBUF_FLAG_POOL; q->type = PBUF_TYPE_POOL;
q->flgs = 0;
q->next = NULL; q->next = NULL;
/* make previous pbuf point to this pbuf */ /* make previous pbuf point to this pbuf */
r->next = q; r->next = q;
@ -214,7 +216,8 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)); p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset));
p->len = p->tot_len = length; p->len = p->tot_len = length;
p->next = NULL; p->next = NULL;
p->flags = PBUF_FLAG_RAM; p->type = PBUF_TYPE_RAM;
p->flgs = 0;
LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
@ -234,7 +237,8 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
p->payload = NULL; p->payload = NULL;
p->len = p->tot_len = length; p->len = p->tot_len = length;
p->next = NULL; p->next = NULL;
p->flags = ((flag == PBUF_ROM) ? PBUF_FLAG_ROM : PBUF_FLAG_REF); p->type = ((flag == PBUF_ROM) ? PBUF_TYPE_ROM : PBUF_TYPE_REF);
p->flgs = 0;
break; break;
default: default:
LWIP_ASSERT("pbuf_alloc: erroneous flag", 0); LWIP_ASSERT("pbuf_alloc: erroneous flag", 0);
@ -269,10 +273,10 @@ pbuf_realloc(struct pbuf *p, u16_t new_len)
u16_t rem_len; /* remaining length */ u16_t rem_len; /* remaining length */
s32_t grow; s32_t grow;
LWIP_ASSERT("pbuf_realloc: sane p->flags", p->flags == PBUF_FLAG_POOL || LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_TYPE_POOL ||
p->flags == PBUF_FLAG_ROM || p->type == PBUF_TYPE_ROM ||
p->flags == PBUF_FLAG_RAM || p->type == PBUF_TYPE_RAM ||
p->flags == PBUF_FLAG_REF); p->type == PBUF_TYPE_REF);
/* desired length larger than current length? */ /* desired length larger than current length? */
if (new_len >= p->tot_len) { if (new_len >= p->tot_len) {
@ -302,7 +306,7 @@ pbuf_realloc(struct pbuf *p, u16_t new_len)
/* shrink allocated memory for PBUF_RAM */ /* shrink allocated memory for PBUF_RAM */
/* (other types merely adjust their length fields */ /* (other types merely adjust their length fields */
if ((q->flags == PBUF_FLAG_RAM) && (rem_len != q->len)) { if ((q->type == PBUF_TYPE_RAM) && (rem_len != q->len)) {
/* reallocate and adjust the length of the pbuf that will be split */ /* reallocate and adjust the length of the pbuf that will be split */
mem_realloc(q, (u8_t *)q->payload - (u8_t *)q + rem_len); mem_realloc(q, (u8_t *)q->payload - (u8_t *)q + rem_len);
} }
@ -343,7 +347,7 @@ pbuf_realloc(struct pbuf *p, u16_t new_len)
u8_t u8_t
pbuf_header(struct pbuf *p, s16_t header_size_increment) pbuf_header(struct pbuf *p, s16_t header_size_increment)
{ {
u16_t flags; u16_t type;
void *payload; void *payload;
u16_t increment_magnitude; u16_t increment_magnitude;
@ -361,20 +365,20 @@ pbuf_header(struct pbuf *p, s16_t header_size_increment)
/* Can't assert these as some callers speculatively call /* Can't assert these as some callers speculatively call
pbuf_header() to see if it's OK. Will return 1 below instead. */ pbuf_header() to see if it's OK. Will return 1 below instead. */
/* Check that we've got the correct type of pbuf to work with */ /* Check that we've got the correct type of pbuf to work with */
LWIP_ASSERT("p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_POOL", LWIP_ASSERT("p->type == PBUF_TYPE_RAM || p->type == PBUF_TYPE_POOL",
p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_POOL); p->type == PBUF_TYPE_RAM || p->type == PBUF_TYPE_POOL);
/* Check that we aren't going to move off the beginning of the pbuf */ /* Check that we aren't going to move off the beginning of the pbuf */
LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF", LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF",
(u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF); (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF);
#endif #endif
} }
flags = p->flags; type = p->type;
/* remember current payload pointer */ /* remember current payload pointer */
payload = p->payload; payload = p->payload;
/* pbuf types containing payloads? */ /* pbuf types containing payloads? */
if (flags == PBUF_FLAG_RAM || flags == PBUF_FLAG_POOL) { if (type == PBUF_TYPE_RAM || type == PBUF_TYPE_POOL) {
/* set new payload pointer */ /* set new payload pointer */
p->payload = (u8_t *)p->payload - header_size_increment; p->payload = (u8_t *)p->payload - header_size_increment;
/* boundary check fails? */ /* boundary check fails? */
@ -388,7 +392,7 @@ pbuf_header(struct pbuf *p, s16_t header_size_increment)
return 1; return 1;
} }
/* pbuf types refering to external payloads? */ /* pbuf types refering to external payloads? */
} else if (flags == PBUF_FLAG_REF || flags == PBUF_FLAG_ROM) { } else if (type == PBUF_TYPE_REF || type == PBUF_TYPE_ROM) {
/* hide a header in the payload? */ /* hide a header in the payload? */
if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { if ((header_size_increment < 0) && (increment_magnitude <= p->len)) {
/* increase payload pointer */ /* increase payload pointer */
@ -450,7 +454,7 @@ pbuf_header(struct pbuf *p, s16_t header_size_increment)
u8_t u8_t
pbuf_free(struct pbuf *p) pbuf_free(struct pbuf *p)
{ {
u16_t flags; u16_t type;
struct pbuf *q; struct pbuf *q;
u8_t count; u8_t count;
@ -464,9 +468,9 @@ pbuf_free(struct pbuf *p)
PERF_START; PERF_START;
LWIP_ASSERT("pbuf_free: sane flags", LWIP_ASSERT("pbuf_free: sane type",
p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_ROM || p->type == PBUF_TYPE_RAM || p->type == PBUF_TYPE_ROM ||
p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_POOL); p->type == PBUF_TYPE_REF || p->type == PBUF_TYPE_POOL);
count = 0; count = 0;
/* de-allocate all consecutive pbufs from the head of the chain that /* de-allocate all consecutive pbufs from the head of the chain that
@ -488,14 +492,14 @@ pbuf_free(struct pbuf *p)
/* remember next pbuf in chain for next iteration */ /* remember next pbuf in chain for next iteration */
q = p->next; q = p->next;
LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: deallocating %p\n", (void *)p)); LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: deallocating %p\n", (void *)p));
flags = p->flags; type = p->type;
/* is this a pbuf from the pool? */ /* is this a pbuf from the pool? */
if (flags == PBUF_FLAG_POOL) { if (type == PBUF_TYPE_POOL) {
memp_free(MEMP_PBUF_POOL, p); memp_free(MEMP_PBUF_POOL, p);
/* is this a ROM or RAM referencing pbuf? */ /* is this a ROM or RAM referencing pbuf? */
} else if (flags == PBUF_FLAG_ROM || flags == PBUF_FLAG_REF) { } else if (type == PBUF_TYPE_ROM || type == PBUF_TYPE_REF) {
memp_free(MEMP_PBUF, p); memp_free(MEMP_PBUF, p);
/* flags == PBUF_FLAG_RAM */ /* type == PBUF_TYPE_RAM */
} else { } else {
mem_free(p); mem_free(p);
} }

View File

@ -301,6 +301,8 @@ tcp_input(struct pbuf *p, struct netif *inp)
} }
if (recv_data != NULL) { if (recv_data != NULL) {
if(flags & TCP_PSH)
recv_data->flgs |= PBUF_FLAG_PUSH;
/* Notify application that data has been received. */ /* Notify application that data has been received. */
TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
} }

View File

@ -59,11 +59,13 @@ typedef enum {
/* Definitions for the pbuf flag field. These are NOT the flags that /* Definitions for the pbuf flag field. These are NOT the flags that
* are passed to pbuf_alloc(). */ * are passed to pbuf_alloc(). */
#define PBUF_FLAG_RAM 0x00U /* Flags that pbuf data is stored in RAM */ #define PBUF_TYPE_RAM 0x00U /* pbuf data is stored in RAM */
#define PBUF_FLAG_ROM 0x01U /* Flags that pbuf data is stored in ROM */ #define PBUF_TYPE_ROM 0x01U /* pbuf data is stored in ROM */
#define PBUF_FLAG_POOL 0x02U /* Flags that the pbuf comes from the pbuf pool */ #define PBUF_TYPE_POOL 0x02U /* pbuf comes from the pbuf pool */
#define PBUF_FLAG_REF 0x04U /* Flags thet the pbuf payload refers to RAM */ #define PBUF_TYPE_REF 0x04U /* pbuf payload refers to RAM */
/** indicates this packet's data should be immediately passed to the application */
#define PBUF_FLAG_PUSH 0x40U
/** indicates this packet was broadcast on the link */ /** indicates this packet was broadcast on the link */
#define PBUF_FLAG_LINK_BROADCAST 0x80U #define PBUF_FLAG_LINK_BROADCAST 0x80U
@ -86,8 +88,11 @@ struct pbuf {
/** length of this buffer */ /** length of this buffer */
u16_t len; u16_t len;
/** flags telling the type of pbuf, see PBUF_FLAG_ */ /** type of pbuf, see PBUF_TYPE_ */
u16_t flags; u8_t type;
/** misc flags */
u8_t flgs;
/** /**
* the reference count always equals the number of pointers * the reference count always equals the number of pointers

View File

@ -936,7 +936,7 @@ etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
p = q; p = q;
while (p) { while (p) {
LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0));
if(p->flags != PBUF_FLAG_ROM) { if(p->type != PBUF_TYPE_ROM) {
copy_needed = 1; copy_needed = 1;
break; break;
} }