summaryrefslogtreecommitdiff
path: root/nuttx/net/uip
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-11-19 23:09:39 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-11-19 23:09:39 +0000
commit0cc9b5ef69aa200c2610f3e87281fe9aa9d7d389 (patch)
tree3b0f4ca1b8066bdd68f41c4640f074c9b5535ffa /nuttx/net/uip
parentbefc37ada0b901ad7c315e4089976508396d496b (diff)
downloadpx4-nuttx-0cc9b5ef69aa200c2610f3e87281fe9aa9d7d389.tar.gz
px4-nuttx-0cc9b5ef69aa200c2610f3e87281fe9aa9d7d389.tar.bz2
px4-nuttx-0cc9b5ef69aa200c2610f3e87281fe9aa9d7d389.zip
Add TCP readahead logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@387 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net/uip')
-rw-r--r--nuttx/net/uip/Make.defs3
-rw-r--r--nuttx/net/uip/uip-arp.c18
-rw-r--r--nuttx/net/uip/uip-chksum.c2
-rw-r--r--nuttx/net/uip/uip-fw.c230
-rw-r--r--nuttx/net/uip/uip-icmpinput.c4
-rw-r--r--nuttx/net/uip/uip-initialize.c6
-rw-r--r--nuttx/net/uip/uip-input.c10
-rw-r--r--nuttx/net/uip/uip-internal.h8
-rw-r--r--nuttx/net/uip/uip-listen.c10
-rw-r--r--nuttx/net/uip/uip-send.c2
-rw-r--r--nuttx/net/uip/uip-setipid.c2
-rw-r--r--nuttx/net/uip/uip-split.c132
-rw-r--r--nuttx/net/uip/uip-tcpcallback.c103
-rw-r--r--nuttx/net/uip/uip-tcpconn.c20
-rw-r--r--nuttx/net/uip/uip-tcpinput.c2
-rw-r--r--nuttx/net/uip/uip-tcpreadahead.c132
-rw-r--r--nuttx/net/uip/uip-tcpsend.c4
-rw-r--r--nuttx/net/uip/uip-udpconn.c6
-rw-r--r--nuttx/net/uip/uip-udpsend.c2
19 files changed, 495 insertions, 201 deletions
diff --git a/nuttx/net/uip/Make.defs b/nuttx/net/uip/Make.defs
index 8a232ffbf..4256e72e9 100644
--- a/nuttx/net/uip/Make.defs
+++ b/nuttx/net/uip/Make.defs
@@ -50,7 +50,8 @@ endif
# TCP source files
UIP_CSRCS += uip-tcpconn.c uip-tcppoll.c uip-tcptimer.c uip-tcpsend.c \
- uip-tcpinput.c uip-tcpappsend.c uip-listen.c uip-tcpcallback.c
+ uip-tcpinput.c uip-tcpappsend.c uip-listen.c uip-tcpcallback.c \
+ uip-tcpreadahead.c
# UDP source files
diff --git a/nuttx/net/uip/uip-arp.c b/nuttx/net/uip/uip-arp.c
index 13dd1ba03..4d95d16d3 100644
--- a/nuttx/net/uip/uip-arp.c
+++ b/nuttx/net/uip/uip-arp.c
@@ -129,7 +129,7 @@ static const struct uip_eth_addr broadcast_ethaddr =
{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
static const uint16 broadcast_ipaddr[2] = {0xffff, 0xffff};
-static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
+static struct arp_entry arp_table[CONFIG_NET_ARPTAB_SIZE];
static uint8 g_arptime;
@@ -170,7 +170,7 @@ static void uip_arp_update(uint16 *pipaddr, uint8 *ethaddr)
* inserted in the ARP table.
*/
- for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
+ for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
@@ -198,7 +198,7 @@ static void uip_arp_update(uint16 *pipaddr, uint8 *ethaddr)
/* First, we try to find an unused entry in the ARP table. */
- for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
+ for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
if (tabptr->at_ipaddr == 0)
@@ -211,11 +211,11 @@ static void uip_arp_update(uint16 *pipaddr, uint8 *ethaddr)
* throw it away.
*/
- if (i == UIP_ARPTAB_SIZE)
+ if (i == CONFIG_NET_ARPTAB_SIZE)
{
uint8 tmpage = 0;
int j = 0;
- for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
+ for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
if (g_arptime - tabptr->at_time > tmpage)
@@ -246,7 +246,7 @@ static void uip_arp_update(uint16 *pipaddr, uint8 *ethaddr)
void uip_arp_init(void)
{
int i;
- for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
+ for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)
{
memset(&arp_table[i].at_ipaddr, 0, sizeof(in_addr_t));
}
@@ -265,7 +265,7 @@ void uip_arp_timer(void)
int i;
++g_arptime;
- for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
+ for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
if (tabptr->at_ipaddr != 0 && g_arptime - tabptr->at_time >= UIP_ARP_MAXAGE)
@@ -451,7 +451,7 @@ void uip_arp_out(struct uip_driver_s *dev)
/* Check if we already have this destination address in the ARP table */
- for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
+ for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
if (uip_ipaddr_cmp(ipaddr, tabptr->at_ipaddr))
@@ -460,7 +460,7 @@ void uip_arp_out(struct uip_driver_s *dev)
}
}
- if (i == UIP_ARPTAB_SIZE)
+ if (i == CONFIG_NET_ARPTAB_SIZE)
{
/* The destination address was not in our ARP table, so we
* overwrite the IP packet with an ARP request.
diff --git a/nuttx/net/uip/uip-chksum.c b/nuttx/net/uip/uip-chksum.c
index c8c173b95..6faaf9817 100644
--- a/nuttx/net/uip/uip-chksum.c
+++ b/nuttx/net/uip/uip-chksum.c
@@ -223,7 +223,7 @@ uint16 uip_udpchksum(struct uip_driver_s *dev)
{
return upper_layer_chksum(dev, UIP_PROTO_UDP);
}
-#endif /* UIP_UDP_CHECKSUMS */
+#endif
#endif /* UIP_ARCH_CHKSUM */
#endif /* CONFIG_NET */
diff --git a/nuttx/net/uip/uip-fw.c b/nuttx/net/uip/uip-fw.c
index 187fb6c39..fa9b5fc4e 100644
--- a/nuttx/net/uip/uip-fw.c
+++ b/nuttx/net/uip/uip-fw.c
@@ -103,15 +103,19 @@ struct icmpip_hdr
};
/* ICMP ECHO. */
+
#define ICMP_ECHO 8
/* ICMP TIME-EXCEEDED. */
+
#define ICMP_TE 11
/* Pointer to the TCP/IP headers of the packet in the d_buf buffer. */
+
#define BUF ((struct tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
/* Pointer to the ICMP/IP headers of the packet in the d_buf buffer. */
+
#define ICMPBUF ((struct icmpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
/* Certain fields of an IP packet that are used for identifying
@@ -158,11 +162,12 @@ void uip_fw_init(void)
{
struct uip_fw_netif *t;
defaultnetif = NULL;
- while(netifs != NULL) {
- t = netifs;
- netifs = netifs->next;
- t->next = NULL;
- }
+ while(netifs != NULL)
+ {
+ t = netifs;
+ netifs = netifs->next;
+ t->next = NULL;
+ }
}
/* Send out an ICMP TIME-EXCEEDED message.
@@ -176,18 +181,24 @@ static void time_exceeded(struct uip_driver_s *dev)
in_addr_t tmp_addr;
/* We don't send out ICMP errors for ICMP messages. */
- if (ICMPBUF->proto == UIP_PROTO_ICMP) {
- dev->d_len = 0;
- return;
- }
+
+ if (ICMPBUF->proto == UIP_PROTO_ICMP)
+ {
+ dev->d_len = 0;
+ return;
+ }
+
/* Copy fields from packet header into payload of this ICMP packet. */
+
memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28);
/* Set the ICMP type and code. */
- ICMPBUF->type = ICMP_TE;
+
+ ICMPBUF->type = ICMP_TE;
ICMPBUF->icode = 0;
/* Calculate the ICMP checksum. */
+
ICMPBUF->icmpchksum = 0;
ICMPBUF->icmpchksum = ~uip_chksum((uint16 *)&(ICMPBUF->type), 36);
@@ -195,30 +206,34 @@ static void time_exceeded(struct uip_driver_s *dev)
* original packet.
*/
- tmp_addr = BUF->destipaddr;
+ tmp_addr = BUF->destipaddr;
BUF->destipaddr = BUF->srcipaddr;
- BUF->srcipaddr = tmp_addr;
+ BUF->srcipaddr = tmp_addr;
/* Set our IP address as the source address. */
BUF->srcipaddr = dev->d_ipaddr;
/* The size of the ICMP time exceeded packet is 36 + the size of the
- IP header (20) = 56. */
- dev->d_len = 56;
+ * IP header (20) = 56.
+ */
+
+ dev->d_len = 56;
ICMPBUF->len[0] = 0;
ICMPBUF->len[1] = dev->d_len;
/* Fill in the other fields in the IP header. */
- ICMPBUF->vhl = 0x45;
- ICMPBUF->tos = 0;
+
+ ICMPBUF->vhl = 0x45;
+ ICMPBUF->tos = 0;
ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
- ICMPBUF->ttl = UIP_TTL;
- ICMPBUF->proto = UIP_PROTO_ICMP;
+ ICMPBUF->ttl = UIP_TTL;
+ ICMPBUF->proto = UIP_PROTO_ICMP;
/* Calculate IP checksum. */
- ICMPBUF->ipchksum = 0;
- ICMPBUF->ipchksum = ~(uip_ipchksum(dev));
+
+ ICMPBUF->ipchksum = 0;
+ ICMPBUF->ipchksum = ~(uip_ipchksum(dev));
}
/* Register a packet in the forwarding cache so that it won't be
@@ -231,31 +246,36 @@ static void fwcache_register(struct uip_driver_s *dev)
int i, oldest;
oldest = FW_TIME;
- fw = NULL;
+ fw = NULL;
/* Find the oldest entry in the cache. */
- for (i = 0; i < FWCACHE_SIZE; ++i) {
- if (fwcache[i].timer == 0) {
- fw = &fwcache[i];
- break;
- } else if (fwcache[i].timer <= oldest) {
- fw = &fwcache[i];
- oldest = fwcache[i].timer;
+
+ for (i = 0; i < FWCACHE_SIZE; ++i)
+ {
+ if (fwcache[i].timer == 0)
+ {
+ fw = &fwcache[i];
+ break;
+ }
+ else if (fwcache[i].timer <= oldest)
+ {
+ fw = &fwcache[i];
+ oldest = fwcache[i].timer;
+ }
}
- }
- fw->timer = FW_TIME;
- fw->ipid = BUF->ipid;
- fw->srcipaddr = BUF->srcipaddr;
+ fw->timer = FW_TIME;
+ fw->ipid = BUF->ipid;
+ fw->srcipaddr = BUF->srcipaddr;
fw->destipaddr = BUF->destipaddr;
- fw->proto = BUF->proto;
+ fw->proto = BUF->proto;
#if notdef
fw->payload[0] = BUF->srcport;
fw->payload[1] = BUF->destport;
#endif
#if UIP_REASSEMBLY > 0
- fw->len = BUF->len;
- fw->offset = BUF->ipoffset;
+ fw->len = BUF->len;
+ fw->offset = BUF->ipoffset;
#endif
}
@@ -301,35 +321,44 @@ uint8 uip_fw_output(struct uip_driver_s *dev)
{
struct uip_fw_netif *netif;
- if (dev->d_len == 0) {
- return UIP_FW_ZEROLEN;
- }
+ if (dev->d_len == 0)
+ {
+ return UIP_FW_ZEROLEN;
+ }
fwcache_register(dev);
-#if UIP_BROADCAST
+#ifdef CONFIG_NET_BROADCAST
/* Link local broadcasts go out on all interfaces. */
+
if (/*BUF->proto == UIP_PROTO_UDP &&*/
- BUF->destipaddr[0] == 0xffff &&
- BUF->destipaddr[1] == 0xffff) {
- if (defaultnetif != NULL) {
- defaultnetif->output();
- }
- for (netif = netifs; netif != NULL; netif = netif->next) {
- netif->output();
+ BUF->destipaddr[0] == 0xffff &&
+ BUF->destipaddr[1] == 0xffff)
+ {
+ if (defaultnetif != NULL)
+ {
+ defaultnetif->output();
+ }
+ for (netif = netifs; netif != NULL; netif = netif->next)
+ {
+ netif->output();
+ }
+ return UIP_FW_OK;
}
- return UIP_FW_OK;
- }
-#endif /* UIP_BROADCAST */
+#endif
netif = find_netif (dev);
dbg("netif: %p output: %p len: %d\n", netif, netif->output, dev->d_len);
- if (netif == NULL) {
- return UIP_FW_NOROUTE;
- }
+ if (netif == NULL)
+ {
+ return UIP_FW_NOROUTE;
+ }
+
/* If we now have found a suitable network interface, we call its
- output function to send out the packet. */
+ * output function to send out the packet.
+ */
+
return netif->output();
}
@@ -353,39 +382,43 @@ uint8 uip_fw_forward(struct uip_driver_s *dev)
}
/* If we use ping IP address configuration, and our IP address is
- not yet configured, we should intercept all ICMP echo packets. */
-#if UIP_PINGADDRCONF
+ * not yet configured, we should intercept all ICMP echo packets.
+ */
+
+#ifdef CONFIG_NET_PINGADDRCONF
if (dev->d_ipaddr == 0 && BUF->proto == UIP_PROTO_ICMP && ICMPBUF->type == ICMP_ECHO)
{
return UIP_FW_LOCAL;
}
-#endif /* UIP_PINGADDRCONF */
+#endif
/* Check if the packet is in the forwarding cache already, and if so
we drop it. */
- for (fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
- if (fw->timer != 0 &&
+ for (fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw)
+ {
+ if (fw->timer != 0 &&
#if UIP_REASSEMBLY > 0
- fw->len == BUF->len &&
- fw->offset == BUF->ipoffset &&
+ fw->len == BUF->len &&
+ fw->offset == BUF->ipoffset &&
#endif
- fw->ipid == BUF->ipid &&
- fw->srcipaddr == BUF->srcipaddr &&
- fw->destipaddr == BUF->destipaddr &&
+ fw->ipid == BUF->ipid &&
+ fw->srcipaddr == BUF->srcipaddr &&
+ fw->destipaddr == BUF->destipaddr &&
#if notdef
- fw->payload[0] == BUF->srcport &&
- fw->payload[1] == BUF->destport &&
+ fw->payload[0] == BUF->srcport &&
+ fw->payload[1] == BUF->destport &&
#endif
- fw->proto == BUF->proto) {
- /* Drop packet. */
- return UIP_FW_FORWARDED;
+ fw->proto == BUF->proto)
+ {
+ /* Drop packet. */
+ return UIP_FW_FORWARDED;
+ }
}
- }
/* If the TTL reaches zero we produce an ICMP time exceeded message
- in the d_buf buffer and forward that packet back to the sender
- of the packet.
+ * in the d_buf buffer and forward that packet back to the sender
+ * of the packet.
*/
if (BUF->ttl <= 1)
@@ -400,28 +433,37 @@ uint8 uip_fw_forward(struct uip_driver_s *dev)
}
/* Decrement the TTL (time-to-live) value in the IP header */
+
BUF->ttl = BUF->ttl - 1;
/* Update the IP checksum. */
- if (BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
- BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
- } else {
- BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
- }
-
- if (dev->d_len > 0) {
- dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
- uip_fw_output(dev);
- }
-
-#if UIP_BROADCAST
- if (BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
- return UIP_FW_LOCAL;
- }
-#endif /* UIP_BROADCAST */
+
+ if (BUF->ipchksum >= HTONS(0xffff - 0x0100))
+ {
+ BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
+ }
+ else
+ {
+ BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
+ }
+
+ if (dev->d_len > 0)
+ {
+ dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
+ uip_fw_output(dev);
+ }
+
+#ifdef CONFIG_NET_BROADCAST
+ if (BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff)
+ {
+ return UIP_FW_LOCAL;
+ }
+#endif
/* Return non-zero to indicate that the packet was forwarded and that no
- other processing should be made. */
+ * other processing should be made.
+ */
+
return UIP_FW_FORWARDED;
}
@@ -434,7 +476,7 @@ uint8 uip_fw_forward(struct uip_driver_s *dev)
void uip_fw_register(struct uip_fw_netif *netif)
{
netif->next = netifs;
- netifs = netif;
+ netifs = netif;
}
/* Register a default network interface.
@@ -456,9 +498,11 @@ void uip_fw_default(struct uip_fw_netif *netif)
void uip_fw_periodic(void)
{
struct fwcache_entry *fw;
- for (fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
- if (fw->timer > 0) {
- --fw->timer;
+ for (fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw)
+ {
+ if (fw->timer > 0)
+ {
+ --fw->timer;
+ }
}
- }
}
diff --git a/nuttx/net/uip/uip-icmpinput.c b/nuttx/net/uip/uip-icmpinput.c
index 8dd276330..5dae94bd7 100644
--- a/nuttx/net/uip/uip-icmpinput.c
+++ b/nuttx/net/uip/uip-icmpinput.c
@@ -119,12 +119,12 @@ void uip_icmpinput(struct uip_driver_s *dev)
* ourself.
*/
-#if UIP_PINGADDRCONF
+#ifdef CONFIG_NET_PINGADDRCONF
if (dev->d_ipaddr == 0)
{
dev->d_ipaddr = ICMPBUF->destipaddr;
}
-#endif /* UIP_PINGADDRCONF */
+#endif
ICMPBUF->type = ICMP_ECHO_REPLY;
diff --git a/nuttx/net/uip/uip-initialize.c b/nuttx/net/uip/uip-initialize.c
index 3a7701cbe..2e00c5d9c 100644
--- a/nuttx/net/uip/uip-initialize.c
+++ b/nuttx/net/uip/uip-initialize.c
@@ -125,6 +125,12 @@ void uip_initialize(void)
uip_tcpinit();
+ /* Initialize the TCP/IP read-ahead buffering */
+
+#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
+ uip_tcpreadaheadinit();
+#endif
+
/* Initialize the UDP connection structures */
#ifdef CONFIG_NET_UDP
diff --git a/nuttx/net/uip/uip-input.c b/nuttx/net/uip/uip-input.c
index 1c3de79e6..71f9b8b9a 100644
--- a/nuttx/net/uip/uip-input.c
+++ b/nuttx/net/uip/uip-input.c
@@ -108,7 +108,7 @@
/* IP fragment re-assembly */
#define IP_MF 0x20
-#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
+#define UIP_REASS_BUFSIZE (CONFIG_NET_BUFSIZE - UIP_LLH_LEN)
#define UIP_REASS_FLAG_LASTFRAG 0x01
/****************************************************************************
@@ -392,7 +392,7 @@ void uip_input(struct uip_driver_s *dev)
* packets.
*/
-#if UIP_PINGADDRCONF && !CONFIG_NET_IPv6
+#if defined(CONFIG_NET_PINGADDRCONF) && !defined(CONFIG_NET_IPv6)
if (BUF->proto == UIP_PROTO_ICMP)
{
dbg("Possible ping config packet received\n");
@@ -400,7 +400,7 @@ void uip_input(struct uip_driver_s *dev)
goto done;
}
else
-#endif /* UIP_PINGADDRCONF */
+#endif
{
dbg("No IP address assigned\n");
goto drop;
@@ -412,13 +412,13 @@ void uip_input(struct uip_driver_s *dev)
* UDP packet, which may be destined to us.
*/
-#if UIP_BROADCAST
+#ifdef CONFIG_NET_BROADCAST
if (BUF->proto == UIP_PROTO_UDP && uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
{
uip_udpinput(dev);
return;
}
-#endif /* UIP_BROADCAST */
+#endif
/* Check if the packet is destined for our IP address. */
#ifndef CONFIG_NET_IPv6
diff --git a/nuttx/net/uip/uip-internal.h b/nuttx/net/uip/uip-internal.h
index 118ccd53f..c358d431f 100644
--- a/nuttx/net/uip/uip-internal.h
+++ b/nuttx/net/uip/uip-internal.h
@@ -194,6 +194,14 @@ EXTERN void uip_udpcallback(struct uip_driver_s *dev,
EXTERN void uip_icmpinput(struct uip_driver_s *dev);
+/* Defined in uip-tcpreadahead.c ********************************************/
+
+#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
+EXTERN void uip_tcpreadaheadinit(void);
+EXTERN struct uip_readahead_s *uip_tcpreadaheadalloc(void);
+EXTERN void uip_tcpreadaheadrelease(struct uip_readahead_s *buf);
+#endif /* CONFIG_NET_NTCP_READAHEAD_BUFFERS */
+
#undef EXTERN
#ifdef __cplusplus
}
diff --git a/nuttx/net/uip/uip-listen.c b/nuttx/net/uip/uip-listen.c
index e7ee8ffc3..643d054cb 100644
--- a/nuttx/net/uip/uip-listen.c
+++ b/nuttx/net/uip/uip-listen.c
@@ -57,7 +57,7 @@
/* The uip_listenports list all currently listening ports. */
-static uint16 uip_listenports[UIP_LISTENPORTS];
+static uint16 uip_listenports[CONFIG_NET_MAX_LISTENPORTS];
/****************************************************************************
* Private Functions
@@ -82,7 +82,7 @@ static uint16 uip_listenports[UIP_LISTENPORTS];
void uip_listeninit(void)
{
int ndx;
- for (ndx = 0; ndx < UIP_LISTENPORTS; ndx++)
+ for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++)
{
uip_listenports[ndx] = 0;
}
@@ -106,7 +106,7 @@ int uip_unlisten(uint16 port)
int ret = -EINVAL;
flags = irqsave();
- for (ndx = 0; ndx < UIP_LISTENPORTS; ndx++)
+ for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++)
{
if (uip_listenports[ndx] == port)
{
@@ -137,7 +137,7 @@ int uip_listen(uint16 port)
int ret = -ENOBUFS;
flags = irqsave();
- for (ndx = 0; ndx < UIP_LISTENPORTS; ndx++)
+ for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++)
{
if (uip_listenports[ndx] == 0)
{
@@ -164,7 +164,7 @@ int uip_listen(uint16 port)
boolean uip_islistener(uint16 portno)
{
int ndx;
- for (ndx = 0; ndx < UIP_LISTENPORTS; ndx++)
+ for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++)
{
if (uip_listenports[ndx] == portno)
{
diff --git a/nuttx/net/uip/uip-send.c b/nuttx/net/uip/uip-send.c
index 6cdfd7252..93096168a 100644
--- a/nuttx/net/uip/uip-send.c
+++ b/nuttx/net/uip/uip-send.c
@@ -93,7 +93,7 @@
void uip_send(struct uip_driver_s *dev, const void *buf, int len)
{
- if (dev && len > 0 && len < UIP_BUFSIZE)
+ if (dev && len > 0 && len < CONFIG_NET_BUFSIZE)
{
dev->d_sndlen = len;
memcpy(dev->d_snddata, buf, len );
diff --git a/nuttx/net/uip/uip-setipid.c b/nuttx/net/uip/uip-setipid.c
index 71467b0f8..5726c7c7a 100644
--- a/nuttx/net/uip/uip-setipid.c
+++ b/nuttx/net/uip/uip-setipid.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * net/uip/uip-udpcallback.c
+ * net/uip/uip-setipid.c
*
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
diff --git a/nuttx/net/uip/uip-split.c b/nuttx/net/uip/uip-split.c
index 8d75487d2..68b19d275 100644
--- a/nuttx/net/uip/uip-split.c
+++ b/nuttx/net/uip/uip-split.c
@@ -42,85 +42,103 @@
void uip_split_output(struct uip_driver_s *dev)
{
- uint16 tcplen, len1, len2;
+ uint16 tcplen;
+ uint16 len1;
+ uint16 len2;
/* We only try to split maximum sized TCP segments. */
- if(BUF->proto == UIP_PROTO_TCP &&
- dev->d_len == UIP_BUFSIZE - UIP_LLH_LEN) {
-
- tcplen = dev->d_len - UIP_TCPIP_HLEN;
- /* Split the segment in two. If the original packet length was
- odd, we make the second packet one byte larger. */
- len1 = len2 = tcplen / 2;
- if(len1 + len2 < tcplen) {
- ++len2;
- }
- /* Create the first packet. This is done by altering the length
- field of the IP header and updating the checksums. */
- dev->d_len = len1 + UIP_TCPIP_HLEN;
+ if (BUF->proto == UIP_PROTO_TCP &&
+ dev->d_len == CONFIG_NET_BUFSIZE - UIP_LLH_LEN)
+ {
+ tcplen = dev->d_len - UIP_TCPIP_HLEN;
+
+ /* Split the segment in two. If the original packet length was
+ * odd, we make the second packet one byte larger.
+ */
+
+ len1 = len2 = tcplen / 2;
+ if (len1 + len2 < tcplen)
+ {
+ ++len2;
+ }
+
+ /* Create the first packet. This is done by altering the length
+ * field of the IP header and updating the checksums.
+ */
+
+ dev->d_len = len1 + UIP_TCPIP_HLEN;
#ifdef CONFIG_NET_IPv6
- /* For IPv6, the IP length field does not include the IPv6 IP header
- length. */
- BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
- BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
+ /* For IPv6, the IP length field does not include the IPv6 IP header
+ * length.
+ */
+ BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
+ BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
#else /* CONFIG_NET_IPv6 */
- BUF->len[0] = dev->d_len >> 8;
- BUF->len[1] = dev->d_len & 0xff;
+ BUF->len[0] = dev->d_len >> 8;
+ BUF->len[1] = dev->d_len & 0xff;
#endif /* CONFIG_NET_IPv6 */
- /* Recalculate the TCP checksum. */
- BUF->tcpchksum = 0;
- BUF->tcpchksum = ~(uip_tcpchksum(dev));
+ /* Recalculate the TCP checksum. */
+
+ BUF->tcpchksum = 0;
+ BUF->tcpchksum = ~(uip_tcpchksum(dev));
#ifndef CONFIG_NET_IPv6
- /* Recalculate the IP checksum. */
- BUF->ipchksum = 0;
- BUF->ipchksum = ~(uip_ipchksum(dev));
+ /* Recalculate the IP checksum. */
+
+ BUF->ipchksum = 0;
+ BUF->ipchksum = ~(uip_ipchksum(dev));
#endif /* CONFIG_NET_IPv6 */
- /* Transmit the first packet. */
- /* uip_fw_output();*/
- tcpip_output();
+ /* Transmit the first packet. */
+ /* uip_fw_output();*/
+ tcpip_output();
+
+ /* Now, create the second packet. To do this, it is not enough to
+ * just alter the length field, but we must also update the TCP
+ * sequence number and point the d_appdata to a new place in
+ * memory. This place is detemined by the length of the first
+ * packet (len1).
+ */
- /* Now, create the second packet. To do this, it is not enough to
- just alter the length field, but we must also update the TCP
- sequence number and point the d_appdata to a new place in
- memory. This place is detemined by the length of the first
- packet (len1). */
- dev->d_len = len2 + UIP_TCPIP_HLEN;
+ dev->d_len = len2 + UIP_TCPIP_HLEN;
#ifdef CONFIG_NET_IPv6
- /* For IPv6, the IP length field does not include the IPv6 IP header
- length. */
- BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
- BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
+ /* For IPv6, the IP length field does not include the IPv6 IP header
+ * length.
+ */
+
+ BUF->len[0] = ((dev->d_len - UIP_IPH_LEN) >> 8);
+ BUF->len[1] = ((dev->d_len - UIP_IPH_LEN) & 0xff);
#else /* CONFIG_NET_IPv6 */
- BUF->len[0] = dev->d_len >> 8;
- BUF->len[1] = dev->d_len & 0xff;
+ BUF->len[0] = dev->d_len >> 8;
+ BUF->len[1] = dev->d_len & 0xff;
#endif /* CONFIG_NET_IPv6 */
- /* dev->d_appdata += len1;*/
- memcpy(dev->d_appdata, dev->d_appdata + len1, len2);
+ /* dev->d_appdata += len1;*/
+ memcpy(dev->d_appdata, dev->d_appdata + len1, len2);
- uip_incr32(BUF->seqno, len1);
+ uip_incr32(BUF->seqno, len1);
- /* Recalculate the TCP checksum. */
+ /* Recalculate the TCP checksum. */
- BUF->tcpchksum = 0;
- BUF->tcpchksum = ~(uip_tcpchksum(dev));
+ BUF->tcpchksum = 0;
+ BUF->tcpchksum = ~(uip_tcpchksum(dev));
#ifndef CONFIG_NET_IPv6
- /* Recalculate the IP checksum. */
+ /* Recalculate the IP checksum. */
- BUF->ipchksum = 0;
- BUF->ipchksum = ~(uip_ipchksum(dev));
+ BUF->ipchksum = 0;
+ BUF->ipchksum = ~(uip_ipchksum(dev));
#endif /* CONFIG_NET_IPv6 */
- /* Transmit the second packet. */
- /* uip_fw_output();*/
- tcpip_output();
- } else {
- /* uip_fw_output();*/
- tcpip_output();
- }
+ /* Transmit the second packet. */
+ /* uip_fw_output();*/
+ tcpip_output();
+ }
+ else
+ {
+ /* uip_fw_output();*/
+ tcpip_output();
+ }
}
diff --git a/nuttx/net/uip/uip-tcpcallback.c b/nuttx/net/uip/uip-tcpcallback.c
index 973a2f2a2..311323059 100644
--- a/nuttx/net/uip/uip-tcpcallback.c
+++ b/nuttx/net/uip/uip-tcpcallback.c
@@ -42,6 +42,7 @@
#ifdef CONFIG_NET
#include <sys/types.h>
+#include <string.h>
#include <debug.h>
#include <net/uip/uipopt.h>
@@ -59,6 +60,89 @@
****************************************************************************/
/****************************************************************************
+ * Function: uip_dataevent
+ *
+ * Description:
+ * This is the default data_event handler that is called when there is no
+ * use data handler in place
+ *
+ * Assumptions:
+ * This function is called at the interrupt level with interrupts disabled.
+ *
+ ****************************************************************************/
+
+static inline uint8
+uip_dataevent(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags)
+{
+#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
+ struct uip_readahead_s *readahead;
+ uint16 recvlen;
+#endif
+ uint8 ret = flags;
+
+ /* Is there new data? With non-zero length? (Certain connection events
+ * can have zero-length with UIP_NEWDATA set just to cause an ACK).
+ */
+
+ if (uip_newdata_event(flags) && dev->d_len > 0)
+ {
+#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
+ /* Allocate a read-ahead buffer to hold the newly received data */
+
+ readahead = uip_tcpreadaheadalloc();
+ if (readahead)
+ {
+ /* Get the length of the data to buffer. If the sizes of the
+ * read-ahead buffers are picked correct, they should always
+ * hold the full received packet.\
+ */
+
+ if (dev->d_len > CONFIG_NET_TCP_READAHEAD_BUFSIZE)
+ {
+ recvlen = CONFIG_NET_TCP_READAHEAD_BUFSIZE;
+ }
+ else
+ {
+ recvlen = dev->d_len;
+ }
+
+ /* Copy the new appdata into the read-ahead buffer */
+
+ memcpy(readahead->rh_buffer, dev->d_appdata, recvlen);
+ readahead->rh_nbytes = recvlen;
+ vdbg("Buffered %d bytes (of %d)\n", recvlen, dev->d_len);
+
+ /* Save the readahead buffer in the connection structure where
+ * it can be found with recv() is called.
+ */
+
+ sq_addlast(&readahead->rh_node, &conn->readahead);
+
+ /* Indicate that all of the data in the buffer has been consumed */
+
+ dev->d_len = 0;
+ }
+ else
+#endif
+ {
+ /* There is no handler to receive new data and there are no free
+ * read-ahead buffers to retain the data. In this case, clear the
+ * UIP_NEWDATA bit so that no ACK will be sent and drop the packet.
+ */
+
+#ifdef CONFIG_NET_STATISTICS
+ uip_stat.tcp.syndrop++;
+ uip_stat.tcp.drop++;
+#endif
+ ret &= ~UIP_NEWDATA;
+ dev->d_len = 0;
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -104,23 +188,12 @@ uint8 uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, uint8 fla
ret = conn->data_event(dev, conn, flags);
}
- else if ((flags & UIP_CONN_EVENTS) == 0)
+ else
{
- /* There is no handler to receive new data in place and this is not a
- * connection event (which may also include new data that must be ACKed).
- * In this case, clear the UIP_NEWDATA bit so that no ACK will be sent
- * and drop the packet.
- */
-
- dbg("No listener on connection\n");
-
-#ifdef CONFIG_NET_STATISTICS
- uip_stat.tcp.syndrop++;
- uip_stat.tcp.drop++;
-#endif
+ /* There is no handler to receive new data in place */
- ret &= ~UIP_NEWDATA;
- dev->d_len = 0;
+ vdbg("No listener on connection\n");
+ ret = uip_dataevent(dev, conn, flags);
}
/* Check if there is a connection-related event and a connection
diff --git a/nuttx/net/uip/uip-tcpconn.c b/nuttx/net/uip/uip-tcpconn.c
index c0c151570..edeb464ec 100644
--- a/nuttx/net/uip/uip-tcpconn.c
+++ b/nuttx/net/uip/uip-tcpconn.c
@@ -70,7 +70,7 @@
/* The array containing all uIP TCP connections. */
-static struct uip_conn g_tcp_connections[UIP_CONNS];
+static struct uip_conn g_tcp_connections[CONFIG_NET_TCP_CONNS];
/* A list of all free TCP connections */
@@ -186,7 +186,7 @@ void uip_tcpinit(void)
/* Now initialize each connection structure */
- for (i = 0; i < UIP_CONNS; i++)
+ for (i = 0; i < CONFIG_NET_TCP_CONNS; i++)
{
/* Mark the connection closed and move it to the free list */
@@ -394,7 +394,7 @@ struct uip_conn *uip_tcplistener(uint16 portno)
/* Check if this port number is in use by any active UIP TCP connection */
- for (i = 0; i < UIP_CONNS; i++)
+ for (i = 0; i < CONFIG_NET_TCP_CONNS; i++)
{
conn = &g_tcp_connections[i];
if (conn->tcpstateflags != UIP_CLOSED && conn->lport == portno)
@@ -450,12 +450,18 @@ struct uip_conn *uip_tcpaccept(struct uip_tcpip_hdr *buf)
conn->rcv_nxt[1] = buf->seqno[1];
conn->rcv_nxt[0] = buf->seqno[0];
+ /* Initialize the list of TCP read-ahead buffers */
+
+#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
+ sq_init(&conn->readahead);
+#endif
+
/* And, finally, put the connection structure into the active list.
* Interrupts should already be disabled in this context.
*/
dq_addlast(&conn->node, &g_active_tcp_connections);
- }
+ }
return conn;
}
@@ -615,6 +621,12 @@ int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr)
uip_ipaddr_copy(conn->ripaddr, addr->sin_addr.s_addr);
+ /* Initialize the list of TCP read-ahead buffers */
+
+#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
+ sq_init(&conn->readahead);
+#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
diff --git a/nuttx/net/uip/uip-tcpinput.c b/nuttx/net/uip/uip-tcpinput.c
index 5ce3e2df6..1a74d5f81 100644
--- a/nuttx/net/uip/uip-tcpinput.c
+++ b/nuttx/net/uip/uip-tcpinput.c
@@ -265,7 +265,7 @@ void uip_tcpinput(struct uip_driver_s *dev)
found:
- flags = 0;
+ flags = 0;
/* We do a very naive form of TCP reset processing; we just accept
* any RST and kill our connection. We should in fact check if the
diff --git a/nuttx/net/uip/uip-tcpreadahead.c b/nuttx/net/uip/uip-tcpreadahead.c
new file mode 100644
index 000000000..6c4c78f1e
--- /dev/null
+++ b/nuttx/net/uip/uip-tcpreadahead.c
@@ -0,0 +1,132 @@
+/****************************************************************************
+ * net/uip/uip-tcpreadahead.c
+ *
+ * Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <net/uip/uipopt.h>
+#if defined(CONFIG_NET) && (CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0)
+
+#include <sys/types.h>
+#include <queue.h>
+#include <debug.h>
+
+#include <net/uip/uip.h>
+
+#include "uip-internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* These are the pre-allocated read-ahead buffers */
+
+static struct uip_readahead_s g_buffers[CONFIG_NET_NTCP_READAHEAD_BUFFERS];
+
+/* This is the list of available read-ahead buffers */
+
+static sq_queue_t g_freebuffers;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: uip_tcpreadaheadinit
+ *
+ * Description:
+ * Initialize the list of free read-ahead buffers
+ *
+ * Assumptions:
+ * Called once early initialization.
+ *
+ ****************************************************************************/
+
+void uip_tcpreadaheadinit(void)
+{
+ int i;
+
+ sq_init(&g_freebuffers);
+ for (i = 0; i < CONFIG_NET_NTCP_READAHEAD_BUFFERS; i++)
+ {
+ sq_addfirst(&g_buffers[i].rh_node, &g_freebuffers);
+ }
+}
+
+/****************************************************************************
+ * Function: uip_tcpreadaheadalloc
+ *
+ * Description:
+ * Allocate a TCP read-ahead buffer by taking a pre-allocated buffer from
+ * the free list. This function is called from TCP logic when new,
+ * incoming TCP data is received but there is no user logic recving the
+ * the data. Note: malloc() cannot be used because this function is
+ * called from interrupt level.
+ *
+ * Assumptions:
+ * Called from interrupt level with interrupts disabled.
+ *
+ ****************************************************************************/
+
+struct uip_readahead_s *uip_tcpreadaheadalloc(void)
+{
+ return (struct uip_readahead_s*)sq_remfirst(&g_freebuffers);
+}
+
+/****************************************************************************
+ * Function: uip_tcpreadaheadrelease
+ *
+ * Description:
+ * Release a TCP read-ahead buffer by returning the buffer to the free list.
+ * This function is called from user logic after it is consumed the buffered
+ * data.
+ *
+ * Assumptions:
+ * Called from user logic BUT with interrupts disabled.
+ *
+ ****************************************************************************/
+
+void uip_tcpreadaheadrelease(struct uip_readahead_s *buf)
+{
+ sq_addfirst(&buf->rh_node, &g_freebuffers);
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_NTCP_READAHEAD_BUFFERS*/
diff --git a/nuttx/net/uip/uip-tcpsend.c b/nuttx/net/uip/uip-tcpsend.c
index 31766d202..02123bc82 100644
--- a/nuttx/net/uip/uip-tcpsend.c
+++ b/nuttx/net/uip/uip-tcpsend.c
@@ -199,8 +199,8 @@ static void uip_tcpsendcommon(struct uip_driver_s *dev, struct uip_conn *conn)
}
else
{
- BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
- BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
+ BUF->wnd[0] = ((CONFIG_NET_TCP_CONNS) >> 8);
+ BUF->wnd[1] = ((CONFIG_NET_TCP_CONNS) & 0xff);
}
/* Finish the IP portion of the message, calculate checksums and send
diff --git a/nuttx/net/uip/uip-udpconn.c b/nuttx/net/uip/uip-udpconn.c
index 87ca3f8a6..b904aaac5 100644
--- a/nuttx/net/uip/uip-udpconn.c
+++ b/nuttx/net/uip/uip-udpconn.c
@@ -66,7 +66,7 @@
/* The array containing all uIP UDP connections. */
-struct uip_udp_conn g_udp_connections[UIP_UDP_CONNS];
+struct uip_udp_conn g_udp_connections[CONFIG_NET_UDP_CONNS];
/* A list of all free UDP connections */
@@ -124,7 +124,7 @@ static struct uip_udp_conn *uip_find_conn( uint16 portno )
/* Now search each connection structure.*/
- for (i = 0; i < UIP_UDP_CONNS; i++)
+ for (i = 0; i < CONFIG_NET_UDP_CONNS; i++)
{
if (g_udp_connections[ i ].lport == portno)
{
@@ -158,7 +158,7 @@ void uip_udpinit(void)
dq_init(&g_active_udp_connections);
sem_init(&g_free_sem, 0, 1);
- for (i = 0; i < UIP_UDP_CONNS; i++)
+ for (i = 0; i < CONFIG_NET_UDP_CONNS; i++)
{
/* Mark the connection closed and move it to the free list */
diff --git a/nuttx/net/uip/uip-udpsend.c b/nuttx/net/uip/uip-udpsend.c
index 7a2a0547c..8f77f78a2 100644
--- a/nuttx/net/uip/uip-udpsend.c
+++ b/nuttx/net/uip/uip-udpsend.c
@@ -160,7 +160,7 @@ void uip_udpsend(struct uip_driver_s *dev, struct uip_udp_conn *conn)
}
#else
UDPBUF->udpchksum = 0;
-#endif /* UIP_UDP_CHECKSUMS */
+#endif
vdbg("Outgoing UDP packet length: %d (%d)\n",
dev->d_len, (UDPBUF->len[0] << 8) | UDPBUF->len[1]);