mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-17 17:10:03 +00:00
sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail is not protected" by using new macros for interlocked access to modify/test netconn->recv_avail.
This commit is contained in:
parent
1cb470662b
commit
48e62e25e9
@ -526,8 +526,13 @@ HISTORY
|
|||||||
|
|
||||||
++ Bug fixes:
|
++ Bug fixes:
|
||||||
|
|
||||||
|
2007-12-21 Simon Goldschmidt
|
||||||
|
* sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail
|
||||||
|
is not protected" by using new macros for interlocked access to modify/test
|
||||||
|
netconn->recv_avail.
|
||||||
|
|
||||||
2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev)
|
2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev)
|
||||||
* tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT stat)e
|
* tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state)
|
||||||
|
|
||||||
2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
|
2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
|
||||||
* tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling
|
* tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling
|
||||||
|
@ -358,7 +358,7 @@ netconn_recv(struct netconn *conn)
|
|||||||
|
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
len = p->tot_len;
|
len = p->tot_len;
|
||||||
conn->recv_avail -= len;
|
SYS_ARCH_DEC(conn->recv_avail, len);
|
||||||
} else {
|
} else {
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
@ -401,7 +401,7 @@ netconn_recv(struct netconn *conn)
|
|||||||
sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, 0);
|
sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, 0);
|
||||||
#endif /* LWIP_SO_RCVTIMEO*/
|
#endif /* LWIP_SO_RCVTIMEO*/
|
||||||
if (buf!=NULL) {
|
if (buf!=NULL) {
|
||||||
conn->recv_avail -= buf->p->tot_len;
|
SYS_ARCH_DEC(conn->recv_avail, buf->p->tot_len);
|
||||||
/* Register event with callback */
|
/* Register event with callback */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
|
API_EVENT(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
|
||||||
}
|
}
|
||||||
|
@ -72,12 +72,16 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
|||||||
{
|
{
|
||||||
struct netbuf *buf;
|
struct netbuf *buf;
|
||||||
struct netconn *conn;
|
struct netconn *conn;
|
||||||
|
#if LWIP_SO_RCVBUF
|
||||||
|
int recv_avail;
|
||||||
|
#endif /* LWIP_SO_RCVBUF */
|
||||||
|
|
||||||
conn = arg;
|
conn = arg;
|
||||||
|
|
||||||
#if LWIP_SO_RCVBUF
|
#if LWIP_SO_RCVBUF
|
||||||
|
SYS_ARCH_GET(conn->recv_avail, recv_avail);
|
||||||
if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) &&
|
if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) &&
|
||||||
(((int)(conn->recv_avail) + (int)(p->tot_len)) <= conn->recv_bufsize)) {
|
((recv_avail + (int)(p->tot_len)) <= conn->recv_bufsize)) {
|
||||||
#else /* LWIP_SO_RCVBUF */
|
#else /* LWIP_SO_RCVBUF */
|
||||||
if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) {
|
if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) {
|
||||||
#endif /* LWIP_SO_RCVBUF */
|
#endif /* LWIP_SO_RCVBUF */
|
||||||
@ -91,7 +95,7 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
|||||||
buf->addr = addr;
|
buf->addr = addr;
|
||||||
buf->port = pcb->protocol;
|
buf->port = pcb->protocol;
|
||||||
|
|
||||||
conn->recv_avail += p->tot_len;
|
SYS_ARCH_INC(conn->recv_avail, p->tot_len);
|
||||||
/* Register event with callback */
|
/* Register event with callback */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
|
||||||
sys_mbox_post(conn->recvmbox, buf);
|
sys_mbox_post(conn->recvmbox, buf);
|
||||||
@ -114,6 +118,9 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
|||||||
{
|
{
|
||||||
struct netbuf *buf;
|
struct netbuf *buf;
|
||||||
struct netconn *conn;
|
struct netconn *conn;
|
||||||
|
#if LWIP_SO_RCVBUF
|
||||||
|
int recv_avail;
|
||||||
|
#endif /* LWIP_SO_RCVBUF */
|
||||||
|
|
||||||
LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
|
LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
|
||||||
LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
|
LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
|
||||||
@ -122,8 +129,9 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
|||||||
LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
|
LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
|
||||||
|
|
||||||
#if LWIP_SO_RCVBUF
|
#if LWIP_SO_RCVBUF
|
||||||
|
SYS_ARCH_GET(conn->recv_avail, recv_avail);
|
||||||
if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) ||
|
if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) ||
|
||||||
(((int)(conn->recv_avail) + (int)(p->tot_len)) > conn->recv_bufsize)) {
|
((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
|
||||||
#else /* LWIP_SO_RCVBUF */
|
#else /* LWIP_SO_RCVBUF */
|
||||||
if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
|
if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
|
||||||
#endif /* LWIP_SO_RCVBUF */
|
#endif /* LWIP_SO_RCVBUF */
|
||||||
@ -142,7 +150,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
|||||||
buf->port = port;
|
buf->port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->recv_avail += p->tot_len;
|
SYS_ARCH_INC(conn->recv_avail, p->tot_len);
|
||||||
/* Register event with callback */
|
/* Register event with callback */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
|
||||||
sys_mbox_post(conn->recvmbox, buf);
|
sys_mbox_post(conn->recvmbox, buf);
|
||||||
@ -176,7 +184,7 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
|||||||
conn->err = err;
|
conn->err = err;
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
len = p->tot_len;
|
len = p->tot_len;
|
||||||
conn->recv_avail += len;
|
SYS_ARCH_INC(conn->recv_avail, len);
|
||||||
} else {
|
} else {
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
|
@ -1872,7 +1872,7 @@ lwip_ioctl(int s, long cmd, void *argp)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*((u16_t*)argp) = sock->conn->recv_avail;
|
SYS_ARCH_GET(sock->conn->recv_avail, *((u16_t*)argp));
|
||||||
|
|
||||||
/* Check if there is data left from the last recv operation. /maq 041215 */
|
/* Check if there is data left from the last recv operation. /maq 041215 */
|
||||||
if (sock->lastdata) {
|
if (sock->lastdata) {
|
||||||
|
@ -193,6 +193,48 @@ void sys_arch_unprotect(sys_prot_t pval);
|
|||||||
|
|
||||||
#endif /* SYS_ARCH_PROTECT */
|
#endif /* SYS_ARCH_PROTECT */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macros to set/get and increase/decrease variables in a thread-safe way.
|
||||||
|
* Use these for accessing variable that are used from more than one thread.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SYS_ARCH_INC
|
||||||
|
#define SYS_ARCH_INC(var, val) do { \
|
||||||
|
SYS_ARCH_DECL_PROTECT(old_level); \
|
||||||
|
SYS_ARCH_PROTECT(old_level); \
|
||||||
|
var += val; \
|
||||||
|
SYS_ARCH_UNPROTECT(old_level); \
|
||||||
|
} while(0)
|
||||||
|
#endif /* SYS_ARCH_INC */
|
||||||
|
|
||||||
|
#ifndef SYS_ARCH_DEC
|
||||||
|
#define SYS_ARCH_DEC(var, val) do { \
|
||||||
|
SYS_ARCH_DECL_PROTECT(old_level); \
|
||||||
|
SYS_ARCH_PROTECT(old_level); \
|
||||||
|
var -= val; \
|
||||||
|
SYS_ARCH_UNPROTECT(old_level); \
|
||||||
|
} while(0)
|
||||||
|
#endif /* SYS_ARCH_DEC */
|
||||||
|
|
||||||
|
#ifndef SYS_ARCH_GET
|
||||||
|
#define SYS_ARCH_GET(var, ret) do { \
|
||||||
|
SYS_ARCH_DECL_PROTECT(old_level); \
|
||||||
|
SYS_ARCH_PROTECT(old_level); \
|
||||||
|
ret = var; \
|
||||||
|
SYS_ARCH_UNPROTECT(old_level); \
|
||||||
|
} while(0)
|
||||||
|
#endif /* SYS_ARCH_GET */
|
||||||
|
|
||||||
|
#ifndef SYS_ARCH_SET
|
||||||
|
#define SYS_ARCH_SET(var, val) do { \
|
||||||
|
SYS_ARCH_DECL_PROTECT(old_level); \
|
||||||
|
SYS_ARCH_PROTECT(old_level); \
|
||||||
|
var = val; \
|
||||||
|
SYS_ARCH_UNPROTECT(old_level); \
|
||||||
|
} while(0)
|
||||||
|
#endif /* SYS_ARCH_SET */
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user