mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-09-22 00:33:46 +08:00
Applied patch #1399 to implement socket options
This commit is contained in:
@@ -126,8 +126,8 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
snmp_inc_icmpoutechoreps();
|
||||
|
||||
pbuf_header(p, hlen);
|
||||
ip_output_if (p, &(iphdr->src), IP_HDRINCL,
|
||||
IPH_TTL(iphdr), IP_PROTO_ICMP, inp);
|
||||
ip_output_if(p, &(iphdr->src), IP_HDRINCL,
|
||||
IPH_TTL(iphdr), 0, IP_PROTO_ICMP, inp);
|
||||
break;
|
||||
default:
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d code %d not supported.\n", (int)type, (int)code));
|
||||
@@ -169,7 +169,7 @@ icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
|
||||
snmp_inc_icmpoutdestunreachs();
|
||||
|
||||
ip_output(q, NULL, &(iphdr->src),
|
||||
ICMP_TTL, IP_PROTO_ICMP);
|
||||
ICMP_TTL, 0, IP_PROTO_ICMP);
|
||||
pbuf_free(q);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@@ -210,7 +210,7 @@ icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
|
||||
/* increase number of destination unreachable messages attempted to send */
|
||||
snmp_inc_icmpouttimeexcds();
|
||||
ip_output(q, NULL, &(iphdr->src),
|
||||
ICMP_TTL, IP_PROTO_ICMP);
|
||||
ICMP_TTL, 0, IP_PROTO_ICMP);
|
||||
pbuf_free(q);
|
||||
}
|
||||
|
||||
|
||||
@@ -448,8 +448,8 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
u8_t ttl,
|
||||
ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
u8_t ttl, u8_t tos,
|
||||
u8_t proto, struct netif *netif)
|
||||
{
|
||||
static struct ip_hdr *iphdr;
|
||||
@@ -475,7 +475,7 @@ ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
|
||||
ip_addr_set(&(iphdr->dest), dest);
|
||||
|
||||
IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);
|
||||
IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, tos);
|
||||
IPH_LEN_SET(iphdr, htons(p->tot_len));
|
||||
IPH_OFFSET_SET(iphdr, htons(IP_DF));
|
||||
IPH_ID_SET(iphdr, htons(ip_id));
|
||||
@@ -521,7 +521,7 @@ ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
u8_t ttl, u8_t proto)
|
||||
u8_t ttl, u8_t tos, u8_t proto)
|
||||
{
|
||||
struct netif *netif;
|
||||
|
||||
@@ -535,7 +535,7 @@ ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
return ERR_RTE;
|
||||
}
|
||||
|
||||
return ip_output_if (p, src, dest, ttl, proto, netif);
|
||||
return ip_output_if(p, src, dest, ttl, tos, proto, netif);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if IP_DEBUG
|
||||
|
||||
@@ -175,7 +175,7 @@ raw_send_payload(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
|
||||
src_ip = &(pcb->local_ip);
|
||||
}
|
||||
|
||||
err = ip_output_if (p, src_ip, ipaddr, 64, pcb->protocol, netif);
|
||||
err = ip_output_if (p, src_ip, ipaddr, 64, pcb->tos, pcb->protocol, netif);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
@@ -318,6 +318,10 @@ tcp_listen(struct tcp_pcb *pcb)
|
||||
lpcb->callback_arg = pcb->callback_arg;
|
||||
lpcb->local_port = pcb->local_port;
|
||||
lpcb->state = LISTEN;
|
||||
lpcb->so_options = pcb->so_options;
|
||||
lpcb->so_options |= SOF_ACCEPTCONN;
|
||||
lpcb->ttl = pcb->ttl;
|
||||
lpcb->tos = pcb->tos;
|
||||
ip_addr_set(&lpcb->local_ip, &pcb->local_ip);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
#if LWIP_CALLBACK_API
|
||||
@@ -520,6 +524,21 @@ tcp_slowtmr(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if KEEPALIVE should be sent */
|
||||
if((pcb->so_options & SOF_KEEPALIVE) && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
|
||||
if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keepalive + TCP_MAXIDLE) / TCP_SLOW_INTERVAL) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %u.%u.%u.%u.\n",
|
||||
ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
|
||||
ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
|
||||
|
||||
tcp_abort(pcb);
|
||||
}
|
||||
else if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keepalive + pcb->keep_cnt * TCP_KEEPINTVL) / TCP_SLOW_INTERVAL) {
|
||||
tcp_keepalive(pcb);
|
||||
pcb->keep_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this PCB has queued out of sequence data, but has been
|
||||
inactive for too long, will drop the data (it will eventually
|
||||
be retransmitted). */
|
||||
@@ -810,6 +829,8 @@ tcp_alloc(u8_t prio)
|
||||
pcb->snd_buf = TCP_SND_BUF;
|
||||
pcb->snd_queuelen = 0;
|
||||
pcb->rcv_wnd = TCP_WND;
|
||||
pcb->tos = 0;
|
||||
pcb->ttl = TCP_TTL;
|
||||
pcb->mss = TCP_MSS;
|
||||
pcb->rto = 3000 / TCP_SLOW_INTERVAL;
|
||||
pcb->sa = 0;
|
||||
@@ -829,6 +850,10 @@ tcp_alloc(u8_t prio)
|
||||
#if LWIP_CALLBACK_API
|
||||
pcb->recv = tcp_recv_null;
|
||||
#endif /* LWIP_CALLBACK_API */
|
||||
|
||||
/* Init KEEPALIVE timer */
|
||||
pcb->keepalive = TCP_KEEPDEFAULT;
|
||||
pcb->keep_cnt = 0;
|
||||
}
|
||||
return pcb;
|
||||
}
|
||||
|
||||
@@ -396,7 +396,8 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
#if LWIP_CALLBACK_API
|
||||
npcb->accept = pcb->accept;
|
||||
#endif /* LWIP_CALLBACK_API */
|
||||
|
||||
/* inherit socket options */
|
||||
npcb->so_options = pcb->so_options & (SOF_DEBUG|SOF_DONTROUTE|SOF_KEEPALIVE|SOF_OOBINLINE|SOF_LINGER);
|
||||
/* Register the new PCB so that we can begin receiving segments
|
||||
for it. */
|
||||
TCP_REG(&tcp_active_pcbs, npcb);
|
||||
@@ -483,6 +484,7 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
|
||||
/* Update the PCB (in)activity timer. */
|
||||
pcb->tmr = tcp_ticks;
|
||||
pcb->keep_cnt = 0;
|
||||
|
||||
/* Do different things depending on the TCP state. */
|
||||
switch (pcb->state) {
|
||||
|
||||
@@ -405,7 +405,8 @@ tcp_output(struct tcp_pcb *pcb)
|
||||
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
|
||||
IP_PROTO_TCP, p->tot_len);
|
||||
|
||||
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL,
|
||||
|
||||
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
|
||||
IP_PROTO_TCP);
|
||||
pbuf_free(p);
|
||||
|
||||
@@ -527,7 +528,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
||||
++lwip_stats.tcp.xmit;
|
||||
#endif /* TCP_STATS */
|
||||
|
||||
ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL,
|
||||
ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
|
||||
IP_PROTO_TCP);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@@ -561,7 +562,8 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
||||
#ifdef TCP_STATS
|
||||
++lwip_stats.tcp.xmit;
|
||||
#endif /* TCP_STATS */
|
||||
ip_output(p, local_ip, remote_ip, TCP_TTL, IP_PROTO_TCP);
|
||||
/* Send output with hardcoded TTL since we have no access to the pcb */
|
||||
ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
|
||||
pbuf_free(p);
|
||||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %lu ackno %lu.\n", seqno, ackno));
|
||||
}
|
||||
@@ -595,6 +597,50 @@ tcp_rexmit(struct tcp_pcb *pcb)
|
||||
tcp_output(pcb);
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
tcp_keepalive(struct tcp_pcb *pcb)
|
||||
{
|
||||
struct pbuf *p;
|
||||
struct tcp_hdr *tcphdr;
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %u.%u.%u.%u\n",
|
||||
ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
|
||||
ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %ld pcb->tmr %ld pcb->keep_cnt %ld\n", tcp_ticks, pcb->tmr, pcb->keep_cnt));
|
||||
|
||||
p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
|
||||
|
||||
if(p == NULL) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: could not allocate memory for pbuf\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
tcphdr = p->payload;
|
||||
tcphdr->src = htons(pcb->local_port);
|
||||
tcphdr->dest = htons(pcb->remote_port);
|
||||
tcphdr->seqno = htonl(pcb->snd_nxt - 1);
|
||||
tcphdr->ackno = htonl(pcb->rcv_nxt);
|
||||
tcphdr->wnd = htons(pcb->rcv_wnd);
|
||||
tcphdr->urgp = 0;
|
||||
TCPH_HDRLEN_SET(tcphdr, 5);
|
||||
|
||||
tcphdr->chksum = 0;
|
||||
tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, IP_PROTO_TCP, p->tot_len);
|
||||
|
||||
#ifdef TCP_STATS
|
||||
++lwip_stats.tcp.xmit;
|
||||
#endif /* TCP_STATS */
|
||||
|
||||
/* Send output to IP */
|
||||
ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
|
||||
|
||||
pbuf_free(p);
|
||||
|
||||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_keepalive: seqno %lu ackno %lu.\n", pcb->snd_nxt - 1, pcb->rcv_nxt));
|
||||
}
|
||||
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
|
||||
/* output to IP */
|
||||
err = ip_output_if (q, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDPLITE, netif);
|
||||
err = ip_output_if (p, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
|
||||
snmp_inc_udpoutdatagrams();
|
||||
} else {
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
|
||||
@@ -422,7 +422,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
snmp_inc_udpoutdatagrams();
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
|
||||
/* output to IP */
|
||||
err = ip_output_if (q, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDP, netif);
|
||||
err = ip_output_if(p, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
|
||||
}
|
||||
|
||||
/* did we chain a header earlier? */
|
||||
@@ -650,6 +650,9 @@ udp_new(void) {
|
||||
/* initialize PCB to all zeroes */
|
||||
memset(pcb, 0, sizeof(struct udp_pcb));
|
||||
}
|
||||
|
||||
pcb->ttl = UDP_TTL;
|
||||
|
||||
return pcb;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
Reference in New Issue
Block a user