TCP之系统调用connect()之二

这篇笔记记录connect()系统调用的后半部分,即客户端收到SYN+ACK响应,然后回复ACK的部分。1. 客户端收到SYN+ACK报文发送SYN请求报文后,TCB的状态由TCP_CLOSE迁移到TCP_SYN_SENT,所以在收到接收响应后,将由tcp_rcv_state_process()处理。1.1 tcp_rcv_state_process()/* * This functio...
摘要由CSDN通过智能技术生成

这篇笔记记录connect()系统调用的后半部分,即客户端收到SYN+ACK响应,然后回复ACK的部分。

1. 客户端收到SYN+ACK报文

发送SYN请求报文后,TCB的状态由TCP_CLOSE迁移到TCP_SYN_SENT,所以在收到接收响应后,将由tcp_rcv_state_process()处理。

1.1 tcp_rcv_state_process()

/*
 *	This function implements the receiving procedure of RFC 793 for
 *	all states except ESTABLISHED and TIME_WAIT.
 *	It's called from both tcp_v4_rcv and tcp_v6_rcv and should be
 *	address independent.
 */

int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
			  struct tcphdr *th, unsigned len)
{
   
	struct tcp_sock *tp = tcp_sk(sk);
	struct inet_connection_sock *icsk = inet_csk(sk);
	int queued = 0;

	tp->rx_opt.saw_tstamp = 0;

	switch (sk->sk_state) {
   
	...
	case TCP_SYN_SENT:
		//由tcp_rcv_synsent_state_process()处理输入报文
		queued = tcp_rcv_synsent_state_process(sk, skb, th, len);
		//返回值大于0表示处理失败,这会导致调用者向服务器端发送RST报文
		if (queued >= 0)
			return queued;

		/* Do step6 onward by hand. */
		//处理紧急数据
		tcp_urg(sk, skb, th);
		__kfree_skb(skb);
		//检测是否有数据要发送,对于客户端,三次握手完成,可以继续发送数据
		tcp_data_snd_check(sk);
		return 0;
	}
}

1.2 SYN_SENT状态输入报文处理

@返回1:发送复位报文;
@返回0:处理正常,停止对数据包的后续处理;
@返回-1:处理正常,继续处理紧急数据,并且尝试触发发送逻辑
static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
					 struct tcphdr *th, unsigned len)
{
   
	struct tcp_sock *tp = tcp_sk(sk);
	struct inet_connection_sock *icsk = inet_csk(sk);
	int saved_clamp = tp->rx_opt.mss_clamp;

	//解析TCP选项
	tcp_parse_options(skb, &tp->rx_opt, 0);

	//报文中携带了ACK标记
	if (th->ack) {
   
		/* rfc793:
		 * "If the state is SYN-SENT then
		 *    first check the ACK bit
		 *      If the ACK bit is set
		 *	  If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send
		 *        a reset (unless the RST bit is set, if so drop
		 *        the segment and return)"
		 *
		 *  We do not send data with SYN, so that RFC-correct
		 *  test reduces to:
		 */
		//输入报文不是对SYN报文的确认,会向对端发送RST报文
		if (TCP_SKB_CB(skb)->ack_seq != tp->snd_nxt)
			
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值