diff options
Diffstat (limited to 'nuttx/net/uip')
-rw-r--r-- | nuttx/net/uip/Make.defs | 2 | ||||
-rw-r--r-- | nuttx/net/uip/uip-internal.h | 12 | ||||
-rw-r--r-- | nuttx/net/uip/uip-listen.c | 206 | ||||
-rw-r--r-- | nuttx/net/uip/uip-tcpconn.c | 72 | ||||
-rw-r--r-- | nuttx/net/uip/uip.c | 64 |
5 files changed, 280 insertions, 76 deletions
diff --git a/nuttx/net/uip/Make.defs b/nuttx/net/uip/Make.defs index fd20143ff..61f89cc7b 100644 --- a/nuttx/net/uip/Make.defs +++ b/nuttx/net/uip/Make.defs @@ -35,5 +35,5 @@ UIP_ASRCS = UIP_CSRCS = uip-arp.c uip.c uip-send.c uip-fw.c uip-neighbor.c uip-split.c \ - uip-tcpconn.c uip-udpconn.c + uip-tcpconn.c uip-udpconn.c uip-listen.c diff --git a/nuttx/net/uip/uip-internal.h b/nuttx/net/uip/uip-internal.h index f8613c63a..6c76f39cf 100644 --- a/nuttx/net/uip/uip-internal.h +++ b/nuttx/net/uip/uip-internal.h @@ -44,6 +44,9 @@ ****************************************************************************/ #include <sys/types.h> +#include <errno.h> +#include <arch/irq.h> +#include <net/uip/uip.h> /**************************************************************************** * Public Macro Definitions @@ -75,7 +78,8 @@ extern "C" { EXTERN void uip_tcpinit(void); EXTERN struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf); -EXTERN struct uip_conn *uip_tcplistener(struct uip_tcpip_hdr *buf); +EXTERN struct uip_conn *uip_tcplistener(uint16 portno); +EXTERN struct uip_conn *uip_tcpaccept(struct uip_tcpip_hdr *buf); EXTERN void uip_tcpnextsequence(void); /* Defined in uip_udpconn.c *************************************************/ @@ -83,6 +87,12 @@ EXTERN void uip_tcpnextsequence(void); EXTERN void uip_udpinit(void); EXTERN struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf); +/* Defined in uip_listen.c **************************************************/ + +EXTERN void uip_listeninit(void); +EXTERN boolean uip_islistener(uint16 port); +EXTERN int uip_accept(struct uip_conn *conn, uint16 portno); + #undef EXTERN #ifdef __cplusplus } diff --git a/nuttx/net/uip/uip-listen.c b/nuttx/net/uip/uip-listen.c new file mode 100644 index 000000000..edbb9d469 --- /dev/null +++ b/nuttx/net/uip/uip-listen.c @@ -0,0 +1,206 @@ +/**************************************************************************** + * net/uip/uip-listen.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * A direct leverage of logic from uIP which also has b BSD style license + * + * Author: Adam Dunkels <adam@dunkels.com> + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <nuttx/config.h> +#ifdef CONFIG_NET + +#include <sys/types.h> +#include <net/uip/uipopt.h> + +#include "uip-internal.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The uip_listenports list all currently listening ports. */ + +static uint16 uip_listenports[UIP_LISTENPORTS]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: uip_listeninit + * + * Description: + * Setup the listening data structures + * + * Assumptions: + * Called early in the inialization phase while the system is still + * single-threaded. + * + ****************************************************************************/ + +void uip_listeninit(void) +{ + int ndx; + for (ndx = 0; ndx < UIP_LISTENPORTS; ndx++) + { + uip_listenports[ndx] = 0; + } +} + +/**************************************************************************** + * Function: uip_unlisten + * + * Description: + * Stop listening on a port + * + * Assumptions: + * Called from normal user code. + * + ****************************************************************************/ + +int uip_unlisten(uint16 port) +{ + irqstate_t flags; + int ndx; + int ret = -EINVAL; + + flags = irqsave(); + for (ndx = 0; ndx < UIP_LISTENPORTS; ndx++) + { + if (uip_listenports[ndx] == port) + { + uip_listenports[ndx] = 0; + ret = OK; + break; + } + } + irqrestore(flags); + return ret; +} + +/**************************************************************************** + * Function: uip_listen + * + * Description: + * Start listening on a port + * + * Assumptions: + * Called from normal user code. + * + ****************************************************************************/ + +int uip_listen(uint16 port) +{ + irqstate_t flags; + int ndx; + int ret = -ENOBUFS; + + flags = irqsave(); + for (ndx = 0; ndx < UIP_LISTENPORTS; ndx++) + { + if (uip_listenports[ndx] == 0) + { + uip_listenports[ndx] = port; + ret = OK; + break; + } + } + irqrestore(flags); + return ret; +} + +/**************************************************************************** + * Function: uip_islistener + * + * Description: + * Return TRUE is there is a listener for the specified port + * + * Assumptions: + * Called at interrupt level + * + ****************************************************************************/ + +boolean uip_islistener(uint16 portno) +{ + int ndx; + for (ndx = 0; ndx < UIP_LISTENPORTS; ndx++) + { + if (uip_listenports[ndx] == portno) + { + return TRUE; + } + } + return FALSE; +} + +/**************************************************************************** + * Function: uip_accept + * + * Description: + * Accept the new connection for the specified listening port. + * + * Assumptions: + * Called at interrupt level + * + ****************************************************************************/ + +int uip_accept(struct uip_conn *conn, uint16 portno) +{ + struct uip_conn *listener; + int ret = ERROR; + + /* The interrupt logic has already allocated and initialized a TCP + * connection -- now check if is an application in place to accept the + * connection. + */ + + listener = uip_tcplistener(portno); + if (listener && listener->accept) + { + /* Yes.. accept the connection */ + + ret = listener->accept(listener->accept_private, conn); + } + return ret; +} + +#endif /* CONFIG_NET */ diff --git a/nuttx/net/uip/uip-tcpconn.c b/nuttx/net/uip/uip-tcpconn.c index f604c26c7..b8bcdb3ce 100644 --- a/nuttx/net/uip/uip-tcpconn.c +++ b/nuttx/net/uip/uip-tcpconn.c @@ -91,38 +91,6 @@ static uint8 g_tcp_sequence[4]; ****************************************************************************/ /**************************************************************************** - * Name: uip_find_conn() - * - * Description: - * Given a port number, find the socket bound to the port number. - * Primary use: to determine if a port number is available. - * - ****************************************************************************/ - -static struct uip_conn *uip_find_conn(uint16 portno) -{ - struct uip_conn *conn; - int i; - - /* Check if this port number is already in use, and if so try to find - * another one. - */ - - for (i = 0; i < UIP_CONNS; i++) - { - conn = &g_tcp_connections[i]; - if (conn->tcpstateflags != UIP_CLOSED && conn->lport == htons(g_last_tcp_port)) - { - /* The portnumber is in use */ - - return conn; - } - } - - return NULL; -} - -/**************************************************************************** * Name: uip_selectport() * * Description: @@ -164,7 +132,7 @@ static int uip_selectport(uint16 portno) g_last_tcp_port = 4096; } } - while (uip_find_conn(g_last_tcp_port)); + while (uip_tcplistener(g_last_tcp_port)); } else { @@ -172,7 +140,7 @@ static int uip_selectport(uint16 portno) * connection is using this local port. */ - if (uip_find_conn(portno)) + if (uip_tcplistener(portno)) { /* It is in use... return EADDRINUSE */ @@ -373,7 +341,39 @@ struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf) } /**************************************************************************** - * Name: uip_tcpactive() + * Name: uip_tcplistener() + * + * Description: + * Given a local port number, find the TCP connection that listens on this + * this port. + * + * Primary uses: (1) to determine if a port number is available, (2) to + * To idenfity the socket that will accept new connections on a local port. + * + ****************************************************************************/ + +struct uip_conn *uip_tcplistener(uint16 portno) +{ + struct uip_conn *conn; + int i; + + /* Check if this port number is in use by any active UIP TCP connection */ + + for (i = 0; i < UIP_CONNS; i++) + { + conn = &g_tcp_connections[i]; + if (conn->tcpstateflags != UIP_CLOSED && conn->lport == htons(g_last_tcp_port)) + { + /* The portnumber is in use, return the connection */ + + return conn; + } + } + return NULL; +} + +/**************************************************************************** + * Name: uip_tcpaccept() * * Description: * Called when uip_interupt matches the incoming packet with a connection @@ -385,7 +385,7 @@ struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf) * ****************************************************************************/ -struct uip_conn *uip_tcplistener(struct uip_tcpip_hdr *buf) +struct uip_conn *uip_tcpaccept(struct uip_tcpip_hdr *buf) { struct uip_conn *conn = uip_tcpalloc(); if (conn) diff --git a/nuttx/net/uip/uip.c b/nuttx/net/uip/uip.c index 49536fa41..3cfb37b2a 100644 --- a/nuttx/net/uip/uip.c +++ b/nuttx/net/uip/uip.c @@ -156,10 +156,6 @@ uint8 uip_flags; struct uip_conn *uip_conn; -/* The uip_listenports list all currently listening ports. */ - -uint16 uip_listenports[UIP_LISTENPORTS]; - #ifdef CONFIG_NET_UDP struct uip_udp_conn *uip_udp_conn; #endif /* CONFIG_NET_UDP */ @@ -361,10 +357,9 @@ uint16 uip_udpchksum(struct uip_driver_s *dev) void uip_init(void) { - for (c = 0; c < UIP_LISTENPORTS; ++c) - { - uip_listenports[c] = 0; - } + /* Initialize the listening port structures */ + + uip_listeninit(); /* Initialize the TCP/IP connection structures */ @@ -379,30 +374,6 @@ void uip_init(void) /* IPv4 initialization. */ } -void uip_unlisten(uint16 port) -{ - for (c = 0; c < UIP_LISTENPORTS; ++c) - { - if (uip_listenports[c] == port) - { - uip_listenports[c] = 0; - return; - } - } -} - -void uip_listen(uint16 port) -{ - for (c = 0; c < UIP_LISTENPORTS; ++c) - { - if (uip_listenports[c] == 0) - { - uip_listenports[c] = port; - return; - } - } -} - /* IP fragment reassembly: not well-tested. */ #if UIP_REASSEMBLY && !defined(CONFIG_NET_IPv6) @@ -1195,9 +1166,8 @@ void uip_interrupt(struct uip_driver_s *dev, uint8 flag) tmp16 = BUF->destport; /* Next, check listening connections. */ - for (c = 0; c < UIP_LISTENPORTS; ++c) + if (uip_islistener(tmp16)) { - if (tmp16 == uip_listenports[c]) goto found_listen; } @@ -1267,14 +1237,32 @@ void uip_interrupt(struct uip_driver_s *dev, uint8 flag) found_listen: - /* First allocate a new connection structure */ + /* First allocate a new connection structure and see if there is any + * user application to accept it. + */ - uip_connr = uip_tcplistener(BUF); + uip_connr = uip_tcpaccept(BUF); + if (uip_connr) + { + /* The connection structure was successfully allocated. Now see + * there is an application waiting to accept the connection (or at + * least queue it it for acceptance). + */ + if (uip_accept(uip_connr, tmp16) != OK) + { + /* No, then we have to give the connection back */ + + uip_tcpfree(uip_connr); + uip_connr = NULL; + } + } + if (!uip_connr) { - /* All connections are used already, we drop packet and hope that + /* Either (1) all available connections are in use, or (2) there is no + * application in place to accept the connection. We drop packet and hope that * the remote end will retransmit the packet at a time when we - * have more spare connections. + * have more spare connections or someone waiting to accept the connection. */ UIP_STAT(++uip_stat.tcp.syndrop); |