Skip to content

Commit 556ed42

Browse files
fmauNekodenji
authored andcommitted
Update patch for NGINX 1.13.0+
1 parent dd7b10a commit 556ed42

File tree

1 file changed

+252
-0
lines changed

1 file changed

+252
-0
lines changed
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
What we do now:
2+
We use a static record size of 4K. This gives a good balance of latency and
3+
throughput.
4+
5+
Optimize latency:
6+
By initialy sending small (1 TCP segment) sized records, we are able to avoid
7+
HoL blocking of the first byte. This means TTFB is sometime lower by a whole
8+
RTT.
9+
10+
Optimizing throughput:
11+
By sending increasingly larger records later in the connection, when HoL is not
12+
a problem, we reduce the overhead of TLS record (29 bytes per record with
13+
GCM/CHACHA-POLY).
14+
15+
Logic:
16+
Start each connection with small records (1369 byte default, change with
17+
ssl_dyn_rec_size_lo). After a given number of records (40, change with
18+
ssl_dyn_rec_threshold) start sending larger records (4229, ssl_dyn_rec_size_hi).
19+
Eventually after the same number of records, start sending the largest records
20+
(ssl_buffer_size).
21+
In case the connection idles for a given amount of time (1s,
22+
ssl_dyn_rec_timeout), the process repeats itself (i.e. begin sending small
23+
records again).
24+
25+
Upstream source:
26+
https://github.com/cloudflare/sslconfig/blob/master/patches/nginx__dynamic_tls_records.patch
27+
28+
--- a/src/event/ngx_event_openssl.c
29+
+++ b/src/event/ngx_event_openssl.c
30+
@@ -1131,6 +1131,7 @@
31+
32+
sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
33+
sc->buffer_size = ssl->buffer_size;
34+
+ sc->dyn_rec = ssl->dyn_rec;
35+
36+
sc->session_ctx = ssl->ctx;
37+
38+
@@ -1669,6 +1670,41 @@
39+
40+
for ( ;; ) {
41+
42+
+ /* Dynamic record resizing:
43+
+ We want the initial records to fit into one TCP segment
44+
+ so we don't get TCP HoL blocking due to TCP Slow Start.
45+
+ A connection always starts with small records, but after
46+
+ a given amount of records sent, we make the records larger
47+
+ to reduce header overhead.
48+
+ After a connection has idled for a given timeout, begin
49+
+ the process from the start. The actual parameters are
50+
+ configurable. If dyn_rec_timeout is 0, we assume dyn_rec is off. */
51+
+
52+
+ if (c->ssl->dyn_rec.timeout > 0 ) {
53+
+
54+
+ if (ngx_current_msec - c->ssl->dyn_rec_last_write >
55+
+ c->ssl->dyn_rec.timeout)
56+
+ {
57+
+ buf->end = buf->start + c->ssl->dyn_rec.size_lo;
58+
+ c->ssl->dyn_rec_records_sent = 0;
59+
+
60+
+ } else {
61+
+ if (c->ssl->dyn_rec_records_sent >
62+
+ c->ssl->dyn_rec.threshold * 2)
63+
+ {
64+
+ buf->end = buf->start + c->ssl->buffer_size;
65+
+
66+
+ } else if (c->ssl->dyn_rec_records_sent >
67+
+ c->ssl->dyn_rec.threshold)
68+
+ {
69+
+ buf->end = buf->start + c->ssl->dyn_rec.size_hi;
70+
+
71+
+ } else {
72+
+ buf->end = buf->start + c->ssl->dyn_rec.size_lo;
73+
+ }
74+
+ }
75+
+ }
76+
+
77+
while (in && buf->last < buf->end && send < limit) {
78+
if (in->buf->last_buf || in->buf->flush) {
79+
flush = 1;
80+
@@ -1770,6 +1806,9 @@
81+
82+
if (n > 0) {
83+
84+
+ c->ssl->dyn_rec_records_sent++;
85+
+ c->ssl->dyn_rec_last_write = ngx_current_msec;
86+
+
87+
if (c->ssl->saved_read_handler) {
88+
89+
c->read->handler = c->ssl->saved_read_handler;
90+
--- a/src/event/ngx_event_openssl.h
91+
+++ b/src/event/ngx_event_openssl.h
92+
@@ -54,10 +54,19 @@
93+
#endif
94+
95+
96+
+typedef struct {
97+
+ ngx_msec_t timeout;
98+
+ ngx_uint_t threshold;
99+
+ size_t size_lo;
100+
+ size_t size_hi;
101+
+} ngx_ssl_dyn_rec_t;
102+
+
103+
+
104+
struct ngx_ssl_s {
105+
SSL_CTX *ctx;
106+
ngx_log_t *log;
107+
size_t buffer_size;
108+
+ ngx_ssl_dyn_rec_t dyn_rec;
109+
};
110+
111+
112+
@@ -80,6 +89,10 @@
113+
unsigned no_wait_shutdown:1;
114+
unsigned no_send_shutdown:1;
115+
unsigned handshake_buffer_set:1;
116+
+
117+
+ ngx_ssl_dyn_rec_t dyn_rec;
118+
+ ngx_msec_t dyn_rec_last_write;
119+
+ ngx_uint_t dyn_rec_records_sent;
120+
};
121+
122+
123+
@@ -89,7 +102,7 @@
124+
#define NGX_SSL_DFLT_BUILTIN_SCACHE -5
125+
126+
127+
-#define NGX_SSL_MAX_SESSION_SIZE 4096
128+
+#define NGX_SSL_MAX_SESSION_SIZE 16384
129+
130+
typedef struct ngx_ssl_sess_id_s ngx_ssl_sess_id_t;
131+
132+
--- a/src/http/modules/ngx_http_ssl_module.c
133+
+++ b/src/http/modules/ngx_http_ssl_module.c
134+
@@ -233,6 +233,41 @@
135+
offsetof(ngx_http_ssl_srv_conf_t, stapling_verify),
136+
NULL },
137+
138+
+ { ngx_string("ssl_dyn_rec_enable"),
139+
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
140+
+ ngx_conf_set_flag_slot,
141+
+ NGX_HTTP_SRV_CONF_OFFSET,
142+
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_enable),
143+
+ NULL },
144+
+
145+
+ { ngx_string("ssl_dyn_rec_timeout"),
146+
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
147+
+ ngx_conf_set_msec_slot,
148+
+ NGX_HTTP_SRV_CONF_OFFSET,
149+
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_timeout),
150+
+ NULL },
151+
+
152+
+ { ngx_string("ssl_dyn_rec_size_lo"),
153+
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
154+
+ ngx_conf_set_size_slot,
155+
+ NGX_HTTP_SRV_CONF_OFFSET,
156+
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_size_lo),
157+
+ NULL },
158+
+
159+
+ { ngx_string("ssl_dyn_rec_size_hi"),
160+
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
161+
+ ngx_conf_set_size_slot,
162+
+ NGX_HTTP_SRV_CONF_OFFSET,
163+
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_size_hi),
164+
+ NULL },
165+
+
166+
+ { ngx_string("ssl_dyn_rec_threshold"),
167+
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
168+
+ ngx_conf_set_num_slot,
169+
+ NGX_HTTP_SRV_CONF_OFFSET,
170+
+ offsetof(ngx_http_ssl_srv_conf_t, dyn_rec_threshold),
171+
+ NULL },
172+
+
173+
ngx_null_command
174+
};
175+
176+
@@ -533,6 +568,11 @@
177+
sscf->session_ticket_keys = NGX_CONF_UNSET_PTR;
178+
sscf->stapling = NGX_CONF_UNSET;
179+
sscf->stapling_verify = NGX_CONF_UNSET;
180+
+ sscf->dyn_rec_enable = NGX_CONF_UNSET;
181+
+ sscf->dyn_rec_timeout = NGX_CONF_UNSET_MSEC;
182+
+ sscf->dyn_rec_size_lo = NGX_CONF_UNSET_SIZE;
183+
+ sscf->dyn_rec_size_hi = NGX_CONF_UNSET_SIZE;
184+
+ sscf->dyn_rec_threshold = NGX_CONF_UNSET_UINT;
185+
186+
return sscf;
187+
}
188+
@@ -598,6 +638,20 @@
189+
ngx_conf_merge_str_value(conf->stapling_responder,
190+
prev->stapling_responder, "");
191+
192+
+ ngx_conf_merge_value(conf->dyn_rec_enable, prev->dyn_rec_enable, 0);
193+
+ ngx_conf_merge_msec_value(conf->dyn_rec_timeout, prev->dyn_rec_timeout,
194+
+ 1000);
195+
+ /* Default sizes for the dynamic record sizes are defined to fit maximal
196+
+ TLS + IPv6 overhead in a single TCP segment for lo and 3 segments for hi:
197+
+ 1369 = 1500 - 40 (IP) - 20 (TCP) - 10 (Time) - 61 (Max TLS overhead) */
198+
+ ngx_conf_merge_size_value(conf->dyn_rec_size_lo, prev->dyn_rec_size_lo,
199+
+ 1369);
200+
+ /* 4229 = (1500 - 40 - 20 - 10) * 3 - 61 */
201+
+ ngx_conf_merge_size_value(conf->dyn_rec_size_hi, prev->dyn_rec_size_hi,
202+
+ 4229);
203+
+ ngx_conf_merge_uint_value(conf->dyn_rec_threshold, prev->dyn_rec_threshold,
204+
+ 40);
205+
+
206+
conf->ssl.log = cf->log;
207+
208+
if (conf->enable) {
209+
@@ -778,6 +832,28 @@
210+
211+
}
212+
213+
+ if (conf->dyn_rec_enable) {
214+
+ conf->ssl.dyn_rec.timeout = conf->dyn_rec_timeout;
215+
+ conf->ssl.dyn_rec.threshold = conf->dyn_rec_threshold;
216+
+
217+
+ if (conf->buffer_size > conf->dyn_rec_size_lo) {
218+
+ conf->ssl.dyn_rec.size_lo = conf->dyn_rec_size_lo;
219+
+
220+
+ } else {
221+
+ conf->ssl.dyn_rec.size_lo = conf->buffer_size;
222+
+ }
223+
+
224+
+ if (conf->buffer_size > conf->dyn_rec_size_hi) {
225+
+ conf->ssl.dyn_rec.size_hi = conf->dyn_rec_size_hi;
226+
+
227+
+ } else {
228+
+ conf->ssl.dyn_rec.size_hi = conf->buffer_size;
229+
+ }
230+
+
231+
+ } else {
232+
+ conf->ssl.dyn_rec.timeout = 0;
233+
+ }
234+
+
235+
return NGX_CONF_OK;
236+
}
237+
238+
--- a/src/http/modules/ngx_http_ssl_module.h
239+
+++ b/src/http/modules/ngx_http_ssl_module.h
240+
@@ -57,6 +57,12 @@
241+
242+
u_char *file;
243+
ngx_uint_t line;
244+
+
245+
+ ngx_flag_t dyn_rec_enable;
246+
+ ngx_msec_t dyn_rec_timeout;
247+
+ size_t dyn_rec_size_lo;
248+
+ size_t dyn_rec_size_hi;
249+
+ ngx_uint_t dyn_rec_threshold;
250+
} ngx_http_ssl_srv_conf_t;
251+
252+

0 commit comments

Comments
 (0)