From 93f5ec043137db88096411229f04d1bdc41ea4b6 Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 19 Nov 2007 23:09:39 +0000 Subject: [PATCH] Add TCP readahead logic git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@387 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/ChangeLog | 1 + nuttx/Documentation/NuttX.html | 1 + nuttx/Documentation/NuttxPortingGuide.html | 10 +- nuttx/arch/arm/src/common/up_sigdeliver.c | 2 + nuttx/arch/sim/src/up_tapdev.c | 6 +- nuttx/arch/sim/src/up_uipdriver.c | 2 +- nuttx/configs/README.txt | 7 +- nuttx/configs/c5471evm/defconfig | 10 +- nuttx/configs/m68332evb/defconfig | 10 +- nuttx/configs/mcu123-lpc214x/defconfig | 10 +- nuttx/configs/ntosd-dm320/defconfig | 10 +- nuttx/configs/ntosd-dm320/netconfig | 10 +- nuttx/configs/pjrc-8051/defconfig | 10 +- nuttx/configs/sim/defconfig | 10 +- nuttx/configs/sim/netconfig | 10 +- nuttx/drivers/net/dm90x0.c | 2 +- nuttx/examples/nettest/nettest-server.c | 11 - nuttx/include/net/uip/uip-arch.h | 2 +- nuttx/include/net/uip/uip-lib.h | 4 +- nuttx/include/net/uip/uip.h | 42 +++- nuttx/include/net/uip/uipopt.h | 130 +++--------- nuttx/net/netdev-ioctl.c | 2 +- nuttx/net/recvfrom.c | 143 +++++++++++-- nuttx/net/socket.c | 5 +- nuttx/net/uip/Make.defs | 3 +- nuttx/net/uip/uip-arp.c | 18 +- nuttx/net/uip/uip-chksum.c | 2 +- nuttx/net/uip/uip-fw.c | 228 ++++++++++++--------- nuttx/net/uip/uip-icmpinput.c | 4 +- nuttx/net/uip/uip-initialize.c | 6 + nuttx/net/uip/uip-input.c | 10 +- nuttx/net/uip/uip-internal.h | 8 + nuttx/net/uip/uip-listen.c | 10 +- nuttx/net/uip/uip-send.c | 2 +- nuttx/net/uip/uip-setipid.c | 2 +- nuttx/net/uip/uip-split.c | 172 +++++++++------- nuttx/net/uip/uip-tcpcallback.c | 103 ++++++++-- nuttx/net/uip/uip-tcpconn.c | 20 +- nuttx/net/uip/uip-tcpinput.c | 2 +- nuttx/net/uip/uip-tcpreadahead.c | 132 ++++++++++++ nuttx/net/uip/uip-tcpsend.c | 4 +- nuttx/net/uip/uip-udpconn.c | 6 +- nuttx/net/uip/uip-udpsend.c | 2 +- nuttx/netutils/uiplib/uip-server.c | 41 ++-- nuttx/netutils/webserver/httpd-cgi.c | 2 +- nuttx/netutils/webserver/httpd.c | 120 ++++++----- nuttx/sched/task_create.c | 2 +- 47 files changed, 873 insertions(+), 476 deletions(-) create mode 100644 nuttx/net/uip/uip-tcpreadahead.c diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index daf3551d7..6422f9997 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -226,4 +226,5 @@ * Basic server functionality verified: listen(), accept() * Fix DM90x0 driver problem that caused TX overruns * Add strncmp() + * Added TCP/IP read-ahead buffer to minimize failed ACKs and packet loss. diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html index 8fa4cc0ad..ce7ebbcc6 100644 --- a/nuttx/Documentation/NuttX.html +++ b/nuttx/Documentation/NuttX.html @@ -683,6 +683,7 @@ Other memory: * Basic server functionality verified: listen(), accept() * Fix DM90x0 driver problem that caused TX overruns * Add strncmp() + * Added TCP/IP read-ahead buffer to minimize failed ACKs and packet loss. diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html index 923f08e84..faf3c5f89 100644 --- a/nuttx/Documentation/NuttxPortingGuide.html +++ b/nuttx/Documentation/NuttxPortingGuide.html @@ -1353,7 +1353,7 @@ The system can be re-made subsequently by just typing make. CONFIG_NSOCKET_DESCRIPTORS: Maximum number of socket descriptors per task/thread.
  • - CONFIG_NET_MAX_CONNECTIONS: Maximum number of TCP connections (all tasks). + CONFIG_NET_TCP_CONNS: Maximum number of TCP connections (all tasks).
  • CONFIG_NET_MAX_LISTENPORTS: Maximum number of listening TCP ports (all tasks). @@ -1362,7 +1362,13 @@ The system can be re-made subsequently by just typing make. CONFIG_NET_SOCKOPTS: Enable or disable support for socket options.
  • - CONFIG_NET_BUFFER_SIZE: uIP buffer size + CONFIG_NET_BUFSIZE: uIP buffer size +
  • +
  • + CONFIG_NET_TCP_READAHEAD_BUFSIZE: Size of TCP read-ahead buffers +
  • +
  • + CONFIG_NET_NTCP_READAHEAD_BUFFERS: Number of TCP read-ahead buffers (may be zero)
  • CONFIG_NET_UDP: UDP support on or off diff --git a/nuttx/arch/arm/src/common/up_sigdeliver.c b/nuttx/arch/arm/src/common/up_sigdeliver.c index e6a0dfd89..673855144 100644 --- a/nuttx/arch/arm/src/common/up_sigdeliver.c +++ b/nuttx/arch/arm/src/common/up_sigdeliver.c @@ -76,6 +76,7 @@ void up_sigdeliver(void) { +#ifndef CONFIG_DISABLE_SIGNALS _TCB *rtcb = (_TCB*)g_readytorun.head; uint32 regs[XCPTCONTEXT_REGS]; sig_deliver_t sigdeliver; @@ -132,4 +133,5 @@ void up_sigdeliver(void) up_ledoff(LED_SIGNAL); up_fullcontextrestore(regs); +#endif } diff --git a/nuttx/arch/sim/src/up_tapdev.c b/nuttx/arch/sim/src/up_tapdev.c index a649c2490..7e9809e5c 100644 --- a/nuttx/arch/sim/src/up_tapdev.c +++ b/nuttx/arch/sim/src/up_tapdev.c @@ -217,10 +217,10 @@ static inline void dump_ethhdr(const char *msg, unsigned char *buf, int buflen) lib_rawprintf(" %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x:%02x:%02x:%02x:%02x %02x%02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], -#if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN - buf[12], buf[13]); -#else +#ifdef CONFIG_ENDIAN_BIG buf[13], buf[12]); +#else + buf[12], buf[13]); #endif } #else diff --git a/nuttx/arch/sim/src/up_uipdriver.c b/nuttx/arch/sim/src/up_uipdriver.c index d7425f82f..dbc78f9c0 100644 --- a/nuttx/arch/sim/src/up_uipdriver.c +++ b/nuttx/arch/sim/src/up_uipdriver.c @@ -141,7 +141,7 @@ void uipdriver_loop(void) /* tapdev_read will return 0 on a timeout event and >0 on a data received event */ - g_sim_dev.d_len = tapdev_read((unsigned char*)g_sim_dev.d_buf, UIP_BUFSIZE); + g_sim_dev.d_len = tapdev_read((unsigned char*)g_sim_dev.d_buf, CONFIG_NET_BUFSIZE); /* Disable preemption through to the following so that it behaves a little more * like an interrupt (otherwise, the following logic gets pre-empted an behaves diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt index cc8643068..da9535e8a 100644 --- a/nuttx/configs/README.txt +++ b/nuttx/configs/README.txt @@ -213,11 +213,14 @@ defconfig -- This is a configuration file similar to the Linux CONFIG_NET_IPv6 - Build in support for IPv6 CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread. - CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks) + CONFIG_NET_TCP_CONNS - Maximum number of TCP connections (all tasks) CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks) CONFIG_NET_SOCKOPTS - Enable or disable support for socket options - CONFIG_NET_BUFFER_SIZE - uIP buffer size + CONFIG_NET_BUFSIZE - uIP buffer size + CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers + CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers + (may be zero) CONFIG_NET_UDP - UDP support on or off CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP diff --git a/nuttx/configs/c5471evm/defconfig b/nuttx/configs/c5471evm/defconfig index db582e93b..2bc085041 100644 --- a/nuttx/configs/c5471evm/defconfig +++ b/nuttx/configs/c5471evm/defconfig @@ -254,10 +254,12 @@ CONFIG_PREALLOC_TIMERS=8 # CONFIG_NET - Enable or disable all network features # CONFIG_NET_IPv6 - Build in support for IPv6 # CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread. -# CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks) +# CONFIG_NET_TCP_CONNS - Maximum number of TCP connections (all tasks) # CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks) # CONFIG_NET_SOCKOPTS - Enable or disable support for socket options -# CONFIG_NET_BUFFER_SIZE - uIP buffer size +# CONFIG_NET_BUFSIZE - uIP buffer size +# CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers +# CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers (may be zero) # CONFIG_NET_UDP - UDP support on or off # CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off # CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP connections @@ -271,10 +273,10 @@ CONFIG_PREALLOC_TIMERS=8 CONFIG_NET=n CONFIG_NET_IPv6=n CONFIG_NSOCKET_DESCRIPTORS=0 -CONFIG_NET_MAX_CONNECTIONS=40 +CONFIG_NET_TCP_CONNS=40 CONFIG_NET_MAX_LISTENPORTS=40 CONFIG_NET_SOCKOPTS=y -CONFIG_NET_BUFFER_SIZE=420 +CONFIG_NET_BUFSIZE=420 CONFIG_NET_UDP=n CONFIG_NET_UDP_CHECKSUMS=y #CONFIG_NET_UDP_CONNS=10 diff --git a/nuttx/configs/m68332evb/defconfig b/nuttx/configs/m68332evb/defconfig index 700bcbb0f..b07ac62a0 100644 --- a/nuttx/configs/m68332evb/defconfig +++ b/nuttx/configs/m68332evb/defconfig @@ -243,10 +243,12 @@ CONFIG_PREALLOC_TIMERS=8 # CONFIG_NET - Enable or disable all network features # CONFIG_NET_IPv6 - Build in support for IPv6 # CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread. -# CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks) +# CONFIG_NET_TCP_CONNS - Maximum number of TCP connections (all tasks) # CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks) # CONFIG_NET_SOCKOPTS - Enable or disable support for socket options -# CONFIG_NET_BUFFER_SIZE - uIP buffer size +# CONFIG_NET_BUFSIZE - uIP buffer size +# CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers +# CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers (may be zero) # CONFIG_NET_UDP - UDP support on or off # CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off # CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP connections @@ -260,10 +262,10 @@ CONFIG_PREALLOC_TIMERS=8 CONFIG_NET=n CONFIG_NET_IPv6=n CONFIG_NSOCKET_DESCRIPTORS=0 -CONFIG_NET_MAX_CONNECTIONS=40 +CONFIG_NET_TCP_CONNS=40 CONFIG_NET_MAX_LISTENPORTS=40 CONFIG_NET_SOCKOPTS=y -CONFIG_NET_BUFFER_SIZE=420 +CONFIG_NET_BUFSIZE=420 CONFIG_NET_UDP=n CONFIG_NET_UDP_CHECKSUMS=y #CONFIG_NET_UDP_CONNS=10 diff --git a/nuttx/configs/mcu123-lpc214x/defconfig b/nuttx/configs/mcu123-lpc214x/defconfig index aa6352420..fe6a93801 100644 --- a/nuttx/configs/mcu123-lpc214x/defconfig +++ b/nuttx/configs/mcu123-lpc214x/defconfig @@ -267,10 +267,12 @@ CONFIG_PREALLOC_TIMERS=8 # CONFIG_NET - Enable or disable all network features # CONFIG_NET_IPv6 - Build in support for IPv6 # CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread. -# CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks) +# CONFIG_NET_TCP_CONNS - Maximum number of TCP connections (all tasks) # CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks) # CONFIG_NET_SOCKOPTS - Enable or disable support for socket options -# CONFIG_NET_BUFFER_SIZE - uIP buffer size +# CONFIG_NET_BUFSIZE - uIP buffer size +# CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers +# CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers (may be zero) # CONFIG_NET_UDP - UDP support on or off # CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off # CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP connections @@ -284,10 +286,10 @@ CONFIG_PREALLOC_TIMERS=8 CONFIG_NET=n CONFIG_NET_IPv6=n CONFIG_NSOCKET_DESCRIPTORS=0 -CONFIG_NET_MAX_CONNECTIONS=40 +CONFIG_NET_TCP_CONNS=40 CONFIG_NET_MAX_LISTENPORTS=40 CONFIG_NET_SOCKOPTS=y -CONFIG_NET_BUFFER_SIZE=420 +CONFIG_NET_BUFSIZE=420 CONFIG_NET_UDP=n CONFIG_NET_UDP_CHECKSUMS=y #CONFIG_NET_UDP_CONNS=10 diff --git a/nuttx/configs/ntosd-dm320/defconfig b/nuttx/configs/ntosd-dm320/defconfig index b3576fd5a..d7ae85b3b 100644 --- a/nuttx/configs/ntosd-dm320/defconfig +++ b/nuttx/configs/ntosd-dm320/defconfig @@ -252,10 +252,12 @@ CONFIG_PREALLOC_TIMERS=8 # CONFIG_NET - Enable or disable all network features # CONFIG_NET_IPv6 - Build in support for IPv6 # CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread. -# CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks) +# CONFIG_NET_TCP_CONNS - Maximum number of TCP connections (all tasks) # CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks) # CONFIG_NET_SOCKOPTS - Enable or disable support for socket options -# CONFIG_NET_BUFFER_SIZE - uIP buffer size +# CONFIG_NET_BUFSIZE - uIP buffer size +# CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers +# CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers (may be zero) # CONFIG_NET_UDP - UDP support on or off # CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off # CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP connections @@ -269,10 +271,10 @@ CONFIG_PREALLOC_TIMERS=8 CONFIG_NET=n CONFIG_NET_IPv6=n CONFIG_NSOCKET_DESCRIPTORS=0 -CONFIG_NET_MAX_CONNECTIONS=40 +CONFIG_NET_TCP_CONNS=40 CONFIG_NET_MAX_LISTENPORTS=40 CONFIG_NET_SOCKOPTS=y -CONFIG_NET_BUFFER_SIZE=420 +CONFIG_NET_BUFSIZE=420 CONFIG_NET_UDP=n CONFIG_NET_UDP_CHECKSUMS=y #CONFIG_NET_UDP_CONNS=10 diff --git a/nuttx/configs/ntosd-dm320/netconfig b/nuttx/configs/ntosd-dm320/netconfig index 050196ee5..042a49077 100644 --- a/nuttx/configs/ntosd-dm320/netconfig +++ b/nuttx/configs/ntosd-dm320/netconfig @@ -253,10 +253,12 @@ CONFIG_PREALLOC_TIMERS=8 # CONFIG_NET - Enable or disable all network features # CONFIG_NET_IPv6 - Build in support for IPv6 # CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread. -# CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks) +# CONFIG_NET_TCP_CONNS - Maximum number of TCP connections (all tasks) # CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks) # CONFIG_NET_SOCKOPTS - Enable or disable support for socket options -# CONFIG_NET_BUFFER_SIZE - uIP buffer size +# CONFIG_NET_BUFSIZE - uIP buffer size +# CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers +# CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers (may be zero) # CONFIG_NET_UDP - UDP support on or off # CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off # CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP connections @@ -270,10 +272,10 @@ CONFIG_PREALLOC_TIMERS=8 CONFIG_NET=y CONFIG_NET_IPv6=n CONFIG_NSOCKET_DESCRIPTORS=8 -CONFIG_NET_MAX_CONNECTIONS=8 +CONFIG_NET_TCP_CONNS=8 CONFIG_NET_MAX_LISTENPORTS=8 CONFIG_NET_SOCKOPTS=y -CONFIG_NET_BUFFER_SIZE=420 +CONFIG_NET_BUFSIZE=420 CONFIG_NET_UDP=y CONFIG_NET_UDP_CHECKSUMS=y #CONFIG_NET_UDP_CONNS=10 diff --git a/nuttx/configs/pjrc-8051/defconfig b/nuttx/configs/pjrc-8051/defconfig index 61ad5c12c..d3abb4e9d 100644 --- a/nuttx/configs/pjrc-8051/defconfig +++ b/nuttx/configs/pjrc-8051/defconfig @@ -240,10 +240,12 @@ CONFIG_PREALLOC_TIMERS=0 # CONFIG_NET - Enable or disable all network features # CONFIG_NET_IPv6 - Build in support for IPv6 # CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread. -# CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks) +# CONFIG_NET_TCP_CONNS - Maximum number of TCP connections (all tasks) # CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks) # CONFIG_NET_SOCKOPTS - Enable or disable support for socket options -# CONFIG_NET_BUFFER_SIZE - uIP buffer size +# CONFIG_NET_BUFSIZE - uIP buffer size +# CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers +# CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers (may be zero) # CONFIG_NET_UDP - UDP support on or off # CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off # CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP connections @@ -257,10 +259,10 @@ CONFIG_PREALLOC_TIMERS=0 CONFIG_NET=n CONFIG_NET_IPv6=n CONFIG_NSOCKET_DESCRIPTORS=0 -CONFIG_NET_MAX_CONNECTIONS=40 +CONFIG_NET_TCP_CONNS=40 CONFIG_NET_MAX_LISTENPORTS=40 CONFIG_NET_SOCKOPTS=y -CONFIG_NET_BUFFER_SIZE=420 +CONFIG_NET_BUFSIZE=420 CONFIG_NET_UDP=n CONFIG_NET_UDP_CHECKSUMS=y #CONFIG_NET_UDP_CONNS=10 diff --git a/nuttx/configs/sim/defconfig b/nuttx/configs/sim/defconfig index 2d959fbcf..45b338948 100644 --- a/nuttx/configs/sim/defconfig +++ b/nuttx/configs/sim/defconfig @@ -214,10 +214,12 @@ CONFIG_FS_FAT=y # CONFIG_NET - Enable or disable all network features # CONFIG_NET_IPv6 - Build in support for IPv6 # CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread. -# CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks) +# CONFIG_NET_TCP_CONNS - Maximum number of TCP connections (all tasks) # CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks) # CONFIG_NET_SOCKOPTS - Enable or disable support for socket options -# CONFIG_NET_BUFFER_SIZE - uIP buffer size +# CONFIG_NET_BUFSIZE - uIP buffer size +# CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers +# CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers (may be zero) # CONFIG_NET_UDP - UDP support on or off # CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off # CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP connections @@ -231,10 +233,10 @@ CONFIG_FS_FAT=y CONFIG_NET=n CONFIG_NET_IPv6=n CONFIG_NSOCKET_DESCRIPTORS=0 -CONFIG_NET_MAX_CONNECTIONS=40 +CONFIG_NET_TCP_CONNS=40 CONFIG_NET_MAX_LISTENPORTS=40 CONFIG_NET_SOCKOPTS=y -CONFIG_NET_BUFFER_SIZE=420 +CONFIG_NET_BUFSIZE=420 CONFIG_NET_UDP=n CONFIG_NET_UDP_CHECKSUMS=y #CONFIG_NET_UDP_CONNS=10 diff --git a/nuttx/configs/sim/netconfig b/nuttx/configs/sim/netconfig index 2cdea0a61..781a4d8c0 100644 --- a/nuttx/configs/sim/netconfig +++ b/nuttx/configs/sim/netconfig @@ -215,10 +215,12 @@ CONFIG_FS_FAT=y # CONFIG_NET - Enable or disable all network features # CONFIG_NET_IPv6 - Build in support for IPv6 # CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread. -# CONFIG_NET_MAX_CONNECTIONS - Maximum number of TCP connections (all tasks) +# CONFIG_NET_TCP_CONNS - Maximum number of TCP connections (all tasks) # CONFIG_NET_MAX_LISTENPORTS - Maximum number of listening TCP ports (all tasks) # CONFIG_NET_SOCKOPTS - Enable or disable support for socket options -# CONFIG_NET_BUFFER_SIZE - uIP buffer size +# CONFIG_NET_BUFSIZE - uIP buffer size +# CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers +# CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers (may be zero) # CONFIG_NET_UDP - UDP support on or off # CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off # CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP connections @@ -232,10 +234,10 @@ CONFIG_FS_FAT=y CONFIG_NET=y CONFIG_NET_IPv6=n CONFIG_NSOCKET_DESCRIPTORS=8 -CONFIG_NET_MAX_CONNECTIONS=40 +CONFIG_NET_TCP_CONNS=40 CONFIG_NET_MAX_LISTENPORTS=40 CONFIG_NET_SOCKOPTS=y -CONFIG_NET_BUFFER_SIZE=420 +CONFIG_NET_BUFSIZE=420 CONFIG_NET_UDP=y CONFIG_NET_UDP_CHECKSUMS=y #CONFIG_NET_UDP_CONNS=10 diff --git a/nuttx/drivers/net/dm90x0.c b/nuttx/drivers/net/dm90x0.c index 0df832e8f..a604b65a3 100644 --- a/nuttx/drivers/net/dm90x0.c +++ b/nuttx/drivers/net/dm90x0.c @@ -958,7 +958,7 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x) /* Also check if the packet is a valid size for the uIP configuration */ - else if (rx.desc.rx_len < UIP_LLH_LEN || rx.desc.rx_len > (UIP_BUFSIZE + 2)) + else if (rx.desc.rx_len < UIP_LLH_LEN || rx.desc.rx_len > (CONFIG_NET_BUFSIZE + 2)) { #if defined(CONFIG_DM9X_STATS) dm9x->dm_nrxlengtherrors++; diff --git a/nuttx/examples/nettest/nettest-server.c b/nuttx/examples/nettest/nettest-server.c index 984dee6b3..354f0560a 100644 --- a/nuttx/examples/nettest/nettest-server.c +++ b/nuttx/examples/nettest/nettest-server.c @@ -194,17 +194,6 @@ void recv_server(void) } } -#ifdef CONFIG_EXAMPLE_NETTEST_HOST - /* At present, data received by the target before it is completed the - * the write opertion and started the read operation results in a failure - * (the data is not received, but it is ACKed). This will have to be - * fixed. - */ - -# warning "FIXME: This should not be necessary" - sleep(10); -#endif - /* Then send the same data back to the client */ message("server: Sending %d bytes\n", totalbytesread); diff --git a/nuttx/include/net/uip/uip-arch.h b/nuttx/include/net/uip/uip-arch.h index 8d2b15d40..b4f21fb64 100644 --- a/nuttx/include/net/uip/uip-arch.h +++ b/nuttx/include/net/uip/uip-arch.h @@ -116,7 +116,7 @@ struct uip_driver_s * } */ - uint8 d_buf[UIP_BUFSIZE + 2]; + uint8 d_buf[CONFIG_NET_BUFSIZE + 2]; /* d_appdata points to the location where application data can be read from * or written into a packet. diff --git a/nuttx/include/net/uip/uip-lib.h b/nuttx/include/net/uip/uip-lib.h index d5799ee56..307a6b277 100644 --- a/nuttx/include/net/uip/uip-lib.h +++ b/nuttx/include/net/uip/uip-lib.h @@ -47,7 +47,7 @@ ****************************************************************************/ #include -#include +#include #include /**************************************************************************** @@ -106,6 +106,6 @@ extern int uip_setnetmask(const char *ifname, const struct in_addr *addr); /* Generic server logic */ -extern void uip_server(uint16 portno, main_t handler, int stacksize); +extern void uip_server(uint16 portno, pthread_startroutine_t handler, int stacksize); #endif /* __UIPLIB_H__ */ diff --git a/nuttx/include/net/uip/uip.h b/nuttx/include/net/uip/uip.h index 46e6907e4..150f594ce 100644 --- a/nuttx/include/net/uip/uip.h +++ b/nuttx/include/net/uip/uip.h @@ -112,7 +112,7 @@ * snprintf(dev->d_appdata, UIP_APPDATA_SIZE, "%u\n", i); */ -#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) +#define UIP_APPDATA_SIZE (CONFIG_NET_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) #define UIP_PROTO_ICMP 1 #define UIP_PROTO_TCP 6 @@ -183,6 +183,12 @@ struct uip_conn uint8 nrtx; /* The number of retransmissions for the last * segment sent */ + /* Read-ahead buffering */ + +#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 + sq_queue_t readahead; +#endif + /* Higher level logic can retain application specific information * in the following: * @@ -212,12 +218,27 @@ struct uip_conn void (*connection_event)(struct uip_conn *conn, uint8 flags); }; +/* The following structure is used to handle read-ahead buffering for TCP + * connection. When incoming TCP data is received while no application is + * listening for the data, that data will be retained in these read-ahead + * buffers so that no data is lost. + */ + +#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 +struct uip_readahead_s +{ + sq_entry_t rh_node; /* Supports a singly linked list */ + uint16 rh_nbytes; /* Number of bytes available in this buffer */ + uint8 rh_buffer[CONFIG_NET_TCP_READAHEAD_BUFSIZE]; +}; +#endif + #ifdef CONFIG_NET_UDP /* Representation of a uIP UDP connection */ struct uip_udp_conn { - dq_entry_t node; /* Implements a doubly linked list */ + dq_entry_t node; /* Supports a doubly linked list */ uip_ipaddr_t ripaddr; /* The IP address of the remote peer */ uint16 lport; /* The local port number in network byte order */ uint16 rport; /* The remote port number in network byte order */ @@ -493,11 +514,11 @@ extern struct uip_stats uip_stat; * TCP/IP stack. */ -void uip_initialize(void); +extern void uip_initialize(void); /* This function may be used at boot time to set the initial ip_id.*/ -void uip_setipid(uint16 id); +extern void uip_setipid(uint16 id); /* uIP application functions * @@ -559,7 +580,7 @@ extern int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr) * port A 16-bit port number in network byte order. */ -int uip_listen(uint16 port); +extern int uip_listen(uint16 port); /* Stop listening to the specified port. * @@ -569,7 +590,7 @@ int uip_listen(uint16 port); * port A 16-bit port number in network byte order. */ -int uip_unlisten(uint16 port); +extern int uip_unlisten(uint16 port); /* Check if a connection has outstanding (i.e., unacknowledged) data */ @@ -598,7 +619,14 @@ int uip_unlisten(uint16 port); * len The maximum amount of data bytes to be sent. */ -void uip_send(struct uip_driver_s *dev, const void *buf, int len); +extern void uip_send(struct uip_driver_s *dev, const void *buf, int len); + +/* Access to TCP read-ahead buffers */ + +#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 +extern struct uip_readahead_s *uip_tcpreadaheadalloc(void); +extern void uip_tcpreadaheadrelease(struct uip_readahead_s *buf); +#endif /* CONFIG_NET_NTCP_READAHEAD_BUFFERS */ /* The length of any incoming data that is currently avaliable (if avaliable) * in the d_appdata buffer. diff --git a/nuttx/include/net/uip/uipopt.h b/nuttx/include/net/uip/uipopt.h index 3a3fc68f2..b50884703 100644 --- a/nuttx/include/net/uip/uipopt.h +++ b/nuttx/include/net/uip/uipopt.h @@ -69,22 +69,6 @@ * Public Type Definitions ****************************************************************************/ -/* Static configuration options */ - -/* Ping IP address asignment. - * - * uIP uses a "ping" packets for setting its own IP address if this - * option is set. If so, uIP will start with an empty IP address and - * the destination IP address of the first incoming "ping" (ICMP echo) - * packet will be used for setting the hosts IP address. - */ - -#ifdef CONFIG_NET_PINGADDRCONF -#define UIP_PINGADDRCONF CONFIG_NET_PINGADDRCONF -#else /* CONFIG_NET_PINGADDRCONF */ -#define UIP_PINGADDRCONF 0 -#endif /* CONFIG_NET_PINGADDRCONF */ - /* IP configuration options */ /* The IP TTL (time to live) of IP packets sent by uIP. @@ -92,7 +76,7 @@ * This should normally not be changed. */ -#define UIP_TTL 64 +#define UIP_TTL 64 /* Turn on support for IP packet reassembly. * @@ -100,7 +84,7 @@ * requires an additonal amount of RAM to hold the reassembly buffer * and the reassembly code size is approximately 700 bytes. The * reassembly buffer is of the same size as the d_buf buffer - * (configured by UIP_BUFSIZE). + * (configured by CONFIG_NET_BUFSIZE). * * Note: IP packet reassembly is not heavily tested. */ @@ -116,26 +100,12 @@ /* UDP configuration options */ -/* Toggles if UDP checksums should be used or not. - * - * Note: Support for UDP checksums is currently not included in uIP, - * so this option has no function. - */ +/* The maximum amount of concurrent UDP connection, Default: 10 */ -#ifdef CONFIG_NET_UDP_CHECKSUMS -# define UIP_UDP_CHECKSUMS CONFIG_NET_UDP_CHECKSUMS -#else -# define UIP_UDP_CHECKSUMS 0 +#ifndef CONFIG_NET_UDP_CONNS +# define CONFIG_NET_UDP_CONNS 10 #endif -/* The maximum amount of concurrent UDP connections. */ - -#ifdef CONFIG_NET_UDP_CONNS -# define UIP_UDP_CONNS CONFIG_NET_UDP_CONNS -#else /* CONFIG_NET_UDP_CONNS */ -# define UIP_UDP_CONNS 10 -#endif /* CONFIG_NET_UDP_CONNS */ - /* TCP configuration options */ /* The maximum number of simultaneously open TCP connections. @@ -145,11 +115,9 @@ * connection requires approximatly 30 bytes of memory. */ -#ifndef CONFIG_NET_MAX_CONNECTIONS -# define UIP_CONNS 10 -#else /* CONFIG_NET_MAX_CONNECTIONS */ -# define UIP_CONNS CONFIG_NET_MAX_CONNECTIONS -#endif /* CONFIG_NET_MAX_CONNECTIONS */ +#ifndef CONFIG_NET_TCP_CONNS +# define CONFIG_NET_TCP_CONNS 10 +#endif /* The maximum number of simultaneously listening TCP ports. * @@ -157,10 +125,8 @@ */ #ifndef CONFIG_NET_MAX_LISTENPORTS -# define UIP_LISTENPORTS 20 -#else /* CONFIG_NET_MAX_LISTENPORTS */ -# define UIP_LISTENPORTS CONFIG_NET_MAX_LISTENPORTS -#endif /* CONFIG_NET_MAX_LISTENPORTS */ +# define CONFIG_NET_MAX_LISTENPORTS 20 +#endif /* Determines if support for TCP urgent data notification should be * compiled in. @@ -169,14 +135,14 @@ * very seldom would be required. */ -#define UIP_URGDATA 0 +#define UIP_URGDATA 0 /* The initial retransmission timeout counted in timer pulses. * * This should not be changed. */ -#define UIP_RTO 3 +#define UIP_RTO 3 /* The maximum number of times a segment should be retransmitted * before the connection should be aborted. @@ -184,7 +150,7 @@ * This should not be changed. */ -#define UIP_MAXRTX 8 +#define UIP_MAXRTX 8 /* The maximum number of times a SYN segment should be retransmitted * before a connection request should be deemed to have been @@ -193,15 +159,15 @@ * This should not need to be changed. */ -#define UIP_MAXSYNRTX 5 +#define UIP_MAXSYNRTX 5 /* The TCP maximum segment size. * * This is should not be to set to more than - * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. + * CONFIG_NET_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. */ -#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) +#define UIP_TCP_MSS (CONFIG_NET_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) /* The size of the advertised receiver's window. * @@ -211,9 +177,7 @@ */ #ifndef CONFIG_NET_RECEIVE_WINDOW -# define UIP_RECEIVE_WINDOW UIP_TCP_MSS -#else -# define UIP_RECEIVE_WINDOW CONFIG_NET_RECEIVE_WINDOW +# define CONFIG_NET_RECEIVE_WINDOW UIP_TCP_MSS #endif /* How long a connection should stay in the TIME_WAIT state. @@ -232,10 +196,8 @@ * have many connections from the local network. */ -#ifdef CONFIG_NET_ARPTAB_SIZE -# define UIP_ARPTAB_SIZE CONFIG_NET_ARPTAB_SIZE -#else -# define UIP_ARPTAB_SIZE 8 +#ifndef CONFIG_NET_ARPTAB_SIZE +# define CONFIG_NET_ARPTAB_SIZE 8 #endif /* The maxium age of ARP table entries measured in 10ths of seconds. @@ -255,23 +217,21 @@ * TCP throughput, larger size results in higher TCP throughput. */ -#ifndef CONFIG_NET_BUFFER_SIZE -# define UIP_BUFSIZE 400 -#else /* CONFIG_NET_BUFFER_SIZE */ -# define UIP_BUFSIZE CONFIG_NET_BUFFER_SIZE -#endif /* CONFIG_NET_BUFFER_SIZE */ +#ifndef CONFIG_NET_BUFSIZE +# define CONFIG_NET_BUFSIZE 400 +#endif -/* Broadcast support. - * - * This flag configures IP broadcast support. This is useful only - * together with UDP. - */ +/* Number of TCP read-ahead buffers (may be zero) */ -#ifndef CONFIG_NET_BROADCAST -# define UIP_BROADCAST 0 -#else /* CONFIG_NET_BROADCAST */ -# define UIP_BROADCAST CONFIG_NET_BROADCAST -#endif /* CONFIG_NET_BROADCAST */ +#ifndef CONFIG_NET_NTCP_READAHEAD_BUFFERS +# define CONFIG_NET_NTCP_READAHEAD_BUFFERS 4 +#endif + +/* The size of the TCP read buffer size */ + +#ifndef CONFIG_NET_TCP_READAHEAD_BUFSIZE +# define CONFIG_NET_TCP_READAHEAD_BUFSIZE UIP_TCP_MSS +#endif /* The link level header length. * @@ -282,32 +242,8 @@ #ifdef CONFIG_NET_LLH_LEN # define UIP_LLH_LEN CONFIG_NET_LLH_LEN -#else /* CONFIG_NET_LLH_LEN */ -# define UIP_LLH_LEN 14 -#endif /* CONFIG_NET_LLH_LEN */ - -/* CPU architecture configuration - * - * The CPU architecture configuration is where the endianess of the - * CPU on which uIP is to be run is specified. Most CPUs today are - * little endian, and the most notable exception are the Motorolas - * which are big endian. The CONFIG_ENDIAN_BIG macro should be changed - * if uIP is to be run on a big endian architecture. - */ - -/* The byte order of the CPU architecture on which uIP is to be run. - * - * This option can be either CONFIG_ENDIAN_BIG (Motorola byte order) or - * default little endian byte order (Intel byte order). - */ - -#define UIP_BIG_ENDIAN 1234 -#define UIP_LITTLE_ENDIAN 3412 - -#ifdef CONFIG_ENDIAN_BIG -# define UIP_BYTE_ORDER UIP_BIG_ENDIAN #else -# define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN +# define UIP_LLH_LEN 14 #endif /**************************************************************************** diff --git a/nuttx/net/netdev-ioctl.c b/nuttx/net/netdev-ioctl.c index 3825a5f7b..e13a22170 100644 --- a/nuttx/net/netdev-ioctl.c +++ b/nuttx/net/netdev-ioctl.c @@ -215,7 +215,7 @@ int netdev_ioctl(int sockfd, int cmd, struct ifreq *req) break; case SIOCGIFMTU: /* Get MTU size */ - req->ifr_mtu = UIP_BUFSIZE; + req->ifr_mtu = CONFIG_NET_BUFSIZE; break; case SIOCGIFHWADDR: /* Get hardware address */ diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index b0c9a223f..906b5aa6e 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -129,6 +129,93 @@ static void recvfrom_newdata(struct uip_driver_s *dev, struct recvfrom_s *pstate dev->d_len = 0; } +/**************************************************************************** + * Function: recvfrom_readahead + * + * Description: + * Copy the read data from the packet + * + * Parameters: + * dev The sructure of the network driver that caused the interrupt + * pstate recvfrom state structure + * + * Returned Value: + * None + * + * Assumptions: + * Running at the interrupt level + * + ****************************************************************************/ + +#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 +static inline void recvfrom_readahead(struct recvfrom_s *pstate) +{ + struct uip_conn *conn = (struct uip_conn *)pstate->rf_sock->s_conn; + struct uip_readahead_s *readahead; + size_t recvlen; + + /* Check there is any TCP data already buffered in a read-ahead + * buffer. + */ + + do + { + /* Get the read-ahead buffer at the head of the list (if any) */ + + readahead = (struct uip_readahead_s *)sq_remfirst(&conn->readahead); + if (readahead) + { + /* We have a new buffer... transfer that buffered data into + * the user buffer. + * + * First, get the length of the data to transfer. + */ + + if (readahead->rh_nbytes > pstate->rf_buflen) + { + recvlen = pstate->rf_buflen; + } + else + { + recvlen = readahead->rh_nbytes; + } + + if (recvlen > 0) + { + /* Copy the read-ahead data into the user buffer */ + + memcpy(pstate->rf_buffer, readahead->rh_buffer, recvlen); + vdbg("Received %d bytes (of %d)\n", recvlen, readahead->rh_nbytes); + + /* Update the accumulated size of the data read */ + + pstate->rf_recvlen += recvlen; + pstate->rf_buffer += recvlen; + pstate->rf_buflen -= recvlen; + } + + /* If the read-ahead buffer is empty, then release it. If not, then + * we will have to move the data down and return the buffer to the + * front of the list. + */ + + if (recvlen < readahead->rh_nbytes) + { + readahead->rh_nbytes -= recvlen; + memcpy(readahead->rh_buffer, &readahead->rh_buffer[recvlen], + readahead->rh_nbytes); + sq_addfirst(&readahead->rh_node, &conn->readahead); + } + else + { + uip_tcpreadaheadrelease(readahead); + } + } + } + while (readahead && pstate->rf_buflen > 0); +} +#endif + /**************************************************************************** * Function: recvfrom_timeout * @@ -449,8 +536,8 @@ static void recvfrom_init(FAR struct socket *psock, FAR void *buf, size_t len, memset(pstate, 0, sizeof(struct recvfrom_s)); (void)sem_init(&pstate->rf_sem, 0, 0); /* Doesn't really fail */ - pstate->rf_buflen = len; - pstate->rf_buffer = buf; + pstate->rf_buflen = len; + pstate->rf_buffer = buf; #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) /* Set up the start time for the timeout */ @@ -538,9 +625,9 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, #endif { struct uip_udp_conn *udp_conn; - struct recvfrom_s state; - irqstate_t save; - int ret; + struct recvfrom_s state; + irqstate_t save; + int ret; /* Perform the UDP recvfrom() operation */ @@ -619,10 +706,10 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, FAR const struct sockaddr_in *infrom ) #endif { - struct uip_conn *conn; - struct recvfrom_s state; - irqstate_t save; - int ret; + struct uip_conn *conn; + struct recvfrom_s state; + irqstate_t save; + int ret; /* Verify that the SOCK_STREAM has been connected */ @@ -642,24 +729,38 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, save = irqsave(); recvfrom_init(psock, buf, len, &state); - /* Set up the callback in the connection */ +#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 - conn = (struct uip_conn *)psock->s_conn; - conn->data_private = (void*)&state; - conn->data_event = recvfrom_tcpinterrupt; + /* Handle any any TCP data already buffered in a read-ahead buffer. */ - /* Wait for either the receive to complete or for an error/timeout to occur. - * NOTES: (1) sem_wait will also terminate if a signal is received, (2) - * interrupts are disabled! They will be re-enabled while the task sleeps - * and automatically re-enabled when the task restarts. + recvfrom_readahead(&state); + + /* If there is space to receive anything more, then we will + * wait to receive the data. */ - ret = sem_wait(&state.rf_sem); + if (state.rf_buflen > 0) +#endif + { + /* Set up the callback in the connection */ - /* Make sure that no further interrupts are processed */ + conn = (struct uip_conn *)psock->s_conn; + conn->data_private = (void*)&state; + conn->data_event = recvfrom_tcpinterrupt; - conn->data_private = NULL; - conn->data_event = NULL; + /* Wait for either the receive to complete or for an error/timeout to occur. + * NOTES: (1) sem_wait will also terminate if a signal is received, (2) + * interrupts are disabled! They will be re-enabled while the task sleeps + * and automatically re-enabled when the task restarts. + */ + + ret = sem_wait(&state.rf_sem); + + /* Make sure that no further interrupts are processed */ + + conn->data_private = NULL; + conn->data_event = NULL; + } irqrestore(save); #warning "Needs to return server address" diff --git a/nuttx/net/socket.c b/nuttx/net/socket.c index 5efc86df9..d7c21d01b 100644 --- a/nuttx/net/socket.c +++ b/nuttx/net/socket.c @@ -135,7 +135,10 @@ int socket(int domain, int type, int protocol) psock->s_type = type; psock->s_conn = NULL; - /* Allocate the appropriate connection structure */ + /* Allocate the appropriate connection structure. This reserves the + * the connection structure is is unallocated at this point. It will + * not actually be initialized until the socket is connected. + */ switch (type) { 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; - } - } - fw->timer = FW_TIME; - fw->ipid = BUF->ipid; - fw->srcipaddr = BUF->srcipaddr; + 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->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(); + 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; } - for (netif = netifs; netif != NULL; netif = netif->next) { - netif->output(); - } - 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 (BUF->ipchksum >= HTONS(0xffff - 0x0100)) + { + BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1; + } + else + { + BUF->ipchksum = BUF->ipchksum + HTONS(0x0100); + } -#if UIP_BROADCAST - if (BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { - return UIP_FW_LOCAL; - } -#endif /* UIP_BROADCAST */ + 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 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; + 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); +#else /* CONFIG_NET_IPv6 */ + 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)); + +#ifndef CONFIG_NET_IPv6 + /* 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(); + + /* 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; +#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); +#else /* CONFIG_NET_IPv6 */ + 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); + + uip_incr32(BUF->seqno, len1); + + /* 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)); +#endif /* CONFIG_NET_IPv6 */ + + /* Transmit the second packet. */ + /* uip_fw_output();*/ + tcpip_output(); + } + else + { + /* uip_fw_output();*/ + tcpip_output(); } - - /* 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); -#else /* CONFIG_NET_IPv6 */ - 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)); - -#ifndef CONFIG_NET_IPv6 - /* 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(); - - /* 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; -#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); -#else /* CONFIG_NET_IPv6 */ - 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); - - uip_incr32(BUF->seqno, len1); - - /* 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)); -#endif /* CONFIG_NET_IPv6 */ - - /* 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 +#include #include #include @@ -58,6 +59,89 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * 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. - */ + /* There is no handler to receive new data in place */ - dbg("No listener on connection\n"); - -#ifdef CONFIG_NET_STATISTICS - uip_stat.tcp.syndrop++; - uip_stat.tcp.drop++; -#endif - - 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 + * + * + * 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 +#if defined(CONFIG_NET) && (CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0) + +#include +#include +#include + +#include + +#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]); diff --git a/nuttx/netutils/uiplib/uip-server.c b/nuttx/netutils/uiplib/uip-server.c index aa0ea5b11..8baccf33d 100644 --- a/nuttx/netutils/uiplib/uip-server.c +++ b/nuttx/netutils/uiplib/uip-server.c @@ -41,8 +41,9 @@ #include #include +#include #include -#include +#include #include #include @@ -75,15 +76,15 @@ * ****************************************************************************/ -void uip_server(uint16 portno, main_t handler, int stacksize) +void uip_server(uint16 portno, pthread_startroutine_t handler, int stacksize) { struct sockaddr_in myaddr; #ifdef CONFIG_NET_HAVE_SOLINGER struct linger ling; #endif - struct sched_param param; + pthread_t child; + pthread_attr_t attr; socklen_t addrlen; - const char *argv[2]; int listensd; int acceptsd; #ifdef CONFIG_NET_HAVE_REUSEADDR @@ -142,7 +143,7 @@ void uip_server(uint16 portno, main_t handler, int stacksize) dbg("accept failure: %d\n", errno); break;; } - dbg("Connection accepted -- spawning\n"); + dbg("Connection accepted -- spawning sd=%d\n", acceptsd); /* Configure to "linger" until all data is sent when the socket is closed */ @@ -157,33 +158,25 @@ void uip_server(uint16 portno, main_t handler, int stacksize) } #endif - /* Spawn a thread to handle the connection. The socket descriptor +1 is - * provided in as the single argument to the new thread. (The +1 is intended - * to handle the valid, zero file descriptor). + /* Create a thread to handle the connection. The socket descriptor is + * provided in as the single argument to the new thread. */ - if (sched_getparam(0, ¶m) < 0) + (void)pthread_attr_init(&attr); + (void)pthread_attr_setstacksize(&attr, stacksize); + + if (pthread_create(&child, &attr, handler, (void*)acceptsd) != 0) { close(acceptsd); - dbg("sched_getparam failed: %d\n", errno); - break;; + dbg("create_create failed\n"); + break; } - argv[0] = (char*)(acceptsd + 1); - argv[1] = NULL; - - if (task_create("", param.sched_priority, stacksize, handler, argv) < 0) - { - close(acceptsd); - dbg("task_create failed: %d\n", errno); - break;; - } - - /* We can close our copy of acceptsd now. This file descriptor was dup'ed - * by task_create and we no longer need to retain the reference. + /* We don't care when/how the child thread exits so detach from it now + * in order to avoid memory leaks. */ - close(acceptsd); + (void)pthread_detach(child); } errout_with_socket: diff --git a/nuttx/netutils/webserver/httpd-cgi.c b/nuttx/netutils/webserver/httpd-cgi.c index e93aff1be..ab39711c8 100644 --- a/nuttx/netutils/webserver/httpd-cgi.c +++ b/nuttx/netutils/webserver/httpd-cgi.c @@ -136,7 +136,7 @@ static void tcp_stats(struct httpd_state *pstate, char *ptr) struct httpd_state *pstate = (struct httpd_state *)arg; char buffer[256]; - for(pstate->count = 0; pstate->count < UIP_CONNS; ++pstate->count) + for(pstate->count = 0; pstate->count < CONFIG_NET_TCP_CONNS; ++pstate->count) { conn = &uip_conns[pstate->count]; if((conn->tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) diff --git a/nuttx/netutils/webserver/httpd.c b/nuttx/netutils/webserver/httpd.c index 2db3436d7..33f93d9b8 100644 --- a/nuttx/netutils/webserver/httpd.c +++ b/nuttx/netutils/webserver/httpd.c @@ -51,7 +51,10 @@ #include #include +#include #include +#include +#include #include #include @@ -74,6 +77,8 @@ #define ISO_slash 0x2f #define ISO_colon 0x3a +#define errno *get_errno_ptr() + #define CONFIG_NETUTILS_HTTPD_DUMPBUFFER 1 /**************************************************************************** @@ -111,7 +116,7 @@ static void httpd_dumpbuffer(struct httpd_state *pstate, ssize_t nbytes) sprintf(&line[strlen(line)], "%c", ch >= 0x20 && ch <= 0x7e ? ch : '.'); } } - dbg("%s", line); + dbg("%s\n", line); } #endif } @@ -131,57 +136,69 @@ static void handle_script(struct httpd_state *pstate) { char *ptr; - while(pstate->file.len > 0) { + while(pstate->file.len > 0) + { + /* Check if we should start executing a script */ - /* Check if we should start executing a script */ - - if (*pstate->file.data == ISO_percent && - *(pstate->file.data + 1) == ISO_bang) { - pstate->scriptptr = pstate->file.data + 3; - pstate->scriptlen = pstate->file.len - 3; - if (*(pstate->scriptptr - 1) == ISO_colon) + if (*pstate->file.data == ISO_percent && *(pstate->file.data + 1) == ISO_bang) { - httpd_fs_open(pstate->scriptptr + 1, &pstate->file); - send(pstate->sockfd, pstate->file.data, pstate->file.len, 0); + pstate->scriptptr = pstate->file.data + 3; + pstate->scriptlen = pstate->file.len - 3; + if (*(pstate->scriptptr - 1) == ISO_colon) + { + httpd_fs_open(pstate->scriptptr + 1, &pstate->file); + send(pstate->sockfd, pstate->file.data, pstate->file.len, 0); + } + else + { + httpd_cgi(pstate->scriptptr)(pstate, pstate->scriptptr); + } + next_scriptstate(pstate); + + /* The script is over, so we reset the pointers and continue + * sending the rest of the file + */ + + pstate->file.data = pstate->scriptptr; + pstate->file.len = pstate->scriptlen; } else { - httpd_cgi(pstate->scriptptr)(pstate, pstate->scriptptr); + /* See if we find the start of script marker in the block of HTML + * to be sent + */ + + if (pstate->file.len > HTTPD_IOBUFFER_SIZE) + { + pstate->len = HTTPD_IOBUFFER_SIZE; + } + else + { + pstate->len = pstate->file.len; + } + + if (*pstate->file.data == ISO_percent) + { + ptr = strchr(pstate->file.data + 1, ISO_percent); + } + else + { + ptr = strchr(pstate->file.data, ISO_percent); + } + + if (ptr != NULL && ptr != pstate->file.data) + { + pstate->len = (int)(ptr - pstate->file.data); + if (pstate->len >= HTTPD_IOBUFFER_SIZE) + { + pstate->len = HTTPD_IOBUFFER_SIZE; + } + } + send(pstate->sockfd, pstate->file.data, pstate->len, 0); + pstate->file.data += pstate->len; + pstate->file.len -= pstate->len; } - next_scriptstate(pstate); - - /* The script is over, so we reset the pointers and continue - sending the rest of the file */ - pstate->file.data = pstate->scriptptr; - pstate->file.len = pstate->scriptlen; - - } else { - /* See if we find the start of script marker in the block of HTML - to be sent */ - - if (pstate->file.len > HTTPD_IOBUFFER_SIZE) { - pstate->len = HTTPD_IOBUFFER_SIZE; - } else { - pstate->len = pstate->file.len; - } - - if (*pstate->file.data == ISO_percent) { - ptr = strchr(pstate->file.data + 1, ISO_percent); - } else { - ptr = strchr(pstate->file.data, ISO_percent); - } - if (ptr != NULL && - ptr != pstate->file.data) { - pstate->len = (int)(ptr - pstate->file.data); - if (pstate->len >= HTTPD_IOBUFFER_SIZE) { - pstate->len = HTTPD_IOBUFFER_SIZE; - } - } - send(pstate->sockfd, pstate->file.data, pstate->len, 0); - pstate->file.data += pstate->len; - pstate->file.len -= pstate->len; } - } } static int send_headers(struct httpd_state *pstate, const char *statushdr) @@ -259,6 +276,7 @@ static inline int httpd_cmd(struct httpd_state *pstate) recvlen = recv(pstate->sockfd, pstate->ht_buffer, HTTPD_IOBUFFER_SIZE, 0); if (recvlen < 0) { + dbg("recv failed: %d\n", errno); return ERROR; } httpd_dumpbuffer(pstate, recvlen); @@ -267,6 +285,7 @@ static inline int httpd_cmd(struct httpd_state *pstate) if (strncmp(pstate->ht_buffer, http_get, 4) != 0) { + dbg("Unsupported command\n"); return ERROR; } @@ -274,6 +293,7 @@ static inline int httpd_cmd(struct httpd_state *pstate) if (pstate->ht_buffer[4] != ISO_slash) { + dbg("Missing path\n"); return ERROR; } else if (pstate->ht_buffer[5] == ISO_space) @@ -304,12 +324,14 @@ static inline int httpd_cmd(struct httpd_state *pstate) * ****************************************************************************/ -static int httpd_handler(int argc, char *argv[]) +static void *httpd_handler(void *arg) { struct httpd_state *pstate = (struct httpd_state *)malloc(sizeof(struct httpd_state)); - int sockfd = (int)argv[1] - 1; + int sockfd = (int)arg; int ret = ERROR; + dbg("Started, sd=%d\n", sockfd); + /* Verify that the state structure was successfully allocated */ if (pstate) @@ -335,7 +357,9 @@ static int httpd_handler(int argc, char *argv[]) /* Exit the task */ - return 0; + dbg("Exitting\n"); + close(sockfd); + pthread_exit(NULL); } /**************************************************************************** diff --git a/nuttx/sched/task_create.c b/nuttx/sched/task_create.c index ee0e86c6e..96df1ae60 100644 --- a/nuttx/sched/task_create.c +++ b/nuttx/sched/task_create.c @@ -130,7 +130,7 @@ int task_create(const char *name, int priority, /* Associate file descriptors with the new task */ -#if CONFIG_NFILE_DESCRIPTORS > 0 +#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 if (sched_setuptaskfiles(tcb) != OK) { sched_releasetcb(tcb);