diff --git a/CHANGELOG b/CHANGELOG index 3188dc5a..8f0f5ba3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,10 @@ HISTORY ++ New features: + 2010-05-02: Simon Goldschmidt + * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending + UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1 + 2010-04-30: Simon Goldschmidt * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that take a precalculated checksum, added pbuf_fill_chksum() to copy data diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 2ebe730d..36d25573 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -180,8 +180,11 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, const struct ip_hdr* iphdr = ip_current_header(); /* get the UDP header - always in the first pbuf, ensured by udp_input */ const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr)); +#if LWIP_CHECKSUM_ON_COPY + buf->flags = NETBUF_FLAG_DESTADDR; +#endif /* LWIP_CHECKSUM_ON_COPY */ buf->toaddr = (ip_addr_t*)&iphdr->dest; - buf->toport = udphdr->dest; + buf->toport_chksum = udphdr->dest; } #endif /* LWIP_NETBUF_RECVINFO */ } @@ -1091,11 +1094,22 @@ do_send(struct api_msg_msg *msg) #endif #if LWIP_UDP case NETCONN_UDP: +#if LWIP_CHECKSUM_ON_COPY + if (msg->msg.b->addr == NULL) { + msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } else { + msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, + msg->msg.b->addr, msg->msg.b->port, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } +#else /* LWIP_CHECKSUM_ON_COPY */ if (msg->msg.b->addr == NULL) { msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); } else { msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port); } +#endif /* LWIP_CHECKSUM_ON_COPY */ break; #endif /* LWIP_UDP */ default: diff --git a/src/api/netbuf.c b/src/api/netbuf.c index f6c898fd..d2d2e42e 100644 --- a/src/api/netbuf.c +++ b/src/api/netbuf.c @@ -63,10 +63,15 @@ netbuf *netbuf_new(void) buf->ptr = NULL; buf->addr = NULL; buf->port = 0; +#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY +#if LWIP_CHECKSUM_ON_COPY + buf->flags = 0; +#endif /* LWIP_CHECKSUM_ON_COPY */ + buf->toport_chksum = 0; #if LWIP_NETBUF_RECVINFO buf->toaddr = NULL; - buf->toport = 0; #endif /* LWIP_NETBUF_RECVINFO */ +#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ return buf; } else { return NULL; diff --git a/src/api/sockets.c b/src/api/sockets.c index 386d5d7e..8d9adb34 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -52,6 +52,9 @@ #include "lwip/udp.h" #include "lwip/tcpip.h" #include "lwip/pbuf.h" +#if LWIP_CHECKSUM_ON_COPY +#include "lwip/inet_chksum.h" +#endif #include @@ -823,6 +826,12 @@ lwip_sendto(int s, const void *data, size_t size, int flags, #if LWIP_NETIF_TX_SINGLE_PBUF p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM); if (p != NULL) { +#if LWIP_CHECKSUM_ON_COPY + u16_t chksum = 0; + if (sock->conn->type != NETCONN_RAW) { + chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ MEMCPY(p->payload, data, size); #else /* LWIP_NETIF_TX_SINGLE_PBUF */ p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_REF); @@ -836,7 +845,13 @@ lwip_sendto(int s, const void *data, size_t size, int flags, if (sock->conn->type == NETCONN_RAW) { err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, &remote_addr); } else { - err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p, &remote_addr, ntohs(to_in->sin_port)); +#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF + err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p, + &remote_addr, ntohs(to_in->sin_port), 1, chksum); +#else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ + err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p, + &remote_addr, ntohs(to_in->sin_port)); +#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ } UNLOCK_TCPIP_CORE(); @@ -848,16 +863,19 @@ lwip_sendto(int s, const void *data, size_t size, int flags, #else /* initialize a buffer */ buf.p = buf.ptr = NULL; +#if LWIP_CHECKSUM_ON_COPY + buf.flags = 0; +#endif /* LWIP_CHECKSUM_ON_COPY */ if (to) { inet_addr_to_ipaddr(&remote_addr, &to_in->sin_addr); - remote_port = ntohs(to_in->sin_port); - buf.addr = &remote_addr; - buf.port = remote_port; + remote_port = ntohs(to_in->sin_port); + netbuf_fromaddr(&buf) = &remote_addr; + netbuf_fromport(&buf) = remote_port; } else { ip_addr_set_zero(&remote_addr); - remote_port = 0; - buf.addr = NULL; - buf.port = 0; + remote_port = 0; + netbuf_fromaddr(&buf) = NULL; + netbuf_fromport(&buf) = 0; } LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%d"U16_F", flags=0x%x to=", @@ -871,7 +889,16 @@ lwip_sendto(int s, const void *data, size_t size, int flags, if (netbuf_alloc(&buf, short_size) == NULL) { err = ERR_MEM; } else { - err = netbuf_take(&buf, data, short_size); +#if LWIP_CHECKSUM_ON_COPY + if (sock->conn->type != NETCONN_RAW) { + u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); + netbuf_set_chksum(&buf, chksum); + err = ERR_OK; + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + err = netbuf_take(&buf, data, short_size); + } } #else /* LWIP_NETIF_TX_SINGLE_PBUF */ err = netbuf_ref(&buf, data, short_size); diff --git a/src/include/lwip/netbuf.h b/src/include/lwip/netbuf.h index 86e4f1d3..d6f2655a 100644 --- a/src/include/lwip/netbuf.h +++ b/src/include/lwip/netbuf.h @@ -40,14 +40,24 @@ extern "C" { #endif +/** This netbuf has dest-addr/port set */ +#define NETBUF_FLAG_DESTADDR 0x01 +/** This netbuf includes a checksum */ +#define NETBUF_FLAG_CHKSUM 0x02 + struct netbuf { struct pbuf *p, *ptr; ip_addr_t *addr; u16_t port; +#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY +#if LWIP_CHECKSUM_ON_COPY + u8_t flags; +#endif /* LWIP_CHECKSUM_ON_COPY */ + u16_t toport_chksum; #if LWIP_NETBUF_RECVINFO - u16_t toport; ip_addr_t *toaddr; #endif /* LWIP_NETBUF_RECVINFO */ +#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ }; /* Network buffer functions: */ @@ -56,12 +66,12 @@ void netbuf_delete (struct netbuf *buf); void * netbuf_alloc (struct netbuf *buf, u16_t size); void netbuf_free (struct netbuf *buf); err_t netbuf_ref (struct netbuf *buf, - const void *dataptr, u16_t size); + const void *dataptr, u16_t size); void netbuf_chain (struct netbuf *head, struct netbuf *tail); err_t netbuf_data (struct netbuf *buf, - void **dataptr, u16_t *len); + void **dataptr, u16_t *len); s8_t netbuf_next (struct netbuf *buf); void netbuf_first (struct netbuf *buf); @@ -75,8 +85,12 @@ void netbuf_first (struct netbuf *buf); #define netbuf_fromport(buf) ((buf)->port) #if LWIP_NETBUF_RECVINFO #define netbuf_destaddr(buf) ((buf)->toaddr) -#define netbuf_destport(buf) ((buf)->toport) +#define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) #endif /* LWIP_NETBUF_RECVINFO */ +#if LWIP_CHECKSUM_ON_COPY +#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \ + (buf)->toport_chksum = chksum; } while(0) +#endif /* LWIP_CHECKSUM_ON_COPY */ #ifdef __cplusplus }