summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-06-29 09:30:09 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-06-29 09:30:09 -0600
commit1deaf2a9634576bf0e0f35a24911c3f22215fbd2 (patch)
treecfc63769fd41a0e4417e2a723d79e4ba8fb6f077
parent02bad8e430f112e7f0bac29f52861c7048cb2bbe (diff)
downloadnuttx-1deaf2a9634576bf0e0f35a24911c3f22215fbd2.tar.gz
nuttx-1deaf2a9634576bf0e0f35a24911c3f22215fbd2.tar.bz2
nuttx-1deaf2a9634576bf0e0f35a24911c3f22215fbd2.zip
Fixes for networking and tiny webserver from Max
-rw-r--r--apps/include/netutils/httpd.h52
-rw-r--r--apps/netutils/webserver/Kconfig9
-rw-r--r--apps/netutils/webserver/httpd.c44
-rw-r--r--nuttx/libc/wqueue/work_thread.c46
-rw-r--r--nuttx/net/socket/net_sendfile.c2
-rw-r--r--nuttx/net/utils/net_chksum.c7
6 files changed, 109 insertions, 51 deletions
diff --git a/apps/include/netutils/httpd.h b/apps/include/netutils/httpd.h
index 56e5da38a..e18542df1 100644
--- a/apps/include/netutils/httpd.h
+++ b/apps/include/netutils/httpd.h
@@ -1,7 +1,7 @@
/****************************************************************************
* apps/include/netutils/httpd.h
*
- * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007, 2009, 2011-2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Based on uIP which also has a BSD style license:
@@ -44,22 +44,17 @@
* Included Files
****************************************************************************/
+#include <nuttx/net/tcp.h>
#include <nuttx/net/uip.h>
#include <stdint.h>
#include <stdbool.h>
+#include <limits.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
-#ifdef __cplusplus
-# define EXTERN extern "C"
-extern "C" {
-#else
-# define EXTERN extern
-#endif
-
/* As threads are created to handle each request, a stack must be allocated
* for the thread. Use a default if the user provided no stacksize.
*/
@@ -89,12 +84,19 @@ extern "C" {
/* This is the maximum size of a file path */
-#if defined(CONFIG_NETUTILS_HTTPD_MMAP) || defined(CONFIG_NETUTILS_HTTPD_SENDFILE)
-#define HTTPD_MAX_FILENAME PATH_MAX
-#else
-#define HTTPD_MAX_FILENAME 20
+#ifndef CONFIG_NETUTILS_HTTPD_MAXPATH
+# define CONFIG_NETUTILS_HTTPD_MAXPATH PATH_MAX
#endif
+#define HTTPD_MAX_FILENAME CONFIG_HTTPD_MAXPATH
+
+/* Other tunable values. If you need to change these values, please create
+ * new configurations in apps/netutils/webserver/Kconfig
+ */
+
+#defien HTTPD_MAX_CONTENTLEN 32
+#defien HTTPD_MAX_HEADERLEN 180
+
/****************************************************************************
* Public types
****************************************************************************/
@@ -160,7 +162,7 @@ struct httpd_cgi_call
* then added to the list of HTTPD CGI functions with the httpd_cgi_register()
* function.
- * Input Paramters:
+ * Input Parameters:
*
* name The C variable name of the function
* str The string name of the function, used in the script file
@@ -172,16 +174,28 @@ static void function(struct httpd_state *, char *); \
static struct httpd_cgi_call name = {NULL, str, function}
/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+# define EXTERN extern "C"
+extern "C"
+{
+#else
+# define EXTERN extern
+#endif
+
+/****************************************************************************
* Public Function Prototypes
****************************************************************************/
-EXTERN void httpd_init(void);
-EXTERN int httpd_listen(void);
-EXTERN void httpd_cgi_register(struct httpd_cgi_call *cgi_call);
-EXTERN uint16_t httpd_fs_count(char *name);
+void httpd_init(void);
+int httpd_listen(void);
+void httpd_cgi_register(struct httpd_cgi_call *cgi_call);
+uint16_t httpd_fs_count(char *name);
-EXTERN const struct httpd_fsdata_file g_httpdfs_root[];
-EXTERN const int g_httpd_numfiles;
+const struct httpd_fsdata_file g_httpdfs_root[];
+const int g_httpd_numfiles;
#undef EXTERN
#ifdef __cplusplus
diff --git a/apps/netutils/webserver/Kconfig b/apps/netutils/webserver/Kconfig
index d984427a3..59dcc5f30 100644
--- a/apps/netutils/webserver/Kconfig
+++ b/apps/netutils/webserver/Kconfig
@@ -33,6 +33,15 @@ config NETUTILS_HTTPD_SCRIPT_DISABLE
---help---
This option, if selected, will elide the %! scripting
+config NETUTILS_HTTPD_MAXPATH
+ bool "Maximum size of a path"
+ default 64
+ ---help---
+ This is the maximum size of a PATH used in the web server. This setting
+ is the logically the same as the PATH_MAX setting that (and in fact, if
+ not defined, the MAX_PATH setting will be used). This setting allows
+ more conservative memory allocation.
+
config NETUTILS_HTTPD_CGIPATH
bool "URL/CGI function mapping"
default n
diff --git a/apps/netutils/webserver/httpd.c b/apps/netutils/webserver/httpd.c
index 26989611b..ab67842ee 100644
--- a/apps/netutils/webserver/httpd.c
+++ b/apps/netutils/webserver/httpd.c
@@ -336,8 +336,9 @@ static int send_headers(struct httpd_state *pstate, int status, int len)
{
const char *mime;
const char *ptr;
- char cl[32];
- char s[128];
+ char contentlen[HTTPD_MAX_CONTENTLEN];
+ char header[HTTPD_MAX_HEADERLEN];
+ int hdrlen;
int i;
static const struct
@@ -381,7 +382,8 @@ static int send_headers(struct httpd_state *pstate, int status, int len)
if (len >= 0)
{
- (void) snprintf(cl, sizeof cl, "Content-Length: %d\r\n", len);
+ (void)snprintf(contentlen, HTTPD_MAX_CONTENTLEN,
+ "Content-Length: %d\r\n", len);
}
#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
else
@@ -395,26 +397,32 @@ static int send_headers(struct httpd_state *pstate, int status, int len)
/* TODO: here we "SHOULD" include a Retry-After header */
}
- i = snprintf(s, sizeof s,
- "HTTP/1.0 %d %s\r\n"
+ /* Construct the header.
+ *
+ * REVISIT: Wouldn't asprintf be a better option than a large stack
+ * array?
+ */
+
+ hdrlen = snprintf(header, HTTPD_MAX_HEADERLEN,
+ "HTTP/1.0 %d %s\r\n"
#ifndef CONFIG_NETUTILS_HTTPD_SERVERHEADER_DISABLE
- "Server: uIP/NuttX http://nuttx.org/\r\n"
-#endif
- "Connection: %s\r\n"
- "Content-type: %s\r\n"
- "%s"
- "\r\n",
- status,
- status >= 400 ? "Error" : "OK",
+ "Server: uIP/NuttX http://nuttx.org/\r\n"
+#endif
+ "Connection: %s\r\n"
+ "Content-type: %s\r\n"
+ "%s"
+ "\r\n",
+ status,
+ status >= 400 ? "Error" : "OK",
#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
- pstate->ht_keepalive ? "keep-alive" : "close",
+ pstate->ht_keepalive ? "keep-alive" : "close",
#else
- "close",
+ "close",
#endif
- mime,
- len >= 0 ? cl : "");
+ mime,
+ len >= 0 ? contentlen : "");
- return send_chunk(pstate, s, i);
+ return send_chunk(pstate, header, hdrlen);
}
static int httpd_senderror(struct httpd_state *pstate, int status)
diff --git a/nuttx/libc/wqueue/work_thread.c b/nuttx/libc/wqueue/work_thread.c
index 285f7183c..c0474ad69 100644
--- a/nuttx/libc/wqueue/work_thread.c
+++ b/nuttx/libc/wqueue/work_thread.c
@@ -148,26 +148,44 @@ static void work_process(FAR struct wqueue_s *wqueue)
*/
worker = work->worker;
- arg = work->arg;
- /* Mark the work as no longer being queued */
+ /* Check for a race condition where the work may be nullified
+ * before it is removed from the queue.
+ */
- work->worker = NULL;
+ if (worker != NULL)
+ {
+ /* Extract the work argument (before re-enabling interrupts) */
- /* Do the work. Re-enable interrupts while the work is being
- * performed... we don't have any idea how long that will take!
- */
+ arg = work->arg;
- irqrestore(flags);
- worker(arg);
+ /* Mark the work as no longer being queued */
- /* Now, unfortunately, since we re-enabled interrupts we don't
- * know the state of the work list and we will have to start
- * back at the head of the list.
- */
+ work->worker = NULL;
+
+ /* Do the work. Re-enable interrupts while the work is being
+ * performed... we don't have any idea how long that will take!
+ */
+
+ irqrestore(flags);
+ worker(arg);
- flags = irqsave();
- work = (FAR struct work_s *)wqueue->q.head;
+ /* Now, unfortunately, since we re-enabled interrupts we don't
+ * know the state of the work list and we will have to start
+ * back at the head of the list.
+ */
+
+ flags = irqsave();
+ work = (FAR struct work_s *)wqueue->q.head;
+ }
+ else
+ {
+ /* Cancelled.. Just move to the next work in the list with
+ * interrupts still disabled.
+ */
+
+ work = (FAR struct work_s *)work->dq.flink;
+ }
}
else
{
diff --git a/nuttx/net/socket/net_sendfile.c b/nuttx/net/socket/net_sendfile.c
index 5b43f297d..bc4181ab4 100644
--- a/nuttx/net/socket/net_sendfile.c
+++ b/nuttx/net/socket/net_sendfile.c
@@ -60,10 +60,12 @@
#include <nuttx/fs/fs.h>
#include <nuttx/net/arp.h>
#include <nuttx/net/netdev.h>
+#include <nuttx/net/tcp.h>
#include "socket/socket.h"
#include "netdev/netdev.h"
#include "devif/devif.h"
+#include "tcp/tcp.h"
/****************************************************************************
* Definitions
diff --git a/nuttx/net/utils/net_chksum.c b/nuttx/net/utils/net_chksum.c
index ff8438678..789646f50 100644
--- a/nuttx/net/utils/net_chksum.c
+++ b/nuttx/net/utils/net_chksum.c
@@ -126,6 +126,13 @@ static uint16_t upper_layer_chksum(FAR struct net_driver_s *dev, uint8_t proto)
upper_layer_len = (((uint16_t)(pbuf->len[0]) << 8) + pbuf->len[1]) - UIP_IPH_LEN;
#endif /* CONFIG_NET_IPv6 */
+ /* Verify some minimal assumptions */
+
+ if (upper_layer_len > CONFIG_NET_BUFSIZE)
+ {
+ return 0;
+ }
+
/* First sum pseudo-header. */
/* IP protocol and length fields. This addition cannot carry. */