mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-12-27 15:16:03 +00:00
tcp_out: combine the tx path of the 4 direct tx functions
tcp_rst, tcp_send_empty_ack, tcp_keepalive and tcp_zero_window_probe all execute the same instructions to send a segment pbuf. Combined into tcp_output_control_segment().
This commit is contained in:
parent
9128a51944
commit
424c33bcb7
@ -1781,6 +1781,46 @@ tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen,
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Output a control segment pbuf to IP.
|
||||||
|
*
|
||||||
|
* Called from tcp_rst, tcp_send_empty_ack, tcp_keepalive and tcp_zero_window_probe,
|
||||||
|
* this function combines selecting a netif for transmission, generating the tcp
|
||||||
|
* header checksum and calling ip_output_if while handling netif hints and stats.
|
||||||
|
*/
|
||||||
|
static err_t
|
||||||
|
tcp_output_control_segment(const struct tcp_pcb *pcb, struct pbuf *p,
|
||||||
|
const ip_addr_t *src, const ip_addr_t *dst)
|
||||||
|
{
|
||||||
|
err_t err;
|
||||||
|
struct netif *netif = tcp_route(pcb, src, dst);
|
||||||
|
if (netif == NULL) {
|
||||||
|
err = ERR_RTE;
|
||||||
|
} else {
|
||||||
|
u8_t ttl, tos;
|
||||||
|
#if CHECKSUM_GEN_TCP
|
||||||
|
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
|
||||||
|
struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload;
|
||||||
|
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
|
||||||
|
src, dst);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (pcb != NULL) {
|
||||||
|
NETIF_SET_HINTS(netif, &(pcb->netif_hints));
|
||||||
|
ttl = pcb->ttl;
|
||||||
|
tos = pcb->tos;
|
||||||
|
} else {
|
||||||
|
/* Send output with hardcoded TTL/HL since we have no access to the pcb */
|
||||||
|
ttl = TCP_TTL;
|
||||||
|
tos = 0;
|
||||||
|
}
|
||||||
|
TCP_STATS_INC(tcp.xmit);
|
||||||
|
err = ip_output_if(p, src, dst, ttl, tos, IP_PROTO_TCP, netif);
|
||||||
|
NETIF_RESET_HINTS(netif);
|
||||||
|
}
|
||||||
|
pbuf_free(p);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a TCP RESET packet (empty segment with RST flag set) either to
|
* Send a TCP RESET packet (empty segment with RST flag set) either to
|
||||||
* abort a connection or to show that there is no matching local connection
|
* abort a connection or to show that there is no matching local connection
|
||||||
@ -1808,7 +1848,6 @@ tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno,
|
|||||||
u16_t local_port, u16_t remote_port)
|
u16_t local_port, u16_t remote_port)
|
||||||
{
|
{
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
struct netif *netif;
|
|
||||||
u16_t wnd;
|
u16_t wnd;
|
||||||
|
|
||||||
#if LWIP_WND_SCALE
|
#if LWIP_WND_SCALE
|
||||||
@ -1824,22 +1863,9 @@ tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCP_STATS_INC(tcp.xmit);
|
|
||||||
MIB2_STATS_INC(mib2.tcpoutrsts);
|
MIB2_STATS_INC(mib2.tcpoutrsts);
|
||||||
|
|
||||||
netif = tcp_route(pcb, local_ip, remote_ip);
|
tcp_output_control_segment(pcb, p, local_ip, remote_ip);
|
||||||
if (netif != NULL) {
|
|
||||||
#if CHECKSUM_GEN_TCP
|
|
||||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
|
|
||||||
struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload;
|
|
||||||
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
|
|
||||||
local_ip, remote_ip);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Send output with hardcoded TTL/HL since we have no access to the pcb */
|
|
||||||
ip_output_if(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP, netif);
|
|
||||||
}
|
|
||||||
pbuf_free(p);
|
|
||||||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
|
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1854,7 +1880,6 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
|
|||||||
err_t err;
|
err_t err;
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
u8_t optlen = 0;
|
u8_t optlen = 0;
|
||||||
struct netif *netif;
|
|
||||||
#if CHECKSUM_GEN_TCP || LWIP_TCP_TIMESTAMPS || LWIP_TCP_SACK_OUT
|
#if CHECKSUM_GEN_TCP || LWIP_TCP_TIMESTAMPS || LWIP_TCP_SACK_OUT
|
||||||
struct tcp_hdr *tcphdr;
|
struct tcp_hdr *tcphdr;
|
||||||
#if LWIP_TCP_TIMESTAMPS || LWIP_TCP_SACK_OUT
|
#if LWIP_TCP_TIMESTAMPS || LWIP_TCP_SACK_OUT
|
||||||
@ -1915,23 +1940,7 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip);
|
err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
|
||||||
if (netif == NULL) {
|
|
||||||
err = ERR_RTE;
|
|
||||||
} else {
|
|
||||||
#if CHECKSUM_GEN_TCP
|
|
||||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
|
|
||||||
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
|
|
||||||
&pcb->local_ip, &pcb->remote_ip);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
NETIF_SET_HINTS(netif, &(pcb->netif_hints));
|
|
||||||
err = ip_output_if(p, &pcb->local_ip, &pcb->remote_ip,
|
|
||||||
pcb->ttl, pcb->tos, IP_PROTO_TCP, netif);
|
|
||||||
NETIF_RESET_HINTS(netif);
|
|
||||||
}
|
|
||||||
pbuf_free(p);
|
|
||||||
|
|
||||||
if (err != ERR_OK) {
|
if (err != ERR_OK) {
|
||||||
/* let tcp_fasttmr retry sending this ACK */
|
/* let tcp_fasttmr retry sending this ACK */
|
||||||
tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
|
tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
|
||||||
@ -1956,7 +1965,6 @@ tcp_keepalive(struct tcp_pcb *pcb)
|
|||||||
{
|
{
|
||||||
err_t err;
|
err_t err;
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
struct netif *netif;
|
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to "));
|
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to "));
|
||||||
ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip);
|
ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip);
|
||||||
@ -1971,25 +1979,7 @@ tcp_keepalive(struct tcp_pcb *pcb)
|
|||||||
("tcp_keepalive: could not allocate memory for pbuf\n"));
|
("tcp_keepalive: could not allocate memory for pbuf\n"));
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip);
|
err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
|
||||||
if (netif == NULL) {
|
|
||||||
err = ERR_RTE;
|
|
||||||
} else {
|
|
||||||
#if CHECKSUM_GEN_TCP
|
|
||||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
|
|
||||||
struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload;
|
|
||||||
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
|
|
||||||
&pcb->local_ip, &pcb->remote_ip);
|
|
||||||
}
|
|
||||||
#endif /* CHECKSUM_GEN_TCP */
|
|
||||||
TCP_STATS_INC(tcp.xmit);
|
|
||||||
|
|
||||||
/* Send output to IP */
|
|
||||||
NETIF_SET_HINTS(netif, &(pcb->netif_hints));
|
|
||||||
err = ip_output_if(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, netif);
|
|
||||||
NETIF_RESET_HINTS(netif);
|
|
||||||
}
|
|
||||||
pbuf_free(p);
|
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n",
|
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n",
|
||||||
pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err));
|
pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err));
|
||||||
@ -2014,7 +2004,6 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
|
|||||||
u16_t len;
|
u16_t len;
|
||||||
u8_t is_fin;
|
u8_t is_fin;
|
||||||
u32_t snd_nxt;
|
u32_t snd_nxt;
|
||||||
struct netif *netif;
|
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to "));
|
LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to "));
|
||||||
ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip);
|
ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip);
|
||||||
@ -2069,26 +2058,7 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
|
|||||||
pcb->snd_nxt = snd_nxt;
|
pcb->snd_nxt = snd_nxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip);
|
err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
|
||||||
if (netif == NULL) {
|
|
||||||
err = ERR_RTE;
|
|
||||||
} else {
|
|
||||||
#if CHECKSUM_GEN_TCP
|
|
||||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
|
|
||||||
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
|
|
||||||
&pcb->local_ip, &pcb->remote_ip);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
TCP_STATS_INC(tcp.xmit);
|
|
||||||
|
|
||||||
/* Send output to IP */
|
|
||||||
NETIF_SET_HINTS(netif, &(pcb->netif_hints));
|
|
||||||
err = ip_output_if(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
|
|
||||||
0, IP_PROTO_TCP, netif);
|
|
||||||
NETIF_RESET_HINTS(netif);
|
|
||||||
}
|
|
||||||
|
|
||||||
pbuf_free(p);
|
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
|
LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
|
||||||
" ackno %"U32_F" err %d.\n",
|
" ackno %"U32_F" err %d.\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user