mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-17 17:10:03 +00:00
- fixed bug #43797 set/getsockopt: SO_SNDTIMEO/SO_RCVTIMEO take int as option but should take timeval (LWIP_SO_SNDRCVTIMEO_STANDARD==0 can be used to revert to the old 'winsock' style behaviour);
- Fixed implementation of SO_ACCEPTCONN to just look at the pcb state; - cleaned up the SO/SOF defines (only 3 left a ip_pcb level);
This commit is contained in:
parent
8e13bcd43d
commit
7ca4fd817e
@ -143,6 +143,12 @@ HISTORY
|
||||
|
||||
++ Bugfixes:
|
||||
|
||||
2014-12-10: Simon Goldschmidt
|
||||
* sockets.c, tcp.c, others: fixed bug #43797 set/getsockopt: SO_SNDTIMEO/SO_RCVTIMEO
|
||||
take int as option but should take timeval (LWIP_SO_SNDRCVTIMEO_STANDARD==0 can
|
||||
be used to revert to the old 'winsock' style behaviour)
|
||||
Fixed implementation of SO_ACCEPTCONN to just look at the pcb state
|
||||
|
||||
2014-12-09: Simon Goldschmidt
|
||||
* ip4.c: fixed bug #43596 IGMP queries from 0.0.0.0 are discarded
|
||||
|
||||
|
@ -1536,7 +1536,7 @@ lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
int
|
||||
lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
{
|
||||
err_t err = ERR_OK;
|
||||
u8_t err = 0;
|
||||
struct lwip_sock *sock = get_socket(s);
|
||||
LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
|
||||
|
||||
@ -1563,12 +1563,6 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
case SO_ERROR:
|
||||
case SO_KEEPALIVE:
|
||||
/* UNIMPL case SO_CONTIMEO: */
|
||||
#if LWIP_SO_SNDTIMEO
|
||||
case SO_SNDTIMEO:
|
||||
#endif /* LWIP_SO_SNDTIMEO */
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
case SO_RCVTIMEO:
|
||||
#endif /* LWIP_SO_RCVTIMEO */
|
||||
#if LWIP_SO_RCVBUF
|
||||
case SO_RCVBUF:
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
@ -1586,6 +1580,24 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
err = EINVAL;
|
||||
}
|
||||
break;
|
||||
#if LWIP_SO_SNDTIMEO || LWIP_SO_RCVTIMEO
|
||||
#if LWIP_SO_SNDTIMEO
|
||||
case SO_SNDTIMEO:
|
||||
#endif /* LWIP_SO_SNDTIMEO */
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
case SO_RCVTIMEO:
|
||||
#endif /* LWIP_SO_RCVTIMEO */
|
||||
if (*optlen <
|
||||
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||||
sizeof(int)
|
||||
#else /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
sizeof(struct timeval)
|
||||
#endif /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD*/
|
||||
) {
|
||||
err = EINVAL;
|
||||
}
|
||||
break;
|
||||
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_RCVTIMEO */
|
||||
|
||||
case SO_NO_CHECK:
|
||||
if (*optlen < sizeof(int)) {
|
||||
@ -1746,7 +1758,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
} /* switch */
|
||||
|
||||
|
||||
if (err != ERR_OK) {
|
||||
if (err != 0) {
|
||||
sock_set_errno(sock, err);
|
||||
return -1;
|
||||
}
|
||||
@ -1811,8 +1823,19 @@ lwip_getsockopt_internal(void *arg)
|
||||
case SOL_SOCKET:
|
||||
switch (optname) {
|
||||
|
||||
/* The option flags */
|
||||
case SO_ACCEPTCONN:
|
||||
if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_TCP) {
|
||||
if ((sock->conn->pcb.tcp != NULL) && (sock->conn->pcb.tcp->state == LISTEN)) {
|
||||
*(int*)optval = 1;
|
||||
} else {
|
||||
*(int*)optval = 0;
|
||||
}
|
||||
} else {
|
||||
data->err = ENOPROTOOPT;
|
||||
}
|
||||
break;
|
||||
|
||||
/* The option flags */
|
||||
case SO_BROADCAST:
|
||||
/* UNIMPL case SO_DEBUG: */
|
||||
/* UNIMPL case SO_DONTROUTE: */
|
||||
@ -1862,12 +1885,28 @@ lwip_getsockopt_internal(void *arg)
|
||||
|
||||
#if LWIP_SO_SNDTIMEO
|
||||
case SO_SNDTIMEO:
|
||||
*(int *)optval = netconn_get_sendtimeout(sock->conn);
|
||||
{
|
||||
s32_t val = netconn_get_sendtimeout(sock->conn);
|
||||
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||||
*(int *)optval = val;
|
||||
#else /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
((struct timeval *)optval)->tv_sec = val / 1000U;
|
||||
((struct timeval *)optval)->tv_sec = (val % 1000U) * 1000U;
|
||||
#endif /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
}
|
||||
break;
|
||||
#endif /* LWIP_SO_SNDTIMEO */
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
case SO_RCVTIMEO:
|
||||
*(int *)optval = netconn_get_recvtimeout(sock->conn);
|
||||
{
|
||||
s32_t val = netconn_get_recvtimeout(sock->conn);
|
||||
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||||
*(int *)optval = (int)val;
|
||||
#else /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
((struct timeval *)optval)->tv_sec = val / 1000U;
|
||||
((struct timeval *)optval)->tv_sec = (val % 1000U) * 1000U;
|
||||
#endif /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
}
|
||||
break;
|
||||
#endif /* LWIP_SO_RCVTIMEO */
|
||||
#if LWIP_SO_RCVBUF
|
||||
@ -2033,7 +2072,7 @@ int
|
||||
lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
|
||||
{
|
||||
struct lwip_sock *sock = get_socket(s);
|
||||
err_t err = ERR_OK;
|
||||
u8_t err = 0;
|
||||
LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
|
||||
|
||||
if (!sock) {
|
||||
@ -2057,12 +2096,6 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
|
||||
/* UNIMPL case SO_DONTROUTE: */
|
||||
case SO_KEEPALIVE:
|
||||
/* UNIMPL case case SO_CONTIMEO: */
|
||||
#if LWIP_SO_SNDTIMEO
|
||||
case SO_SNDTIMEO:
|
||||
#endif /* LWIP_SO_SNDTIMEO */
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
case SO_RCVTIMEO:
|
||||
#endif /* LWIP_SO_RCVTIMEO */
|
||||
#if LWIP_SO_RCVBUF
|
||||
case SO_RCVBUF:
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
@ -2079,6 +2112,24 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
|
||||
err = EINVAL;
|
||||
}
|
||||
break;
|
||||
#if LWIP_SO_SNDTIMEO || LWIP_SO_RCVTIMEO
|
||||
#if LWIP_SO_SNDTIMEO
|
||||
case SO_SNDTIMEO:
|
||||
#endif /* LWIP_SO_SNDTIMEO */
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
case SO_RCVTIMEO:
|
||||
#endif /* LWIP_SO_RCVTIMEO */
|
||||
if (optlen <
|
||||
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||||
sizeof(int)
|
||||
#else /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
sizeof(struct timeval)
|
||||
#endif /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD*/
|
||||
) {
|
||||
err = EINVAL;
|
||||
}
|
||||
break;
|
||||
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_RCVTIMEO */
|
||||
case SO_NO_CHECK:
|
||||
if (optlen < sizeof(int)) {
|
||||
err = EINVAL;
|
||||
@ -2269,7 +2320,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
|
||||
} /* switch (level) */
|
||||
|
||||
|
||||
if (err != ERR_OK) {
|
||||
if (err != 0) {
|
||||
sock_set_errno(sock, err);
|
||||
return -1;
|
||||
}
|
||||
@ -2356,12 +2407,28 @@ lwip_setsockopt_internal(void *arg)
|
||||
break;
|
||||
#if LWIP_SO_SNDTIMEO
|
||||
case SO_SNDTIMEO:
|
||||
netconn_set_sendtimeout(sock->conn, (s32_t)*(int*)optval);
|
||||
{
|
||||
s32_t val;
|
||||
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||||
val = (s32_t)*(int*)optval;
|
||||
#else /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
val = (((struct timeval *)optval)->tv_sec * 1000U) + (((struct timeval *)optval)->tv_usec / 1000U);
|
||||
#endif /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
netconn_set_sendtimeout(sock->conn, val);
|
||||
}
|
||||
break;
|
||||
#endif /* LWIP_SO_SNDTIMEO */
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
case SO_RCVTIMEO:
|
||||
netconn_set_recvtimeout(sock->conn, *(int*)optval);
|
||||
{
|
||||
s32_t val;
|
||||
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||||
val = (s32_t)*(int*)optval;
|
||||
#else /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
val = (((struct timeval *)optval)->tv_sec * 1000U) + (((struct timeval *)optval)->tv_usec / 1000U);
|
||||
#endif /* LWIP_SO_SNDRCVTIMEO_NONSTANDARD */
|
||||
netconn_set_recvtimeout(sock->conn, (int)val);
|
||||
}
|
||||
break;
|
||||
#endif /* LWIP_SO_RCVTIMEO */
|
||||
#if LWIP_SO_RCVBUF
|
||||
@ -2415,17 +2482,18 @@ lwip_setsockopt_internal(void *arg)
|
||||
case IP_DROP_MEMBERSHIP:
|
||||
{
|
||||
/* If this is a TCP or a RAW socket, ignore these options. */
|
||||
err_t err;
|
||||
struct ip_mreq *imr = (struct ip_mreq *)optval;
|
||||
ip_addr_t if_addr;
|
||||
ip_addr_t multi_addr;
|
||||
inet_addr_to_ipaddr(&if_addr, &imr->imr_interface);
|
||||
inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr);
|
||||
if(optname == IP_ADD_MEMBERSHIP){
|
||||
data->err = igmp_joingroup(&if_addr, &multi_addr);
|
||||
err = igmp_joingroup(&if_addr, &multi_addr);
|
||||
} else {
|
||||
data->err = igmp_leavegroup(&if_addr, &multi_addr);
|
||||
err = igmp_leavegroup(&if_addr, &multi_addr);
|
||||
}
|
||||
if(data->err != ERR_OK) {
|
||||
if(err != ERR_OK) {
|
||||
data->err = EADDRNOTAVAIL;
|
||||
}
|
||||
}
|
||||
|
@ -213,9 +213,6 @@
|
||||
#endif /* LWIP_NETCONN && LWIP_TCP */
|
||||
#if LWIP_SOCKET
|
||||
/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */
|
||||
#if SO_ACCEPTCONN != SOF_ACCEPTCONN
|
||||
#error "SO_ACCEPTCONN != SOF_ACCEPTCONN"
|
||||
#endif
|
||||
#if SO_REUSEADDR != SOF_REUSEADDR
|
||||
#error "WARNING: SO_REUSEADDR != SOF_REUSEADDR"
|
||||
#endif
|
||||
@ -225,9 +222,6 @@
|
||||
#if SO_BROADCAST != SOF_BROADCAST
|
||||
#error "WARNING: SO_BROADCAST != SOF_BROADCAST"
|
||||
#endif
|
||||
#if SO_LINGER != SOF_LINGER
|
||||
#error "WARNING: SO_LINGER != SOF_LINGER"
|
||||
#endif
|
||||
#endif /* LWIP_SOCKET */
|
||||
|
||||
|
||||
|
@ -563,7 +563,6 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
||||
lpcb->state = LISTEN;
|
||||
lpcb->prio = pcb->prio;
|
||||
lpcb->so_options = pcb->so_options;
|
||||
ip_set_option(lpcb, SOF_ACCEPTCONN);
|
||||
lpcb->ttl = pcb->ttl;
|
||||
lpcb->tos = pcb->tos;
|
||||
#if LWIP_IPV6
|
||||
|
@ -98,21 +98,14 @@ struct ip_pcb {
|
||||
};
|
||||
|
||||
/*
|
||||
* Option flags per-socket. These are the same like SO_XXX.
|
||||
* Option flags per-socket. These are the same like SO_XXX in sockets.h
|
||||
*/
|
||||
/*#define SOF_DEBUG 0x01U Unimplemented: turn on debugging info recording */
|
||||
#define SOF_ACCEPTCONN 0x02U /* socket has had listen() */
|
||||
#define SOF_REUSEADDR 0x04U /* allow local address reuse */
|
||||
#define SOF_KEEPALIVE 0x08U /* keep connections alive */
|
||||
/*#define SOF_DONTROUTE 0x10U Unimplemented: just use interface addresses */
|
||||
#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
|
||||
/*#define SOF_USELOOPBACK 0x40U Unimplemented: bypass hardware when possible */
|
||||
#define SOF_LINGER 0x80U /* linger on close if data present */
|
||||
/*#define SOF_OOBINLINE 0x0100U Unimplemented: leave received OOB data in line */
|
||||
/*#define SOF_REUSEPORT 0x0200U Unimplemented: allow local address & port reuse */
|
||||
|
||||
/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */
|
||||
#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/)
|
||||
#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE)
|
||||
|
||||
/* Global variables of this module, kept in a struct for efficient access using base+index. */
|
||||
struct ip_globals
|
||||
|
@ -1548,6 +1548,14 @@
|
||||
#define LWIP_SO_RCVTIMEO 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LWIP_SO_SNDRCVTIMEO_NONSTANDARD==1: SO_RCVTIMEO/SO_SNDTIMEO take an int
|
||||
* (milliseconds, much like winsock does) instead of a struct timeval (default).
|
||||
*/
|
||||
#ifndef LWIP_SO_SNDRCVTIMEO_NONSTANDARD
|
||||
#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing.
|
||||
*/
|
||||
|
@ -142,22 +142,22 @@ struct lwip_setgetsockopt_data {
|
||||
/*
|
||||
* Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
|
||||
*/
|
||||
#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_KEEPALIVE 0x0008 /* keep connections alive */
|
||||
#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */
|
||||
#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
|
||||
#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
|
||||
#define SO_LINGER 0x0080 /* linger on close if data present */
|
||||
#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_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */
|
||||
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
|
||||
#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */
|
||||
#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
|
||||
#define SO_LINGER 0x0080 /* linger on close if data present */
|
||||
#define SO_DONTLINGER ((int)(~SO_LINGER))
|
||||
#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */
|
||||
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
|
||||
#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
|
||||
#define SO_RCVBUF 0x1002 /* receive buffer size */
|
||||
#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
|
||||
|
Loading…
Reference in New Issue
Block a user