tcp_transmit_skb的发送时机梳理

在上文数据通过网络发送的过程中,当程序调用tcp_sendmsg发送数据的时候有可能当前的数据不会马上发送出去,当前在哪些场景下会触发数据的发送呢。

检查mtu

创建 一个新的路径MTU 发现段

  1. 未启用路径MTU

  2. 当前路径MTU探测段的长度不为0,表示路径MTU发现段已经发出尚未得到确认

  3. 拥塞控制状态不处于Open 状态

  4. 拥塞窗又大小不足使用时

  5. 下 一个发送的段中存在SACK选 项

在tcp_write_xmit函数执行的场景下有可能执行tcp_mtu_probe

tcp_write_xmit->tcp_transmit_skb

tcp_mtu_probe->tcp_transmit_skb

定时重传-tcp_retransmit_timer定时器和tcp_send_loss_probe定时器等
void tcp_write_timer_handler(struct sock *sk)
{
	struct inet_connection_sock *icsk = inet_csk(sk);
	int event;

	if (sk->sk_state == TCP_CLOSE || !icsk->icsk_pending)
		goto out;

	if (time_after(icsk->icsk_timeout, jiffies)) {
		sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout);
		goto out;
	}

	event = icsk->icsk_pending;

	switch (event) {
	case ICSK_TIME_EARLY_RETRANS:
		tcp_resume_early_retransmit(sk);
		break;
	case ICSK_TIME_LOSS_PROBE:
		tcp_send_loss_probe(sk);   // tlp超时
		break;
	case ICSK_TIME_RETRANS:
		icsk->icsk_pending = 0;
		tcp_retransmit_timer(sk);   // 重传的场景
		break;
	case ICSK_TIME_PROBE0:
		icsk->icsk_pending = 0;
		tcp_probe_timer(sk);  // 探测场景
		break;
	}

out:
	sk_mem_reclaim(sk);
}

tcp_probe_timer的调用路径为tcp_send_probe0->tcp_write_wakeup->tcp_transmit_skb,

tcp_check_sack_reneging

如果 ACK 到达指向一个记住的 SACK,这意味着我们的记住的 SACK 不反映接收者的真实状态,即接收器 host严重拥塞(或有故障)

tcp_rcv_fastopen_synack

Fast Open 启用的情况下,SYN 包也会带有数据。这里
调用 tcp_rcv_fastopen_synack函数处理 SYN 包附带的数据。

tcp_retransmit_skb->__tcp_retransmit_skb->tcp_transmit_skb

tcp_xmit_retransmit_queue

这在重传超时后被调用,重传的数据被确认。 它试图重新发送重传队列的其余部分,直到我们已经全部发送或达到拥塞窗口限制。如果做 SACK,第一个超时返回的 ACK基于重传数据包可能会再次向我们提供 FACK 信息。如果是这样,我们使用它来避免不必要的重传。

tcp_keepalive_timer保活定时器场景

tcp_keepalive_timer相关内容

tcp_send_active_reset->tcp_transmit_skb

tcp_rcv_synsent_state_process

如果是接收到了syn之后建立了链接之后,就会检查状态并且查看能否立即发送数据

tcp_rcv_synsent_state_process在接受到数据之后发送。

tcp_send_synack->tcp_transmit_skb

tcp_connect

tcp_connect当建立链接之后尝试发送数据看是否是通过fast open来发送syn带data的数据或者只发送syn报文。

tcp_connect->tcp_transmit_skb

tcp_send_syn_data->tcp_transmit_skb

tcp_ack场景下

发送ack的场景下调用数据发送

tcp_send_ack->tcp_transmit_skb

do_tcp_setsockopt设置tcp连接修复

do_tcp_setsockopt在设置TCP_REPAIR参数场景下

tcp_send_window_probe->tcp_xmit_probe_skb->tcp_transmit_skb

总结

在梳理了调用流程上来说,当前会触发调用的场景里面,在tcp_ack或者超时重传的场景下,会继续发送未经ack的数据,在其他的场景下更多的是发送一些窗口探测等相关的协议数据来完成tcp设计的保活,mtu等探测的功能,由于对tcp/ip协议的理解还不够还未能详细的将每个调用函数的场景细节进行学习。

https://void-star.icu/archives/1005

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值