TCP networking: Add support for network driver events

This commit is contained in:
Gregory Nutt 2015-05-30 09:12:27 -06:00
parent ab50e9d04d
commit 04a661a97c
17 changed files with 324 additions and 131 deletions

View File

@ -193,8 +193,11 @@
/* The set of events that and implications to the TCP connection state */
#define TCP_CONN_EVENTS (TCP_CLOSE | TCP_ABORT | TCP_CONNECTED | \
TCP_TIMEDOUT | NETDEV_DOWN)
#define TCP_CONN_EVENTS \
(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 */

View File

@ -68,9 +68,11 @@ extern "C"
#define EXTERN extern
#endif
/* List of registered Ethernet device drivers */
#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;
#endif

View File

@ -118,7 +118,7 @@ static inline int psock_setup_callbacks(FAR struct socket *psock,
/* Set up the connection "interrupt" handler */
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->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)
{
/* Indicate that the remote host is unreachable (or should this be timedout?) */
/* Indicate that the connection timedout?)*/
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 */
else if ((flags & TCP_CONNECTED) != 0)

View File

@ -167,12 +167,14 @@ static uint16_t netclose_interrupt(FAR struct net_driver_s *dev,
nllvdbg("conn: %p flags: %04x\n", conn, flags);
/* TCP_CLOSE: The remote host has closed the connection
* TCP_ABORT: The remote host has aborted the connection
* TCP_TIMEDOUT: The remote did not respond, the connection timed out
/* TCP_DISCONN_EVENTS:
* TCP_CLOSE: The remote host has closed the connection
* 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 */
@ -371,8 +373,7 @@ static inline int netclose_disconnect(FAR struct socket *psock)
{
/* Set up to receive TCP data event callbacks */
state.cl_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_CLOSE | TCP_ABORT |
TCP_TIMEDOUT);
state.cl_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_DISCONN_EVENTS);
state.cl_cb->event = netclose_interrupt;
#ifdef CONFIG_NET_SOLINGER

View File

@ -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);
/* 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);
}
@ -218,6 +220,7 @@ void net_lostconnection(FAR struct socket *psock, uint16_t flags)
* TCP_CLOSE: The remote host has closed the connection
* 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
*
* 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_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)
* be reported as an ENOTCONN error.

View File

@ -217,7 +217,7 @@ static uint16_t ack_interrupt(FAR struct net_driver_s *dev, FAR void *pvconn,
/* 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 */
@ -329,7 +329,7 @@ static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvcon
/* Check for a loss of connection */
if ((flags & (TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT)) != 0)
if ((flags & TCP_DISCONN_EVENTS) != 0)
{
/* 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 */
state.snd_ackcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_CLOSE |
TCP_ABORT | TCP_TIMEDOUT);
state.snd_ackcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_DISCONN_EVENTS);
state.snd_ackcb->priv = (void*)&state;
state.snd_ackcb->event = ack_interrupt;

View File

@ -804,12 +804,14 @@ static uint16_t recvfrom_tcpinterrupt(FAR struct net_driver_s *dev,
/* Check for a loss of connection.
*
* TCP_CLOSE: The remote host has closed the connection
* TCP_ABORT: The remote host has aborted the connection
* TCP_TIMEDOUT: Connection aborted due to too many retransmissions.
* TCP_DISCONN_EVENTS:
* TCP_CLOSE: The remote host has closed the connection
* 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");
@ -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);
if (state.rf_cb)
{
state.rf_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_CLOSE |
TCP_ABORT | TCP_TIMEDOUT);
state.rf_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_DISCONN_EVENTS);
state.rf_cb->priv = (void*)&state;
state.rf_cb->event = recvfrom_tcpinterrupt;

View File

@ -55,9 +55,9 @@ endif
# Transport layer
NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_devpoll.c tcp_timer.c tcp_send.c
NET_CSRCS += tcp_input.c tcp_appsend.c tcp_listen.c tcp_callback.c
NET_CSRCS += tcp_backlog.c tcp_ipselect.c
NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_devpoll.c tcp_finddev.c tcp_timer.c
NET_CSRCS += tcp_send.c tcp_input.c tcp_appsend.c tcp_listen.c
NET_CSRCS += tcp_callback.c tcp_backlog.c tcp_ipselect.c
# TCP write buffering

View File

@ -62,8 +62,17 @@
/* Allocate a new TCP data callback */
#define tcp_callback_alloc(conn) devif_callback_alloc(NULL, &conn->list)
#define tcp_callback_free(conn,cb) devif_callback_free(NULL, cb, &conn->list)
#ifdef CONFIG_NETDEV_MULTINIC
# 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
* TCP connection.
@ -141,16 +150,26 @@ struct tcp_conn_s
uint16_t unacked; /* Number bytes sent but not yet ACKed */
#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.
*
* readahead - A singly linked list of type struct iob_qentry_s
* where the TCP/IP read-ahead data is retained.
*/
#ifdef CONFIG_NET_TCP_READAHEAD
struct iob_queue_s readahead; /* Read-ahead buffering */
#endif
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
/* Write buffering
*
* 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.
*/
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
sq_queue_t write_q; /* Write buffering for segments */
sq_queue_t unacked_q; /* Write buffering for un-ACKed segments */
uint16_t expired; /* Number segments retransmitted but not yet ACKed,
@ -168,6 +186,7 @@ struct tcp_conn_s
uint32_t isn; /* Initial sequence number */
#endif
#ifdef CONFIG_NET_TCPBACKLOG
/* Listen backlog support
*
* 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.
*/
#ifdef CONFIG_NET_TCPBACKLOG
FAR struct tcp_conn_s *blparent;
FAR struct tcp_backlog_s *backlog;
#endif
@ -269,6 +287,14 @@ extern "C"
# define EXTERN extern
#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
****************************************************************************/
@ -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);
/****************************************************************************
* 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
*

View File

@ -130,9 +130,22 @@ void tcp_appsend(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
}
#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 */
if ((result & TCP_ABORT) != 0)
else if ((result & TCP_ABORT) != 0)
{
dev->d_sndlen = 0;
conn->tcpstateflags = TCP_CLOSED;

View File

@ -514,6 +514,7 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
{
net_lock_t flags;
int port;
int ret;
/* 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));
#endif
net_unlock(flags);
if (port < 0)
{
ndbg("tcp_selectport failed: %d\n", port);
return port;
}
/* Save the local address in the connection structure. */
conn->lport = addr->sin_port;
#ifdef CONFIG_NETDEV_MULTINIC
net_ipv4addr_copy(conn->u.ipv4.laddr, addr->sin_addr.s_addr);
#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;
}
#endif /* CONFIG_NET_IPv4 */
@ -569,6 +589,7 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
{
net_lock_t flags;
int port;
int ret;
/* 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));
#endif
net_unlock(flags);
if (port < 0)
{
ndbg("tcp_selectport failed: %d\n", port);
return port;
}
/* Save the local address in the connection structure. */
conn->lport = addr->sin6_port;
#ifdef CONFIG_NETDEV_MULTINIC
net_ipv6addr_copy(conn->u.ipv6.laddr, addr->sin6_addr.in6_u.u6_addr16);
#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;
}
#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;
uint8_t domain;
int ret;
/* 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);
if (conn)
{
/* 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;
/* Set up the local address (laddr) and the remote address (raddr)
* that describes the TCP connection.
*/
#ifdef CONFIG_NET_IPv6
#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;
/* Set the IPv6 specific MSS and the IPv6 locally bound address */
conn->mss = TCP_IPv6_INITIAL_MSS(dev);
net_ipv6addr_copy(conn->u.ipv6.raddr, ip->srcipaddr);
#ifdef CONFIG_NETDEV_MULTINIC
net_ipv6addr_copy(conn->u.ipv6.laddr, ip->destipaddr);
#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 */
@ -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;
/* Set the IPv6 specific MSS and the IPv4 locally bound address. */
conn->mss = TCP_IPv4_INITIAL_MSS(dev);
net_ipv4addr_copy(conn->u.ipv4.raddr,
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_ip4addr_conv32(ip->destipaddr));
#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 */
/* 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;
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;
int port;
int ret;
/* 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
@ -1153,13 +1230,80 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
#endif /* CONFIG_NETDEV_MULTINIC */
net_unlock(flags);
/* Did we have a port assignment? */
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
@ -1184,46 +1328,6 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
conn->sent = 0;
#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
/* 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);
#endif
/* And, finally, put the connection structure into the active
* 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.
*/
/* And, finally, put the connection structure into the active list. */
flags = net_lock();
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 */

View File

@ -89,7 +89,7 @@
* None
*
* Assumptions:
* Called from the interrupt level or with interrupts disabled.
* Called with the network locked.
*
****************************************************************************/

View File

@ -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. */
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);
eventset |= (POLLERR | POLLHUP);
@ -208,13 +208,12 @@ int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
* callback processing.
*/
cb->flags = (TCP_NEWDATA | TCP_BACKLOG | TCP_POLL | TCP_CLOSE |
TCP_ABORT | TCP_TIMEDOUT | NETDEV_DOWN);
cb->flags = (TCP_NEWDATA | TCP_BACKLOG | TCP_POLL | TCP_DISCONN_EVENTS);
cb->priv = (FAR void *)info;
cb->event = tcp_poll_interrupt;
/* 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;

View File

@ -488,7 +488,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev,
/* 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);
@ -1024,7 +1024,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
/* Set up the callback in the connection */
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->event = psock_send_interrupt;

View File

@ -376,7 +376,7 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev,
/* 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 */
@ -810,7 +810,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
/* Set up the callback in the connection */
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->event = tcpsend_interrupt;

View File

@ -342,6 +342,7 @@ int udp_ipv6_input(FAR struct net_driver_s *dev);
*
* Input Parameters:
* conn - UDP connection structure (not currently used).
* ipv4addr - The IPv4 address to use in the device selection.
*
* Returned Value:
* 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:
* conn - UDP connection structure (not currently used).
* ipv6addr - The IPv6 address to use in the device selection.
*
* Returned Value:
* A pointer to the network driver to use.

View File

@ -40,6 +40,8 @@
#include <nuttx/config.h>
#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
#include <string.h>
#include <nuttx/net/netdev.h>
#include <nuttx/net/ip.h>
@ -66,6 +68,7 @@
*
* Input Parameters:
* conn - UDP connection structure (not currently used).
* ipv4addr - The IPv4 address to use in the device selection.
*
* Returned Value:
* 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)
{
#ifdef CONFIG_NETDEV_MULTINIC
FAR struct net_driver_s *dev;
/* Return NULL if the address is INADDR_ANY. In this case, there is
* there may be multiple devices that can provide data so the exceptional
* events from any particular device are not important.
/* Return NULL if the address is INADDR_ANY. In this case, 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
* sendto().
*/
if ((net_ipv4addr_cmp(ipv4addr, INADDR_ANY))
if (net_ipv4addr_cmp(ipv4addr, INADDR_ANY))
{
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);
#else
/* Return NULL if the address is IN6ADDR_ANY */
/* There is only a single network device... the one at the head of the
* g_netdevices list.
*/
@ -118,6 +117,7 @@ FAR struct net_driver_s *udp_find_ipv4_device(FAR struct udp_conn_s *conn,
*
* Input Parameters:
* conn - UDP connection structure (not currently used).
* ipv6addr - The IPv6 address to use in the device selection.
*
* Returned Value:
* 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)
{
#ifdef CONFIG_NETDEV_MULTINIC
FAR struct net_driver_s *dev;
/* Return NULL if the address is IN6ADDR_ANY. In this case, there is
* there may be multiple devices that can provide data so the exceptional
* events from any particular device are not important.
/* Return NULL if the address is IN6ADDR_ANY. In this case, 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
* 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)
{
#ifdef CONFIG_NETDEV_MULTINIC
FAR struct net_driver_s *dev;
/* 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.
*/
@ -189,7 +185,7 @@ FAR struct net_driver_s *udp_find_laddr_device(FAR struct udp_conn_s *conn)
if (conn->domain == PF_INET)
#endif
{
return upd_find_ipv4_device(conn, conn->u.ipv4.laddr);
return udp_find_ipv4_device(conn, conn->u.ipv4.laddr);
}
#endif
@ -198,7 +194,7 @@ FAR struct net_driver_s *udp_find_laddr_device(FAR struct udp_conn_s *conn)
else
#endif
{
return upd_find_ipv6_device(conn, conn->u.ipv6.laddr);
return udp_find_ipv6_device(conn, conn->u.ipv6.laddr);
}
#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)
{
#ifdef CONFIG_NETDEV_MULTINIC
FAR struct net_driver_s *dev;
/* 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.
*/
@ -240,7 +234,7 @@ FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn)
if (conn->domain == PF_INET)
#endif
{
return upd_find_ipv4_device(conn, conn->u.ipv4.raddr);
return udp_find_ipv4_device(conn, conn->u.ipv4.raddr);
}
#endif
@ -249,7 +243,7 @@ FAR struct net_driver_s *udp_find_raddr_device(FAR struct udp_conn_s *conn)
else
#endif
{
return upd_find_ipv6_device(conn, conn->u.ipv6.raddr);
return udp_find_ipv6_device(conn, conn->u.ipv6.raddr);
}
#endif