Networking: Fix accept() so that it returns the correct IP address for the selected socket IP domain.
This commit is contained in:
parent
a90ccb0c1c
commit
820509eadc
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user