diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-06-29 09:30:09 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-06-29 09:30:09 -0600 |
commit | 1deaf2a9634576bf0e0f35a24911c3f22215fbd2 (patch) | |
tree | cfc63769fd41a0e4417e2a723d79e4ba8fb6f077 | |
parent | 02bad8e430f112e7f0bac29f52861c7048cb2bbe (diff) | |
download | nuttx-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.h | 52 | ||||
-rw-r--r-- | apps/netutils/webserver/Kconfig | 9 | ||||
-rw-r--r-- | apps/netutils/webserver/httpd.c | 44 | ||||
-rw-r--r-- | nuttx/libc/wqueue/work_thread.c | 46 | ||||
-rw-r--r-- | nuttx/net/socket/net_sendfile.c | 2 | ||||
-rw-r--r-- | nuttx/net/utils/net_chksum.c | 7 |
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. */ |