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
15 changed files with 139 additions and 67 deletions

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"));
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"));
}

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);
/* 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 */

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()))) {
#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) {

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. */
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);
}
@@ -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
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 */
@@ -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.
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 */
@@ -523,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. */
@@ -547,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
@@ -742,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;
@@ -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;
@@ -903,7 +914,7 @@ tcp_slowtmr(void)
}
/* 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) >
@@ -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;

View File

@@ -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);
}

View File

@@ -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)) {

View File

@@ -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 {