diff --git a/ChangeLog b/ChangeLog
index 9c9386b0c9b187283906dcec863f345bcd628bdc..05b8b3f1ae06196f465363a7018401839122a547 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -265,3 +265,4 @@
 	* Fix UDP recvfrom timeout bug
 	* Correct processing of input UDP broadcast packets.
 	* Verfied basic DHCP client functionality (netutils/dhcpc)
+	* Implemented send() timeout logic
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index e6fd36bddeea5942d3fa060233aecc6b08db5454..a0546ee630de6911371db4a6208faf8816cf35d4 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -753,6 +753,7 @@ Other memory:
 	* Fix UDP recvfrom timeout bug
 	* Correct processing of input UDP broadcast packets.
 	* Verfied basic DHCP client functionality (netutils/dhcpc)
+	* Implemented send() timeout logic
 </pre></ul>
 
 <table width ="100%">
diff --git a/TODO b/TODO
index 500013d146fa78c31050f417e8f082f50d88c5a0..a41b5f59d842e1f9160b6513ca781546d4fab6a0 100644
--- a/TODO
+++ b/TODO
@@ -29,10 +29,8 @@ o C++ Support
 - Need to call static constructors
 
 o Network
-- Did not implement send() and sendto() timeouts.  Option is setable via setsockopt,
-  but is not implemented.
-- uIP's netutils/smtp, dpcpc, resolv, webclient -- untested
-- Should implement SOCK_RAW
+- uIP's netutils/smtp, resolv, webclient -- untested
+- Should implement SOCK_RAW, SOCK_PACKET
 - uIP polling issues:
   (1) Current logic will not support multiple ethernet drivers.  Each driver should
       poll on TCP connections connect on the network supported by the driver; UDP
@@ -44,6 +42,7 @@ o Network
 - uIP/Socket callback logic is not thread safe. This means that a socket cannot be
   used concurrently by two threads.  Minimal fix:  Add mutex to support exclusion.
 - IPv6 support is incomplete
+- Incoming UDP broadcast should only be accepted if listening on INADDR_ANY(?)
 
 o USB
 - Implement USB device support
diff --git a/net/accept.c b/net/accept.c
index 8c32eac3a888cc146e8a91f0bb5ffecc34ce18bb..0541fa0617ab33fb813b38428eabc9859a321f7b 100644
--- a/net/accept.c
+++ b/net/accept.c
@@ -111,12 +111,7 @@ static inline void accept_tcpsender(struct uip_conn *conn, struct accept_s *psta
     {
       addr->sin_family = AF_INET;
       addr->sin_port   = conn->rport;
-
-#ifdef CONFIG_NET_IPv6
       uip_ipaddr_copy(addr->sin_addr.s_addr, conn->ripaddr);
-#else
-      uip_ipaddr_copy(addr->sin_addr.s_addr, conn->ripaddr);
-#endif
     }
 }
 #endif
@@ -400,4 +395,4 @@ errout:
   return ERROR;
 }
 
-#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS && CONFIG_NET_TCP*/
+#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS && CONFIG_NET_TCP */
diff --git a/net/send.c b/net/send.c
index 67acc62856bcd1d862c161237b0bbbd661035969..15a7adc0b544ac7c96becad11d20ddc6c59cefcf 100644
--- a/net/send.c
+++ b/net/send.c
@@ -75,6 +75,9 @@ struct send_s
   ssize_t            snd_sent;    /* The number of bytes sent */
   uint32             snd_isn;     /* Initial sequence number */
   uint32             snd_acked;   /* The number of bytes acked */
+#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+  uint32             snd_time;    /* last send time for determining timeout */
+#endif
 };
 
 /****************************************************************************
@@ -129,6 +132,46 @@ static uint32 send_getackno(struct uip_driver_s *dev)
    return ntohl(tmp);
 }
 
+/****************************************************************************
+ * Function: send_timeout
+ *
+ * Description:
+ *   Check for send timeout.
+ *
+ * Parameters:
+ *   pstate   send state structure
+ *
+ * Returned Value:
+ *   TRUE:timeout FALSE:no timeout
+ *
+ * Assumptions:
+ *   Running at the interrupt level
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+static inline int send_timeout(struct send_s *pstate)
+{
+  FAR struct socket *psock = 0;
+
+  /* Check for a timeout configured via setsockopts(SO_SNDTIMEO).
+   * If none... we well let the send wait forever.
+   */
+
+  psock = pstate->snd_sock;
+  if (psock && psock->s_sndtimeo != 0)
+    {
+      /* Check if the configured timeout has elapsed */
+
+      return net_timeo(pstate->snd_time, psock->s_sndtimeo);
+    }
+
+  /* No timeout */
+
+  return FALSE;
+}
+#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
+
 /****************************************************************************
  * Function: send_interrupt
  *
@@ -149,7 +192,8 @@ static uint32 send_getackno(struct uip_driver_s *dev)
  *
  ****************************************************************************/
 
-static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags)
+static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn,
+                            uint8 flags)
 {
   struct send_s *pstate = (struct send_s *)conn->data_private;
 
@@ -161,10 +205,10 @@ static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uin
 
   if ((flags & UIP_ACKDATA) != 0)
     {
-      /* The current acknowledgement number number is the (relative) offset of
-       * the of the next byte needed by the receiver.  The snd_isn is the offset
-       * of the first byte to send to the receiver.  The difference is the number
-       * of bytes to be acknowledged.
+      /* The current acknowledgement number number is the (relative) offset
+       * of the of the next byte needed by the receiver.  The snd_isn is the
+       * offset of the first byte to send to the receiver.  The difference
+       * is the number of bytes to be acknowledged.
        */
 
       pstate->snd_acked = send_getackno(dev) - pstate->snd_isn;
@@ -175,23 +219,14 @@ static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uin
 
       if ( pstate->snd_acked >= pstate->snd_buflen)
         {
-          /* Yes.  Then pstate->snd_len should hold the number of bytes actually
-           * sent.
-           *
-           * Don't allow any further call backs.
-           */
-
-          conn->data_flags   = 0;
-          conn->data_private = NULL;
-          conn->data_event   = NULL;
-
-          /* Wake up the waiting thread, returning the number of bytes
+          /* Yes.  Then pstate->snd_len should hold the number of bytes
            * actually sent.
            */
 
-          sem_post(&pstate->snd_sem);
-          return flags;
+          goto end_wait;
         }
+
+      /* No.. fall through to send more data if necessary */
     }
 
   /* Check if we are being asked to retransmit data */
@@ -203,25 +238,19 @@ static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uin
        */
 
       pstate->snd_sent = pstate->snd_acked;
+
+      /* Fall through to re-send data from the last that was ACKed */
     }
 
  /* Check for a loss of connection */
 
   else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
     {
-      /* Stop further callbacks */
-
-      conn->data_flags   = 0;
-      conn->data_private = NULL;
-      conn->data_event   = NULL;
-
       /* Report not connected */
 
+      nvdbg("Lost connection\n");
       pstate->snd_sent = -ENOTCONN;
-
-      /* Wake up the waiting thread */
-
-      sem_post(&pstate->snd_sem);
+      goto end_wait;
     }
 
   /* We get here if (1) not all of the data has been ACKed, (2) we have been
@@ -250,6 +279,35 @@ static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uin
             pstate->snd_acked, pstate->snd_sent, pstate->snd_buflen);
     }
 
+  /* All data has been send and we are just waiting for ACK or re-tranmist
+   * indications to complete the send.  Check for a timeout.
+   */
+
+#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+  else if (send_timeout(pstate))
+    {
+      /* Yes.. report the timeout */
+
+      nvdbg("TCP timeout\n");
+      pstate->snd_sent = -EAGAIN;
+      goto end_wait;
+    }
+#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
+
+  /* Continue waiting */
+
+  return flags;
+
+end_wait:
+  /* Do not allow any further callbacks */
+
+  conn->data_flags   = 0;
+  conn->data_private = NULL;
+  conn->data_event   = NULL;
+
+  /* Wake up the waiting thread */
+
+  sem_post(&pstate->snd_sem);
   return flags;
 }