summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-03-19 00:18:21 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-03-19 00:18:21 +0000
commit9ce24cc300a68f59cab05eebeff5356f7d476e80 (patch)
treebf3c08e272edcb9a9698d90abc3180df1ed761c1
parente5f697c8ff96f2993c57a60809ad23ae00b091d1 (diff)
downloadnuttx-9ce24cc300a68f59cab05eebeff5356f7d476e80.tar.gz
nuttx-9ce24cc300a68f59cab05eebeff5356f7d476e80.tar.bz2
nuttx-9ce24cc300a68f59cab05eebeff5356f7d476e80.zip
If port=0, UDP should select a port number
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1625 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/net/uip/uip_udpconn.c105
1 files changed, 73 insertions, 32 deletions
diff --git a/nuttx/net/uip/uip_udpconn.c b/nuttx/net/uip/uip_udpconn.c
index a1a12993c..ce23d2504 100644
--- a/nuttx/net/uip/uip_udpconn.c
+++ b/nuttx/net/uip/uip_udpconn.c
@@ -1,7 +1,7 @@
/****************************************************************************
* net/uip/uip_udpconn.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Large parts of this file were leveraged from uIP logic:
@@ -138,6 +138,62 @@ static struct uip_udp_conn *uip_find_conn(uint16 portno)
}
/****************************************************************************
+ * Name: uip_selectport()
+ *
+ * Description:
+ * Select an unused port number.
+ *
+ * NOTE that in prinicple this function could fail if there is no available
+ * port number. There is no check for that case and it would actually
+ * in an infinite loop if that were the case. In this simple, small UDP
+ * implementation, it is reasonable to assume that that error cannot happen
+ * and that a port number will always be available.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Return:
+ * Next available port number
+ *
+ ****************************************************************************/
+
+static uint16 uip_selectport(void)
+{
+ uint16 portno;
+
+ /* Find an unused local port number. Loop until we find a valid
+ * listen port number that is not being used by any other connection.
+ */
+
+ irqstate_t flags = irqsave();
+ do
+ {
+ /* Guess that the next available port number will be the one after
+ * the last port number assigned.
+ */
+
+ ++g_last_udp_port;
+
+ /* Make sure that the port number is within range */
+
+ if (g_last_udp_port >= 32000)
+ {
+ g_last_udp_port = 4096;
+ }
+ }
+ while (uip_find_conn(htons(g_last_udp_port)));
+
+ /* Initialize and return the connection structure, bind it to the
+ * port number
+ */
+
+ portno = g_last_udp_port;
+ irqrestore(flags);
+
+ return portno;
+}
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -311,9 +367,16 @@ int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
int ret = -EADDRINUSE;
irqstate_t flags;
- /* Never set lport to zero! */
+ /* Is the user requesting to bind to any port? */
+
+ if (!addr->sin_port)
+ {
+ /* Yes.. Find an unused local port number */
- if (addr->sin_port)
+ conn->lport = htons(uip_selectport());
+ ret = OK;
+ }
+ else
{
/* Interrupts must be disabled while access the UDP connection list */
@@ -326,12 +389,11 @@ int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
/* No.. then bind the socket to the port */
conn->lport = addr->sin_port;
- ret = OK;
+ ret = OK;
}
irqrestore(flags);
}
-
return ret;
}
@@ -361,40 +423,19 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in6 *addr)
int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
#endif
{
- /* Has this structure already been bound to a local port? */
+ /* Has this address already been bound to a local port (lport)? */
if (!conn->lport)
{
- /* No..Find an unused local port number. Loop until we find a valid
- * listen port number that is not being used by any other connection.
+ /* No.. Find an unused local port number and bind it to the
+ * connection structure.
*/
- irqstate_t flags = irqsave();
- do
- {
- /* Guess that the next available port number will be the one after
- * the last port number assigned.
- */
-
- ++g_last_udp_port;
-
- /* Make sure that the port number is within range */
-
- if (g_last_udp_port >= 32000)
- {
- g_last_udp_port = 4096;
- }
- }
- while (uip_find_conn(htons(g_last_udp_port)));
-
- /* Initialize and return the connection structure, bind it to the
- * port number
- */
-
- conn->lport = HTONS(g_last_udp_port);
- irqrestore(flags);
+ conn->lport = htons(uip_selectport());
}
+ /* Is there a remote port (rport) */
+
if (addr)
{
conn->rport = addr->sin_port;