summaryrefslogtreecommitdiff
path: root/include/internal/bio_tfo.h
blob: 729e5b833dcf73a02d50a6f621c7086ce31a4727 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * Contains definitions for simplifying the use of TCP Fast Open
 * (RFC7413) in OpenSSL socket BIOs.
 */

/* If a supported OS is added here, update test/bio_tfo_test.c */
#if defined(TCP_FASTOPEN) && !defined(OPENSSL_NO_TFO)

# if defined(OPENSSL_SYS_MACOSX) || defined(__FreeBSD__)
#  include <sys/sysctl.h>
# endif

/*
 * OSSL_TFO_SYSCTL is used to determine if TFO is supported by
 * this kernel, and if supported, if it is enabled. This is more of
 * a problem on FreeBSD 10.3 ~ 11.4, where TCP_FASTOPEN was defined,
 * but not enabled by default in the kernel, and only for the server.
 * Linux does not have sysctlbyname(), and the closest equivalent
 * is to go into the /proc filesystem, but I'm not sure it's
 * worthwhile.
 *
 * On MacOS and Linux:
 * These operating systems use a single parameter to control TFO.
 * The OSSL_TFO_CLIENT_FLAG and OSSL_TFO_SERVER_FLAGS are used to
 * determine if TFO is enabled for the client and server respectively.
 *
 * OSSL_TFO_CLIENT_FLAG = 1 = client TFO enabled
 * OSSL_TFO_SERVER_FLAG = 2 = server TFO enabled
 *
 * Such that:
 * 0 = TFO disabled
 * 3 = server and client TFO enabled
 *
 * macOS 10.14 and later support TFO.
 * Linux kernel 3.6 added support for client TFO.
 * Linux kernel 3.7 added support for server TFO.
 * Linux kernel 3.13 enabled TFO by default.
 * Linux kernel 4.11 added the TCP_FASTOPEN_CONNECT option.
 *
 * On FreeBSD:
 * FreeBSD 10.3 ~ 11.4 uses a single sysctl for server enable.
 * FreeBSD 12.0 and later uses separate sysctls for server and
 * client enable.
 *
 * Some options are purposely NOT defined per-platform
 *
 * OSSL_TFO_SYSCTL
 *     Defined as a sysctlbyname() option to to determine if
 *     TFO is enabled in the kernel (macOS, FreeBSD)
 *
 * OSSL_TFO_SERVER_SOCKOPT
 *     Defined to indicate the socket option used to enable
 *     TFO on a server socket (all)
 *
 * OSSL_TFO_SERVER_SOCKOPT_VALUE
 *     Value to be used with OSSL_TFO_SERVER_SOCKOPT
 *
 * OSSL_TFO_CONNECTX
 *     Use the connectx() function to make a client connection
 *     (macOS)
 *
 * OSSL_TFO_CLIENT_SOCKOPT
 *     Defined to indicate the socket option used to enable
 *     TFO on a client socket (FreeBSD, Linux 4.14 and later)
 *
 * OSSL_TFO_SENDTO
 *     Defined to indicate the sendto() message type to
 *     be used to initiate a TFO connection (FreeBSD,
 *     Linux pre-4.14)
 *
 * OSSL_TFO_DO_NOT_CONNECT
 *     Defined to skip calling conect() when creating a
 *     client socket (macOS, FreeBSD, Linux pre-4.14)
 */

# if defined(OPENSSL_SYS_WINDOWS)
/*
 * NO WINDOWS SUPPORT
 *
 * But this is is what would be used on the server:
 *
 * define OSSL_TFO_SERVER_SOCKOPT       TCP_FASTOPEN
 * define OSSL_TFO_SERVER_SOCKOPT_VALUE 1
 *
 * Still have to figure out client support
 */
#  undef TCP_FASTOPEN
# endif

/* NO VMS SUPPORT */
# if defined(OPENSSL_SYS_VMS)
#  undef TCP_FASTOPEN
# endif

# if defined(OPENSSL_SYS_MACOSX)
#  define OSSL_TFO_SYSCTL               "net.inet.tcp.fastopen"
#  define OSSL_TFO_SERVER_SOCKOPT       TCP_FASTOPEN
#  define OSSL_TFO_SERVER_SOCKOPT_VALUE 1
#  define OSSL_TFO_CONNECTX             1
#  define OSSL_TFO_DO_NOT_CONNECT       1
#  define OSSL_TFO_CLIENT_FLAG          1
#  define OSSL_TFO_SERVER_FLAG          2
# endif

# if defined(__FreeBSD__)
#  if defined(TCP_FASTOPEN_PSK_LEN)
/* As of 12.0 these are the SYSCTLs */
#   define OSSL_TFO_SYSCTL_SERVER        "net.inet.tcp.fastopen.server_enable"
#   define OSSL_TFO_SYSCTL_CLIENT        "net.inet.tcp.fastopen.client_enable"
#   define OSSL_TFO_SERVER_SOCKOPT       TCP_FASTOPEN
#   define OSSL_TFO_SERVER_SOCKOPT_VALUE MAX_LISTEN
#   define OSSL_TFO_CLIENT_SOCKOPT       TCP_FASTOPEN
#   define OSSL_TFO_DO_NOT_CONNECT       1
#   define OSSL_TFO_SENDTO               0
/* These are the same because the sysctl are client/server-specific */
#   define OSSL_TFO_CLIENT_FLAG          1
#   define OSSL_TFO_SERVER_FLAG          1
#  else
/* 10.3 through 11.4 SYSCTL - ONLY SERVER SUPPORT */
#   define OSSL_TFO_SYSCTL               "net.inet.tcp.fastopen.enabled"
#   define OSSL_TFO_SERVER_SOCKOPT       TCP_FASTOPEN
#   define OSSL_TFO_SERVER_SOCKOPT_VALUE MAX_LISTEN
#   define OSSL_TFO_SERVER_FLAG          1
#  endif
# endif

# if defined(OPENSSL_SYS_LINUX)
/* OSSL_TFO_PROC not used, but of interest */
#  define OSSL_TFO_PROC                 "/proc/sys/net/ipv4/tcp_fastopen"
#  define OSSL_TFO_SERVER_SOCKOPT       TCP_FASTOPEN
#  define OSSL_TFO_SERVER_SOCKOPT_VALUE MAX_LISTEN
#  if defined(TCP_FASTOPEN_CONNECT)
#   define OSSL_TFO_CLIENT_SOCKOPT      TCP_FASTOPEN_CONNECT
#  else
#   define OSSL_TFO_SENDTO              MSG_FASTOPEN
#   define OSSL_TFO_DO_NOT_CONNECT      1
#  endif
#  define OSSL_TFO_CLIENT_FLAG          1
#  define OSSL_TFO_SERVER_FLAG          2
# endif

#endif