From 820509eadccd94bee9f1c034cad66f7499a12044 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 17 Jan 2015 09:27:05 -0600 Subject: [PATCH] Networking: Fix accept() so that it returns the correct IP address for the selected socket IP domain. --- net/devif/ipv6_input.c | 2 +- net/icmpv6/icmpv6_input.c | 2 +- net/socket/accept.c | 127 +++++++++++++++++++++------------- net/socket/net_close.c | 6 +- net/socket/net_sendfile.c | 6 +- net/socket/recvfrom.c | 10 +-- net/socket/sendto.c | 12 ++-- net/tcp/tcp_send_buffered.c | 12 ++-- net/tcp/tcp_send_unbuffered.c | 12 ++-- 9 files changed, 111 insertions(+), 78 deletions(-) diff --git a/net/devif/ipv6_input.c b/net/devif/ipv6_input.c index c9b3741b75..e190e19118 100644 --- a/net/devif/ipv6_input.c +++ b/net/devif/ipv6_input.c @@ -90,7 +90,7 @@ #include #include -#include "ipv6/ipv6.h" +#include "neighbor/neighbor.h" #include "tcp/tcp.h" #include "udp/udp.h" #include "pkt/pkt.h" diff --git a/net/icmpv6/icmpv6_input.c b/net/icmpv6/icmpv6_input.c index da17c3c60f..22b2d567f1 100644 --- a/net/icmpv6/icmpv6_input.c +++ b/net/icmpv6/icmpv6_input.c @@ -59,7 +59,7 @@ #include "devif/devif.h" #include "utils/utils.h" -#include "ipv6/ipv6.h" +#include "neighbor/neighbor.h" #include "icmpv6/icmpv6.h" #ifdef CONFIG_NET_ICMPv6 diff --git a/net/socket/accept.c b/net/socket/accept.c index 91e8197ed1..9ba43a4b50 100644 --- a/net/socket/accept.c +++ b/net/socket/accept.c @@ -58,7 +58,7 @@ #include "socket/socket.h" /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ /**************************************************************************** @@ -67,14 +67,11 @@ struct accept_s { - sem_t acpt_sem; /* Wait for interrupt event */ -#ifdef CONFIG_NET_IPv6 - FAR struct sockaddr_in6 *acpt_addr; /* Return connection adress */ -#else - FAR struct sockaddr_in *acpt_addr; /* Return connection adress */ -#endif - FAR struct tcp_conn_s *acpt_newconn; /* The accepted connection */ - int acpt_result; /* The result of the wait */ + FAR struct socket *acpt_sock; /* The accepting socket */ + sem_t acpt_sem; /* Wait for interrupt event */ + FAR struct sockaddr *acpt_addr; /* Return connection address */ + FAR struct tcp_conn_s *acpt_newconn; /* The accepted connection */ + int acpt_result; /* The result of the wait */ }; /**************************************************************************** @@ -89,9 +86,10 @@ struct accept_s * Function: accept_tcpsender * * Description: - * Getting the sender's address from the UDP packet + * Get the sender's address from the UDP packet * * Parameters: + * psock - The state structure of the accepting socket * conn - The newly accepted TCP connection * pstate - the recvfrom state structure * @@ -100,33 +98,50 @@ struct accept_s * * Assumptions: * Running at the interrupt level - * +* ****************************************************************************/ #ifdef CONFIG_NET_TCP +static inline void accept_tcpsender(FAR struct socket *psock, + FAR struct tcp_conn_s *conn, + FAR struct sockaddr *addr) +{ + if (addr) + { #ifdef CONFIG_NET_IPv4 -static inline void accept_tcpsender(FAR struct tcp_conn_s *conn, - FAR struct sockaddr_in *addr) -{ - if (addr) - { - addr->sin_family = AF_INET; - addr->sin_port = conn->rport; - net_ipv4addr_copy(addr->sin_addr.s_addr, conn->u.ipv4.raddr); - } -} -#else -static inline void accept_tcpsender(FAR struct tcp_conn_s *conn, - FAR struct sockaddr_in6 *addr) -{ - if (addr) - { - addr->sin_family = AF_INET6; - addr->sin_port = conn->rport; - net_ipv6addr_copy(addr->sin6_addr.s6_addr, conn->u.ipv4.raddr); - } -} +#ifdef CONFIG_NET_IPv6 + /* If both IPv4 and IPv6 support are enabled, then we will need to + * select which one to use when obtaining the sender's IP address. + */ + + if (psock->s_domain == PF_INET) +#endif /* CONFIG_NET_IPv6 */ + { + FAR struct sockaddr_in *inaddr = (FAR struct sockaddr_in *)addr; + + inaddr->sin_family = AF_INET; + inaddr->sin_port = conn->rport; + net_ipv4addr_copy(inaddr->sin_addr.s_addr, conn->u.ipv4.raddr); + } #endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + /* Otherwise, this the IPv6 address is needed */ + + else +#endif /* CONFIG_NET_IPv4 */ + { + FAR struct sockaddr_in6 *inaddr = (FAR struct sockaddr_in6 *)addr; + + DEBUGASSERT(psock->s_domain == PF_INET6); + inaddr->sin_family = AF_INET6; + inaddr->sin_port = conn->rport; + net_ipv6addr_copy(inaddr->sin6_addr.s6_addr, conn->u.ipv6.raddr); + } +#endif /* CONFIG_NET_IPv6 */ + } +} #endif /* CONFIG_NET_TCP */ /**************************************************************************** @@ -157,7 +172,7 @@ static int accept_interrupt(FAR struct tcp_conn_s *listener, { /* Get the connection address */ - accept_tcpsender(conn, pstate->acpt_addr); + accept_tcpsender(pstate->acpt_sock, conn, pstate->acpt_addr); /* Save the connection structure */ @@ -256,17 +271,12 @@ static int accept_interrupt(FAR struct tcp_conn_s *listener, * ****************************************************************************/ -int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) +int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) { FAR struct socket *psock = sockfd_socket(sockfd); FAR struct socket *pnewsock; FAR struct tcp_conn_s *conn; struct accept_s state; -#ifdef CONFIG_NET_IPv6 - FAR struct sockaddr_in6 *inaddr = (struct sockaddr_in6 *)addr; -#else - FAR struct sockaddr_in *inaddr = (struct sockaddr_in *)addr; -#endif net_lock_t save; int newfd; int err; @@ -316,13 +326,35 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) if (addr) { -#ifdef CONFIG_NET_IPv6 - if (*addrlen < sizeof(struct sockaddr_in6)) -#else - if (*addrlen < sizeof(struct sockaddr_in)) -#endif + switch (psock->s_domain) { - err = EBADF; +#ifdef CONFIG_NET_IPv4 + case PF_INET: + { + if (*addrlen < sizeof(struct sockaddr_in)) + { + err = EBADF; + goto errout; + } + } + break; +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 + case PF_INET: + { + if (*addrlen < sizeof(struct sockaddr_in6)) + { + err = EBADF; + goto errout; + } + } + break; +#endif /* CONFIG_NET_IPv6 */ + + default: + DEBUGPANIC(); + err = EINVAL; goto errout; } } @@ -359,7 +391,7 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) /* Yes... get the address of the connected client */ nvdbg("Pending conn=%p\n", state.acpt_newconn); - accept_tcpsender(state.acpt_newconn, inaddr); + accept_tcpsender(psock, state.acpt_newconn, addr); } /* In general, this uIP-based implementation will not support non-blocking @@ -387,7 +419,8 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) * are ready. */ - state.acpt_addr = inaddr; + state.acpt_sock = psock; + state.acpt_addr = addr; state.acpt_newconn = NULL; state.acpt_result = OK; sem_init(&state.acpt_sem, 0, 0); diff --git a/net/socket/net_close.c b/net/socket/net_close.c index 4a8c2d464a..42949baf8a 100644 --- a/net/socket/net_close.c +++ b/net/socket/net_close.c @@ -282,7 +282,7 @@ static inline void netclose_txnotify(FAR struct socket *psock, * the device driver using the appropriate IP domain. */ - if (psock->domain == PF_INET) + if (psock->s_domain == PF_INET) #endif { /* Notify the device driver that send data is available */ @@ -297,12 +297,12 @@ static inline void netclose_txnotify(FAR struct socket *psock, #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 - else /* if (psock->domain == PF_INET6) */ + else /* if (psock->s_domain == PF_INET6) */ #endif /* CONFIG_NET_IPv4 */ { /* Notify the device driver that send data is available */ - DEBUGASSERT(psock->domain == PF_INET6); + DEBUGASSERT(psock->s_domain == PF_INET6); #ifdef CONFIG_NET_MULTILINK netdev_ipv6_txnotify(conn->u.ipv6.laddr, conn->u.ipv6.raddr); #else diff --git a/net/socket/net_sendfile.c b/net/socket/net_sendfile.c index df72cecef7..0432626c5a 100644 --- a/net/socket/net_sendfile.c +++ b/net/socket/net_sendfile.c @@ -411,7 +411,7 @@ static inline void sendfile_txnotify(FAR struct socket *psock, * the device driver using the appropriate IP domain. */ - if (psock->domain == PF_INET) + if (psock->s_domain == PF_INET) #endif { /* Notify the device driver that send data is available */ @@ -426,12 +426,12 @@ static inline void sendfile_txnotify(FAR struct socket *psock, #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 - else /* if (psock->domain == PF_INET6) */ + else /* if (psock->s_domain == PF_INET6) */ #endif /* CONFIG_NET_IPv4 */ { /* Notify the device driver that send data is available */ - DEBUGASSERT(psock->domain == PF_INET6); + DEBUGASSERT(psock->s_domain == PF_INET6); #ifdef CONFIG_NET_MULTILINK netdev_ipv6_txnotify(conn->u.ipv6.laddr, conn->u.ipv6.raddr); #else diff --git a/net/socket/recvfrom.c b/net/socket/recvfrom.c index 4cc8d82755..cf07e69c7c 100644 --- a/net/socket/recvfrom.c +++ b/net/socket/recvfrom.c @@ -1086,7 +1086,7 @@ static inline void recvfrom_udp_rxnotify(FAR struct socket *psock, * the device driver using the appropriate IP domain. */ - if (psock->domain == PF_INET) + if (psock->s_domain == PF_INET) #endif { /* Notify the device driver of the receive ready */ @@ -1101,12 +1101,12 @@ static inline void recvfrom_udp_rxnotify(FAR struct socket *psock, #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 - else /* if (psock->domain == PF_INET6) */ + else /* if (psock->s_domain == PF_INET6) */ #endif /* CONFIG_NET_IPv4 */ { /* Notify the device driver of the receive ready */ - DEBUGASSERT(psock->domain == PF_INET6); + DEBUGASSERT(psock->s_domain == PF_INET6); #ifdef CONFIG_NET_MULTILINK netdev_ipv6_rxnotify(conn->u.ipv6.laddr, conn->u.ipv6.raddr); #else @@ -1226,10 +1226,10 @@ errout_with_state: #ifdef CONFIG_NET_UDP #ifdef CONFIG_NET_IPv6 static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, - FAR struct sockaddr_in6 *infrom ) + FAR struct sockaddr_in6 *infrom) #else static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, - FAR struct sockaddr_in *infrom ) + FAR struct sockaddr_in *infrom) #endif { FAR struct udp_conn_s *conn = (FAR struct udp_conn_s *)psock->s_conn; diff --git a/net/socket/sendto.c b/net/socket/sendto.c index bced1ea825..0b678d1da0 100644 --- a/net/socket/sendto.c +++ b/net/socket/sendto.c @@ -183,17 +183,17 @@ static inline void sendto_ipselect(FAR struct net_driver_s *dev, /* Which domain the the socket support */ - if (psock->domain == PF_INET) + if (psock->s_domain == PF_INET) { /* Select the IPv4 domain */ udp_ipv4_select(dev); } - else /* if (psock->domain == PF_INET6) */ + else /* if (psock->s_domain == PF_INET6) */ { /* Select the IPv6 domain */ - DEBUGASSERT(psock->domain == PF_INET6); + DEBUGASSERT(psock->s_domain == PF_INET6); udp_ipv4_select(dev); } } @@ -319,7 +319,7 @@ static inline void sendto_txnotify(FAR struct socket *psock, * the device driver using the appropriate IP domain. */ - if (psock->domain == PF_INET) + if (psock->s_domain == PF_INET) #endif { /* Notify the device driver that send data is available */ @@ -334,12 +334,12 @@ static inline void sendto_txnotify(FAR struct socket *psock, #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 - else /* if (psock->domain == PF_INET6) */ + else /* if (psock->s_domain == PF_INET6) */ #endif /* CONFIG_NET_IPv4 */ { /* Notify the device driver that send data is available */ - DEBUGASSERT(psock->domain == PF_INET6); + DEBUGASSERT(psock->s_domain == PF_INET6); #ifdef CONFIG_NET_MULTILINK netdev_ipv6_txnotify(conn->u.ipv6.laddr, conn->u.ipv6.raddr); #else diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index ce71c0e0b5..3b53db91b2 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -233,17 +233,17 @@ static inline void send_ipselect(FAR struct net_driver_s *dev, { /* Which domain the the socket support */ - if (psock->domain == PF_INET) + if (psock->s_domain == PF_INET) { /* Select the IPv4 domain */ tcp_ipv4_select(dev); } - else /* if (psock->domain == PF_INET6) */ + else /* if (psock->s_domain == PF_INET6) */ { /* Select the IPv6 domain */ - DEBUGASSERT(psock->domain == PF_INET6); + DEBUGASSERT(psock->s_domain == PF_INET6); tcp_ipv4_select(dev); } } @@ -750,7 +750,7 @@ static inline void send_txnotify(FAR struct socket *psock, * the device driver using the appropriate IP domain. */ - if (psock->domain == PF_INET) + if (psock->s_domain == PF_INET) #endif { /* Notify the device driver that send data is available */ @@ -765,12 +765,12 @@ static inline void send_txnotify(FAR struct socket *psock, #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 - else /* if (psock->domain == PF_INET6) */ + else /* if (psock->s_domain == PF_INET6) */ #endif /* CONFIG_NET_IPv4 */ { /* Notify the device driver that send data is available */ - DEBUGASSERT(psock->domain == PF_INET6); + DEBUGASSERT(psock->s_domain == PF_INET6); #ifdef CONFIG_NET_MULTILINK netdev_ipv6_txnotify(conn->u.ipv6.laddr, conn->u.ipv6.raddr); #else diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index b685838b80..f0156c85ba 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -180,17 +180,17 @@ static inline void tcpsend_ipselect(FAR struct net_driver_s *dev, /* Which domain the the socket support */ - if (psock->domain == PF_INET) + if (psock->s_domain == PF_INET) { /* Select the IPv4 domain */ tcp_ipv4_select(dev); } - else /* if (psock->domain == PF_INET6) */ + else /* if (psock->s_domain == PF_INET6) */ { /* Select the IPv6 domain */ - DEBUGASSERT(psock->domain == PF_INET6); + DEBUGASSERT(psock->s_domain == PF_INET6); tcp_ipv4_select(dev); } } @@ -533,7 +533,7 @@ static inline void send_txnotify(FAR struct socket *psock, * the device driver using the appropriate IP domain. */ - if (psock->domain == PF_INET) + if (psock->s_domain == PF_INET) #endif { /* Notify the device driver that send data is available */ @@ -548,12 +548,12 @@ static inline void send_txnotify(FAR struct socket *psock, #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 - else /* if (psock->domain == PF_INET6) */ + else /* if (psock->s_domain == PF_INET6) */ #endif /* CONFIG_NET_IPv4 */ { /* Notify the device driver that send data is available */ - DEBUGASSERT(psock->domain == PF_INET6); + DEBUGASSERT(psock->s_domain == PF_INET6); #ifdef CONFIG_NET_MULTILINK netdev_ipv6_txnotify(conn->u.ipv6.laddr, conn->u.ipv6.raddr); #else