PAWS 在tcp协议栈中的实现

PAWS 检查:

  1. tcp_timewait_state_process 中使用,也就是在syn 报文明中了 tw 状态的 socket 山海,才使用。 不是所有syn报文都做检查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 91 enum tcp_tw_status
92 tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
93 const struct tcphdr *th)
94 {
95 struct tcp_options_received tmp_opt;
96 struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
97 bool paws_reject = false;
98
99 tmp_opt.saw_tstamp = 0;
100 if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) {
101 tcp_parse_options(skb, &tmp_opt, 0, NULL);
102
103 if (tmp_opt.saw_tstamp) {
104 tmp_opt.rcv_tsecr -= tcptw->tw_ts_offset;
105 tmp_opt.ts_recent = tcptw->tw_ts_recent;
106 tmp_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
107 paws_reject = tcp_paws_reject(&tmp_opt, th->rst);
108 }
109 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1142
1143 static inline bool tcp_paws_check(const struct tcp_options_received *rx_opt,
1144 int paws_win)
1145 {
1146 if ((s32)(rx_opt->ts_recent - rx_opt->rcv_tsval) <= paws_win)
1147 return true;
1148 if (unlikely(get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS))
1149 return true;
1150 /*
1151 * Some OSes send SYN and SYNACK messages with tsval=0 tsecr=0,
1152 * then following tcp messages have valid values. Ignore 0 value,
1153 * or else 'negative' tsval might forbid us to accept their packets.
1154 */
1155 if (!rx_opt->ts_recent)
1156 return true;
1157 return false;
1158 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1160 static inline bool tcp_paws_reject(const struct tcp_options_received *rx_opt,
1161 int rst)
1162 {
1163 if (tcp_paws_check(rx_opt, 0))
1164 return false;
1165
1166 /* RST segments are not recommended to carry timestamp,
1167 and, if they do, it is recommended to ignore PAWS because
1168 "their cleanup function should take precedence over timestamps."
1169 Certainly, it is mistake. It is necessary to understand the reasons
1170 of this constraint to relax it: if peer reboots, clock may go
1171 out-of-sync and half-open connections will not be reset.
1172 Actually, the problem would be not existing if all
1173 the implementations followed draft about maintaining clock
1174 via reboots. Linux-2.2 DOES NOT!
1175
1176 However, we can relax time bounds for RST segments to MSL.
1177 */
1178 if (rst && get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL)
1179 return false;
1180 return true;
1181 }