Chinaunix首页 | 论坛 | 博客
  • 博客访问: 403782
  • 博文数量: 124
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 872
  • 用 户 组: 普通用户
  • 注册时间: 2018-03-29 14:38
个人简介

默默的一块石头

文章分类

全部博文(124)

文章存档

2022年(26)

2021年(10)

2020年(28)

2019年(60)

我的朋友

分类: LINUX

2020-08-31 16:15:39

1.tcp_init_xmit_timers()
void tcp_init_xmit_timers(struct sock *sk)
{
inet_csk_init_xmit_timers(sk, &tcp_write_timer, &tcp_delack_timer,
  &tcp_keepalive_timer);
}

2.tcp_write_timer()
static void tcp_write_timer(unsigned long data)
{
if (!sock_owned_by_user(sk)) {
tcp_write_timer_handler(sk);
}
}

3.tcp_write_timer_handler()
void tcp_write_timer_handler(struct sock *sk)
{
switch (event) {
case ICSK_TIME_LOSS_PROBE:
tcp_send_loss_probe(sk);
break;
case ICSK_TIME_RETRANS:
icsk->icsk_pending = 0;
tcp_retransmit_timer(sk);
break;
}
}

4.tcp_retransmit_timer()
/*
 * The TCP retransmit timer.
 */
void tcp_retransmit_timer(struct sock *sk)
{
tcp_enter_loss(sk, 0);
tcp_retransmit_skb(sk, tcp_write_queue_head(sk));
}

5.tcp_enter_loss()
/* Enter Loss state. If "how" is not zero, forget all SACK information
 * and reset tags completely, otherwise preserve SACKs. If receiver
 * dropped its ofo queue, we will know this due to reneging detection.
 */
void tcp_enter_loss(struct sock *sk, int how)
{
tcp_set_ca_state(sk, TCP_CA_Loss);
}

6.tcp_ack()
/* This routine deals with incoming acks, but not outgoing ones. */
static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
{
tcp_fastretrans_alert(sk, acked, prior_unsacked,is_dupack, flag);
}

7.tcp_fastretrans_alert()
/* Process an event, which can update packets-in-flight not trivially.
 * Main goal of this function is to calculate new estimate for left_out,
 * taking into account both packets sitting in receiver's buffer and
 * packets lost by network.
 *
 * Besides that it does CWND reduction, when packet loss is detected
 * and changes state of machine.
 *
 * It does _not_ decide what to send, it is made in function
 * tcp_xmit_retransmit_queue().
 */
static void tcp_fastretrans_alert(struct sock *sk, const int acked,const int prior_unsacked,
  bool is_dupack, int flag)
{
case TCP_CA_Loss:
tcp_process_loss(sk, flag, is_dupack);
if (icsk->icsk_ca_state != TCP_CA_Open)
return;
}

8.tcp_process_loss()
/* Process an ACK in CA_Loss state. Move to CA_Open if lost data are
 * recovered or spurious. Otherwise retransmits more on partial ACKs.
 */
static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack)
{
tcp_xmit_retransmit_queue(sk);
}

9.tcp_xmit_retransmit_queue()
/* This gets called after a retransmit timeout, and the initially
 * retransmitted data is acknowledged.  It tries to continue
 * resending the rest of the retransmit queue, until either
 * we've sent it all or the congestion window limit is reached.
 * If doing SACK, the first ACK which comes back for a timeout
 * based retransmit packet might feed us FACK information again.
 * If so, we use it to avoid unnecessarily retransmissions.
 */
void tcp_xmit_retransmit_queue(struct sock *sk)
{
tcp_for_write_queue_from(skb, sk) {
if (tcp_retransmit_skb(sk, skb))
    return;
}
}
Note:
1.丢失一组数据,则调用tcp_retransmit_skb传输即可
2.丢失N组数据,则在调用tcp_retransmit_skb重传之后,在成功接收到ack后,又会再进一步传输丢失的数据
3.实验手法:在传输数据时,单纯的断掉客户端以到达超时的目的=-=

阅读(2318) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~