Added some documentation (mainly what is unimplemented in contrast to 'std-BSD'), alloc_socket returns the sock pointer directly (for speedup)

This commit is contained in:
goldsimon 2007-11-24 17:39:53 +00:00
parent c86b446d4c
commit 8cfd923aaa
2 changed files with 130 additions and 32 deletions

View File

@ -55,47 +55,74 @@
#define NUM_SOCKETS MEMP_NUM_NETCONN
/** Contains all internal pointers and states used for a socket */
struct lwip_socket {
/** sockets currently are built on netconns, each socket has one netconn */
struct netconn *conn;
/** data that was left from the previous read */
struct netbuf *lastdata;
/** offset in the data that was left from the previous read */
u16_t lastoffset;
/** number of times data was received, set by event_callback(),
tested by the receive and select functions */
u16_t rcvevent;
/** number of times data was received, set by event_callback(),
tested by select */
u16_t sendevent;
u16_t flags;
/** socket flags (currently, only used for O_NONBLOCK) */
u16_t flags;
/** last error that occurred on this socket */
int err;
};
/** Description for a task waiting in select */
struct lwip_select_cb {
/** Pointer to the next waiting task */
struct lwip_select_cb *next;
/** readset passed to select */
fd_set *readset;
/** writeset passed to select */
fd_set *writeset;
/** unimplemented: exceptset passed to select */
fd_set *exceptset;
/** don't signal the same semaphore twice: set to 1 when signalled */
int sem_signalled;
/** semaphore to wake up a task waiting for select */
sys_sem_t sem;
};
/* This struct is used to pass data to the set/getsockopt_internal
/** This struct is used to pass data to the set/getsockopt_internal
* functions running in tcpip_thread context (only a void* is allowed) */
struct lwip_setgetsockopt_data {
/** socket struct for which to change options */
struct lwip_socket *sock;
/** socket index for which to change options */
int s;
/** level of the option to process */
int level;
/** name of the option to process */
int optname;
/** set: value to set the option to
* get: value of the option is stored here */
void *optval;
/** size of *optval */
socklen_t *optlen;
/** if an error occures, it is temporarily stored here */
err_t err;
};
/** The global array of available sockets */
static struct lwip_socket sockets[NUM_SOCKETS];
/** The global list of tasks waiting for select */
static struct lwip_select_cb *select_cb_list;
/** Semaphore protecting the sockets array */
static sys_sem_t socksem;
/** Semaphore protecting select_cb_list */
static sys_sem_t selectsem;
static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
static void lwip_getsockopt_internal(void *arg);
static void lwip_setsockopt_internal(void *arg);
/** Table to quickly map an lwIP error (err_t) to a socket error
* by using -err as an index */
static const int err_to_errno_table[] = {
0, /* ERR_OK 0 No error, everything OK. */
ENOMEM, /* ERR_MEM -1 Out of memory error. */
@ -131,7 +158,15 @@ static const int err_to_errno_table[] = {
set_errno(sk->err); \
} while (0)
/* Forward delcaration of some functions */
static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
static void lwip_getsockopt_internal(void *arg);
static void lwip_setsockopt_internal(void *arg);
/**
* Initialize this module. This function has to be called before any other
* functions in this module!
*/
void
lwip_socket_init(void)
{
@ -139,6 +174,12 @@ lwip_socket_init(void)
selectsem = sys_sem_new(1);
}
/**
* Map a externally used socket index to the internal socket representation.
*
* @param s externally used socket index
* @return struct lwip_socket for the socket or NULL if not found
*/
static struct lwip_socket *
get_socket(int s)
{
@ -161,10 +202,21 @@ get_socket(int s)
return sock;
}
/**
* Allocate a new socket for a given netconn.
*
* @param newconn the netconn for which to allocate a socket
* @return the index of the new socket; -1 on error
*/
static int
alloc_socket(struct netconn *newconn)
alloc_socket(struct netconn *newconn, struct lwip_socket **sock)
{
int i;
struct lwip_socket *unused;
if (sock == NULL) {
sock = &unused;
}
*sock = NULL;
/* Protect socket array */
sys_sem_wait(socksem);
@ -180,6 +232,7 @@ alloc_socket(struct netconn *newconn)
sockets[i].flags = 0;
sockets[i].err = 0;
sys_sem_signal(socksem);
*sock = &sockets[i];
return i;
}
}
@ -187,6 +240,12 @@ alloc_socket(struct netconn *newconn)
return -1;
}
/* Below this, the well-known socket functions are implemented.
* Use google.com or opengroup.org to get a good description :-)
*
* Exceptions are documented!
*/
int
lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
@ -229,14 +288,15 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
SMEMCPY(addr, &sin, *addrlen);
newsock = alloc_socket(newconn);
newsock = alloc_socket(newconn, &sock);
if (newsock == -1) {
netconn_delete(newconn);
sock_set_errno(sock, ENFILE);
return -1;
}
newconn->callback = event_callback;
sock = get_socket(newsock);
LWIP_ASSERT("invalid socket pointer", sock != NULL);
LWIP_ASSERT("socket pointer doesn't match the array", &sockets[newsock] == sock);
sys_sem_wait(socksem);
sock->rcvevent += -1 - newconn->socket;
@ -355,6 +415,14 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
return 0;
}
/**
* Set a socket into listen mode.
* The socket may not have been used for another connection previously.
*
* @param s the socket to set to listening mode
* @param backlog (ATTENTION: this is not implemented, yet!)
* @return 0 on success, non-zero on failure
*/
int
lwip_listen(int s, int backlog)
{
@ -676,7 +744,7 @@ lwip_socket(int domain, int type, int protocol)
return -1;
}
i = alloc_socket(conn);
i = alloc_socket(conn, NULL);
if (i == -1) {
netconn_delete(conn);
@ -695,6 +763,21 @@ lwip_write(int s, const void *data, int size)
return lwip_send(s, data, size, 0);
}
/**
* Go through the readset and writeset lists and see which socket of the sockets
* set in the sets has events. On return, readset, writeset and exceptset have
* the sockets enabled that had events.
*
* exceptset is not used for now!!!
*
* @param maxfdp1 the highest socket index in the sets
* @param readset in: set of sockets to check for read events;
* out: set of sockets that had read events
* @param writeset in: set of sockets to check for write events;
* out: set of sockets that had write events
* @param exceptset not yet implemented
* @return number of sockets that had events (read+write)
*/
static int
lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
{
@ -735,6 +818,10 @@ lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
return nready;
}
/**
* Processing exceptset is not yet implemented.
*/
int
lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
struct timeval *timeout)
@ -880,6 +967,10 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
return nready;
}
/**
* Callback registered in the netconn layer for each socket-netconn.
* Processes recvevent (data available) and wakes up tasks waiting for select.
*/
static void
event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
{
@ -958,6 +1049,10 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
}
}
/**
* Unimplemented: Close one end of a full-duplex connection.
* Currently, the full connection is closed.
*/
int
lwip_shutdown(int s, int how)
{

View File

@ -64,39 +64,39 @@ struct sockaddr {
# define socklen_t u32_t
#endif
/* Socket protocol types (TCP/UDP/RAW) */
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_RAW 3
/*
* Option flags per-socket.
* Option flags per-socket. These must match the SOF_ flags in ip.h!
*/
#define SO_DEBUG 0x0001 /* turn on debugging info recording */
#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
#define SO_REUSEADDR 0x0004 /* Unimplemented: allow local address reuse */
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
#define SO_DONTROUTE 0x0010 /* just use interface addresses */
#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */
#define SO_BROADCAST 0x0020 /* Unimplemented: permit sending of broadcast msgs */
#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */
#define SO_DONTLINGER ((int)(~SO_LINGER))
/*
* Additional options, not kept in so_options.
*/
#define SO_SNDBUF 0x1001 /* send buffer size */
#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
#define SO_RCVBUF 0x1002 /* receive buffer size */
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* Unimplemented: send timeout */
#define SO_RCVTIMEO 0x1006 /* receive timeout */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
#define SO_CONTIMEO 0x1009 /* connect timeout */
#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
@ -129,8 +129,8 @@ struct linger {
/* Flags we can use with send and recv. */
#define MSG_PEEK 0x01 /* Peeks at an incoming message */
#define MSG_WAITALL 0x02 /* Requests that the function block until the full amount of data requested can be returned */
#define MSG_OOB 0x04 /* Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
#define MSG_MORE 0x10 /* Sender will send more */
@ -177,6 +177,7 @@ typedef struct ip_mreq {
} ip_mreq;
#endif /* LWIP_IGMP */
/* Unimplemented for now... */
#define IPTOS_TOS_MASK 0x1E
#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
#define IPTOS_LOWDELAY 0x10
@ -186,7 +187,7 @@ typedef struct ip_mreq {
#define IPTOS_MINCOST IPTOS_LOWCOST
/*
* Definitions for IP precedence (also in ip_tos) (hopefully unused)
* Definitions for IP precedence (also in ip_tos) (Unimplemented)
*/
#define IPTOS_PREC_MASK 0xe0
#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
@ -202,7 +203,7 @@ typedef struct ip_mreq {
/*
* Commands for ioctlsocket(), taken from the BSD file fcntl.h.
*
* lwip_ioctl only supports FIONREAD and FIONBIO, for now
*
* Ioctl's have the command encoded in the lower word,
* and the size of any in or out parameters in the upper
@ -223,7 +224,7 @@ typedef struct ip_mreq {
#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#endif
#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
#ifndef FIONREAD
#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
@ -232,7 +233,7 @@ typedef struct ip_mreq {
#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
#endif
/* Socket I/O Controls */
/* Socket I/O Controls: unimplemented */
#ifndef SIOCSHIWAT
#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */
#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */
@ -241,10 +242,12 @@ typedef struct ip_mreq {
#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */
#endif
/* Socket flags: */
#ifndef O_NONBLOCK
#define O_NONBLOCK 04000U
#endif
/* FD_SET used for lwip_select */
#ifndef FD_SET
#undef FD_SETSIZE
/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
@ -271,9 +274,9 @@ typedef struct ip_mreq {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
#endif
#endif /* LWIP_TIMEVAL_PRIVATE */
#endif
#endif /* FD_SET */
void lwip_socket_init(void);