summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_syncache.h
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2013-07-11 15:29:25 +0000
committerandre <andre@FreeBSD.org>2013-07-11 15:29:25 +0000
commitfc2be30b217171175bae209edb4f697cc0cb542d (patch)
tree3f97c14caf5a4975b54bcc14baf86641ede6647f /sys/netinet/tcp_syncache.h
parentae0660c3545b5992aebd66823f9277eda546c0b9 (diff)
downloadFreeBSD-src-fc2be30b217171175bae209edb4f697cc0cb542d.zip
FreeBSD-src-fc2be30b217171175bae209edb4f697cc0cb542d.tar.gz
Improve SYN cookies by encoding the MSS, WSCALE (window scaling) and SACK
information into the ISN (initial sequence number) without the additional use of timestamp bits and switching to the very fast and cryptographically strong SipHash-2-4 MAC hash algorithm to protect the SYN cookie against forgeries. The purpose of SYN cookies is to encode all necessary session state in the 32 bits of our initial sequence number to avoid storing any information locally in memory. This is especially important when under heavy spoofed SYN attacks where we would either run out of memory or the syncache would fill with bogus connection attempts swamping out legitimate connections. The original SYN cookies method only stored an indexed MSS values in the cookie. This isn't sufficient anymore and breaks down in the presence of WSCALE information which is only exchanged during SYN and SYN-ACK. If we can't keep track of it then we may severely underestimate the available send or receive window. This is compounded with large windows whose size information on the TCP segment header is even lower numerically. A number of years back SYN cookies were extended to store the additional state in the TCP timestamp fields, if available on a connection. While timestamps are common among the BSD, Linux and other *nix systems Windows never enabled them by default and thus are not present for the vast majority of clients seen on the Internet. The common parameters used on TCP sessions have changed quite a bit since SYN cookies very invented some 17 years ago. Today we have a lot more bandwidth available making the use window scaling almost mandatory. Also SACK has become standard making recovering from packet loss much more efficient. This change moves all necessary information into the ISS removing the need for timestamps. Both the MSS (16 bits) and send WSCALE (4 bits) are stored in 3 bit indexed form together with a single bit for SACK. While this is significantly less than the original range, it is sufficient to encode all common values with minimal rounding. The MSS depends on the MTU of the path and with the dominance of ethernet the main value seen is around 1460 bytes. Encapsulations for DSL lines and some other overheads reduce it by a few more bytes for many connections seen. Rounding down to the next lower value in some cases isn't a problem as we send only slightly more packets for the same amount of data. The send WSCALE index is bit more tricky as rounding down under-estimates the available send space available towards the remote host, however a small number values dominate and are carefully selected again. The receive WSCALE isn't encoded at all but recalculated based on the local receive socket buffer size when a valid SYN cookie returns. A listen socket buffer size is unlikely to change while active. The index values for MSS and WSCALE are selected for minimal rounding errors based on large traffic surveys. These values have to be periodically validated against newer traffic surveys adjusting the arrays tcp_sc_msstab[] and tcp_sc_wstab[] if necessary. In addition the hash MAC to protect the SYN cookies is changed from MD5 to SipHash-2-4, a much faster and cryptographically secure algorithm. Reviewed by: dwmalone Tested by: Fabian Keil <fk@fabiankeil.de>
Diffstat (limited to 'sys/netinet/tcp_syncache.h')
-rw-r--r--sys/netinet/tcp_syncache.h32
1 files changed, 24 insertions, 8 deletions
diff --git a/sys/netinet/tcp_syncache.h b/sys/netinet/tcp_syncache.h
index 1ff8a46..2e99c3c 100644
--- a/sys/netinet/tcp_syncache.h
+++ b/sys/netinet/tcp_syncache.h
@@ -90,20 +90,23 @@ struct syncache {
#define SCF_SACK 0x80 /* send SACK option */
#define SCF_ECN 0x100 /* send ECN setup packet */
-#define SYNCOOKIE_SECRET_SIZE 8 /* dwords */
-#define SYNCOOKIE_LIFETIME 16 /* seconds */
-
struct syncache_head {
- struct vnet *sch_vnet;
struct mtx sch_mtx;
TAILQ_HEAD(sch_head, syncache) sch_bucket;
struct callout sch_timer;
int sch_nextc;
u_int sch_length;
- u_int sch_oddeven;
- u_int32_t sch_secbits_odd[SYNCOOKIE_SECRET_SIZE];
- u_int32_t sch_secbits_even[SYNCOOKIE_SECRET_SIZE];
- u_int sch_reseed; /* time_uptime, seconds */
+ struct tcp_syncache *sch_sc;
+};
+
+#define SYNCOOKIE_SECRET_SIZE 16
+#define SYNCOOKIE_LIFETIME 15 /* seconds */
+
+struct syncookie_secret {
+ volatile u_int oddeven;
+ uint8_t key[2][SYNCOOKIE_SECRET_SIZE];
+ struct callout reseed;
+ u_int lifetime;
};
struct tcp_syncache {
@@ -115,6 +118,19 @@ struct tcp_syncache {
u_int cache_limit;
u_int rexmt_limit;
u_int hash_secret;
+ struct vnet *sch_vnet;
+ struct syncookie_secret secret;
+};
+
+/* Internal use for the syncookie functions. */
+union syncookie {
+ uint8_t cookie;
+ struct {
+ uint8_t odd_even:1,
+ sack_ok:1,
+ wscale_idx:3,
+ mss_idx:3;
+ } flags;
};
#endif /* _KERNEL */
OpenPOWER on IntegriCloud