diff --git a/CHANGELOG b/CHANGELOG index 3f28fa19..bb3edc83 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,14 @@ HISTORY ++ New features: + 2007-11-03 Frédéric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP & + RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled + by default). Netconn API users can use the netconn_recv_bufsize macro to access + it. This is a first release which have to be improve for TCP. Note it used the + netconn::recv_avail which need to be more "thread-safe" (note there is already + the problem for FIONREAD with lwip_ioctl/ioctlsocket). + 2007-11-01 Frédéric Bernon, Marc Chaland * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api diff --git a/src/api/api_lib.c b/src/api/api_lib.c index 273ad1c5..50926738 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -89,6 +89,9 @@ netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, #if LWIP_SO_RCVTIMEO conn->recv_timeout = 0; #endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + conn->recv_bufsize = INT_MAX; +#endif /* LWIP_SO_RCVBUF */ msg.function = do_newconn; msg.msg.msg.n.proto = proto; diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 1510cc9e..16f8d28f 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -69,7 +69,12 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, conn = arg; +#if LWIP_SO_RCVBUF + if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) && + (((int)(conn->recv_avail) + (int)(p->tot_len)) <= conn->recv_bufsize)) { +#else /* LWIP_SO_RCVBUF */ if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) { +#endif /* LWIP_SO_RCVBUF */ buf = memp_malloc(MEMP_NETBUF); if (buf == NULL) { return 0; @@ -108,7 +113,12 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, conn = arg; +#if LWIP_SO_RCVBUF + if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) || + (((int)(conn->recv_avail) + (int)(p->tot_len)) > conn->recv_bufsize)) { +#else /* LWIP_SO_RCVBUF */ if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) { +#endif /* LWIP_SO_RCVBUF */ pbuf_free(p); return; } @@ -340,6 +350,9 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) #if LWIP_SO_RCVTIMEO newconn->recv_timeout = 0; #endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + newconn->recv_bufsize = INT_MAX; +#endif /* LWIP_SO_RCVBUF */ sys_mbox_post(conn->acceptmbox, newconn); return ERR_OK; diff --git a/src/api/sockets.c b/src/api/sockets.c index 06affdcd..029dc20f 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -1041,11 +1041,13 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) case SO_KEEPALIVE: /* UNIMPL case SO_CONTIMEO: */ /* UNIMPL case SO_SNDTIMEO: */ -#if LWIP_SO_RCVTIMEO +#if LWIP_SO_RCVTIMEO case SO_RCVTIMEO: #endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: +#endif /* LWIP_SO_RCVBUF */ /* UNIMPL case SO_OOBINLINE: */ - /* UNIMPL case SO_RCVBUF: */ /* UNIMPL case SO_SNDBUF: */ /* UNIMPL case SO_RCVLOWAT: */ /* UNIMPL case SO_SNDLOWAT: */ @@ -1275,6 +1277,11 @@ lwip_getsockopt_internal(void *arg) *(int *)optval = sock->conn->recv_timeout; break; #endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + *(int *)optval = sock->conn->recv_bufsize; + break; +#endif /* LWIP_SO_RCVBUF */ #if LWIP_UDP case SO_NO_CHECK: *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0; @@ -1399,8 +1406,10 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt #if LWIP_SO_RCVTIMEO case SO_RCVTIMEO: #endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: +#endif /* LWIP_SO_RCVBUF */ /* UNIMPL case SO_OOBINLINE: */ - /* UNIMPL case SO_RCVBUF: */ /* UNIMPL case SO_SNDBUF: */ /* UNIMPL case SO_RCVLOWAT: */ /* UNIMPL case SO_SNDLOWAT: */ @@ -1613,6 +1622,11 @@ lwip_setsockopt_internal(void *arg) sock->conn->recv_timeout = ( *(int*)optval ); break; #endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + sock->conn->recv_bufsize = ( *(int*)optval ); + break; +#endif /* LWIP_SO_RCVBUF */ #if LWIP_UDP case SO_NO_CHECK: if (*(int*)optval) { diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index 70aecd26..39debe08 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -114,6 +114,9 @@ struct netconn { #if LWIP_SO_RCVTIMEO int recv_timeout; #endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + int recv_bufsize; +#endif /* LWIP_SO_RCVBUF */ u16_t recv_avail; /** TCP: when data passed to netconn_write doesn't fit into the send buffer, this temporarily stores the message. */ @@ -176,7 +179,8 @@ err_t netconn_join_leave_group (struct netconn *conn, enum netconn_igmp join_or_leave); #endif /* LWIP_IGMP */ -#define netconn_err(conn) ((conn)->err) +#define netconn_err(conn) ((conn)->err) +#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) #ifdef __cplusplus } diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 0fc2a891..fbb8a392 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -927,6 +927,13 @@ #define LWIP_SO_RCVTIMEO 0 #endif +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#ifndef LWIP_SO_RCVBUF +#define LWIP_SO_RCVBUF 0 +#endif + /** * SO_REUSE==1: Enable SO_REUSEADDR and SO_REUSEPORT options. DO NOT USE! */