Merge branch 'master' of git.sv.gnu.org:/srv/git/lwip

This commit is contained in:
goldsimon 2012-01-12 15:40:41 +01:00
commit e9255d3714
15 changed files with 139 additions and 67 deletions

View File

@ -6,6 +6,10 @@ HISTORY
++ New features: ++ New features:
2011-12-17: Simon Goldschmidt
* ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW)
(fixes bug #35061)
2011-09-27: Simon Goldschmidt 2011-09-27: Simon Goldschmidt
* opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989)
(define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h)
@ -69,6 +73,10 @@ HISTORY
++ Bugfixes: ++ Bugfixes:
2011-11-25: Simon Goldschmidt
* tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt
tcp_active_pcbs in some cases
2011-11-23: Simon Goldschmidt 2011-11-23: Simon Goldschmidt
* sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with
'#ifndef sys_msleep' '#ifndef sys_msleep'

View File

@ -1761,7 +1761,7 @@ lwip_getsockopt_internal(void *arg)
case SO_REUSEPORT: case SO_REUSEPORT:
#endif /* SO_REUSE */ #endif /* SO_REUSE */
/*case SO_USELOOPBACK: UNIMPL */ /*case SO_USELOOPBACK: UNIMPL */
*(int*)optval = sock->conn->pcb.ip->so_options & optname; *(int*)optval = ip_get_option(sock->conn->pcb.ip, optname);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n",
s, optname, (*(int*)optval?"on":"off"))); s, optname, (*(int*)optval?"on":"off")));
break; break;
@ -2178,9 +2178,9 @@ lwip_setsockopt_internal(void *arg)
#endif /* SO_REUSE */ #endif /* SO_REUSE */
/* UNIMPL case SO_USELOOPBACK: */ /* UNIMPL case SO_USELOOPBACK: */
if (*(int*)optval) { if (*(int*)optval) {
sock->conn->pcb.ip->so_options |= optname; ip_set_option(sock->conn->pcb.ip, optname);
} else { } else {
sock->conn->pcb.ip->so_options &= ~optname; ip_reset_option(sock->conn->pcb.ip, optname);
} }
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n",
s, optname, (*(int*)optval?"on":"off"))); s, optname, (*(int*)optval?"on":"off")));

View File

@ -680,7 +680,7 @@ dhcp_start(struct netif *netif)
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));
return ERR_MEM; return ERR_MEM;
} }
dhcp->pcb->so_options |= SOF_BROADCAST; ip_set_option(dhcp->pcb, SOF_BROADCAST);
/* set up local and remote port for the pcb */ /* set up local and remote port for the pcb */
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
@ -730,7 +730,7 @@ dhcp_inform(struct netif *netif)
return; return;
} }
dhcp.pcb = pcb; dhcp.pcb = pcb;
dhcp.pcb->so_options |= SOF_BROADCAST; ip_set_option(dhcp.pcb, SOF_BROADCAST);
udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));
} }

View File

@ -283,14 +283,11 @@ icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
IP6_HLEN + LWIP_ICMP6_DATASIZE); IP6_HLEN + LWIP_ICMP6_DATASIZE);
/* Get the destination address and netif for this ICMP message. */ /* Get the destination address and netif for this ICMP message. */
if (ip_current_netif() != NULL) { if ((ip_current_netif() == NULL) ||
netif = ip_current_netif(); ((code == ICMP6_TE_FRAG) && (type == ICMP6_TYPE_TE))) {
reply_dest = ip6_current_src_addr(); /* Special case, as ip6_current_xxx is either NULL, or points
} * to a different packet than the one that expired.
else { * We must use the addresses that are stored in the expired packet. */
/* We are not being called from input context, so we must determine
* addresses from the packet in question. reply_src is temporarily
* set to try and find the original netif where packet was accepted. */
ip6hdr = (struct ip6_hdr *)p->payload; ip6hdr = (struct ip6_hdr *)p->payload;
/* copy from packed address to aligned address */ /* copy from packed address to aligned address */
ip6_addr_copy(reply_dest_local, ip6hdr->src); ip6_addr_copy(reply_dest_local, ip6hdr->src);
@ -305,6 +302,9 @@ icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
return; return;
} }
} }
else {
netif = ip_current_netif();
reply_dest = ip6_current_src_addr();
/* Select an address to use as source. */ /* Select an address to use as source. */
reply_src = ip6_select_source_address(netif, reply_dest); reply_src = ip6_select_source_address(netif, reply_dest);
@ -314,6 +314,7 @@ icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
ICMP6_STATS_INC(icmp6.rterr); ICMP6_STATS_INC(icmp6.rterr);
return; return;
} }
}
/* calculate checksum */ /* calculate checksum */
icmp6hdr->chksum = 0; icmp6hdr->chksum = 0;

View File

@ -110,7 +110,7 @@ raw_input(struct pbuf *p, struct netif *inp)
ipX_addr_cmp(PCB_ISIPV6(pcb), &(pcb->local_ip), ipX_current_dest_addr()))) { ipX_addr_cmp(PCB_ISIPV6(pcb), &(pcb->local_ip), ipX_current_dest_addr()))) {
#if IP_SOF_BROADCAST_RECV #if IP_SOF_BROADCAST_RECV
/* broadcast filter? */ /* broadcast filter? */
if (((pcb->so_options & SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp)) if ((ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp))
#if LWIP_IPV6 #if LWIP_IPV6
&& !PCB_ISIPV6(pcb) && !PCB_ISIPV6(pcb)
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
@ -279,7 +279,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
{ {
/* broadcast filter? */ /* broadcast filter? */
if (((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(ipaddr, netif)) { if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
/* free any temporary header pbuf allocated by pbuf_header() */ /* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) { if (q != p) {

View File

@ -119,8 +119,11 @@ struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcb
/** Only used for temporary storage. */ /** Only used for temporary storage. */
struct tcp_pcb *tcp_tmp_pcb; struct tcp_pcb *tcp_tmp_pcb;
u8_t tcp_active_pcbs_changed;
/** Timer counter to handle calling slow-timer from tcp_tmr() */ /** Timer counter to handle calling slow-timer from tcp_tmr() */
static u8_t tcp_timer; static u8_t tcp_timer;
static u8_t tcp_timer_ctr;
static u16_t tcp_new_port(void); static u16_t tcp_new_port(void);
/** /**
@ -187,7 +190,7 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
/* TODO: to which state do we move now? */ /* TODO: to which state do we move now? */
/* move to TIME_WAIT since we close actively */ /* move to TIME_WAIT since we close actively */
TCP_RMV(&tcp_active_pcbs, pcb); TCP_RMV_ACTIVE(pcb);
pcb->state = TIME_WAIT; pcb->state = TIME_WAIT;
TCP_REG(&tcp_tw_pcbs, pcb); TCP_REG(&tcp_tw_pcbs, pcb);
@ -219,7 +222,7 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
break; break;
case SYN_SENT: case SYN_SENT:
err = ERR_OK; err = ERR_OK;
tcp_pcb_remove(&tcp_active_pcbs, pcb); TCP_PCB_REMOVE_ACTIVE(pcb);
memp_free(MEMP_TCP_PCB, pcb); memp_free(MEMP_TCP_PCB, pcb);
pcb = NULL; pcb = NULL;
snmp_inc_tcpattemptfails(); snmp_inc_tcpattemptfails();
@ -371,7 +374,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
errf = pcb->errf; errf = pcb->errf;
#endif /* LWIP_CALLBACK_API */ #endif /* LWIP_CALLBACK_API */
errf_arg = pcb->callback_arg; errf_arg = pcb->callback_arg;
tcp_pcb_remove(&tcp_active_pcbs, pcb); TCP_PCB_REMOVE_ACTIVE(pcb);
if (pcb->unacked != NULL) { if (pcb->unacked != NULL) {
tcp_segs_free(pcb->unacked); tcp_segs_free(pcb->unacked);
} }
@ -437,7 +440,7 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
We do not dump TIME_WAIT pcb's; they can still be matched by incoming We do not dump TIME_WAIT pcb's; they can still be matched by incoming
packets using both local and remote IP addresses and ports to distinguish. packets using both local and remote IP addresses and ports to distinguish.
*/ */
if ((pcb->so_options & SOF_REUSEADDR) != 0) { if (ip_get_option(pcb, SOF_REUSEADDR)) {
max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
} }
#endif /* SO_REUSE */ #endif /* SO_REUSE */
@ -457,8 +460,8 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
/* Omit checking for the same port if both pcbs have REUSEADDR set. /* Omit checking for the same port if both pcbs have REUSEADDR set.
For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in
tcp_connect. */ tcp_connect. */
if (((pcb->so_options & SOF_REUSEADDR) == 0) || if (!ip_get_option(pcb, SOF_REUSEADDR) ||
((cpcb->so_options & SOF_REUSEADDR) == 0)) !ip_get_option(cpcb, SOF_REUSEADDR))
#endif /* SO_REUSE */ #endif /* SO_REUSE */
{ {
/* @todo: check accept_any_ip_version */ /* @todo: check accept_any_ip_version */
@ -523,7 +526,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
return pcb; return pcb;
} }
#if SO_REUSE #if SO_REUSE
if ((pcb->so_options & SOF_REUSEADDR) != 0) { if (ip_get_option(pcb, SOF_REUSEADDR)) {
/* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage
is declared (listen-/connection-pcb), we have to make sure now that is declared (listen-/connection-pcb), we have to make sure now that
this port is only used once for every local IP. */ this port is only used once for every local IP. */
@ -547,7 +550,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
lpcb->state = LISTEN; lpcb->state = LISTEN;
lpcb->prio = pcb->prio; lpcb->prio = pcb->prio;
lpcb->so_options = pcb->so_options; lpcb->so_options = pcb->so_options;
lpcb->so_options |= SOF_ACCEPTCONN; ip_set_option(lpcb, SOF_ACCEPTCONN);
lpcb->ttl = pcb->ttl; lpcb->ttl = pcb->ttl;
lpcb->tos = pcb->tos; lpcb->tos = pcb->tos;
#if LWIP_IPV6 #if LWIP_IPV6
@ -742,7 +745,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
} }
} }
#if SO_REUSE #if SO_REUSE
if ((pcb->so_options & SOF_REUSEADDR) != 0) { if (ip_get_option(pcb, SOF_REUSEADDR)) {
/* Since SOF_REUSEADDR allows reusing a local address, we have to make sure /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure
now that the 5-tuple is unique. */ now that the 5-tuple is unique. */
struct tcp_pcb *cpcb; struct tcp_pcb *cpcb;
@ -793,7 +796,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
if (old_local_port != 0) { if (old_local_port != 0) {
TCP_RMV(&tcp_bound_pcbs, pcb); TCP_RMV(&tcp_bound_pcbs, pcb);
} }
TCP_REG(&tcp_active_pcbs, pcb); TCP_REG_ACTIVE(pcb);
snmp_inc_tcpactiveopens(); snmp_inc_tcpactiveopens();
tcp_output(pcb); tcp_output(pcb);
@ -820,7 +823,9 @@ tcp_slowtmr(void)
err = ERR_OK; err = ERR_OK;
++tcp_ticks; ++tcp_ticks;
++tcp_timer_ctr;
tcp_slowtmr_start:
/* Steps through all of the active PCBs. */ /* Steps through all of the active PCBs. */
prev = NULL; prev = NULL;
pcb = tcp_active_pcbs; pcb = tcp_active_pcbs;
@ -832,6 +837,12 @@ tcp_slowtmr(void)
LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
if (pcb->last_timer == tcp_timer_ctr) {
/* skip this pcb, we have already processed it */
pcb = pcb->next;
continue;
}
pcb->last_timer = tcp_timer_ctr;
pcb_remove = 0; pcb_remove = 0;
pcb_reset = 0; pcb_reset = 0;
@ -903,7 +914,7 @@ tcp_slowtmr(void)
} }
/* Check if KEEPALIVE should be sent */ /* Check if KEEPALIVE should be sent */
if((pcb->so_options & SOF_KEEPALIVE) && if(ip_get_option(pcb, SOF_KEEPALIVE) &&
((pcb->state == ESTABLISHED) || ((pcb->state == ESTABLISHED) ||
(pcb->state == CLOSE_WAIT))) { (pcb->state == CLOSE_WAIT))) {
if((u32_t)(tcp_ticks - pcb->tmr) > if((u32_t)(tcp_ticks - pcb->tmr) >
@ -957,6 +968,8 @@ tcp_slowtmr(void)
/* If the PCB should be removed, do it. */ /* If the PCB should be removed, do it. */
if (pcb_remove) { if (pcb_remove) {
struct tcp_pcb *pcb2; struct tcp_pcb *pcb2;
tcp_err_fn err_fn;
void *err_arg;
tcp_pcb_purge(pcb); tcp_pcb_purge(pcb);
/* Remove PCB from tcp_active_pcbs list. */ /* Remove PCB from tcp_active_pcbs list. */
if (prev != NULL) { if (prev != NULL) {
@ -968,15 +981,22 @@ tcp_slowtmr(void)
tcp_active_pcbs = pcb->next; tcp_active_pcbs = pcb->next;
} }
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
if (pcb_reset) { if (pcb_reset) {
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb));
} }
err_fn = pcb->errf;
err_arg = pcb->callback_arg;
pcb2 = pcb; pcb2 = pcb;
pcb = pcb->next; pcb = pcb->next;
memp_free(MEMP_TCP_PCB, pcb2); memp_free(MEMP_TCP_PCB, pcb2);
tcp_active_pcbs_changed = 0;
TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT);
if (tcp_active_pcbs_changed) {
goto tcp_slowtmr_start;
}
} else { } else {
/* get the 'next' element now and work with 'prev' below (in case of abort) */ /* get the 'next' element now and work with 'prev' below (in case of abort) */
prev = pcb; prev = pcb;
@ -987,7 +1007,11 @@ tcp_slowtmr(void)
if (prev->polltmr >= prev->pollinterval) { if (prev->polltmr >= prev->pollinterval) {
prev->polltmr = 0; prev->polltmr = 0;
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
tcp_active_pcbs_changed = 0;
TCP_EVENT_POLL(prev, err); TCP_EVENT_POLL(prev, err);
if (tcp_active_pcbs_changed) {
goto tcp_slowtmr_start;
}
/* if err == ERR_ABRT, 'prev' is already deallocated */ /* if err == ERR_ABRT, 'prev' is already deallocated */
if (err == ERR_OK) { if (err == ERR_OK) {
tcp_output(prev); tcp_output(prev);
@ -1043,28 +1067,40 @@ tcp_slowtmr(void)
void void
tcp_fasttmr(void) tcp_fasttmr(void)
{ {
struct tcp_pcb *pcb = tcp_active_pcbs; struct tcp_pcb *pcb;
++tcp_timer_ctr;
tcp_fasttmr_start:
pcb = tcp_active_pcbs;
while(pcb != NULL) { while(pcb != NULL) {
struct tcp_pcb *next = pcb->next; if (pcb->last_timer != tcp_timer_ctr) {
/* If there is data which was previously "refused" by upper layer */ struct tcp_pcb *next;
if (pcb->refused_data != NULL) { pcb->last_timer = tcp_timer_ctr;
if (tcp_process_refused_data(pcb) == ERR_ABRT) {
pcb = NULL;
}
}
/* send delayed ACKs */ /* send delayed ACKs */
if (pcb && (pcb->flags & TF_ACK_DELAY)) { if (pcb->flags & TF_ACK_DELAY) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
tcp_ack_now(pcb); tcp_ack_now(pcb);
tcp_output(pcb); tcp_output(pcb);
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
} }
next = pcb->next;
/* If there is data which was previously "refused" by upper layer */
if (pcb->refused_data != NULL) {
tcp_active_pcbs_changed = 0;
tcp_process_refused_data(pcb);
if (tcp_active_pcbs_changed) {
/* application callback has changed the pcb list: restart the loop */
goto tcp_fasttmr_start;
}
}
pcb = next; pcb = next;
} }
} }
}
/** Pass pcb->refused_data to the recv callback */ /** Pass pcb->refused_data to the recv callback */
err_t err_t
@ -1312,6 +1348,7 @@ tcp_alloc(u8_t prio)
pcb->lastack = iss; pcb->lastack = iss;
pcb->snd_lbb = iss; pcb->snd_lbb = iss;
pcb->tmr = tcp_ticks; pcb->tmr = tcp_ticks;
pcb->last_timer = tcp_timer_ctr;
pcb->polltmr = 0; pcb->polltmr = 0;

View File

@ -505,7 +505,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
npcb->so_options = pcb->so_options & SOF_INHERITED; npcb->so_options = pcb->so_options & SOF_INHERITED;
/* Register the new PCB so that we can begin receiving segments /* Register the new PCB so that we can begin receiving segments
for it. */ for it. */
TCP_REG(&tcp_active_pcbs, npcb); TCP_REG_ACTIVE(npcb);
/* Parse any options in the SYN. */ /* Parse any options in the SYN. */
tcp_parseopt(npcb); tcp_parseopt(npcb);
@ -755,7 +755,7 @@ tcp_process(struct tcp_pcb *pcb)
("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
tcp_ack_now(pcb); tcp_ack_now(pcb);
tcp_pcb_purge(pcb); tcp_pcb_purge(pcb);
TCP_RMV(&tcp_active_pcbs, pcb); TCP_RMV_ACTIVE(pcb);
pcb->state = TIME_WAIT; pcb->state = TIME_WAIT;
TCP_REG(&tcp_tw_pcbs, pcb); TCP_REG(&tcp_tw_pcbs, pcb);
} else { } else {
@ -772,7 +772,7 @@ tcp_process(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
tcp_ack_now(pcb); tcp_ack_now(pcb);
tcp_pcb_purge(pcb); tcp_pcb_purge(pcb);
TCP_RMV(&tcp_active_pcbs, pcb); TCP_RMV_ACTIVE(pcb);
pcb->state = TIME_WAIT; pcb->state = TIME_WAIT;
TCP_REG(&tcp_tw_pcbs, pcb); TCP_REG(&tcp_tw_pcbs, pcb);
} }
@ -782,7 +782,7 @@ tcp_process(struct tcp_pcb *pcb)
if (flags & TCP_ACK && ackno == pcb->snd_nxt) { if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
tcp_pcb_purge(pcb); tcp_pcb_purge(pcb);
TCP_RMV(&tcp_active_pcbs, pcb); TCP_RMV_ACTIVE(pcb);
pcb->state = TIME_WAIT; pcb->state = TIME_WAIT;
TCP_REG(&tcp_tw_pcbs, pcb); TCP_REG(&tcp_tw_pcbs, pcb);
} }

View File

@ -989,6 +989,9 @@ tcp_output(struct tcp_pcb *pcb)
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
} }
#if TCP_OVERSIZE_DBGCHECK
seg->oversize_left = 0;
#endif /* TCP_OVERSIZE_DBGCHECK */
tcp_output_segment(seg, pcb); tcp_output_segment(seg, pcb);
snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {

View File

@ -260,7 +260,7 @@ udp_input(struct pbuf *p, struct netif *inp)
ip_addr_ismulticast(ip_current_dest_addr()) || ip_addr_ismulticast(ip_current_dest_addr()) ||
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
#if IP_SOF_BROADCAST_RECV #if IP_SOF_BROADCAST_RECV
(broadcast && (pcb->so_options & SOF_BROADCAST) && (broadcast && ip_get_option(pcb, SOF_BROADCAST) &&
(ipX_addr_isany(0, &pcb->local_ip) || (ipX_addr_isany(0, &pcb->local_ip) ||
ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) { ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) {
#else /* IP_SOF_BROADCAST_RECV */ #else /* IP_SOF_BROADCAST_RECV */
@ -365,7 +365,7 @@ udp_input(struct pbuf *p, struct netif *inp)
ip6_addr_ismulticast(ip6_current_dest_addr()) || ip6_addr_ismulticast(ip6_current_dest_addr()) ||
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
ip_addr_ismulticast(ip_current_dest_addr())) && ip_addr_ismulticast(ip_current_dest_addr())) &&
((pcb->so_options & SOF_REUSEADDR) != 0)) { ip_get_option(pcb, SOF_REUSEADDR)) {
/* pass broadcast- or multicast packets to all multicast pcbs /* pass broadcast- or multicast packets to all multicast pcbs
if SOF_REUSEADDR is set on the first match */ if SOF_REUSEADDR is set on the first match */
struct udp_pcb *mpcb; struct udp_pcb *mpcb;
@ -389,7 +389,7 @@ udp_input(struct pbuf *p, struct netif *inp)
ip_addr_ismulticast(ip_current_dest_addr()) || ip_addr_ismulticast(ip_current_dest_addr()) ||
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
#if IP_SOF_BROADCAST_RECV #if IP_SOF_BROADCAST_RECV
(broadcast && (mpcb->so_options & SOF_BROADCAST)))))) { (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))))) {
#else /* IP_SOF_BROADCAST_RECV */ #else /* IP_SOF_BROADCAST_RECV */
(broadcast))))) { (broadcast))))) {
#endif /* IP_SOF_BROADCAST_RECV */ #endif /* IP_SOF_BROADCAST_RECV */
@ -632,7 +632,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
#if IP_SOF_BROADCAST #if IP_SOF_BROADCAST
/* broadcast filter? */ /* broadcast filter? */
if ( ((pcb->so_options & SOF_BROADCAST) == 0) && if (!ip_get_option(pcb, SOF_BROADCAST) &&
#if LWIP_IPV6 #if LWIP_IPV6
!PCB_ISIPV6(pcb) && !PCB_ISIPV6(pcb) &&
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
@ -900,8 +900,8 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
PCB is alread bound to, unless *all* PCBs with that port have tha PCB is alread bound to, unless *all* PCBs with that port have tha
REUSEADDR flag set. */ REUSEADDR flag set. */
#if SO_REUSE #if SO_REUSE
else if (((pcb->so_options & SOF_REUSEADDR) == 0) && else if (!ip_get_option(pcb, SOF_REUSEADDR) &&
((ipcb->so_options & SOF_REUSEADDR) == 0)) { !ip_get_option(ipcb, SOF_REUSEADDR)) {
#else /* SO_REUSE */ #else /* SO_REUSE */
/* port matches that of PCB in list and REUSEADDR not set -> reject */ /* port matches that of PCB in list and REUSEADDR not set -> reject */
else { else {

View File

@ -197,6 +197,13 @@ extern struct ip_globals ip_data;
/** Union destination address of current_header */ /** Union destination address of current_header */
#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) #define ipX_current_dest_addr() (&ip_data.current_iphdr_dest)
/** Gets an IP pcb option (SOF_* flags) */
#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt))
/** Sets an IP pcb option (SOF_* flags) */
#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt))
/** Resets an IP pcb option (SOF_* flags) */
#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt))
#if LWIP_IPV6 #if LWIP_IPV6
#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ #define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \
((isipv6) ? \ ((isipv6) ? \

View File

@ -47,7 +47,7 @@ LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg),
#if IP_REASSEMBLY #if IP_REASSEMBLY
LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA")
#endif /* IP_REASSEMBLY */ #endif /* IP_REASSEMBLY */
#if (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) || LWIP_IPv6_FRAG #if (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) || LWIP_IPV6_FRAG
LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF") LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF")
#endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ #endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */

View File

@ -367,9 +367,9 @@ void netif_poll_all(void);
#endif /* ENABLE_LOOPBACK */ #endif /* ENABLE_LOOPBACK */
#if LWIP_IPV6 #if LWIP_IPV6
#define netif_ip6_addr(netif, i) (&(netif->ip6_addr[(i)])) #define netif_ip6_addr(netif, i) (&((netif)->ip6_addr[(i)]))
#define netif_ip6_addr_state(netif, i) (netif->ip6_addr_state[(i)]) #define netif_ip6_addr_state(netif, i) ((netif)->ip6_addr_state[(i)])
#define netif_ip6_addr_set_state(netif, i, state) (netif->ip6_addr_state[(i)] = (state)) #define netif_ip6_addr_set_state(netif, i, state) ((netif)->ip6_addr_state[(i)] = (state))
s8_t netif_matches_ip6_addr(struct netif * netif, ip6_addr_t * ip6addr); s8_t netif_matches_ip6_addr(struct netif * netif, ip6_addr_t * ip6addr);
void netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit); void netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit);
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */

View File

@ -191,6 +191,7 @@ struct tcp_pcb {
/* Timers */ /* Timers */
u8_t polltmr, pollinterval; u8_t polltmr, pollinterval;
u8_t last_timer;
u32_t tmr; u32_t tmr;
/* receiver variables */ /* receiver variables */

View File

@ -309,6 +309,7 @@ struct tcp_seg {
/* Global variables: */ /* Global variables: */
extern struct tcp_pcb *tcp_input_pcb; extern struct tcp_pcb *tcp_input_pcb;
extern u32_t tcp_ticks; extern u32_t tcp_ticks;
extern u8_t tcp_active_pcbs_changed;
/* The TCP PCB lists. */ /* The TCP PCB lists. */
union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
@ -395,6 +396,24 @@ extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */
#endif /* LWIP_DEBUG */ #endif /* LWIP_DEBUG */
#define TCP_REG_ACTIVE(npcb) \
do { \
TCP_REG(&tcp_active_pcbs, npcb); \
tcp_active_pcbs_changed = 1; \
} while (0)
#define TCP_RMV_ACTIVE(npcb) \
do { \
TCP_RMV(&tcp_active_pcbs, npcb); \
tcp_active_pcbs_changed = 1; \
} while (0)
#define TCP_PCB_REMOVE_ACTIVE(pcb) \
do { \
tcp_pcb_remove(&tcp_active_pcbs, pcb); \
tcp_active_pcbs_changed = 1; \
} while (0)
/* Internal functions: */ /* Internal functions: */
struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);

View File

@ -191,9 +191,7 @@ etharp_free_entry(int i)
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
/* for debugging, clean out the complete entry */ /* for debugging, clean out the complete entry */
arp_table[i].ctime = 0; arp_table[i].ctime = 0;
#if LWIP_SNMP
arp_table[i].netif = NULL; arp_table[i].netif = NULL;
#endif /* LWIP_SNMP */
ip_addr_set_zero(&arp_table[i].ipaddr); ip_addr_set_zero(&arp_table[i].ipaddr);
arp_table[i].ethaddr = ethzero; arp_table[i].ethaddr = ethzero;
#endif /* LWIP_DEBUG */ #endif /* LWIP_DEBUG */
@ -482,9 +480,7 @@ etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr
} }
/* record network interface */ /* record network interface */
#if LWIP_SNMP
arp_table[i].netif = netif; arp_table[i].netif = netif;
#endif /* LWIP_SNMP */
/* insert in SNMP ARP index tree */ /* insert in SNMP ARP index tree */
snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);