lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] [bug #52403] lwIP TCP implementation violate RFC2525 sectio


From: Gao Qingshui
Subject: [lwip-devel] [bug #52403] lwIP TCP implementation violate RFC2525 section 2.17
Date: Wed, 15 Nov 2017 03:47:08 -0500 (EST)
User-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36

Follow-up Comment #2, bug #52403 (project lwip):

Hi Simon, no code changes was made in socket/netconn/tcp layer. I just made OS
adaption to make lwIP running on my platform. 
let me explain why lwIP violate RFC2525 section 2.17 more specific: 
1: when there was data not recved by user application and then close this
socket, function lwip_close was called to do resource recycle. lwip_close
would call netconn_delete. 
2: In function netconn_delete, one TCPIP_MSG_API message was sent to
tcpip_thread and the callback function was lwip_netconn_do_delconn. 
3: In function lwip_netconn_do_delconn, netconn_drain was called, and then for
tcp socket, lwip_netconn_do_close_internal was called to do protocol handing.

4: In function netconn_drain, if the socket type was tcp and there was data
pending in recvmbox, tcp_recved was called and then the buffered pbuf was
freed. In tcp_recved, the pcb->rcv_wnd was increased by the pbuf length. when
all the buffered pbuf was handled, the pcb->rcv_wnd was equal to the TCP_WND.

/*********netconn_drain************/ 
/* Delete and drain the recvmbox. */ 
if (sys_mbox_valid(&conn->recvmbox)) { 
while (sys_arch_mbox_fetch(&conn->recvmbox, &mem, 1) != SYS_MBOX_EMPTY) { 
#if LWIP_TCP 
if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) { 
if (mem != NULL) { 
p = (struct pbuf*)mem; 
/* pcb might be set to NULL already by err_tcp() */ 
if (conn->pcb.tcp != NULL) { 
tcp_recved(conn->pcb.tcp, p->tot_len); 
} 
pbuf_free(p); 
} 
} else 
#endif /* LWIP_TCP */ 
/************************************/ 
5: after netconn_drain, lwip_netconn_do_close_internal was called. and finally
function tcp_close_shutdown was called. 
6: In function tcp_close_shutdown, lwip would check if there was any data not
recved. But the checking condition was wrong because the pcb->tcp_wnd was
already equal to TCP_WND which was handled in function netconn_drain
previously. so no RESET segment was send, but FIN segment was send in function
tcp_close_shutdown_fin. 
/**************tcp_close_shutdown*****************/ 
static err_t 
tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) 
{ 
if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state ==
CLOSE_WAIT))) { 
if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND_MAX(pcb))) { 
/* Not all data received by application, send RST to tell the remote 
side about this. */ 
LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); 
/* don't call tcp_abort here: we must not deallocate the pcb since 
that might not be expected when calling tcp_close */ 
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, 
pcb->local_port, pcb->remote_port); 
/****************************************************/ 

    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?52403>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.nongnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]