- moved processing of refused_data to an own function (used from tcp_fasttmr and tcp_input);

- improved readability of tcp_slowtmr by using defines to access keepalive variables
This commit is contained in:
goldsimon 2011-10-23 18:10:46 +02:00
parent 3585cc1a70
commit 386a4b7079
3 changed files with 62 additions and 89 deletions

View File

@ -63,6 +63,14 @@
#define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START)
#endif
#if LWIP_TCP_KEEPALIVE
#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl)
#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl)
#else /* LWIP_TCP_KEEPALIVE */
#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE
#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT
#endif /* LWIP_TCP_KEEPALIVE */
const char * const tcp_state_str[] = {
"CLOSED",
"LISTEN",
@ -821,8 +829,9 @@ tcp_slowtmr(void)
}
} else {
/* Increase the retransmission timer if it is running */
if(pcb->rtime >= 0)
if(pcb->rtime >= 0) {
++pcb->rtime;
}
if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
/* Time for a retransmission. */
@ -869,14 +878,8 @@ tcp_slowtmr(void)
if((pcb->so_options & SOF_KEEPALIVE) &&
((pcb->state == ESTABLISHED) ||
(pcb->state == CLOSE_WAIT))) {
#if LWIP_TCP_KEEPALIVE
if((u32_t)(tcp_ticks - pcb->tmr) >
(pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl))
/ TCP_SLOW_INTERVAL)
#else
if((u32_t)(tcp_ticks - pcb->tmr) >
(pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL)
#endif /* LWIP_TCP_KEEPALIVE */
(pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL)
{
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
@ -885,15 +888,9 @@ tcp_slowtmr(void)
++pcb_remove;
++pcb_reset;
}
#if LWIP_TCP_KEEPALIVE
else if((u32_t)(tcp_ticks - pcb->tmr) >
(pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl)
(pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb))
/ TCP_SLOW_INTERVAL)
#else
else if((u32_t)(tcp_ticks - pcb->tmr) >
(pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT)
/ TCP_SLOW_INTERVAL)
#endif /* LWIP_TCP_KEEPALIVE */
{
tcp_keepalive(pcb);
pcb->keep_cnt_sent++;
@ -1024,34 +1021,8 @@ tcp_fasttmr(void)
struct tcp_pcb *next = pcb->next;
/* If there is data which was previously "refused" by upper layer */
if (pcb->refused_data != NULL) {
/* Notify again application with data previously received. */
err_t err;
u8_t refused_flags = pcb->refused_data->flags;
/* set pcb->refused_data to NULL in case the callback frees it and then
closes the pcb */
struct pbuf *refused_data = pcb->refused_data;
pcb->refused_data = NULL;
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n"));
TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
if (err == ERR_OK) {
/* did refused_data include a FIN? If so, handle it now. */
if (refused_flags & PBUF_FLAG_TCP_FIN) {
/* correct rcv_wnd as the application won't call tcp_recved()
for the FIN's seqno */
if (pcb->rcv_wnd != TCP_WND) {
pcb->rcv_wnd++;
}
TCP_EVENT_CLOSED(pcb, err);
if (err == ERR_ABRT) {
pcb = NULL;
}
}
} else if (err == ERR_ABRT) {
/* if err == ERR_ABRT, 'pcb' is already deallocated */
if (tcp_process_refused_data(pcb) == ERR_ABRT) {
pcb = NULL;
} else {
/* data is still refused */
pcb->refused_data = refused_data;
}
}
@ -1067,6 +1038,45 @@ tcp_fasttmr(void)
}
}
/** Pass pcb->refused_data to the recv callback */
err_t
tcp_process_refused_data(struct tcp_pcb *pcb)
{
err_t err;
u8_t refused_flags = pcb->refused_data->flags;
/* set pcb->refused_data to NULL in case the callback frees it and then
closes the pcb */
struct pbuf *refused_data = pcb->refused_data;
pcb->refused_data = NULL;
/* Notify again application with data previously received. */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
if (err == ERR_OK) {
/* did refused_data include a FIN? */
if (refused_flags & PBUF_FLAG_TCP_FIN) {
/* correct rcv_wnd as the application won't call tcp_recved()
for the FIN's seqno */
if (pcb->rcv_wnd != TCP_WND) {
pcb->rcv_wnd++;
}
TCP_EVENT_CLOSED(pcb, err);
if (err == ERR_ABRT) {
return ERR_ABRT;
}
}
} else if (err == ERR_ABRT) {
/* if err == ERR_ABRT, 'pcb' is already deallocated */
/* Drop incoming packets because pcb is "full" (only if the incoming
segment contains data). */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
return ERR_ABRT;
} else {
/* data is still refused, pbuf is still valid (go on for ACK-only packets) */
pcb->refused_data = refused_data;
}
return ERR_OK;
}
/**
* Deallocates a list of TCP segments (tcp_seg structures).
*

View File

@ -117,20 +117,14 @@ tcp_input(struct pbuf *p, struct netif *inp)
/* drop short packets */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
TCP_STATS_INC(tcp.lenerr);
TCP_STATS_INC(tcp.drop);
snmp_inc_tcpinerrs();
pbuf_free(p);
return;
goto dropped;
}
/* Don't even process incoming broadcasts/multicasts. */
if (ip_addr_isbroadcast(&current_iphdr_dest, inp) ||
ip_addr_ismulticast(&current_iphdr_dest)) {
TCP_STATS_INC(tcp.proterr);
TCP_STATS_INC(tcp.drop);
snmp_inc_tcpinerrs();
pbuf_free(p);
return;
goto dropped;
}
#if CHECKSUM_CHECK_TCP
@ -144,10 +138,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
tcp_debug_print(tcphdr);
#endif /* TCP_DEBUG */
TCP_STATS_INC(tcp.chkerr);
TCP_STATS_INC(tcp.drop);
snmp_inc_tcpinerrs();
pbuf_free(p);
return;
goto dropped;
}
#endif
@ -158,10 +149,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
/* drop short packets */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n"));
TCP_STATS_INC(tcp.lenerr);
TCP_STATS_INC(tcp.drop);
snmp_inc_tcpinerrs();
pbuf_free(p);
return;
goto dropped;
}
/* Convert fields in TCP header to host byte order. */
@ -303,39 +291,13 @@ tcp_input(struct pbuf *p, struct netif *inp)
/* If there is data which was previously "refused" by upper layer */
if (pcb->refused_data != NULL) {
u8_t refused_flags = pcb->refused_data->flags;
/* set pcb->refused_data to NULL in case the callback frees it and then
closes the pcb */
struct pbuf *refused_data = pcb->refused_data;
pcb->refused_data = NULL;
/* Notify again application with data previously received. */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
if (err == ERR_OK) {
/* did refused_data include a FIN? */
if (refused_flags & PBUF_FLAG_TCP_FIN) {
/* correct rcv_wnd as the application won't call tcp_recved()
for the FIN's seqno */
if (pcb->rcv_wnd != TCP_WND) {
pcb->rcv_wnd++;
}
TCP_EVENT_CLOSED(pcb, err);
if (err == ERR_ABRT) {
goto dropped;
}
}
} else if ((err == ERR_ABRT) || (tcplen > 0)) {
/* if err == ERR_ABRT, 'pcb' is already deallocated */
/* Drop incoming packets because pcb is "full" (only if the incoming
segment contains data). */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
if ((tcp_process_refused_data(pcb) == ERR_ABRT) ||
((pcb->refused_data != NULL) && (tcplen > 0))) {
/* pcb has been aborted or refused data is still refused and the new
segment contains data */
TCP_STATS_INC(tcp.drop);
snmp_inc_tcpinerrs();
pbuf_free(p);
return;
} else {
/* data is still refused, pbuf is still valid (go on for ACK-only packets) */
pcb->refused_data = refused_data;
goto aborted;
}
}
tcp_input_pcb = pcb;

View File

@ -70,6 +70,7 @@ void tcp_rexmit (struct tcp_pcb *pcb);
void tcp_rexmit_rto (struct tcp_pcb *pcb);
void tcp_rexmit_fast (struct tcp_pcb *pcb);
u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb);
err_t tcp_process_refused_data(struct tcp_pcb *pcb);
/**
* This is the Nagle algorithm: try to combine user data to send as few TCP