From 14c766e750540160934796523f4fe9fefcbe8bb8 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Thu, 24 Nov 2011 21:11:11 +0100 Subject: [PATCH 1/7] fix for bug #34684 was wrong (netif for arp table entries was only set/reset with SNMP enabled) --- src/netif/etharp.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/netif/etharp.c b/src/netif/etharp.c index 99187b4a..9183b847 100644 --- a/src/netif/etharp.c +++ b/src/netif/etharp.c @@ -191,9 +191,7 @@ etharp_free_entry(int i) #ifdef LWIP_DEBUG /* for debugging, clean out the complete entry */ arp_table[i].ctime = 0; -#if LWIP_SNMP arp_table[i].netif = NULL; -#endif /* LWIP_SNMP */ ip_addr_set_zero(&arp_table[i].ipaddr); arp_table[i].ethaddr = ethzero; #endif /* LWIP_DEBUG */ @@ -482,9 +480,7 @@ etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr } /* record network interface */ -#if LWIP_SNMP arp_table[i].netif = netif; -#endif /* LWIP_SNMP */ /* insert in SNMP ARP index tree */ snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); From dd8729063c34c0073ae98190b0174bd045d240ca Mon Sep 17 00:00:00 2001 From: goldsimon Date: Fri, 25 Nov 2011 18:36:52 +0100 Subject: [PATCH 2/7] fixed bug #31177: tcp timers can corrupt tcp_active_pcbs in some cases --- CHANGELOG | 4 ++ src/core/tcp.c | 77 +++++++++++++++++++++++++++---------- src/core/tcp_in.c | 8 ++-- src/include/lwip/tcp.h | 1 + src/include/lwip/tcp_impl.h | 19 +++++++++ 5 files changed, 85 insertions(+), 24 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3d827ca7..bfef4810 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -69,6 +69,10 @@ HISTORY ++ 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 * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with '#ifndef sys_msleep' diff --git a/src/core/tcp.c b/src/core/tcp.c index 1fa75153..e981d530 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -119,8 +119,11 @@ struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcb /** Only used for temporary storage. */ struct tcp_pcb *tcp_tmp_pcb; +u8_t tcp_active_pcbs_changed; + /** Timer counter to handle calling slow-timer from tcp_tmr() */ static u8_t tcp_timer; +static u8_t tcp_timer_ctr; 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? */ /* move to TIME_WAIT since we close actively */ - TCP_RMV(&tcp_active_pcbs, pcb); + TCP_RMV_ACTIVE(pcb); pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); @@ -219,7 +222,7 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) break; case SYN_SENT: err = ERR_OK; - tcp_pcb_remove(&tcp_active_pcbs, pcb); + TCP_PCB_REMOVE_ACTIVE(pcb); memp_free(MEMP_TCP_PCB, pcb); pcb = NULL; snmp_inc_tcpattemptfails(); @@ -371,7 +374,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) errf = pcb->errf; #endif /* LWIP_CALLBACK_API */ errf_arg = pcb->callback_arg; - tcp_pcb_remove(&tcp_active_pcbs, pcb); + TCP_PCB_REMOVE_ACTIVE(pcb); if (pcb->unacked != NULL) { tcp_segs_free(pcb->unacked); } @@ -793,7 +796,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, if (old_local_port != 0) { TCP_RMV(&tcp_bound_pcbs, pcb); } - TCP_REG(&tcp_active_pcbs, pcb); + TCP_REG_ACTIVE(pcb); snmp_inc_tcpactiveopens(); tcp_output(pcb); @@ -820,7 +823,9 @@ tcp_slowtmr(void) err = ERR_OK; ++tcp_ticks; + ++tcp_timer_ctr; +tcp_slowtmr_start: /* Steps through all of the active PCBs. */ prev = NULL; 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 != LISTEN\n", pcb->state != LISTEN); 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_reset = 0; @@ -957,6 +968,8 @@ tcp_slowtmr(void) /* If the PCB should be removed, do it. */ if (pcb_remove) { struct tcp_pcb *pcb2; + tcp_err_fn err_fn; + void *err_arg; tcp_pcb_purge(pcb); /* Remove PCB from tcp_active_pcbs list. */ if (prev != NULL) { @@ -968,15 +981,22 @@ tcp_slowtmr(void) tcp_active_pcbs = pcb->next; } - TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT); if (pcb_reset) { tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); } + err_fn = pcb->errf; + err_arg = pcb->callback_arg; pcb2 = pcb; pcb = pcb->next; 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 { /* get the 'next' element now and work with 'prev' below (in case of abort) */ prev = pcb; @@ -987,7 +1007,11 @@ tcp_slowtmr(void) if (prev->polltmr >= prev->pollinterval) { prev->polltmr = 0; LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); + tcp_active_pcbs_changed = 0; 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_OK) { tcp_output(prev); @@ -1043,26 +1067,38 @@ tcp_slowtmr(void) 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) { - struct tcp_pcb *next = pcb->next; - /* If there is data which was previously "refused" by upper layer */ - if (pcb->refused_data != NULL) { - if (tcp_process_refused_data(pcb) == ERR_ABRT) { - pcb = NULL; + if (pcb->last_timer != tcp_timer_ctr) { + struct tcp_pcb *next; + pcb->last_timer = tcp_timer_ctr; + /* send delayed ACKs */ + if (pcb->flags & TF_ACK_DELAY) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); + tcp_ack_now(pcb); + tcp_output(pcb); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); } - } - /* send delayed ACKs */ - if (pcb && (pcb->flags & TF_ACK_DELAY)) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); - tcp_ack_now(pcb); - tcp_output(pcb); - pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); - } + next = pcb->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; + } } } @@ -1312,6 +1348,7 @@ tcp_alloc(u8_t prio) pcb->lastack = iss; pcb->snd_lbb = iss; pcb->tmr = tcp_ticks; + pcb->last_timer = tcp_timer_ctr; pcb->polltmr = 0; diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 0dd2c904..6af07211 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -505,7 +505,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) npcb->so_options = pcb->so_options & SOF_INHERITED; /* Register the new PCB so that we can begin receiving segments for it. */ - TCP_REG(&tcp_active_pcbs, npcb); + TCP_REG_ACTIVE(npcb); /* Parse any options in the SYN. */ 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_ack_now(pcb); tcp_pcb_purge(pcb); - TCP_RMV(&tcp_active_pcbs, pcb); + TCP_RMV_ACTIVE(pcb); pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); } 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)); tcp_ack_now(pcb); tcp_pcb_purge(pcb); - TCP_RMV(&tcp_active_pcbs, pcb); + TCP_RMV_ACTIVE(pcb); pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); } @@ -782,7 +782,7 @@ tcp_process(struct tcp_pcb *pcb) 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)); tcp_pcb_purge(pcb); - TCP_RMV(&tcp_active_pcbs, pcb); + TCP_RMV_ACTIVE(pcb); pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); } diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h index 6af71583..4dc1df2a 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -191,6 +191,7 @@ struct tcp_pcb { /* Timers */ u8_t polltmr, pollinterval; + u8_t last_timer; u32_t tmr; /* receiver variables */ diff --git a/src/include/lwip/tcp_impl.h b/src/include/lwip/tcp_impl.h index 9b745a0d..b068eef2 100644 --- a/src/include/lwip/tcp_impl.h +++ b/src/include/lwip/tcp_impl.h @@ -309,6 +309,7 @@ struct tcp_seg { /* Global variables: */ extern struct tcp_pcb *tcp_input_pcb; extern u32_t tcp_ticks; +extern u8_t tcp_active_pcbs_changed; /* The TCP PCB lists. */ 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 */ +#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: */ struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); From 85f8a59d7f7f1dc973b2dc70ba3d0237cd59d24e Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Mon, 28 Nov 2011 14:07:53 -0700 Subject: [PATCH 3/7] Added parenthesis to netif/ip6 macros. Change-Id: I32d7f28c9e106641e3d5be8342d2c884e166bb0e --- src/include/lwip/netif.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h index a658e51b..322d2d0e 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -367,9 +367,9 @@ void netif_poll_all(void); #endif /* ENABLE_LOOPBACK */ #if LWIP_IPV6 -#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_set_state(netif, i, state) (netif->ip6_addr_state[(i)] = (state)) +#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_set_state(netif, i, state) ((netif)->ip6_addr_state[(i)] = (state)) 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); #endif /* LWIP_IPV6 */ From ce6fb83ef4e1e29f4e9244d69eaa6b249d88092d Mon Sep 17 00:00:00 2001 From: Ivan Delamer Date: Tue, 29 Nov 2011 12:49:43 -0700 Subject: [PATCH 4/7] bug #34846: time-exceeded was sometimes not sent to original fragment source, but to the sender of a packet fragment that triggered a buffer purge. Change-Id: I4bf20747bd900150491852649918a85cb7bf2aad --- src/core/ipv6/icmp6.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/core/ipv6/icmp6.c b/src/core/ipv6/icmp6.c index fbfda5e7..dfe92107 100644 --- a/src/core/ipv6/icmp6.c +++ b/src/core/ipv6/icmp6.c @@ -283,14 +283,11 @@ icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type) IP6_HLEN + LWIP_ICMP6_DATASIZE); /* Get the destination address and netif for this ICMP message. */ - if (ip_current_netif() != NULL) { - netif = ip_current_netif(); - reply_dest = ip6_current_src_addr(); - } - else { - /* 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. */ + if ((ip_current_netif() == NULL) || + ((code == ICMP6_TE_FRAG) && (type == ICMP6_TYPE_TE))) { + /* Special case, as ip6_current_xxx is either NULL, or points + * to a different packet than the one that expired. + * We must use the addresses that are stored in the expired packet. */ ip6hdr = (struct ip6_hdr *)p->payload; /* copy from packed address to aligned address */ ip6_addr_copy(reply_dest_local, ip6hdr->src); @@ -305,14 +302,18 @@ icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type) return; } } + else { + netif = ip_current_netif(); + reply_dest = ip6_current_src_addr(); - /* Select an address to use as source. */ - reply_src = ip6_select_source_address(netif, reply_dest); - if (reply_src == NULL) { - /* drop */ - pbuf_free(q); - ICMP6_STATS_INC(icmp6.rterr); - return; + /* Select an address to use as source. */ + reply_src = ip6_select_source_address(netif, reply_dest); + if (reply_src == NULL) { + /* drop */ + pbuf_free(q); + ICMP6_STATS_INC(icmp6.rterr); + return; + } } /* calculate checksum */ From 5048a30fc748c06ddb9741a45e540411ef77c612 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Tue, 6 Dec 2011 21:21:44 +0100 Subject: [PATCH 5/7] Another fix for bug #32417 (debug assert that fires) --- src/core/tcp_out.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index 49c9679a..1bbd587e 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -989,6 +989,9 @@ tcp_output(struct tcp_pcb *pcb) 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); snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { From 8114627d6a68641110f87ff434069631f537b67e Mon Sep 17 00:00:00 2001 From: goldsimon Date: Wed, 14 Dec 2011 21:42:51 +0100 Subject: [PATCH 6/7] Fixed typo in define check: LWIP_IPv6_FRAG -> LWIP_IPV6_FRAG --- src/include/lwip/memp_std.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/lwip/memp_std.h b/src/include/lwip/memp_std.h index 90679f6d..592a2824 100644 --- a/src/include/lwip/memp_std.h +++ b/src/include/lwip/memp_std.h @@ -47,7 +47,7 @@ LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), #if IP_REASSEMBLY LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") #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") #endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ From c8647c03966feadcb33cc8ade27fda4b44571d13 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Sat, 17 Dec 2011 22:12:01 +0100 Subject: [PATCH 7/7] implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) (fixes bug #35061) --- CHANGELOG | 4 ++++ src/api/sockets.c | 6 +++--- src/core/dhcp.c | 4 ++-- src/core/raw.c | 4 ++-- src/core/tcp.c | 14 +++++++------- src/core/udp.c | 12 ++++++------ src/include/lwip/ip.h | 7 +++++++ 7 files changed, 31 insertions(+), 20 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index bfef4810..31fa1d50 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,10 @@ HISTORY ++ 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 * 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) diff --git a/src/api/sockets.c b/src/api/sockets.c index 3bc96f97..1b236a84 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -1761,7 +1761,7 @@ lwip_getsockopt_internal(void *arg) case SO_REUSEPORT: #endif /* SO_REUSE */ /*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", s, optname, (*(int*)optval?"on":"off"))); break; @@ -2178,9 +2178,9 @@ lwip_setsockopt_internal(void *arg) #endif /* SO_REUSE */ /* UNIMPL case SO_USELOOPBACK: */ if (*(int*)optval) { - sock->conn->pcb.ip->so_options |= optname; + ip_set_option(sock->conn->pcb.ip, optname); } 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", s, optname, (*(int*)optval?"on":"off"))); diff --git a/src/core/dhcp.c b/src/core/dhcp.c index 489e6bc9..7c1fc4d5 100644 --- a/src/core/dhcp.c +++ b/src/core/dhcp.c @@ -680,7 +680,7 @@ dhcp_start(struct netif *netif) LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); 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 */ udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); @@ -730,7 +730,7 @@ dhcp_inform(struct netif *netif) return; } 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); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); } diff --git a/src/core/raw.c b/src/core/raw.c index 2adc8a96..6f50848c 100644 --- a/src/core/raw.c +++ b/src/core/raw.c @@ -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()))) { #if IP_SOF_BROADCAST_RECV /* 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 && !PCB_ISIPV6(pcb) #endif /* LWIP_IPV6 */ @@ -279,7 +279,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) #endif /* LWIP_IPV6 */ { /* 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)); /* free any temporary header pbuf allocated by pbuf_header() */ if (q != p) { diff --git a/src/core/tcp.c b/src/core/tcp.c index e981d530..150cd966 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -440,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 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; } #endif /* SO_REUSE */ @@ -460,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. For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in tcp_connect. */ - if (((pcb->so_options & SOF_REUSEADDR) == 0) || - ((cpcb->so_options & SOF_REUSEADDR) == 0)) + if (!ip_get_option(pcb, SOF_REUSEADDR) || + !ip_get_option(cpcb, SOF_REUSEADDR)) #endif /* SO_REUSE */ { /* @todo: check accept_any_ip_version */ @@ -526,7 +526,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) return pcb; } #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 is declared (listen-/connection-pcb), we have to make sure now that this port is only used once for every local IP. */ @@ -550,7 +550,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) lpcb->state = LISTEN; lpcb->prio = pcb->prio; lpcb->so_options = pcb->so_options; - lpcb->so_options |= SOF_ACCEPTCONN; + ip_set_option(lpcb, SOF_ACCEPTCONN); lpcb->ttl = pcb->ttl; lpcb->tos = pcb->tos; #if LWIP_IPV6 @@ -745,7 +745,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, } } #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 now that the 5-tuple is unique. */ struct tcp_pcb *cpcb; @@ -914,7 +914,7 @@ tcp_slowtmr_start: } /* Check if KEEPALIVE should be sent */ - if((pcb->so_options & SOF_KEEPALIVE) && + if(ip_get_option(pcb, SOF_KEEPALIVE) && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { if((u32_t)(tcp_ticks - pcb->tmr) > diff --git a/src/core/udp.c b/src/core/udp.c index 04d52b19..1086fb03 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -260,7 +260,7 @@ udp_input(struct pbuf *p, struct netif *inp) ip_addr_ismulticast(ip_current_dest_addr()) || #endif /* LWIP_IGMP */ #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) || ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) { #else /* IP_SOF_BROADCAST_RECV */ @@ -365,7 +365,7 @@ udp_input(struct pbuf *p, struct netif *inp) ip6_addr_ismulticast(ip6_current_dest_addr()) || #endif /* LWIP_IPV6 */ 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 if SOF_REUSEADDR is set on the first match */ struct udp_pcb *mpcb; @@ -389,7 +389,7 @@ udp_input(struct pbuf *p, struct netif *inp) ip_addr_ismulticast(ip_current_dest_addr()) || #endif /* LWIP_IGMP */ #if IP_SOF_BROADCAST_RECV - (broadcast && (mpcb->so_options & SOF_BROADCAST)))))) { + (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))))) { #else /* IP_SOF_BROADCAST_RECV */ (broadcast))))) { #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 /* broadcast filter? */ - if ( ((pcb->so_options & SOF_BROADCAST) == 0) && + if (!ip_get_option(pcb, SOF_BROADCAST) && #if LWIP_IPV6 !PCB_ISIPV6(pcb) && #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 REUSEADDR flag set. */ #if SO_REUSE - else if (((pcb->so_options & SOF_REUSEADDR) == 0) && - ((ipcb->so_options & SOF_REUSEADDR) == 0)) { + else if (!ip_get_option(pcb, SOF_REUSEADDR) && + !ip_get_option(ipcb, SOF_REUSEADDR)) { #else /* SO_REUSE */ /* port matches that of PCB in list and REUSEADDR not set -> reject */ else { diff --git a/src/include/lwip/ip.h b/src/include/lwip/ip.h index 6de95b18..a0cd1d4d 100644 --- a/src/include/lwip/ip.h +++ b/src/include/lwip/ip.h @@ -197,6 +197,13 @@ extern struct ip_globals ip_data; /** Union destination address of current_header */ #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 #define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ ((isipv6) ? \