api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on the mailbox is active". Now, the post is only done during a connect, and do_send, do_write and do_join_leave_group don't do anything if a previous error was signaled.

This commit is contained in:
fbernon 2007-04-05 16:54:20 +00:00
parent 7fdd312cca
commit 5f1aac1450
2 changed files with 82 additions and 69 deletions

View File

@ -106,6 +106,11 @@ HISTORY
++ Bug fixes: ++ Bug fixes:
2007-04-05 Frédéric Bernon, Jonathan Larmour
* api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on
the mailbox is active". Now, the post is only done during a connect, and do_send,
do_write and do_join_leave_group don't do anything if a previous error was signaled.
2007-04-03 Frédéric Bernon 2007-04-03 Frédéric Bernon
* ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output
packets. See patch #5834. packets. See patch #5834.

View File

@ -196,7 +196,8 @@ err_tcp(void *arg, err_t err)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0); (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
sys_mbox_post(conn->recvmbox, NULL); sys_mbox_post(conn->recvmbox, NULL);
} }
if (conn->mbox != SYS_MBOX_NULL) { if (conn->mbox != SYS_MBOX_NULL && conn->state == NETCONN_CONNECT) {
conn->state = NETCONN_NONE;
sys_mbox_post(conn->mbox, NULL); sys_mbox_post(conn->mbox, NULL);
} }
if (conn->acceptmbox != SYS_MBOX_NULL) { if (conn->acceptmbox != SYS_MBOX_NULL) {
@ -458,6 +459,7 @@ do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
if (conn->type == NETCONN_TCP && err == ERR_OK) { if (conn->type == NETCONN_TCP && err == ERR_OK) {
setup_tcp(conn); setup_tcp(conn);
} }
conn->state = NETCONN_NONE;
sys_mbox_post(conn->mbox, NULL); sys_mbox_post(conn->mbox, NULL);
return ERR_OK; return ERR_OK;
} }
@ -492,11 +494,10 @@ do_connect(struct api_msg_msg *msg)
#endif /* LWIP_UDP */ #endif /* LWIP_UDP */
#if LWIP_TCP #if LWIP_TCP
case NETCONN_TCP: case NETCONN_TCP:
/*tcp_arg(msg->conn->pcb.tcp, msg->conn);*/ msg->conn->state = NETCONN_CONNECT;
setup_tcp(msg->conn); setup_tcp(msg->conn);
tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port, tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
do_connected); do_connected);
/*tcp_output(msg->conn->pcb.tcp);*/
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
default: default:
@ -574,24 +575,27 @@ do_listen(struct api_msg_msg *msg)
static void static void
do_send(struct api_msg_msg *msg) do_send(struct api_msg_msg *msg)
{ {
if (msg->conn->pcb.tcp != NULL) {
switch (msg->conn->type) { if (msg->conn->err!=ERR_OK) {
if (msg->conn->pcb.tcp != NULL) {
switch (msg->conn->type) {
#if LWIP_RAW #if LWIP_RAW
case NETCONN_RAW: case NETCONN_RAW:
raw_send(msg->conn->pcb.raw, msg->msg.p); raw_send(msg->conn->pcb.raw, msg->msg.p);
break; break;
#endif #endif
#if LWIP_UDP #if LWIP_UDP
case NETCONN_UDPLITE: case NETCONN_UDPLITE:
/* FALLTHROUGH */ /* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM: case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */ /* FALLTHROUGH */
case NETCONN_UDP: case NETCONN_UDP:
udp_send(msg->conn->pcb.udp, msg->msg.p); udp_send(msg->conn->pcb.udp, msg->msg.p);
break; break;
#endif /* LWIP_UDP */ #endif /* LWIP_UDP */
case NETCONN_TCP: case NETCONN_TCP:
break; break;
}
} }
} }
sys_mbox_post(msg->conn->mbox, NULL); sys_mbox_post(msg->conn->mbox, NULL);
@ -616,44 +620,46 @@ do_write(struct api_msg_msg *msg)
#if LWIP_TCP #if LWIP_TCP
err_t err; err_t err;
#endif #endif
if (msg->conn->pcb.tcp != NULL) { if (msg->conn->err!=ERR_OK) {
switch (msg->conn->type) { if (msg->conn->pcb.tcp != NULL) {
switch (msg->conn->type) {
#if LWIP_RAW #if LWIP_RAW
case NETCONN_RAW: case NETCONN_RAW:
msg->conn->err = ERR_VAL; msg->conn->err = ERR_VAL;
break; break;
#endif #endif
#if LWIP_UDP #if LWIP_UDP
case NETCONN_UDPLITE: case NETCONN_UDPLITE:
/* FALLTHROUGH */ /* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM: case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */ /* FALLTHROUGH */
case NETCONN_UDP: case NETCONN_UDP:
msg->conn->err = ERR_VAL; msg->conn->err = ERR_VAL;
break; break;
#endif /* LWIP_UDP */ #endif /* LWIP_UDP */
#if LWIP_TCP #if LWIP_TCP
case NETCONN_TCP: case NETCONN_TCP:
err = tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr, err = tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr,
msg->msg.w.len, msg->msg.w.copy); msg->msg.w.len, msg->msg.w.copy);
/* This is the Nagle algorithm: inhibit the sending of new TCP /* This is the Nagle algorithm: inhibit the sending of new TCP
segments when new outgoing data arrives from the user if any segments when new outgoing data arrives from the user if any
previously transmitted data on the connection remains previously transmitted data on the connection remains
unacknowledged. */ unacknowledged. */
if(err == ERR_OK && (msg->conn->pcb.tcp->unacked == NULL || if(err == ERR_OK && (msg->conn->pcb.tcp->unacked == NULL ||
(msg->conn->pcb.tcp->flags & TF_NODELAY) || (msg->conn->pcb.tcp->flags & TF_NODELAY) ||
(msg->conn->pcb.tcp->snd_queuelen) > 1)) { (msg->conn->pcb.tcp->snd_queuelen) > 1)) {
tcp_output(msg->conn->pcb.tcp); tcp_output(msg->conn->pcb.tcp);
}
msg->conn->err = err;
if (msg->conn->callback)
if (err == ERR_OK) {
if (tcp_sndbuf(msg->conn->pcb.tcp) <= TCP_SNDLOWAT)
(*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDMINUS, msg->msg.w.len);
} }
msg->conn->err = err;
if (msg->conn->callback)
if (err == ERR_OK) {
if (tcp_sndbuf(msg->conn->pcb.tcp) <= TCP_SNDLOWAT)
(*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDMINUS, msg->msg.w.len);
}
#endif #endif
default: default:
break; break;
}
} }
} }
sys_mbox_post(msg->conn->mbox, NULL); sys_mbox_post(msg->conn->mbox, NULL);
@ -702,31 +708,33 @@ do_join_leave_group(struct api_msg_msg *msg)
{ {
err_t err = ERR_OK; err_t err = ERR_OK;
if (msg->conn->pcb.tcp != NULL) { if (msg->conn->err!=ERR_OK) {
switch (msg->conn->type) { if (msg->conn->pcb.tcp != NULL) {
switch (msg->conn->type) {
#if LWIP_RAW #if LWIP_RAW
case NETCONN_RAW: case NETCONN_RAW:
break;
#endif
#if LWIP_UDP
case NETCONN_UDPLITE:
case NETCONN_UDPNOCHKSUM:
case NETCONN_UDP:
switch(msg->msg.bc.port){
case NETCONN_JOIN: err = igmp_joingroup (netif_default, ((struct ip_addr**)(msg->msg.bc.ipaddr))[0]); break;
case NETCONN_LEAVE: err = igmp_leavegroup(netif_default, ((struct ip_addr**)(msg->msg.bc.ipaddr))[0]); break;
}
break;
#endif /* LWIP_UDP */
#if LWIP_TCP
case NETCONN_TCP:
break; break;
#endif #endif
default: #if LWIP_UDP
break; case NETCONN_UDPLITE:
case NETCONN_UDPNOCHKSUM:
case NETCONN_UDP:
switch(msg->msg.bc.port){
case NETCONN_JOIN: err = igmp_joingroup (netif_default, ((struct ip_addr**)(msg->msg.bc.ipaddr))[0]); break;
case NETCONN_LEAVE: err = igmp_leavegroup(netif_default, ((struct ip_addr**)(msg->msg.bc.ipaddr))[0]); break;
}
break;
#endif /* LWIP_UDP */
#if LWIP_TCP
case NETCONN_TCP:
break;
#endif
default:
break;
}
} }
msg->conn->err = err;
} }
msg->conn->err = err;
sys_mbox_post(msg->conn->mbox, NULL); sys_mbox_post(msg->conn->mbox, NULL);
} }
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
@ -746,7 +754,7 @@ static api_msg_decode decode[API_MSG_MAX] = {
#if LWIP_IGMP #if LWIP_IGMP
do_join_leave_group do_join_leave_group
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
}; };
void void
api_msg_input(struct api_msg *msg) api_msg_input(struct api_msg *msg)