mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-08-24 15:16:02 +00:00
Merge branch 'master' of git.sv.gnu.org:/srv/git/lwip
This commit is contained in:
commit
e9255d3714
|
@ -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'
|
||||||
|
|
|
@ -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")));
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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,27 +1067,39 @@ 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 */
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) ? \
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user