mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 23:29:25 +00:00
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:
parent
c86b446d4c
commit
8cfd923aaa
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user