mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 23:29:25 +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:
|
||||
|
||||
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)
|
||||
* 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)
|
||||
* 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) {
|
||||
len = p->tot_len;
|
||||
conn->recv_avail -= len;
|
||||
SYS_ARCH_DEC(conn->recv_avail, len);
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
@ -401,7 +401,7 @@ netconn_recv(struct netconn *conn)
|
||||
sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, 0);
|
||||
#endif /* LWIP_SO_RCVTIMEO*/
|
||||
if (buf!=NULL) {
|
||||
conn->recv_avail -= buf->p->tot_len;
|
||||
SYS_ARCH_DEC(conn->recv_avail, buf->p->tot_len);
|
||||
/* Register event with callback */
|
||||
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 netconn *conn;
|
||||
#if LWIP_SO_RCVBUF
|
||||
int recv_avail;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
|
||||
conn = arg;
|
||||
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_GET(conn->recv_avail, recv_avail);
|
||||
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 */
|
||||
if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) {
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
@ -91,7 +95,7 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
||||
buf->addr = addr;
|
||||
buf->port = pcb->protocol;
|
||||
|
||||
conn->recv_avail += p->tot_len;
|
||||
SYS_ARCH_INC(conn->recv_avail, p->tot_len);
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
|
||||
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 netconn *conn;
|
||||
#if LWIP_SO_RCVBUF
|
||||
int recv_avail;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
|
||||
LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
|
||||
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);
|
||||
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_GET(conn->recv_avail, recv_avail);
|
||||
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 */
|
||||
if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
@ -142,7 +150,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
||||
buf->port = port;
|
||||
}
|
||||
|
||||
conn->recv_avail += p->tot_len;
|
||||
SYS_ARCH_INC(conn->recv_avail, p->tot_len);
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
|
||||
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;
|
||||
if (p != NULL) {
|
||||
len = p->tot_len;
|
||||
conn->recv_avail += len;
|
||||
SYS_ARCH_INC(conn->recv_avail, len);
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
|
@ -1872,7 +1872,7 @@ lwip_ioctl(int s, long cmd, void *argp)
|
||||
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 */
|
||||
if (sock->lastdata) {
|
||||
|
@ -193,6 +193,48 @@ void sys_arch_unprotect(sys_prot_t pval);
|
||||
|
||||
#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
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user