TCP networking: Add support for network driver events
This commit is contained in:
parent
ab50e9d04d
commit
04a661a97c
@ -193,8 +193,11 @@
|
|||||||
|
|
||||||
/* The set of events that and implications to the TCP connection state */
|
/* The set of events that and implications to the TCP connection state */
|
||||||
|
|
||||||
#define TCP_CONN_EVENTS (TCP_CLOSE | TCP_ABORT | TCP_CONNECTED | \
|
#define TCP_CONN_EVENTS \
|
||||||
TCP_TIMEDOUT | NETDEV_DOWN)
|
(TCP_CLOSE | TCP_ABORT | TCP_CONNECTED | TCP_TIMEDOUT | NETDEV_DOWN)
|
||||||
|
|
||||||
|
#define TCP_DISCONN_EVENTS \
|
||||||
|
(TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT | NETDEV_DOWN)
|
||||||
|
|
||||||
/* IPv4/IPv6 Helpers */
|
/* IPv4/IPv6 Helpers */
|
||||||
|
|
||||||
|
@ -68,9 +68,11 @@ extern "C"
|
|||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* List of registered Ethernet device drivers */
|
|
||||||
|
|
||||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
|
/* List of registered Ethernet device drivers. This duplicates a declaration
|
||||||
|
* in net/netdev/netdev.h
|
||||||
|
*/
|
||||||
|
|
||||||
EXTERN struct net_driver_s *g_netdevices;
|
EXTERN struct net_driver_s *g_netdevices;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ static inline int psock_setup_callbacks(FAR struct socket *psock,
|
|||||||
/* Set up the connection "interrupt" handler */
|
/* Set up the connection "interrupt" handler */
|
||||||
|
|
||||||
pstate->tc_cb->flags = (TCP_NEWDATA | TCP_CLOSE | TCP_ABORT |
|
pstate->tc_cb->flags = (TCP_NEWDATA | TCP_CLOSE | TCP_ABORT |
|
||||||
TCP_TIMEDOUT | TCP_CONNECTED);
|
TCP_TIMEDOUT | TCP_CONNECTED | NETDEV_DOWN);
|
||||||
pstate->tc_cb->priv = (void*)pstate;
|
pstate->tc_cb->priv = (void*)pstate;
|
||||||
pstate->tc_cb->event = psock_connect_interrupt;
|
pstate->tc_cb->event = psock_connect_interrupt;
|
||||||
|
|
||||||
@ -227,11 +227,20 @@ static uint16_t psock_connect_interrupt(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
else if ((flags & TCP_TIMEDOUT) != 0)
|
else if ((flags & TCP_TIMEDOUT) != 0)
|
||||||
{
|
{
|
||||||
/* Indicate that the remote host is unreachable (or should this be timedout?) */
|
/* Indicate that the connection timedout?)*/
|
||||||
|
|
||||||
pstate->tc_result = -ETIMEDOUT;
|
pstate->tc_result = -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if ((flags & NETDEV_DOWN) != 0)
|
||||||
|
{
|
||||||
|
/* The network device went down. Indicate that the remote host
|
||||||
|
* is unreachable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pstate->tc_result = -ENETUNREACH;
|
||||||
|
}
|
||||||
|
|
||||||
/* TCP_CONNECTED: The socket is successfully connected */
|
/* TCP_CONNECTED: The socket is successfully connected */
|
||||||
|
|
||||||
else if ((flags & TCP_CONNECTED) != 0)
|
else if ((flags & TCP_CONNECTED) != 0)
|
||||||
|
@ -167,12 +167,14 @@ static uint16_t netclose_interrupt(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
nllvdbg("conn: %p flags: %04x\n", conn, flags);
|
nllvdbg("conn: %p flags: %04x\n", conn, flags);
|
||||||
|
|
||||||
/* TCP_CLOSE: The remote host has closed the connection
|
/* TCP_DISCONN_EVENTS:
|
||||||
* TCP_ABORT: The remote host has aborted the connection
|
* TCP_CLOSE: The remote host has closed the connection
|
||||||
* TCP_TIMEDOUT: The remote did not respond, the connection timed out
|
* TCP_ABORT: The remote host has aborted the connection
|
||||||
|
* TCP_TIMEDOUT: The remote did not respond, the connection timed out
|
||||||
|
* NETDEV_DOWN: The network device went down
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT)) != 0)
|
if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||||
{
|
{
|
||||||
/* The disconnection is complete */
|
/* The disconnection is complete */
|
||||||
|
|
||||||
@ -371,8 +373,7 @@ static inline int netclose_disconnect(FAR struct socket *psock)
|
|||||||
{
|
{
|
||||||
/* Set up to receive TCP data event callbacks */
|
/* Set up to receive TCP data event callbacks */
|
||||||
|
|
||||||
state.cl_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_CLOSE | TCP_ABORT |
|
state.cl_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_DISCONN_EVENTS);
|
||||||
TCP_TIMEDOUT);
|
|
||||||
state.cl_cb->event = netclose_interrupt;
|
state.cl_cb->event = netclose_interrupt;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_SOLINGER
|
#ifdef CONFIG_NET_SOLINGER
|
||||||
|
@ -89,9 +89,11 @@ static void connection_event(FAR struct tcp_conn_s *conn, uint16_t flags)
|
|||||||
{
|
{
|
||||||
nllvdbg("flags: %04x s_flags: %02x\n", flags, psock->s_flags);
|
nllvdbg("flags: %04x s_flags: %02x\n", flags, psock->s_flags);
|
||||||
|
|
||||||
/* TCP_CLOSE, TCP_ABORT, or TCP_TIMEDOUT: Loss-of-connection events */
|
/* TCP_DISCONN_EVENTS: TCP_CLOSE, TCP_ABORT, TCP_TIMEDOUT, or
|
||||||
|
* NETDEV_DOWN. All loss-of-connection events.
|
||||||
|
*/
|
||||||
|
|
||||||
if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT)) != 0)
|
if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||||
{
|
{
|
||||||
net_lostconnection(psock, flags);
|
net_lostconnection(psock, flags);
|
||||||
}
|
}
|
||||||
@ -218,6 +220,7 @@ void net_lostconnection(FAR struct socket *psock, uint16_t flags)
|
|||||||
* TCP_CLOSE: The remote host has closed the connection
|
* TCP_CLOSE: The remote host has closed the connection
|
||||||
* TCP_ABORT: The remote host has aborted the connection
|
* TCP_ABORT: The remote host has aborted the connection
|
||||||
* TCP_TIMEDOUT: Connection aborted due to too many retransmissions.
|
* TCP_TIMEDOUT: Connection aborted due to too many retransmissions.
|
||||||
|
* NETDEV_DOWN: The network device went down
|
||||||
*
|
*
|
||||||
* And we need to set these two socket status bits appropriately:
|
* And we need to set these two socket status bits appropriately:
|
||||||
*
|
*
|
||||||
@ -237,7 +240,7 @@ void net_lostconnection(FAR struct socket *psock, uint16_t flags)
|
|||||||
psock->s_flags &= ~_SF_CONNECTED;
|
psock->s_flags &= ~_SF_CONNECTED;
|
||||||
psock->s_flags |= _SF_CLOSED;
|
psock->s_flags |= _SF_CLOSED;
|
||||||
}
|
}
|
||||||
else if ((flags & (TCP_ABORT | TCP_TIMEDOUT)) != 0)
|
else if ((flags & (TCP_ABORT | TCP_TIMEDOUT | NETDEV_DOWN)) != 0)
|
||||||
{
|
{
|
||||||
/* The loss of connection was less than graceful. This will (eventually)
|
/* The loss of connection was less than graceful. This will (eventually)
|
||||||
* be reported as an ENOTCONN error.
|
* be reported as an ENOTCONN error.
|
||||||
|
@ -217,7 +217,7 @@ static uint16_t ack_interrupt(FAR struct net_driver_s *dev, FAR void *pvconn,
|
|||||||
|
|
||||||
/* Check for a loss of connection */
|
/* Check for a loss of connection */
|
||||||
|
|
||||||
else if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT)) != 0)
|
else if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||||
{
|
{
|
||||||
/* Report not connected */
|
/* Report not connected */
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvcon
|
|||||||
|
|
||||||
/* Check for a loss of connection */
|
/* Check for a loss of connection */
|
||||||
|
|
||||||
if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT)) != 0)
|
if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||||
{
|
{
|
||||||
/* Report not connected */
|
/* Report not connected */
|
||||||
|
|
||||||
@ -707,8 +707,7 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
|
|||||||
|
|
||||||
/* Set up the ACK callback in the connection */
|
/* Set up the ACK callback in the connection */
|
||||||
|
|
||||||
state.snd_ackcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_CLOSE |
|
state.snd_ackcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_DISCONN_EVENTS);
|
||||||
TCP_ABORT | TCP_TIMEDOUT);
|
|
||||||
state.snd_ackcb->priv = (void*)&state;
|
state.snd_ackcb->priv = (void*)&state;
|
||||||
state.snd_ackcb->event = ack_interrupt;
|
state.snd_ackcb->event = ack_interrupt;
|
||||||
|
|
||||||
|
@ -804,12 +804,14 @@ static uint16_t recvfrom_tcpinterrupt(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
/* Check for a loss of connection.
|
/* Check for a loss of connection.
|
||||||
*
|
*
|
||||||
* TCP_CLOSE: The remote host has closed the connection
|
* TCP_DISCONN_EVENTS:
|
||||||
* TCP_ABORT: The remote host has aborted the connection
|
* TCP_CLOSE: The remote host has closed the connection
|
||||||
* TCP_TIMEDOUT: Connection aborted due to too many retransmissions.
|
* TCP_ABORT: The remote host has aborted the connection
|
||||||
|
* TCP_TIMEDOUT: Connection aborted due to too many retransmissions.
|
||||||
|
* NETDEV_DOWN: The network device went down
|
||||||
*/
|
*/
|
||||||
|
|
||||||
else if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT)) != 0)
|
else if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||||
{
|
{
|
||||||
nllvdbg("Lost connection\n");
|
nllvdbg("Lost connection\n");
|
||||||
|
|
||||||
@ -1692,8 +1694,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||||||
state.rf_cb = tcp_callback_alloc(conn);
|
state.rf_cb = tcp_callback_alloc(conn);
|
||||||
if (state.rf_cb)
|
if (state.rf_cb)
|
||||||
{
|
{
|
||||||
state.rf_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_CLOSE |
|
state.rf_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_DISCONN_EVENTS);
|
||||||
TCP_ABORT | TCP_TIMEDOUT);
|
|
||||||
state.rf_cb->priv = (void*)&state;
|
state.rf_cb->priv = (void*)&state;
|
||||||
state.rf_cb->event = recvfrom_tcpinterrupt;
|
state.rf_cb->event = recvfrom_tcpinterrupt;
|
||||||
|
|
||||||
|
@ -55,9 +55,9 @@ endif
|
|||||||
|
|
||||||
# Transport layer
|
# Transport layer
|
||||||
|
|
||||||
NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_devpoll.c tcp_timer.c tcp_send.c
|
NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_devpoll.c tcp_finddev.c tcp_timer.c
|
||||||
NET_CSRCS += tcp_input.c tcp_appsend.c tcp_listen.c tcp_callback.c
|
NET_CSRCS += tcp_send.c tcp_input.c tcp_appsend.c tcp_listen.c
|
||||||
NET_CSRCS += tcp_backlog.c tcp_ipselect.c
|
NET_CSRCS += tcp_callback.c tcp_backlog.c tcp_ipselect.c
|
||||||
|
|
||||||
# TCP write buffering
|
# TCP write buffering
|
||||||
|
|
||||||
|
@ -62,8 +62,17 @@
|
|||||||
|
|
||||||
/* Allocate a new TCP data callback */
|
/* Allocate a new TCP data callback */
|
||||||
|
|
||||||
#define tcp_callback_alloc(conn) devif_callback_alloc(NULL, &conn->list)
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
#define tcp_callback_free(conn,cb) devif_callback_free(NULL, cb, &conn->list)
|
# define tcp_callback_alloc(conn) \
|
||||||
|
devif_callback_alloc(conn->dev, &conn->list)
|
||||||
|
# define tcp_callback_free(conn,cb) \
|
||||||
|
devif_callback_free(conn->dev, cb, &conn->list)
|
||||||
|
#else
|
||||||
|
# define tcp_callback_alloc(conn) \
|
||||||
|
devif_callback_alloc(g_netdevices, &conn->list)
|
||||||
|
# define tcp_callback_free(conn,cb) \
|
||||||
|
devif_callback_free(g_netdevices, cb, &conn->list)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get the current maximum segment size that can be sent on the current
|
/* Get the current maximum segment size that can be sent on the current
|
||||||
* TCP connection.
|
* TCP connection.
|
||||||
@ -141,16 +150,26 @@ struct tcp_conn_s
|
|||||||
uint16_t unacked; /* Number bytes sent but not yet ACKed */
|
uint16_t unacked; /* Number bytes sent but not yet ACKed */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
|
/* If the TCP socket is bound to a local address, then this is
|
||||||
|
* a reference to the device that routes traffic on the corresponding
|
||||||
|
* network.
|
||||||
|
*/
|
||||||
|
|
||||||
|
FAR struct net_driver_s *dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_READAHEAD
|
||||||
/* Read-ahead buffering.
|
/* Read-ahead buffering.
|
||||||
*
|
*
|
||||||
* readahead - A singly linked list of type struct iob_qentry_s
|
* readahead - A singly linked list of type struct iob_qentry_s
|
||||||
* where the TCP/IP read-ahead data is retained.
|
* where the TCP/IP read-ahead data is retained.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TCP_READAHEAD
|
|
||||||
struct iob_queue_s readahead; /* Read-ahead buffering */
|
struct iob_queue_s readahead; /* Read-ahead buffering */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
|
||||||
/* Write buffering
|
/* Write buffering
|
||||||
*
|
*
|
||||||
* write_q - The queue of unsent I/O buffers. The head of this
|
* write_q - The queue of unsent I/O buffers. The head of this
|
||||||
@ -159,7 +178,6 @@ struct tcp_conn_s
|
|||||||
* chains. Sequence number ordering.
|
* chains. Sequence number ordering.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
|
|
||||||
sq_queue_t write_q; /* Write buffering for segments */
|
sq_queue_t write_q; /* Write buffering for segments */
|
||||||
sq_queue_t unacked_q; /* Write buffering for un-ACKed segments */
|
sq_queue_t unacked_q; /* Write buffering for un-ACKed segments */
|
||||||
uint16_t expired; /* Number segments retransmitted but not yet ACKed,
|
uint16_t expired; /* Number segments retransmitted but not yet ACKed,
|
||||||
@ -168,6 +186,7 @@ struct tcp_conn_s
|
|||||||
uint32_t isn; /* Initial sequence number */
|
uint32_t isn; /* Initial sequence number */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCPBACKLOG
|
||||||
/* Listen backlog support
|
/* Listen backlog support
|
||||||
*
|
*
|
||||||
* blparent - The backlog parent. If this connection is backlogged,
|
* blparent - The backlog parent. If this connection is backlogged,
|
||||||
@ -178,7 +197,6 @@ struct tcp_conn_s
|
|||||||
* struct tcp_backlog_s tear-off structure that manages that backlog.
|
* struct tcp_backlog_s tear-off structure that manages that backlog.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TCPBACKLOG
|
|
||||||
FAR struct tcp_conn_s *blparent;
|
FAR struct tcp_conn_s *blparent;
|
||||||
FAR struct tcp_backlog_s *backlog;
|
FAR struct tcp_backlog_s *backlog;
|
||||||
#endif
|
#endif
|
||||||
@ -269,6 +287,14 @@ extern "C"
|
|||||||
# define EXTERN extern
|
# define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
|
/* List of registered Ethernet device drivers. This duplicates a declaration
|
||||||
|
* in net/tcp/tcp.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
EXTERN struct net_driver_s *g_netdevices;
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -340,6 +366,46 @@ FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn);
|
FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: tcp_find_ipv4_device
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Select the network driver to use with the IPv4 TCP transaction.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* conn - TCP connection structure. The locally bound address, laddr,
|
||||||
|
* should be set to a non-zero value in this structure.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned
|
||||||
|
* on failure. -ENODEV is the only expected error value.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv4
|
||||||
|
int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: tcp_find_ipv6_device
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Select the network driver to use with the IPv6 TCP transaction.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* conn - TCP connection structure. The locally bound address, laddr,
|
||||||
|
* should be set to a non-zero value in this structure.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned
|
||||||
|
* on failure. -EHOSTUNREACH is the only expected error value.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
int tcp_find_ipv6_device(FAR struct tcp_conn_s *conn);
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: tcp_alloc_accept
|
* Name: tcp_alloc_accept
|
||||||
*
|
*
|
||||||
|
@ -130,9 +130,22 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv6 */
|
#endif /* CONFIG_NET_IPv6 */
|
||||||
|
|
||||||
|
/* Check If the device went down */
|
||||||
|
|
||||||
|
if ((result & NETDEV_DOWN) != 0)
|
||||||
|
{
|
||||||
|
/* If so, make sure that the connection is marked closed
|
||||||
|
* and do not try to send anything.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dev->d_sndlen = 0;
|
||||||
|
conn->tcpstateflags = TCP_CLOSED;
|
||||||
|
nllvdbg("TCP state: NETDEV_DOWN\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for connection aborted */
|
/* Check for connection aborted */
|
||||||
|
|
||||||
if ((result & TCP_ABORT) != 0)
|
else if ((result & TCP_ABORT) != 0)
|
||||||
{
|
{
|
||||||
dev->d_sndlen = 0;
|
dev->d_sndlen = 0;
|
||||||
conn->tcpstateflags = TCP_CLOSED;
|
conn->tcpstateflags = TCP_CLOSED;
|
||||||
|
@ -514,6 +514,7 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
|
|||||||
{
|
{
|
||||||
net_lock_t flags;
|
net_lock_t flags;
|
||||||
int port;
|
int port;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Verify or select a local port and address */
|
/* Verify or select a local port and address */
|
||||||
|
|
||||||
@ -529,21 +530,40 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
|
|||||||
port = tcp_selectport(ntohs(addr->sin_port));
|
port = tcp_selectport(ntohs(addr->sin_port));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
net_unlock(flags);
|
|
||||||
|
|
||||||
if (port < 0)
|
if (port < 0)
|
||||||
{
|
{
|
||||||
|
ndbg("tcp_selectport failed: %d\n", port);
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the local address in the connection structure. */
|
/* Save the local address in the connection structure. */
|
||||||
|
|
||||||
conn->lport = addr->sin_port;
|
conn->lport = addr->sin_port;
|
||||||
|
|
||||||
#ifdef CONFIG_NETDEV_MULTINIC
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
net_ipv4addr_copy(conn->u.ipv4.laddr, addr->sin_addr.s_addr);
|
net_ipv4addr_copy(conn->u.ipv4.laddr, addr->sin_addr.s_addr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Find the device that can receive packets on the network
|
||||||
|
* associated with this local address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = tcp_find_ipv4_device(conn);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
/* If no device is found, then the address is not reachable */
|
||||||
|
|
||||||
|
ndbg("tcp_find_ipv4_device failed: %d\n", ret);
|
||||||
|
|
||||||
|
/* Back out the local address setting */
|
||||||
|
|
||||||
|
conn->lport = 0;
|
||||||
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
|
net_ipv4addr_copy(conn->u.ipv4.laddr, INADDR_ANY);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_unlock(flags);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv4 */
|
#endif /* CONFIG_NET_IPv4 */
|
||||||
@ -569,6 +589,7 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
|
|||||||
{
|
{
|
||||||
net_lock_t flags;
|
net_lock_t flags;
|
||||||
int port;
|
int port;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Verify or select a local port and address */
|
/* Verify or select a local port and address */
|
||||||
|
|
||||||
@ -590,21 +611,40 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
|
|||||||
port = tcp_selectport(ntohs(addr->sin6_port));
|
port = tcp_selectport(ntohs(addr->sin6_port));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
net_unlock(flags);
|
|
||||||
|
|
||||||
if (port < 0)
|
if (port < 0)
|
||||||
{
|
{
|
||||||
|
ndbg("tcp_selectport failed: %d\n", port);
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the local address in the connection structure. */
|
/* Save the local address in the connection structure. */
|
||||||
|
|
||||||
conn->lport = addr->sin6_port;
|
conn->lport = addr->sin6_port;
|
||||||
|
|
||||||
#ifdef CONFIG_NETDEV_MULTINIC
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
net_ipv6addr_copy(conn->u.ipv6.laddr, addr->sin6_addr.in6_u.u6_addr16);
|
net_ipv6addr_copy(conn->u.ipv6.laddr, addr->sin6_addr.in6_u.u6_addr16);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Find the device that can receive packets on the network
|
||||||
|
* associated with this local address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = tcp_find_ipv6_device(conn);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
/* If no device is found, then the address is not reachable */
|
||||||
|
|
||||||
|
ndbg("tcp_find_ipv6_device failed: %d\n", ret);
|
||||||
|
|
||||||
|
/* Back out the local address setting */
|
||||||
|
|
||||||
|
conn->lport = 0;
|
||||||
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
|
net_ipv6addr_copy(conn->u.ipv6.laddr, g_ipv6_allzeroaddr);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_unlock(flags);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv6 */
|
#endif /* CONFIG_NET_IPv6 */
|
||||||
@ -928,6 +968,7 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
|
|||||||
{
|
{
|
||||||
FAR struct tcp_conn_s *conn;
|
FAR struct tcp_conn_s *conn;
|
||||||
uint8_t domain;
|
uint8_t domain;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Get the appropriate IP domain */
|
/* Get the appropriate IP domain */
|
||||||
|
|
||||||
@ -945,15 +986,9 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
|
|||||||
conn = tcp_alloc(domain);
|
conn = tcp_alloc(domain);
|
||||||
if (conn)
|
if (conn)
|
||||||
{
|
{
|
||||||
/* Fill in the necessary fields for the new connection. */
|
/* Set up the local address (laddr) and the remote address (raddr)
|
||||||
|
* that describes the TCP connection.
|
||||||
conn->rto = TCP_RTO;
|
*/
|
||||||
conn->timer = TCP_RTO;
|
|
||||||
conn->sa = 0;
|
|
||||||
conn->sv = 4;
|
|
||||||
conn->nrtx = 0;
|
|
||||||
conn->lport = tcp->destport;
|
|
||||||
conn->rport = tcp->srcport;
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
@ -962,11 +997,19 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
|
|||||||
{
|
{
|
||||||
FAR struct ipv6_hdr_s *ip = IPv6BUF;
|
FAR struct ipv6_hdr_s *ip = IPv6BUF;
|
||||||
|
|
||||||
|
/* Set the IPv6 specific MSS and the IPv6 locally bound address */
|
||||||
|
|
||||||
conn->mss = TCP_IPv6_INITIAL_MSS(dev);
|
conn->mss = TCP_IPv6_INITIAL_MSS(dev);
|
||||||
net_ipv6addr_copy(conn->u.ipv6.raddr, ip->srcipaddr);
|
net_ipv6addr_copy(conn->u.ipv6.raddr, ip->srcipaddr);
|
||||||
#ifdef CONFIG_NETDEV_MULTINIC
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
net_ipv6addr_copy(conn->u.ipv6.laddr, ip->destipaddr);
|
net_ipv6addr_copy(conn->u.ipv6.laddr, ip->destipaddr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Find the device that can receive packets on the network
|
||||||
|
* associated with this local address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = tcp_find_ipv6_device(conn);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv6 */
|
#endif /* CONFIG_NET_IPv6 */
|
||||||
|
|
||||||
@ -977,6 +1020,8 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
|
|||||||
{
|
{
|
||||||
FAR struct ipv4_hdr_s *ip = IPv4BUF;
|
FAR struct ipv4_hdr_s *ip = IPv4BUF;
|
||||||
|
|
||||||
|
/* Set the IPv6 specific MSS and the IPv4 locally bound address. */
|
||||||
|
|
||||||
conn->mss = TCP_IPv4_INITIAL_MSS(dev);
|
conn->mss = TCP_IPv4_INITIAL_MSS(dev);
|
||||||
net_ipv4addr_copy(conn->u.ipv4.raddr,
|
net_ipv4addr_copy(conn->u.ipv4.raddr,
|
||||||
net_ip4addr_conv32(ip->srcipaddr));
|
net_ip4addr_conv32(ip->srcipaddr));
|
||||||
@ -984,9 +1029,40 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
|
|||||||
net_ipv4addr_copy(conn->u.ipv4.laddr,
|
net_ipv4addr_copy(conn->u.ipv4.laddr,
|
||||||
net_ip4addr_conv32(ip->destipaddr));
|
net_ip4addr_conv32(ip->destipaddr));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Find the device that can receive packets on the network
|
||||||
|
* associated with this local address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = tcp_find_ipv4_device(conn);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv4 */
|
#endif /* CONFIG_NET_IPv4 */
|
||||||
|
|
||||||
|
/* Verify that a network device that can provide packets to this
|
||||||
|
* local address was found.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
/* If no device is found, then the address is not reachable.
|
||||||
|
* That should be impossible in this context and we should
|
||||||
|
* probably really just assert here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ndbg("Failed to find network device: %d\n", ret);
|
||||||
|
tcp_free(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in the necessary fields for the new connection. */
|
||||||
|
|
||||||
|
conn->rto = TCP_RTO;
|
||||||
|
conn->timer = TCP_RTO;
|
||||||
|
conn->sa = 0;
|
||||||
|
conn->sv = 4;
|
||||||
|
conn->nrtx = 0;
|
||||||
|
conn->lport = tcp->destport;
|
||||||
|
conn->rport = tcp->srcport;
|
||||||
conn->tcpstateflags = TCP_SYN_RCVD;
|
conn->tcpstateflags = TCP_SYN_RCVD;
|
||||||
|
|
||||||
tcp_initsequence(conn->sndseq);
|
tcp_initsequence(conn->sndseq);
|
||||||
@ -1090,6 +1166,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
|
|||||||
{
|
{
|
||||||
net_lock_t flags;
|
net_lock_t flags;
|
||||||
int port;
|
int port;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* The connection is expected to be in the TCP_ALLOCATED state.. i.e.,
|
/* The connection is expected to be in the TCP_ALLOCATED state.. i.e.,
|
||||||
* allocated via up_tcpalloc(), but not yet put into the active connections
|
* allocated via up_tcpalloc(), but not yet put into the active connections
|
||||||
@ -1153,13 +1230,80 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
|
|||||||
|
|
||||||
#endif /* CONFIG_NETDEV_MULTINIC */
|
#endif /* CONFIG_NETDEV_MULTINIC */
|
||||||
|
|
||||||
net_unlock(flags);
|
|
||||||
|
|
||||||
/* Did we have a port assignment? */
|
/* Did we have a port assignment? */
|
||||||
|
|
||||||
if (port < 0)
|
if (port < 0)
|
||||||
{
|
{
|
||||||
return port;
|
ret = port;
|
||||||
|
goto errout_with_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up the local address (laddr) and the remote address (raddr) that describes the TCP connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv4
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
if (conn->domain == PF_INET)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
FAR const struct sockaddr_in *inaddr =
|
||||||
|
(FAR const struct sockaddr_in *)addr;
|
||||||
|
|
||||||
|
/* Save MSS and the port from the sockaddr (already in network order) */
|
||||||
|
|
||||||
|
conn->mss = MIN_IPv4_TCP_INITIAL_MSS;
|
||||||
|
conn->rport = inaddr->sin_port;
|
||||||
|
|
||||||
|
/* The sockaddr address is 32-bits in network order. */
|
||||||
|
|
||||||
|
net_ipv4addr_copy(conn->u.ipv4.raddr, inaddr->sin_addr.s_addr);
|
||||||
|
|
||||||
|
/* Find the device that can receive packets on the network associated
|
||||||
|
* with this local address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = tcp_find_ipv4_device(conn);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NET_IPv4 */
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
#ifdef CONFIG_NET_IPv4
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
FAR const struct sockaddr_in6 *inaddr =
|
||||||
|
(FAR const struct sockaddr_in6 *)addr;
|
||||||
|
|
||||||
|
/* Save MSS and the port from the sockaddr (already in network order) */
|
||||||
|
|
||||||
|
conn->mss = MIN_IPv6_TCP_INITIAL_MSS;
|
||||||
|
conn->rport = inaddr->sin6_port;
|
||||||
|
|
||||||
|
/* The sockaddr address is 128-bits in network order. */
|
||||||
|
|
||||||
|
net_ipv6addr_copy(conn->u.ipv6.raddr, inaddr->sin6_addr.s6_addr16);
|
||||||
|
|
||||||
|
/* Find the device that can receive packets on the network associated
|
||||||
|
* with this local address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = tcp_find_ipv6_device(conn);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NET_IPv6 */
|
||||||
|
|
||||||
|
/* Verify that a network device that can provide packets to this local
|
||||||
|
* address was found.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
/* If no device is found, then the address is not reachable. That
|
||||||
|
* should be impossible in this context and we should probably really
|
||||||
|
* just assert here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ndbg("Failed to find network device: %d\n", ret);
|
||||||
|
goto errout_with_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize and return the connection structure, bind it to the port
|
/* Initialize and return the connection structure, bind it to the port
|
||||||
@ -1184,46 +1328,6 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
|
|||||||
conn->sent = 0;
|
conn->sent = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Save values that are specific to the IP address domain */
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
|
||||||
if (conn->domain == PF_INET)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
FAR const struct sockaddr_in *inaddr =
|
|
||||||
(FAR const struct sockaddr_in *)addr;
|
|
||||||
|
|
||||||
/* Save MSS and the port from the sockaddr (already in network order) */
|
|
||||||
|
|
||||||
conn->mss = MIN_IPv4_TCP_INITIAL_MSS;
|
|
||||||
conn->rport = inaddr->sin_port;
|
|
||||||
|
|
||||||
/* The sockaddr address is 32-bits in network order. */
|
|
||||||
|
|
||||||
net_ipv4addr_copy(conn->u.ipv4.raddr, inaddr->sin_addr.s_addr);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NET_IPv4 */
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
FAR const struct sockaddr_in6 *inaddr =
|
|
||||||
(FAR const struct sockaddr_in6 *)addr;
|
|
||||||
|
|
||||||
/* Save MSS and the port from the sockaddr (already in network order) */
|
|
||||||
|
|
||||||
conn->mss = MIN_IPv6_TCP_INITIAL_MSS;
|
|
||||||
conn->rport = inaddr->sin6_port;
|
|
||||||
|
|
||||||
/* The sockaddr address is 32-bits in network order. */
|
|
||||||
|
|
||||||
net_ipv6addr_copy(conn->u.ipv6.raddr, inaddr->sin6_addr.s6_addr16);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NET_IPv6 */
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TCP_READAHEAD
|
#ifdef CONFIG_NET_TCP_READAHEAD
|
||||||
/* Initialize the list of TCP read-ahead buffers */
|
/* Initialize the list of TCP read-ahead buffers */
|
||||||
|
|
||||||
@ -1237,17 +1341,14 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
|
|||||||
sq_init(&conn->unacked_q);
|
sq_init(&conn->unacked_q);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* And, finally, put the connection structure into the active
|
/* And, finally, put the connection structure into the active list. */
|
||||||
* list. Because g_active_tcp_connections is accessed from user level and
|
|
||||||
* interrupt level, code, it is necessary to keep interrupts disabled during
|
|
||||||
* this operation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
flags = net_lock();
|
|
||||||
dq_addlast(&conn->node, &g_active_tcp_connections);
|
dq_addlast(&conn->node, &g_active_tcp_connections);
|
||||||
net_unlock(flags);
|
ret = OK;
|
||||||
|
|
||||||
return OK;
|
errout_with_lock:
|
||||||
|
net_unlock(flags);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET && CONFIG_NET_TCP */
|
#endif /* CONFIG_NET && CONFIG_NET_TCP */
|
||||||
|
@ -89,7 +89,7 @@
|
|||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
* Called from the interrupt level or with interrupts disabled.
|
* Called with the network locked.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
@ -119,9 +119,9 @@ static uint16_t tcp_poll_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
|
|||||||
|
|
||||||
/* Check for a loss of connection events. */
|
/* Check for a loss of connection events. */
|
||||||
|
|
||||||
if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT | NETDEV_DOWN)) != 0)
|
if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||||
{
|
{
|
||||||
/* Marki that the connection has been lost */
|
/* Mark that the connection has been lost */
|
||||||
|
|
||||||
net_lostconnection(info->psock, flags);
|
net_lostconnection(info->psock, flags);
|
||||||
eventset |= (POLLERR | POLLHUP);
|
eventset |= (POLLERR | POLLHUP);
|
||||||
@ -208,13 +208,12 @@ int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
|||||||
* callback processing.
|
* callback processing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cb->flags = (TCP_NEWDATA | TCP_BACKLOG | TCP_POLL | TCP_CLOSE |
|
cb->flags = (TCP_NEWDATA | TCP_BACKLOG | TCP_POLL | TCP_DISCONN_EVENTS);
|
||||||
TCP_ABORT | TCP_TIMEDOUT | NETDEV_DOWN);
|
|
||||||
cb->priv = (FAR void *)info;
|
cb->priv = (FAR void *)info;
|
||||||
cb->event = tcp_poll_interrupt;
|
cb->event = tcp_poll_interrupt;
|
||||||
|
|
||||||
/* Save the reference in the poll info structure as fds private as well
|
/* Save the reference in the poll info structure as fds private as well
|
||||||
* for use durring poll teardown as well.
|
* for use during poll teardown as well.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fds->priv = (FAR void *)info;
|
fds->priv = (FAR void *)info;
|
||||||
|
@ -488,7 +488,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
/* Check for a loss of connection */
|
/* Check for a loss of connection */
|
||||||
|
|
||||||
else if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT)) != 0)
|
else if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||||
{
|
{
|
||||||
nllvdbg("Lost connection: %04x\n", flags);
|
nllvdbg("Lost connection: %04x\n", flags);
|
||||||
|
|
||||||
@ -1024,7 +1024,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
|||||||
/* Set up the callback in the connection */
|
/* Set up the callback in the connection */
|
||||||
|
|
||||||
psock->s_sndcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL |
|
psock->s_sndcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL |
|
||||||
TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT);
|
TCP_DISCONN_EVENTS);
|
||||||
psock->s_sndcb->priv = (void*)psock;
|
psock->s_sndcb->priv = (void*)psock;
|
||||||
psock->s_sndcb->event = psock_send_interrupt;
|
psock->s_sndcb->event = psock_send_interrupt;
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
/* Check for a loss of connection */
|
/* Check for a loss of connection */
|
||||||
|
|
||||||
else if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT)) != 0)
|
else if ((flags & TCP_DISCONN_EVENTS) != 0)
|
||||||
{
|
{
|
||||||
/* Report not connected */
|
/* Report not connected */
|
||||||
|
|
||||||
@ -810,7 +810,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
|
|||||||
/* Set up the callback in the connection */
|
/* Set up the callback in the connection */
|
||||||
|
|
||||||
state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL |
|
state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL |
|
||||||
TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT);
|
TCP_DISCONN_EVENTS);
|
||||||
state.snd_cb->priv = (FAR void *)&state;
|
state.snd_cb->priv = (FAR void *)&state;
|
||||||
state.snd_cb->event = tcpsend_interrupt;
|
state.snd_cb->event = tcpsend_interrupt;
|
||||||
|
|
||||||
|
@ -342,6 +342,7 @@ int udp_ipv6_input(FAR struct net_driver_s *dev);
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* conn - UDP connection structure (not currently used).
|
* conn - UDP connection structure (not currently used).
|
||||||
|
* ipv4addr - The IPv4 address to use in the device selection.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* A pointer to the network driver to use.
|
* A pointer to the network driver to use.
|
||||||
@ -361,6 +362,7 @@ FAR struct net_driver_s *udp_find_ipv4_device(FAR struct udp_conn_s *conn,
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* conn - UDP connection structure (not currently used).
|
* conn - UDP connection structure (not currently used).
|
||||||
|
* ipv6addr - The IPv6 address to use in the device selection.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* A pointer to the network driver to use.
|
* A pointer to the network driver to use.
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
|
#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
#include <nuttx/net/ip.h>
|
#include <nuttx/net/ip.h>
|
||||||
|
|
||||||
@ -66,6 +68,7 @@
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* conn - UDP connection structure (not currently used).
|
* conn - UDP connection structure (not currently used).
|
||||||
|
* ipv4addr - The IPv4 address to use in the device selection.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* A pointer to the network driver to use.
|
* A pointer to the network driver to use.
|
||||||
@ -77,17 +80,15 @@ FAR struct net_driver_s *udp_find_ipv4_device(FAR struct udp_conn_s *conn,
|
|||||||
in_addr_t ipv4addr)
|
in_addr_t ipv4addr)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NETDEV_MULTINIC
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
FAR struct net_driver_s *dev;
|
/* Return NULL if the address is INADDR_ANY. In this case, there may
|
||||||
|
* be multiple devices that can provide data so the exceptional events
|
||||||
/* Return NULL if the address is INADDR_ANY. In this case, there is
|
* from any particular device are not important.
|
||||||
* there may be multiple devices that can provide data so the exceptional
|
|
||||||
* events from any particular device are not important.
|
|
||||||
*
|
*
|
||||||
* Of course, it would be a problem if this is the remote address of
|
* Of course, it would be a problem if this is the remote address of
|
||||||
* sendto().
|
* sendto().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((net_ipv4addr_cmp(ipv4addr, INADDR_ANY))
|
if (net_ipv4addr_cmp(ipv4addr, INADDR_ANY))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -99,8 +100,6 @@ FAR struct net_driver_s *udp_find_ipv4_device(FAR struct udp_conn_s *conn,
|
|||||||
return netdev_findby_ipv4addr(conn->u.ipv4.laddr, ipv4addr);
|
return netdev_findby_ipv4addr(conn->u.ipv4.laddr, ipv4addr);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* Return NULL if the address is IN6ADDR_ANY */
|
|
||||||
|
|
||||||
/* There is only a single network device... the one at the head of the
|
/* There is only a single network device... the one at the head of the
|
||||||
* g_netdevices list.
|
* g_netdevices list.
|
||||||
*/
|
*/
|
||||||
@ -118,6 +117,7 @@ FAR struct net_driver_s *udp_find_ipv4_device(FAR struct udp_conn_s *conn,
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* conn - UDP connection structure (not currently used).
|
* conn - UDP connection structure (not currently used).
|
||||||
|
* ipv6addr - The IPv6 address to use in the device selection.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* A pointer to the network driver to use.
|
* A pointer to the network driver to use.
|
||||||
@ -129,11 +129,9 @@ FAR struct net_driver_s *udp_find_ipv6_device(FAR struct udp_conn_s *conn,
|
|||||||
net_ipv6addr_t ipv6addr)
|
net_ipv6addr_t ipv6addr)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NETDEV_MULTINIC
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
FAR struct net_driver_s *dev;
|
/* Return NULL if the address is IN6ADDR_ANY. In this case, there may
|
||||||
|
* be multiple devices that can provide data so the exceptional events
|
||||||
/* Return NULL if the address is IN6ADDR_ANY. In this case, there is
|
* from any particular device are not important.
|
||||||
* there may be multiple devices that can provide data so the exceptional
|
|
||||||
* events from any particular device are not important.
|
|
||||||
*
|
*
|
||||||
* Of course, it would be a problem if this is the remote address of
|
* Of course, it would be a problem if this is the remote address of
|
||||||
* sendto().
|
* sendto().
|
||||||
@ -178,8 +176,6 @@ FAR struct net_driver_s *udp_find_ipv6_device(FAR struct udp_conn_s *conn,
|
|||||||
FAR struct net_driver_s *udp_find_laddr_device(FAR struct udp_conn_s *conn)
|
FAR struct net_driver_s *udp_find_laddr_device(FAR struct udp_conn_s *conn)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NETDEV_MULTINIC
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
FAR struct net_driver_s *dev;
|
|
||||||
|
|
||||||
/* There are multiple network devices. We need to select the device that
|
/* There are multiple network devices. We need to select the device that
|
||||||
* is going to route the UDP packet based on the provided IP address.
|
* is going to route the UDP packet based on the provided IP address.
|
||||||
*/
|
*/
|
||||||
@ -189,7 +185,7 @@ FAR struct net_driver_s *udp_find_laddr_device(FAR struct udp_conn_s *conn)
|
|||||||
if (conn->domain == PF_INET)
|
if (conn->domain == PF_INET)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return upd_find_ipv4_device(conn, conn->u.ipv4.laddr);
|
return udp_find_ipv4_device(conn, conn->u.ipv4.laddr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -198,7 +194,7 @@ FAR struct net_driver_s *udp_find_laddr_device(FAR struct udp_conn_s *conn)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return upd_find_ipv6_device(conn, conn->u.ipv6.laddr);
|
return udp_find_ipv6_device(conn, conn->u.ipv6.laddr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -229,8 +225,6 @@ FAR struct net_driver_s *udp_find_laddr_device(FAR struct udp_conn_s *conn)
|
|||||||
FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn)
|
FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NETDEV_MULTINIC
|
#ifdef CONFIG_NETDEV_MULTINIC
|
||||||
FAR struct net_driver_s *dev;
|
|
||||||
|
|
||||||
/* There are multiple network devices. We need to select the device that
|
/* There are multiple network devices. We need to select the device that
|
||||||
* is going to route the UDP packet based on the provided IP address.
|
* is going to route the UDP packet based on the provided IP address.
|
||||||
*/
|
*/
|
||||||
@ -240,7 +234,7 @@ FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn)
|
|||||||
if (conn->domain == PF_INET)
|
if (conn->domain == PF_INET)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return upd_find_ipv4_device(conn, conn->u.ipv4.raddr);
|
return udp_find_ipv4_device(conn, conn->u.ipv4.raddr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -249,7 +243,7 @@ FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return upd_find_ipv6_device(conn, conn->u.ipv6.raddr);
|
return udp_find_ipv6_device(conn, conn->u.ipv6.raddr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user