From e07d71f5e8212ca9ca4634b1516f8c5f24b0a8e9 Mon Sep 17 00:00:00 2001 From: fbernon Date: Thu, 13 Mar 2008 20:03:57 +0000 Subject: [PATCH] sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a TCP connection caused a crash. Note that using (lwip_)recvfrom like this is a bit slow and that using (lwip)getpeername is the good lwip way to do it (so, using recv is faster on tcp sockets). --- CHANGELOG | 7 +++++++ src/api/sockets.c | 22 +++++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 740e4973..75fd6115 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -600,6 +600,13 @@ HISTORY ++ Bug fixes: + 2008-03-13 Frédéric Bernon + * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using + (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a + TCP connection caused a crash. Note that using (lwip_)recvfrom + like this is a bit slow and that using (lwip)getpeername is the + good lwip way to do it (so, using recv is faster on tcp sockets). + 2008-03-12 Frédéric Bernon, Jonathan Larmour * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's recv_raw() does not consume data", and the ping sample (with diff --git a/src/api/sockets.c b/src/api/sockets.c index bc7dbef5..88fec436 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -549,8 +549,13 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags, if (from && fromlen) { struct sockaddr_in sin; - addr = netbuf_fromaddr(buf); - port = netbuf_fromport(buf); + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = (struct ip_addr*)&(sin.sin_addr.s_addr); + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr(buf); + port = netbuf_fromport(buf); + } memset(&sin, 0, sizeof(sin)); sin.sin_len = sizeof(sin); @@ -568,13 +573,20 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags, LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off)); } else { #if SOCKETS_DEBUG - addr = netbuf_fromaddr(buf); - port = netbuf_fromport(buf); + struct sockaddr_in sin; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = (struct ip_addr*)&(sin.sin_addr.s_addr); + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr(buf); + port = netbuf_fromport(buf); + } LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); ip_addr_debug_print(SOCKETS_DEBUG, addr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off)); -#endif +#endif /* SOCKETS_DEBUG */ } sock_set_errno(sock, 0);