summaryrefslogtreecommitdiff
path: root/nuttx/net
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-08-18 16:22:14 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-08-18 16:22:14 -0600
commit4f670b87fdecc7e9314f8bac0717e8961f9151bf (patch)
tree25ea58943bc0a26b0efed11ef97eaab1b3d1845e /nuttx/net
parentd0b89b78f0cce276ed9bee65cb640787080d6062 (diff)
downloadpx4-nuttx-4f670b87fdecc7e9314f8bac0717e8961f9151bf.tar.gz
px4-nuttx-4f670b87fdecc7e9314f8bac0717e8961f9151bf.tar.bz2
px4-nuttx-4f670b87fdecc7e9314f8bac0717e8961f9151bf.zip
If CONFIG_NET_ARP_SEND is enabled, then all ICMP, TCP, and UDP send operations will call arp_send() before attempting the real send operation. arp_send() will check if the the IP address mapping is in the ARP table and, if not send ARP requests periodically until it is. This eliminates losing the first outgoing message because there is not mapping in the ARP table.
Diffstat (limited to 'nuttx/net')
-rw-r--r--nuttx/net/icmp/icmp_ping.c13
-rw-r--r--nuttx/net/socket/net_sendfile.c26
-rw-r--r--nuttx/net/socket/sendto.c17
-rw-r--r--nuttx/net/tcp/tcp_send_buffered.c27
-rw-r--r--nuttx/net/tcp/tcp_send_unbuffered.c27
5 files changed, 98 insertions, 12 deletions
diff --git a/nuttx/net/icmp/icmp_ping.c b/nuttx/net/icmp/icmp_ping.c
index 53838b47e..3cd900b94 100644
--- a/nuttx/net/icmp/icmp_ping.c
+++ b/nuttx/net/icmp/icmp_ping.c
@@ -58,6 +58,7 @@
#include "netdev/netdev.h"
#include "devif/devif.h"
+#include "arp/arp.h"
#include "icmp/icmp.h"
/****************************************************************************
@@ -331,6 +332,18 @@ int icmp_ping(net_ipaddr_t addr, uint16_t id, uint16_t seqno,
{
struct icmp_ping_s state;
net_lock_t save;
+#ifdef CONFIG_NET_ARP_SEND
+ int ret;
+
+ /* Make sure that the IP address mapping is in the ARP table */
+
+ ret = arp_send(addr);
+ if (ret < 0)
+ {
+ ndbg("ERROR: Not reachable\n");
+ return -ENETUNREACH;
+ }
+#endif
/* Initialize the state structure */
diff --git a/nuttx/net/socket/net_sendfile.c b/nuttx/net/socket/net_sendfile.c
index b87a0192f..de5a01efc 100644
--- a/nuttx/net/socket/net_sendfile.c
+++ b/nuttx/net/socket/net_sendfile.c
@@ -2,7 +2,7 @@
* net/socket/net_sendfile.c
*
* Copyright (C) 2013 UVC Ingenieure. All rights reserved.
- * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
* Max Holtzberg <mh@uvc.de>
*
@@ -65,10 +65,10 @@
#include "netdev/netdev.h"
#include "devif/devif.h"
+#include "arp/arp.h"
#include "tcp/tcp.h"
#include "socket/socket.h"
-
/****************************************************************************
* Definitions
****************************************************************************/
@@ -322,10 +322,14 @@ static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvcon
*
* NOTE 2: If we are actually harvesting IP addresses on incoming IP
* packets, then this check should not be necessary; the MAC mapping
- * should already be in the ARP table.
+ * should already be in the ARP table in many cases.
+ *
+ * NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP
+ * address mapping is already in the ARP table.
*/
-#if defined(CONFIG_NET_ETHERNET) && !defined (CONFIG_NET_ARP_IPIN)
+#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \
+ !defined(CONFIG_NET_ARP_SEND)
if (pstate->snd_sent != 0 || arp_find(conn->ripaddr) != NULL)
#endif
{
@@ -463,6 +467,7 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
if (!psock || psock->s_crefs <= 0)
{
+ ndbg("ERROR: Invalid socket\n");
err = EBADF;
goto errout;
}
@@ -471,10 +476,23 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags))
{
+ ndbg("ERROR: Not connected\n");
err = ENOTCONN;
goto errout;
}
+ /* Make sure that the IP address mapping is in the ARP table */
+
+#ifdef CONFIG_NET_ARP_SEND
+ ret = arp_send(conn->ripaddr);
+ if (ret < 0)
+ {
+ ndbg("ERROR: Not reachable\n");
+ err = ENETUNREACH;
+ goto errout;
+ }
+#endif
+
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
diff --git a/nuttx/net/socket/sendto.c b/nuttx/net/socket/sendto.c
index 2827bd3b0..09a5dd7d4 100644
--- a/nuttx/net/socket/sendto.c
+++ b/nuttx/net/socket/sendto.c
@@ -55,6 +55,7 @@
#include "netdev/netdev.h"
#include "devif/devif.h"
+#include "arp/arp.h"
#include "udp/udp.h"
#include "socket/socket.h"
@@ -322,6 +323,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
#ifdef CONFIG_NET_TCP
return psock_send(psock, buf, len, flags);
#else
+ ndbg("ERROR: No to address\n");
err = EINVAL;
goto errout;
#endif
@@ -335,6 +337,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
if (to->sa_family != AF_INET || tolen < sizeof(struct sockaddr_in))
#endif
{
+ ndbg("ERROR: Invalid address\n");
err = EBADF;
goto errout;
}
@@ -343,6 +346,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
if (!psock || psock->s_crefs <= 0)
{
+ ndbg("ERROR: Invalid socket\n");
err = EBADF;
goto errout;
}
@@ -351,10 +355,23 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
if (psock->s_type != SOCK_DGRAM)
{
+ ndbg("ERROR: Connected socket\n");
err = EISCONN;
goto errout;
}
+ /* Make sure that the IP address mapping is in the ARP table */
+
+#ifdef CONFIG_NET_ARP_SEND
+ ret = arp_send(into->sin_addr.s_addr);
+ if (ret < 0)
+ {
+ ndbg("ERROR: Not reachable\n");
+ err = ENETUNREACH;
+ goto errout;
+ }
+#endif
+
/* Perform the UDP sendto operation */
#ifdef CONFIG_NET_UDP
diff --git a/nuttx/net/tcp/tcp_send_buffered.c b/nuttx/net/tcp/tcp_send_buffered.c
index bb0eb729f..231eeebe7 100644
--- a/nuttx/net/tcp/tcp_send_buffered.c
+++ b/nuttx/net/tcp/tcp_send_buffered.c
@@ -71,6 +71,7 @@
#include "socket/socket.h"
#include "netdev/netdev.h"
+#include "arp/arp.h"
#include "tcp/tcp.h"
#include "devif/devif.h"
@@ -539,10 +540,14 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev,
*
* NOTE 2: If we are actually harvesting IP addresses on incoming IP
* packets, then this check should not be necessary; the MAC mapping
- * should already be in the ARP table.
+ * should already be in the ARP table in many cases.
+ *
+ * NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP
+ * address mapping is already in the ARP table.
*/
-#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN)
+#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \
+ !defined(CONFIG_NET_ARP_SEND)
if (arp_find(conn->ripaddr) != NULL)
#endif
{
@@ -721,6 +726,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev,
ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
size_t len)
{
+ FAR struct tcp_conn_s *conn;
net_lock_t save;
ssize_t result = 0;
int err;
@@ -728,16 +734,31 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
if (!psock || psock->s_crefs <= 0)
{
+ ndbg("ERROR: Invalid socket\n");
err = EBADF;
goto errout;
}
if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags))
{
+ ndbg("ERROR: Not connected\n");
err = ENOTCONN;
goto errout;
}
+ /* Make sure that the IP address mapping is in the ARP table */
+
+ conn = (FAR struct tcp_conn_s *)psock->s_conn;
+#ifdef CONFIG_NET_ARP_SEND
+ ret = arp_send(conn->ripaddr);
+ if (ret < 0)
+ {
+ ndbg("ERROR: Not reachable\n");
+ err = ENETUNREACH;
+ goto errout;
+ }
+#endif
+
/* Dump the incoming buffer */
BUF_DUMP("psock_tcp_send", buf, len);
@@ -750,8 +771,6 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
if (len > 0)
{
- FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn;
-
/* Allocate resources to receive a callback */
if (!psock->s_sndcb)
diff --git a/nuttx/net/tcp/tcp_send_unbuffered.c b/nuttx/net/tcp/tcp_send_unbuffered.c
index 66453773d..22f686082 100644
--- a/nuttx/net/tcp/tcp_send_unbuffered.c
+++ b/nuttx/net/tcp/tcp_send_unbuffered.c
@@ -59,6 +59,7 @@
#include "netdev/netdev.h"
#include "devif/devif.h"
+#include "arp/arp.h"
#include "tcp/tcp.h"
#include "socket/socket.h"
@@ -388,10 +389,14 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev,
*
* NOTE 2: If we are actually harvesting IP addresses on incoming IP
* packets, then this check should not be necessary; the MAC mapping
- * should already be in the ARP table.
+ * should already be in the ARP table in many cases.
+ *
+ * NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP
+ * address mapping is already in the ARP table.
*/
-#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN)
+#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \
+ !defined(CONFIG_NET_ARP_SEND)
if (pstate->snd_sent != 0 || arp_find(conn->ripaddr) != NULL)
#endif
{
@@ -505,6 +510,7 @@ end_wait:
ssize_t psock_tcp_send(FAR struct socket *psock,
FAR const void *buf, size_t len)
{
+ FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn;
struct send_s state;
net_lock_t save;
int err;
@@ -514,6 +520,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
if (!psock || psock->s_crefs <= 0)
{
+ ndbg("ERROR: Invalid socket\n");
err = EBADF;
goto errout;
}
@@ -522,10 +529,24 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags))
{
+ ndbg("ERROR: Not connected\n");
err = ENOTCONN;
goto errout;
}
+ /* Make sure that the IP address mapping is in the ARP table */
+
+ conn = (FAR struct tcp_conn_s *)psock->s_conn;
+#ifdef CONFIG_NET_ARP_SEND
+ ret = arp_send(conn->ripaddr);
+ if (ret < 0)
+ {
+ ndbg("ERROR: Not reachable\n");
+ err = ENETUNREACH;
+ goto errout;
+ }
+#endif
+
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
@@ -546,8 +567,6 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
if (len > 0)
{
- FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn;
-
/* Allocate resources to receive a callback */
state.snd_cb = tcp_callback_alloc(conn);