Networking: Fix accept() so that it returns the correct IP address for the selected socket IP domain.

This commit is contained in:
Gregory Nutt 2015-01-17 09:27:05 -06:00
parent a90ccb0c1c
commit 820509eadc
9 changed files with 111 additions and 78 deletions

View File

@ -90,7 +90,7 @@
#include <nuttx/net/netstats.h>
#include <nuttx/net/ip.h>
#include "ipv6/ipv6.h"
#include "neighbor/neighbor.h"
#include "tcp/tcp.h"
#include "udp/udp.h"
#include "pkt/pkt.h"

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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