tcp当主动发出syn_TCP主动打开 之 第二次握手-接收SYN+ACK

1 static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,2 const struct tcphdr *th)3 {4 struct inet_connection_sock *icsk =inet_csk(sk);5 struct tcp_sock *tp =tcp_sk(sk);6 struct tcp_fastopen_cookie foc = { .len = -1};7 int saved_clamp = tp->rx_opt.mss_clamp;8 boolfastopen_fail;9

10 /*解析tcp选项*/

11 tcp_parse_options(skb, &tp->rx_opt, 0, &foc);12

13 /*有时间戳,有回显,记录回显*/

14 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)15 tp->rx_opt.rcv_tsecr -= tp->tsoffset;16

17 if (th->ack) {18 /*rfc793:19 * "If the state is SYN-SENT then20 * first check the ACK bit21 * If the ACK bit is set22 * If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send23 * a reset (unless the RST bit is set, if so drop24 * the segment and return)"25 */

26 /*ack <= una || ack > nxt,ack确认序号错误*/

27 if (!after(TCP_SKB_CB(skb)->ack_seq, tp->snd_una) ||

28 after(TCP_SKB_CB(skb)->ack_seq, tp->snd_nxt))29 gotoreset_and_undo;30

31 /*对端时间戳不合法*/

32 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&

33 !between(tp->rx_opt.rcv_tsecr, tp->retrans_stamp,34 tcp_time_stamp)) {35 NET_INC_STATS(sock_net(sk),36 LINUX_MIB_PAWSACTIVEREJECTED);37 gotoreset_and_undo;38 }39

40 /*Now ACK is acceptable.41 *42 * "If the RST bit is set43 * If the ACK was acceptable then signal the user "error:44 * connection reset", drop the segment, enter CLOSED state,45 * delete TCB, and return."46 */

47

48 /*设置了rst标志*/

49 if (th->rst) {50 tcp_reset(sk);51 gotodiscard;52 }53

54 /*rfc793:55 * "fifth, if neither of the SYN or RST bits is set then56 * drop the segment and return."57 *58 * See note below!59 * --ANK(990513)60 */

61 /*未设置syn标志*/

62 if (!th->syn)63 gotodiscard_and_undo;64

65 /*rfc793:66 * "If the SYN bit is on ...67 * are acceptable then ...68 * (our SYN has been ACKed), change the connection69 * state to ESTABLISHED..."70 */

71 /*ecn标记*/

72 tcp_ecn_rcv_synack(tp, th);73

74 /*记录窗口更新时数据包序号*/

75 tcp_init_wl(tp, TCP_SKB_CB(skb)->seq);76

77 //输入ack处理,使用慢速路径,可能会更新发送窗口

78 tcp_ack(sk, skb, FLAG_SLOWPATH);79

80 /*Ok.. it's good. Set up sequence numbers and81 * move to established.82 */

83

84 /*更新下一个要接收的序号*/

85 tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;86 /*更新窗口左边,即窗口中最小的序号*/

87 tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1;88

89 /*RFC1323: The window in SYN & SYN/ACK segments is90 * never scaled.91 */

92 /*获取发送窗口*/

93 tp->snd_wnd = ntohs(th->window);94

95 /*没有窗口扩大因子*/

96 if (!tp->rx_opt.wscale_ok) {97 /*设置为0*/

98 tp->rx_opt.snd_wscale = tp->rx_opt.rcv_wscale = 0;99 /*设置最大值*/

100 tp->window_clamp = min(tp->window_clamp, 65535U);101 }102

103 /*有时间戳选项*/

104 if (tp->rx_opt.saw_tstamp) {105 /*在syn中有时间戳选项*/

106 tp->rx_opt.tstamp_ok = 1;107

108 /*tcp首部需要增加时间戳长度*/

109 tp->tcp_header_len =

110 sizeof(struct tcphdr) +TCPOLEN_TSTAMP_ALIGNED;111

112 /*mss需要减去时间戳长度*/

113 tp->advmss -=TCPOLEN_TSTAMP_ALIGNED;114

115 /*设置回显时间戳*/

116 tcp_store_ts_recent(tp);117 } else{118 /*记录tcp首部长度*/

119 tp->tcp_header_len = sizeof(structtcphdr);120 }121

122 /*有sack选项,开启了fack算法,则打标记*/

123 if (tcp_is_sack(tp) &&sysctl_tcp_fack)124 tcp_enable_fack(tp);125

126 /*MTU探测相关初始化*/

127 tcp_mtup_init(sk);128 /*计算mss*/

129 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);130 /*初始化rcv_mss*/

131 tcp_initialize_rcv_mss(sk);132

133 /*Remember, tcp_poll() does not lock socket!134 * Change state from SYN-SENT only after copied_seq135 * is initialized.*/

136

137 /*记录用户空间待读取的序号*/

138 tp->copied_seq = tp->rcv_nxt;139

140 smp_mb();141

142 /*连接建立完成的状态改变和相关初始化*/

143 tcp_finish_connect(sk, skb);144

145 /*fastopen处理*/

146 fastopen_fail = (tp->syn_fastopen || tp->syn_data) &&

147 tcp_rcv_fastopen_synack(sk, skb, &foc);148

149 /*连接未在关闭态,则进行一些唤醒操作*/

150 if (!sock_flag(sk, SOCK_DEAD)) {151 sk->sk_state_change(sk);152 sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);153 }154 if(fastopen_fail)155 return -1;156

157 /*有写数据请求|| 收包accept || 延迟ack*/

158 if (sk->sk_write_pending ||

159 icsk->icsk_accept_queue.rskq_defer_accept ||

160 icsk->icsk_ack.pingpong) {161 /*Save one ACK. Data will be ready after162 * several ticks, if write_pending is set.163 *164 * It may be deleted, but with this feature tcpdumps165 * look so _wonderfully_ clever, that I was not able166 * to stand against the temptation 8) --ANK167 */

168 /*标志ack调度*/

169 inet_csk_schedule_ack(sk);170 /*进入快速ack模式*/

171 tcp_enter_quickack_mode(sk);172 /*设置延迟ack定时器*/

173 inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,174 TCP_DELACK_MAX, TCP_RTO_MAX);175

176 discard:177 tcp_drop(sk, skb);178 return 0;179 } else{180 /*回复ack*/

181 tcp_send_ack(sk);182 }183 return -1;184 }185

186 /*省略了rst以及syn状态的代码*/

187 }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值