diff options
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r-- | include/net/tcp.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h index 28e9bd3abceb..b81f45c67b2e 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -274,6 +274,7 @@ extern int sysctl_tcp_challenge_ack_limit; | |||
274 | extern unsigned int sysctl_tcp_notsent_lowat; | 274 | extern unsigned int sysctl_tcp_notsent_lowat; |
275 | extern int sysctl_tcp_min_tso_segs; | 275 | extern int sysctl_tcp_min_tso_segs; |
276 | extern int sysctl_tcp_autocorking; | 276 | extern int sysctl_tcp_autocorking; |
277 | extern int sysctl_tcp_invalid_ratelimit; | ||
277 | 278 | ||
278 | extern atomic_long_t tcp_memory_allocated; | 279 | extern atomic_long_t tcp_memory_allocated; |
279 | extern struct percpu_counter tcp_sockets_allocated; | 280 | extern struct percpu_counter tcp_sockets_allocated; |
@@ -1236,6 +1237,37 @@ static inline bool tcp_paws_reject(const struct tcp_options_received *rx_opt, | |||
1236 | return true; | 1237 | return true; |
1237 | } | 1238 | } |
1238 | 1239 | ||
1240 | /* Return true if we're currently rate-limiting out-of-window ACKs and | ||
1241 | * thus shouldn't send a dupack right now. We rate-limit dupacks in | ||
1242 | * response to out-of-window SYNs or ACKs to mitigate ACK loops or DoS | ||
1243 | * attacks that send repeated SYNs or ACKs for the same connection. To | ||
1244 | * do this, we do not send a duplicate SYNACK or ACK if the remote | ||
1245 | * endpoint is sending out-of-window SYNs or pure ACKs at a high rate. | ||
1246 | */ | ||
1247 | static inline bool tcp_oow_rate_limited(struct net *net, | ||
1248 | const struct sk_buff *skb, | ||
1249 | int mib_idx, u32 *last_oow_ack_time) | ||
1250 | { | ||
1251 | /* Data packets without SYNs are not likely part of an ACK loop. */ | ||
1252 | if ((TCP_SKB_CB(skb)->seq != TCP_SKB_CB(skb)->end_seq) && | ||
1253 | !tcp_hdr(skb)->syn) | ||
1254 | goto not_rate_limited; | ||
1255 | |||
1256 | if (*last_oow_ack_time) { | ||
1257 | s32 elapsed = (s32)(tcp_time_stamp - *last_oow_ack_time); | ||
1258 | |||
1259 | if (0 <= elapsed && elapsed < sysctl_tcp_invalid_ratelimit) { | ||
1260 | NET_INC_STATS_BH(net, mib_idx); | ||
1261 | return true; /* rate-limited: don't send yet! */ | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | *last_oow_ack_time = tcp_time_stamp; | ||
1266 | |||
1267 | not_rate_limited: | ||
1268 | return false; /* not rate-limited: go ahead, send dupack now! */ | ||
1269 | } | ||
1270 | |||
1239 | static inline void tcp_mib_init(struct net *net) | 1271 | static inline void tcp_mib_init(struct net *net) |
1240 | { | 1272 | { |
1241 | /* See RFC 2012 */ | 1273 | /* See RFC 2012 */ |