9
0
Fork 0

Add TCP readahead logic

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@387 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2007-11-19 23:09:39 +00:00
parent de45c054e2
commit 93f5ec0431
47 changed files with 873 additions and 476 deletions

View File

@ -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.

View File

@ -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.
</pre></ul>
<table width ="100%">

View File

@ -1353,7 +1353,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
<code>CONFIG_NSOCKET_DESCRIPTORS</code>: Maximum number of socket descriptors per task/thread.
</li>
<li>
<code>CONFIG_NET_MAX_CONNECTIONS</code>: Maximum number of TCP connections (all tasks).
<code>CONFIG_NET_TCP_CONNS</code>: Maximum number of TCP connections (all tasks).
</li>
<li>
<code>CONFIG_NET_MAX_LISTENPORTS</code>: Maximum number of listening TCP ports (all tasks).
@ -1362,7 +1362,13 @@ The system can be re-made subsequently by just typing <code>make</code>.
<code>CONFIG_NET_SOCKOPTS</code>: Enable or disable support for socket options.
</li>
<li>
<code>CONFIG_NET_BUFFER_SIZE</code>: uIP buffer size
<code>CONFIG_NET_BUFSIZE</code>: uIP buffer size
</li>
<li>
<code>CONFIG_NET_TCP_READAHEAD_BUFSIZE</code>: Size of TCP read-ahead buffers
</li>
<li>
<code>CONFIG_NET_NTCP_READAHEAD_BUFFERS</code>: Number of TCP read-ahead buffers (may be zero)
</li>
<li>
<code>CONFIG_NET_UDP</code>: UDP support on or off

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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++;

View File

@ -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);

View File

@ -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.

View File

@ -47,7 +47,7 @@
****************************************************************************/
#include <nuttx/config.h>
#include <sched.h>
#include <pthread.h>
#include <netinet/in.h>
/****************************************************************************
@ -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__ */

View File

@ -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.

View File

@ -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
/****************************************************************************

View File

@ -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 */

View File

@ -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"

View File

@ -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)
{

View File

@ -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

View File

@ -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.

View File

@ -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 */

View File

@ -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;
}
}
}
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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)
{

View File

@ -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 );

View File

@ -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>

View File

@ -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();
}
}

View File

@ -42,6 +42,7 @@
#ifdef CONFIG_NET
#include <sys/types.h>
#include <string.h>
#include <debug.h>
#include <net/uip/uipopt.h>
@ -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

View File

@ -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

View File

@ -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

View File

@ -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*/

View File

@ -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

View File

@ -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 */

View File

@ -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]);

View File

@ -41,8 +41,9 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
#include <errno.h>
#include <debug.h>
@ -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, &param) < 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:

View File

@ -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)

View File

@ -51,7 +51,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <debug.h>
#include <net/uip/uip.h>
@ -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);
}
/****************************************************************************

View File

@ -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);