Partial implementation of accept() and listen()

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@354 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2007-09-23 20:45:30 +00:00
parent b85008dc63
commit 69ec9510a0
12 changed files with 620 additions and 123 deletions

View File

@ -34,6 +34,6 @@
#include <sys/types.h>
extern void httpd_init(void);
extern void httpd_listen(void);
extern int httpd_listen(void);
#endif /* _NET_UIP_HTTPD_H */

View File

@ -159,32 +159,30 @@ typedef uip_ip4addr_t uip_ipaddr_t;
* file pointers) for the connection.
*/
struct uip_driver_s; /* Forward reference */
struct uip_driver_s; /* Forward reference */
struct uip_conn
{
dq_entry_t node; /* Implements a doubly linked list */
uip_ipaddr_t ripaddr; /* The IP address of the remote host. */
uint16 lport; /* The local TCP port, in network byte order. */
uint16 rport; /* The local remote TCP port, in network byte
order. */
uint16 rport; /* The local remote TCP port, in network byte order. */
uint8 rcv_nxt[4]; /* The sequence number that we expect to
receive next. */
uint8 snd_nxt[4]; /* The sequence number that was last sent by
us. */
* receive next. */
uint8 snd_nxt[4]; /* The sequence number that was last sent by us. */
uint16 len; /* Length of the data that was previously sent. */
uint16 mss; /* Current maximum segment size for the
connection. */
* connection. */
uint16 initialmss; /* Initial maximum segment size for the
connection. */
* connection. */
uint8 sa; /* Retransmission time-out calculation state
variable. */
* variable. */
uint8 sv; /* Retransmission time-out calculation state
variable. */
* variable. */
uint8 rto; /* Retransmission time-out. */
uint8 tcpstateflags; /* TCP state and flags. */
uint8 timer; /* The retransmission timer. */
uint8 nrtx; /* The number of retransmissions for the last
segment sent. */
* segment sent. */
/* Higher level logic can retain application specific information
* in the following:
@ -192,6 +190,8 @@ struct uip_conn
void *data_private;
void (*data_event)(struct uip_driver_s *dev, void *private);
void *accept_private;
int (*accept)(void *private, struct uip_conn *conn);
void *connection_private;
void (*connection_event)(void *private);
};
@ -564,7 +564,7 @@ extern int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr)
* port A 16-bit port number in network byte order.
*/
void uip_listen(uint16 port);
int uip_listen(uint16 port);
/* Stop listening to the specified port.
*
@ -574,7 +574,7 @@ void uip_listen(uint16 port);
* port A 16-bit port number in network byte order.
*/
void uip_unlisten(uint16 port);
int uip_unlisten(uint16 port);
/* Check if a connection has outstanding (i.e., unacknowledged) data.
*

View File

@ -42,12 +42,72 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <semaphore.h>
#include <string.h>
#include <errno.h>
#include <arch/irq.h>
#include "net-internal.h"
/****************************************************************************
* Global Functions
* Private Types
****************************************************************************/
struct accept_s
{
sem_t acpt_sem; /* Wait for interrupt event */
#ifdef CONFIG_NET_IPv6
FAR const struct sockaddr_in6 *acpt_addr; /* Return connection adress */
#else
FAR const struct sockaddr_in *acpt_addr; /* Return connection adress */
#endif
FAR struct uip_conn *acpt_listenconn; /* The listener connection */
FAR struct uip_conn *acpt_newconn; /* The accepted connection */
int acpt_result; /* The result of the wait */
};
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Function: accept_interrupt
*
* Description:
* Receive interrupt level callbacks when connections occur
*
****************************************************************************/
static int accept_interrupt(void *private, struct uip_conn *conn)
{
struct accept_s *pstate = (struct accept_s *)private;
int ret = -EINVAL;
if (pstate)
{
/* Get the connection address */
#warning "need to return the address of the connection"
/* Save the connection structure */
pstate->acpt_newconn = conn;
pstate->acpt_result = OK;
sem_post(&pstate->acpt_sem);
/* Stop any further callbacks */
pstate->acpt_listenconn->accept_private = NULL;
pstate->acpt_listenconn->accept = NULL;
ret = OK;
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
@ -122,7 +182,160 @@
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
*get_errno_ptr() = ENOSYS;
FAR struct socket *psock = sockfd_socket(sockfd);
FAR struct socket *pnewsock;
FAR struct uip_conn *conn;
struct accept_s state;
#ifdef CONFIG_NET_IPv6
FAR const struct sockaddr_in6 *inaddr = (const struct sockaddr_in6 *)addr;
#else
FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
#endif
irqstate_t save;
int newfd;
int err;
int ret;
/* Verify that the sockfd corresponds to valid, allocated socket */
if (!psock || psock->s_crefs <= 0)
{
/* It is not a valid socket description. Distinguish between the cases
* where sockfd is a just valid and when it is a valid file descriptor used
* in the wrong context.
*/
#if CONFIG_NFILE_DESCRIPTORS > 0
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
{
err = ENOTSOCK;
}
else
#endif
{
err = EBADF;
}
goto errout;
}
/* We have a socket descriptor, but it is a stream? */
if (psock->s_type != SOCK_STREAM)
{
err = EOPNOTSUPP;
goto errout;
}
/* Is the socket listening for a connection? */
if (!_SS_ISLISTENING(psock->s_flags))
{
err = EINVAL;
goto errout;
}
/* Verify that a valid memory block has been provided to receive the address address */
#ifdef CONFIG_NET_IPv6
if (addr->sa_family != AF_INET6 || *addrlen < sizeof(struct sockaddr_in6))
#else
if (addr->sa_family != AF_INET || *addrlen < sizeof(struct sockaddr_in))
#endif
{
err = EBADF;
goto errout;
}
/* Allocate a socket descriptor for the new connection now (so that it cannot fail later) */
newfd = sockfd_allocate();
if (newfd < 0)
{
err = ENFILE;
goto errout;
}
pnewsock = sockfd_socket(newfd);
if (newfd)
{
err = ENFILE;
goto errout_with_socket;
}
/* Set the socket state to accepting */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_ACCEPT);
/* Perform the TCP accept operation */
/* Initialize the state structure. This is done with interrupts
* disabled because we don't want anything to happen until we
* are ready.
*/
save = irqsave();
state.acpt_addr = inaddr;
state.acpt_listenconn = psock->s_conn;
state.acpt_newconn = NULL;
state.acpt_result = OK;
/* Set up the callback in the connection */
conn = (struct uip_conn *)psock->s_conn;
conn->accept_private = (void*)&state;
conn->accept = accept_interrupt;
/* Wait for the send to complete or an error 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. acpt_sem);
/* Make sure that no further interrupts are processed */
conn->accept_private = NULL;
conn->accept = NULL;
sem_destroy(&state. acpt_sem);
irqrestore(save);
/* Set the socket state to idle */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);
/* Check for a errors. Errors are signaled by negative errno values
* for the send length
*/
if (state.acpt_result != 0)
{
err = state.acpt_result;
goto errout_with_socket;
}
/* If sem_wait failed, then we were probably reawakened by a signal. In
* this case, sem_wait will have set errno appropriately.
*/
if (ret < 0)
{
err = -ret;
goto errout_with_socket;
}
/* Initialize the socket structure */
pnewsock->s_type = SOCK_STREAM;
pnewsock->s_conn = state.acpt_newconn;
return newfd;
errout_with_socket:
sockfd_release(newfd);
errout:
*get_errno_ptr() = err;
return ERROR;
}

View File

@ -56,7 +56,7 @@
* Description:
* To accept connections, a socket is first created with socket(), a
* willingness to accept incoming connections and a queue limit for incoming
* connections are specified with listen, and then the connections are
* connections are specified with listen(), and then the connections are
* accepted with accept(). The listen() call applies only to sockets of
* type SOCK_STREAM or SOCK_SEQPACKET.
*
@ -87,7 +87,51 @@
int listen(int sockfd, int backlog)
{
*get_errno_ptr() = ENOSYS;
FAR struct socket *psock = sockfd_socket(sockfd);
struct uip_conn *conn;
int err;
/* Verify that the sockfd corresponds to valid, allocated socket */
if (!psock || psock->s_crefs <= 0)
{
/* It is not a valid socket description. Distinguish between the cases
* where sockfd is a just valid and when it is a valid file descriptor used
* in the wrong context.
*/
#if CONFIG_NFILE_DESCRIPTORS > 0
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
{
err = ENOTSOCK;
}
else
#endif
{
err = EBADF;
}
goto errout;
}
/* Verify that the sockfd corresponds to a connected SOCK_STREAM */
conn = (struct uip_conn *)psock->s_conn;
if (psock->s_type != SOCK_STREAM || !psock->s_conn || conn->lport <= 0)
{
err = EOPNOTSUPP;
goto errout;
}
/* Start listening to the bound port. This enables callbacks when accept()
* is called; and someday should enable post() or select() logic.
*/
uip_listen(conn->lport);
psock->s_flags |= _SF_LISTENING;
return OK;
errout:
*get_errno_ptr() = err;
return ERROR;
}

View File

@ -56,11 +56,12 @@
/* Bits 0:2 : Socket state */
#define _SF_IDLE 0x00 /* There is no socket activity */
#define _SF_LISTEN 0x01 /* Socket is listening */
#define _SF_ACCEPT 0x01 /* Socket is waiting to accept a connection */
#define _SF_RECV 0x02 /* Waiting for recv action to complete */
#define _SF_SEND 0x03 /* Waiting for send action to complete */
#define _SF_MASK 0x03 /* Mask to isolate the above actions */
/* Bits 3:5 : unused */
/* Bits 3:4 : unused */
#define _SF_LISTENING 0x20 /* Bit 5: SOCK_STREAM is listening */
#define _SF_BOUND 0x40 /* Bit 6: SOCK_STREAM is bound to an address */
#define _SF_CONNECTED 0x80 /* Bit 7: SOCK_STREAM is connected */
@ -69,8 +70,9 @@
#define _SS_SETSTATE(s,f) (((s) & ~_SF_MASK) | (f))
#define _SS_GETSTATE(s) ((s) & _SF_MASK)
#define _SS_ISBUSY(s) (_SS_GETSTATE(s) != _SF_IDLE)
#define _SS_ISCONNECTED(s) (((s) & _SF_CONNECTED) != 0)
#define _SS_ISLISTENING(s) (((s) & _SF_LISTENING) != 0)
#define _SS_ISBOUND(s) (((s) & _SF_CONNECTED) != 0)
#define _SS_ISCONNECTED(s) (((s) & _SF_CONNECTED) != 0)
/* This macro converts a socket option value into a bit setting */

View File

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

View File

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

206
net/uip/uip-listen.c Normal file
View File

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

View File

@ -90,38 +90,6 @@ static uint8 g_tcp_sequence[4];
* Private Functions
****************************************************************************/
/****************************************************************************
* 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()
*
@ -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)

View File

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

View File

@ -72,38 +72,39 @@ $(COBJS): %$(OBJEXT): %.c
$(CC) -c $(CFLAGS) $< -o $@
$(BIN): $(OBJS)
( for obj in $(OBJS) ; do \
@( for obj in $(OBJS) ; do \
$(AR) $@ $${obj} || \
{ echo "$(AR) $@ $obj FAILED!" ; exit 1 ; } ; \
done ; )
makestrings$(EXEEXT): uiplib/makestrings.c
gcc -O2 -Wall -o makestrings$(EXEEXT) uiplib/makestrings.c
@gcc -O2 -Wall $< -o $@
.strings: makestrings$(EXEEXT) uiplib/netutil-strings
./makestrings uiplib/netutil-strings
@./makestrings uiplib/netutil-strings
@touch $@
Make.str: makestrings$(EXEEXT) uiplib/netutil-strings
./makestrings -s uiplib/netutil-strings >Make.str
@./makestrings -s uiplib/netutil-strings >Make.str
.depend: Makefile $(SRCS)
ifeq ($(CONFIG_NET),y)
$(MKDEP) --dep-path . --dep-path uiplib --dep-path dhcpc --dep-path smtp --dep-path webclient \
@$(MKDEP) --dep-path . --dep-path uiplib --dep-path dhcpc --dep-path smtp --dep-path webclient \
--dep-path resolv --dep-path telnetd --dep-path webserver \
$(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
endif
touch $@
@touch $@
depend: .strings Make.str .depend
clean:
rm -f $(BIN) *.o *.rel *.asm *.lst *.sym *.adb *~
rm -f uiplib/*~ dhcpc/*~ resolv/*~ smtp/*~ telnetd/*~ webclient/*~ webserver/*~
if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
@rm -f $(BIN) *.o *.rel *.asm *.lst *.sym *.adb *~
@rm -f uiplib/*~ dhcpc/*~ resolv/*~ smtp/*~ telnetd/*~ webclient/*~ webserver/*~
@if [ ! -z "$(OBJEXT)" ]; then rm -f *$(OBJEXT); fi
distclean: clean
rm -f Make.dep .depend
rm -f $(STRNG_CSRCS) $(STRNG_ASRCS)
rm -f Make.str netutil-strings.h makestrings$(EXEEXT)
@rm -f Make.dep .depend
@rm -f $(STRNG_CSRCS) $(STRNG_ASRCS)
@rm -f Make.str netutil-strings.h makestrings$(EXEEXT)
-include Make.dep

View File

@ -1,17 +1,24 @@
/* httpd
/****************************************************************************
* httpd
* httpd Web server
* Author: Adam Dunkels <adam@sics.se>
*
* The uIP web server is a very simplistic implementation of an HTTP
* server. It can serve web pages and files from a read-only ROM
* filesystem, and provides a very small scripting language.
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Copyright (c) 2004, Adam Dunkels.
* All rights reserved.
* This is a leverage of similar logic from uIP:
*
* Author: Adam Dunkels <adam@sics.se>
* Copyright (c) 2004, Adam Dunkels.
* All rights reserved.
*
* The uIP web server is a very simplistic implementation of an HTTP
* server. It can serve web pages and files from a read-only ROM
* filesystem, and provides a very small scripting language.
*
* 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
@ -32,10 +39,15 @@
* 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 <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <net/uip/uip.h>
#include <net/uip/httpd.h>
@ -44,7 +56,9 @@
#include "httpd-cgi.h"
#include "netutil-strings.h"
#include <string.h>
/****************************************************************************
* Definitions
****************************************************************************/
#define STATE_WAITING 0
#define STATE_OUTPUT 1
@ -59,6 +73,10 @@
#define SEND_STR(psock, str) psock_send(psock, str, strlen(str))
/****************************************************************************
* Private Functions
****************************************************************************/
static inline int send_file(struct httpd_state *pstate)
{
return send(pstate->sockout, pstate->file.data, pstate->file.len, 0);
@ -256,16 +274,31 @@ static void handle_connection(struct httpd_state *pstate)
}
}
void httpd_listen(void)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: httpd_listen
*
* Description:
* This is the main processing thread for the webserver. It never returns
* unless an error occurs
*
****************************************************************************/
int httpd_listen(void)
{
#warning "this is all very broken at the moment"
}
/* Initialize the web server
/****************************************************************************
* Name: httpd_init
*
* This function initializes the web server and should be
* called at system boot-up.
*/
* Description:
* This function initializes the web server and should be called at system
* boot-up.
*
****************************************************************************/
void httpd_init(void)
{