Coverage Report

Created: 2026-09-13 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/h2o/lib/common/socket.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2015 DeNA Co., Ltd., Kazuho Oku, Justin Zhu
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to
6
 * deal in the Software without restriction, including without limitation the
7
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
 * sell copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
 * IN THE SOFTWARE.
21
 */
22
#include <errno.h>
23
#include <fcntl.h>
24
#include <inttypes.h>
25
#include <limits.h>
26
#include <netdb.h>
27
#include <netinet/in.h>
28
#include <netinet/tcp.h>
29
#include <string.h>
30
#include <sys/syscall.h>
31
#include <sys/un.h>
32
#include <unistd.h>
33
#include <openssl/err.h>
34
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
35
#include <sys/ioctl.h>
36
#endif
37
#include "picotls.h"
38
#if H2O_USE_FUSION
39
#include "picotls/fusion.h"
40
#endif
41
#include "quicly.h"
42
#include "h2o/socket.h"
43
#include "h2o/multithread.h"
44
#include "../probes_.h"
45
46
#if defined(__APPLE__) && defined(__clang__)
47
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
48
#endif
49
50
#ifndef IOV_MAX
51
#define IOV_MAX UIO_MAXIOV
52
#endif
53
54
/* kernel-headers bundled with Ubuntu 14.04 does not have the constant defined in netinet/tcp.h */
55
#if defined(__linux__) && !defined(TCP_NOTSENT_LOWAT)
56
#define TCP_NOTSENT_LOWAT 25
57
#endif
58
59
#define OPENSSL_HOSTNAME_VALIDATION_LINKAGE static
60
#pragma GCC diagnostic push
61
#pragma GCC diagnostic ignored "-Wpragmas"
62
#pragma GCC diagnostic ignored "-Wshorten-64-to-32"
63
#include "../../deps/ssl-conservatory/openssl/openssl_hostname_validation.c"
64
#pragma GCC diagnostic pop
65
66
#define SOCKET_PROBE(label, sock, ...) H2O_PROBE(SOCKET_##label, sock, __VA_ARGS__)
67
68
struct st_h2o_socket_ssl_t {
69
    SSL_CTX *ssl_ctx;
70
    SSL *ossl;
71
    ptls_t *ptls;
72
    enum {
73
        H2O_SOCKET_SSL_OFFLOAD_NONE,
74
        H2O_SOCKET_SSL_OFFLOAD_ON,
75
        H2O_SOCKET_SSL_OFFLOAD_TBD,
76
    } offload;
77
    int *did_write_in_read; /* used for detecting and closing the connection upon renegotiation (FIXME implement renegotiation) */
78
    size_t record_overhead;
79
    struct {
80
        uint64_t send_finished_iv; /* UINT64_MAX if not available */
81
        struct {
82
            uint8_t type;
83
            uint16_t length;
84
        } last_received[2];
85
    } tls12_record_layer;
86
    struct {
87
        h2o_socket_cb cb;
88
        union {
89
            struct {
90
                struct {
91
                    enum {
92
                        ASYNC_RESUMPTION_STATE_COMPLETE = 0, /* just pass thru */
93
                        ASYNC_RESUMPTION_STATE_RECORD,       /* record first input, restore SSL state if it changes to REQUEST_SENT
94
                                                              */
95
                        ASYNC_RESUMPTION_STATE_REQUEST_SENT  /* async request has been sent, and is waiting for response */
96
                    } state;
97
                    SSL_SESSION *session_data;
98
                } async_resumption;
99
            } server;
100
            struct {
101
                char *server_name;
102
                h2o_cache_t *session_cache;
103
                h2o_iovec_t session_cache_key;
104
                h2o_cache_hashcode_t session_cache_key_hash;
105
            } client;
106
        };
107
    } handshake;
108
    struct {
109
        h2o_buffer_t *encrypted;
110
    } input;
111
    /**
112
     * Pending TLS data to be sent.
113
     */
114
    struct {
115
        /**
116
         * This buffer is initialized when and only when pending data is stored. Otherwise, all the members are zero-cleared; see
117
         * `has_pending_ssl_data`.
118
         * To reduce the cost of repeated memory allocation, expansion, and release, this buffer points to a chunk of memory being
119
         * allocated from `h2o_socket_ssl_buffer_allocator` when initialized. Upon disposal, the memory chunk being used by this
120
         * buffer is returned to that memory pool, unless the chunk has been expanded. It is designed as such because sometimes it
121
         * is hard to limit the amount of TLS records being generated at once (who knows how large the server's handshake messages
122
         * will be, or when it has to send a KeyUpdate message?). But for most of the case, handshake messages will be smaller than
123
         * the default size (H2O_SOCKET_DEFAULT_SSL_BUFFER_SIZE), and application traffic will not cause expansion (see
124
         * * `generate_tls_records`). Therefore, the memory chunk will be recycled.
125
         */
126
        ptls_buffer_t buf;
127
        size_t pending_off;
128
        unsigned zerocopy_owned : 1;
129
        unsigned allocated_for_zerocopy : 1;
130
    } output;
131
    struct {
132
        unsigned inflight : 1;
133
        unsigned sock_is_closed : 1;
134
        ptls_buffer_t ptls_wbuf;
135
    } async;
136
};
137
138
struct st_h2o_ssl_context_t {
139
    SSL_CTX *ctx;
140
    const h2o_iovec_t *protocols;
141
    h2o_iovec_t _npn_list_of_protocols;
142
};
143
144
/**
145
 * Holds list of buffers to be retain until notified by the kernel.
146
 */
147
struct st_h2o_socket_zerocopy_buffers_t {
148
    void **bufs;
149
    size_t first, last, capacity;
150
    uint64_t first_counter;
151
};
152
153
/* backend functions */
154
static void init_write_buf(h2o_socket_t *sock, h2o_iovec_t *bufs, size_t bufcnt, size_t first_buf_written);
155
static void dispose_write_buf(h2o_socket_t *sock);
156
static void dispose_ssl_output_buffer(struct st_h2o_socket_ssl_t *ssl);
157
static int has_pending_ssl_bytes(struct st_h2o_socket_ssl_t *ssl);
158
static size_t generate_tls_records(h2o_socket_t *sock, h2o_iovec_t **bufs, size_t *bufcnt, size_t first_buf_written);
159
static void do_dispose_socket(h2o_socket_t *sock);
160
static void report_early_write_error(h2o_socket_t *sock);
161
static void do_write(h2o_socket_t *sock, h2o_iovec_t *bufs, size_t bufcnt);
162
static void do_read_start(h2o_socket_t *sock);
163
static void do_read_stop(h2o_socket_t *sock);
164
static int do_export(h2o_socket_t *_sock, h2o_socket_export_t *info);
165
static h2o_socket_t *do_import(h2o_loop_t *loop, h2o_socket_export_t *info);
166
static socklen_t get_peername_uncached(h2o_socket_t *sock, struct sockaddr *sa);
167
static socklen_t get_sockname_uncached(h2o_socket_t *sock, struct sockaddr *sa);
168
static int zerocopy_buffers_is_empty(struct st_h2o_socket_zerocopy_buffers_t *buffers);
169
static void zerocopy_buffers_dispose(struct st_h2o_socket_zerocopy_buffers_t *buffers);
170
static void zerocopy_buffers_push(struct st_h2o_socket_zerocopy_buffers_t *buffers, void *p);
171
static void *zerocopy_buffers_release(struct st_h2o_socket_zerocopy_buffers_t *buffers, uint64_t counter);
172
173
/* internal functions called from the backend */
174
static const char *decode_ssl_input(h2o_socket_t *sock);
175
static size_t flatten_sendvec(h2o_socket_t *sock, h2o_sendvec_t *sendvec);
176
static void on_write_complete(h2o_socket_t *sock, const char *err);
177
178
h2o_buffer_mmap_settings_t h2o_socket_buffer_mmap_settings = {
179
    32 * 1024 * 1024, /* 32MB, should better be greater than max frame size of HTTP2 for performance reasons */
180
    "/tmp/h2o.b.XXXXXX"};
181
182
h2o_buffer_prototype_t h2o_socket_buffer_prototype = {
183
    {H2O_SOCKET_INITIAL_INPUT_BUFFER_SIZE}, /* minimum initial capacity; actual initial size is ~8KB, see h2o_buffer_reserve */
184
    &h2o_socket_buffer_mmap_settings};
185
186
h2o_mem_recycle_conf_t h2o_socket_ssl_buffer_conf = {.memsize = H2O_SOCKET_DEFAULT_SSL_BUFFER_SIZE,
187
                                                     .align_bits =
188
#ifdef H2O_USE_FUSION
189
                                                         PTLS_X86_CACHE_LINE_ALIGN_BITS
190
#else
191
                                                         0
192
#endif
193
};
194
__thread h2o_mem_recycle_t h2o_socket_ssl_buffer_allocator = {&h2o_socket_ssl_buffer_conf};
195
__thread h2o_mem_recycle_t h2o_socket_zerocopy_buffer_allocator = {&h2o_socket_ssl_buffer_conf};
196
__thread size_t h2o_socket_num_zerocopy_buffers_inflight;
197
198
int h2o_socket_use_ktls = 0;
199
200
const char h2o_socket_error_out_of_memory[] = "out of memory";
201
const char h2o_socket_error_io[] = "I/O error";
202
const char h2o_socket_error_closed[] = "socket closed by peer";
203
const char h2o_socket_error_conn_fail[] = "connection failure";
204
const char h2o_socket_error_conn_refused[] = "connection refused";
205
const char h2o_socket_error_conn_timed_out[] = "connection timed out";
206
const char h2o_socket_error_network_unreachable[] = "network unreachable";
207
const char h2o_socket_error_host_unreachable[] = "host unreachable";
208
const char h2o_socket_error_socket_fail[] = "socket creation failed";
209
const char h2o_socket_error_ssl_no_cert[] = "no certificate";
210
const char h2o_socket_error_ssl_cert_invalid[] = "invalid certificate";
211
const char h2o_socket_error_ssl_cert_name_mismatch[] = "certificate name mismatch";
212
const char h2o_socket_error_ssl_decode[] = "SSL decode error";
213
const char h2o_socket_error_ssl_handshake[] = "ssl handshake failure";
214
const char h2o_socket_error_write_progress[] = "write progress";
215
216
static void (*resumption_get_async)(h2o_socket_t *sock, h2o_iovec_t session_id);
217
static void (*resumption_new)(h2o_socket_t *sock, h2o_iovec_t session_id, h2o_iovec_t session_data);
218
219
#if H2O_USE_LIBUV
220
#include "socket/uv-binding.c.h"
221
#else
222
#include "socket/evloop.c.h"
223
#endif
224
225
static int read_bio(BIO *b, char *out, int len)
226
0
{
227
0
    h2o_socket_t *sock = BIO_get_data(b);
228
229
0
    if (len == 0)
230
0
        return 0;
231
232
0
    if (sock->ssl->input.encrypted->size == 0) {
233
0
        BIO_set_retry_read(b);
234
0
        return -1;
235
0
    }
236
237
0
    if (len == 5 && sock->ssl->input.encrypted->size >= 5) {
238
0
        sock->ssl->tls12_record_layer.last_received[1] = sock->ssl->tls12_record_layer.last_received[0];
239
0
        sock->ssl->tls12_record_layer.last_received[0].type = sock->ssl->input.encrypted->bytes[0];
240
0
        sock->ssl->tls12_record_layer.last_received[0].length =
241
0
            ((sock->ssl->input.encrypted->bytes[3] & 0xff) << 8) | (sock->ssl->input.encrypted->bytes[4] & 0xff);
242
0
    }
243
244
0
    if (sock->ssl->input.encrypted->size < len) {
245
0
        len = (int)sock->ssl->input.encrypted->size;
246
0
    }
247
0
    memcpy(out, sock->ssl->input.encrypted->bytes, len);
248
0
    h2o_buffer_consume(&sock->ssl->input.encrypted, len);
249
250
0
    return len;
251
0
}
252
253
static void init_write_buf(h2o_socket_t *sock, h2o_iovec_t *bufs, size_t bufcnt, size_t first_buf_written)
254
0
{
255
    /* Use smallbufs or allocate slots. An additional slot is reserved at the end so that sendvec can be flattened there for
256
     * encryption. */
257
0
    if (bufcnt < PTLS_ELEMENTSOF(sock->_write_buf.smallbufs)) {
258
0
        sock->_write_buf.bufs = sock->_write_buf.smallbufs;
259
0
    } else {
260
0
        sock->_write_buf.bufs = h2o_mem_alloc(sizeof(sock->_write_buf.bufs[0]) * (bufcnt + 1));
261
0
        sock->_write_buf.alloced_ptr = sock->_write_buf.bufs;
262
0
    }
263
264
    /* Initialize the vector. */
265
0
    if (bufcnt != 0) {
266
0
        sock->_write_buf.bufs[0].base = bufs[0].base + first_buf_written;
267
0
        sock->_write_buf.bufs[0].len = bufs[0].len - first_buf_written;
268
0
        for (size_t i = 1; i < bufcnt; ++i)
269
0
            sock->_write_buf.bufs[i] = bufs[i];
270
0
    }
271
0
    sock->_write_buf.cnt = bufcnt;
272
0
}
273
274
static void dispose_write_buf(h2o_socket_t *sock)
275
19.3k
{
276
19.3k
    if (sock->_write_buf.smallbufs <= sock->_write_buf.bufs &&
277
610
        sock->_write_buf.bufs <=
278
610
            sock->_write_buf.smallbufs + sizeof(sock->_write_buf.smallbufs) / sizeof(sock->_write_buf.smallbufs[0])) {
279
        /* no need to free */
280
18.6k
    } else {
281
18.6k
        free(sock->_write_buf.alloced_ptr);
282
18.6k
        sock->_write_buf.bufs = sock->_write_buf.smallbufs;
283
18.6k
    }
284
285
19.3k
    if (sock->_write_buf.flattened != NULL) {
286
0
        h2o_mem_free_recycle(&h2o_socket_ssl_buffer_allocator, sock->_write_buf.flattened);
287
0
        sock->_write_buf.flattened = NULL;
288
0
    }
289
19.3k
}
290
291
static void init_ssl_output_buffer(struct st_h2o_socket_ssl_t *ssl, int zerocopy)
292
0
{
293
0
    h2o_mem_recycle_t *allocator = zerocopy ? &h2o_socket_zerocopy_buffer_allocator : &h2o_socket_ssl_buffer_allocator;
294
0
    ptls_buffer_init(&ssl->output.buf, h2o_mem_alloc_recycle(allocator), allocator->conf->memsize);
295
0
    ssl->output.buf.is_allocated = 1; /* set to true, so that the allocated memory is freed when the buffer is expanded */
296
0
    ssl->output.buf.align_bits = allocator->conf->align_bits;
297
0
    ssl->output.pending_off = 0;
298
0
    ssl->output.zerocopy_owned = 0;
299
0
    ssl->output.allocated_for_zerocopy = zerocopy;
300
0
}
301
302
static void dispose_ssl_output_buffer(struct st_h2o_socket_ssl_t *ssl)
303
0
{
304
    /* The destruction logic that we have here are different from `ptls_buffer_dispose` in following two aspects:
305
     * - returns the allocated memory to the pool if possible
306
     * - does not zero-clear the memory (there's no need to, because the content is something to be sent in clear) */
307
308
0
    assert(ssl->output.buf.is_allocated);
309
310
0
    if (!ssl->output.zerocopy_owned) {
311
0
        h2o_mem_recycle_t *allocator =
312
0
            ssl->output.allocated_for_zerocopy ? &h2o_socket_zerocopy_buffer_allocator : &h2o_socket_ssl_buffer_allocator;
313
0
        if (ssl->output.buf.capacity == allocator->conf->memsize) {
314
0
            h2o_mem_free_recycle(allocator, ssl->output.buf.base);
315
0
        } else {
316
0
            free(ssl->output.buf.base);
317
0
        }
318
0
    }
319
0
    ssl->output.buf = (ptls_buffer_t){};
320
0
    ssl->output.pending_off = 0;
321
0
    ssl->output.zerocopy_owned = 0;
322
0
}
323
324
static int has_pending_ssl_bytes(struct st_h2o_socket_ssl_t *ssl)
325
92.2k
{
326
    /* for convenience, this function can be invoked for non-TLS connections too, in which case ssl will be NULL */
327
92.2k
    if (ssl == NULL)
328
92.2k
        return 0;
329
330
    /* the contract is that `dispose_ssl_output_buffer` is called immediately when all the data are written out */
331
0
    return ssl->output.buf.base != NULL;
332
92.2k
}
333
334
static void write_ssl_bytes(h2o_socket_t *sock, const void *in, size_t len)
335
0
{
336
0
    if (len != 0) {
337
0
        if (!has_pending_ssl_bytes(sock->ssl))
338
0
            init_ssl_output_buffer(sock->ssl, sock->_zerocopy != NULL);
339
0
        if (ptls_buffer_reserve(&sock->ssl->output.buf, len) != 0)
340
0
            h2o_fatal("no memory; tried to allocate %zu bytes", len);
341
0
        memcpy(sock->ssl->output.buf.base + sock->ssl->output.buf.off, in, len);
342
0
        sock->ssl->output.buf.off += len;
343
0
    }
344
0
}
345
346
static int write_bio(BIO *b, const char *in, int len)
347
0
{
348
0
    h2o_socket_t *sock = BIO_get_data(b);
349
350
    /* FIXME no support for SSL renegotiation (yet) */
351
0
    if (sock->ssl->did_write_in_read != NULL) {
352
0
        *sock->ssl->did_write_in_read = 1;
353
0
        return -1;
354
0
    }
355
356
    /* Record bytes where the explicit IV will exist within a TLS 1.2 Finished message. When migrating the connection to picotls,
357
     * Finished is going to be the last and the only encrypted record being sent by OpenSSL. We record that explicit IV and picotls
358
     * starts with that explicit IV incremented by 1. */
359
0
    if (len >= 45 && memcmp(in + len - 45, H2O_STRLIT("\x16\x03\x03\x00\x28")) == 0) {
360
0
        const uint8_t *p = (const uint8_t *)in + len - 40;
361
0
        sock->ssl->tls12_record_layer.send_finished_iv = quicly_decode64(&p);
362
0
    } else {
363
0
        sock->ssl->tls12_record_layer.send_finished_iv = UINT64_MAX;
364
0
    }
365
366
0
    write_ssl_bytes(sock, in, len);
367
0
    return len;
368
0
}
369
370
static int puts_bio(BIO *b, const char *str)
371
0
{
372
0
    return write_bio(b, str, (int)strlen(str));
373
0
}
374
375
static long ctrl_bio(BIO *b, int cmd, long num, void *ptr)
376
0
{
377
0
    switch (cmd) {
378
0
    case BIO_CTRL_GET_CLOSE:
379
0
        return BIO_get_shutdown(b);
380
0
    case BIO_CTRL_SET_CLOSE:
381
0
        BIO_set_shutdown(b, (int)num);
382
0
        return 1;
383
0
    case BIO_CTRL_FLUSH:
384
0
        return 1;
385
0
    default:
386
0
        return 0;
387
0
    }
388
0
}
389
390
static void setup_bio(h2o_socket_t *sock)
391
0
{
392
0
    static BIO_METHOD *volatile bio_methods = NULL;
393
0
    H2O_MULTITHREAD_ONCE({
394
0
        bio_methods = BIO_meth_new(BIO_TYPE_FD, "h2o_socket");
395
0
        BIO_meth_set_write(bio_methods, write_bio);
396
0
        BIO_meth_set_read(bio_methods, read_bio);
397
0
        BIO_meth_set_puts(bio_methods, puts_bio);
398
0
        BIO_meth_set_ctrl(bio_methods, ctrl_bio);
399
0
    });
400
401
0
    BIO *bio = BIO_new(bio_methods);
402
0
    if (bio == NULL)
403
0
        h2o_fatal("no memory");
404
0
    BIO_set_data(bio, sock);
405
0
    BIO_set_init(bio, 1);
406
0
    SSL_set_bio(sock->ssl->ossl, bio, bio);
407
0
}
408
409
const char *decode_ssl_input(h2o_socket_t *sock)
410
0
{
411
0
    assert(sock->ssl != NULL);
412
0
    assert(sock->ssl->handshake.cb == NULL);
413
414
0
    if (sock->ssl->ptls != NULL) {
415
0
        if (sock->ssl->input.encrypted->size != 0) {
416
0
            const char *src = sock->ssl->input.encrypted->bytes, *src_end = src + sock->ssl->input.encrypted->size;
417
0
            h2o_iovec_t reserved;
418
0
            ptls_buffer_t rbuf;
419
0
            int ret;
420
0
            if ((reserved = h2o_buffer_try_reserve(&sock->input, sock->ssl->input.encrypted->size)).base == NULL)
421
0
                return h2o_socket_error_out_of_memory;
422
0
            ptls_buffer_init(&rbuf, reserved.base, reserved.len);
423
0
            do {
424
0
                size_t consumed = src_end - src;
425
0
                if ((ret = ptls_receive(sock->ssl->ptls, &rbuf, src, &consumed)) != 0)
426
0
                    break;
427
0
                src += consumed;
428
0
            } while (src != src_end);
429
0
            h2o_buffer_consume(&sock->ssl->input.encrypted, sock->ssl->input.encrypted->size - (src_end - src));
430
0
            if (rbuf.is_allocated) {
431
0
                if ((reserved = h2o_buffer_try_reserve(&sock->input, rbuf.off)).base == NULL)
432
0
                    return h2o_socket_error_out_of_memory;
433
0
                memcpy(reserved.base, rbuf.base, rbuf.off);
434
0
                sock->input->size += rbuf.off;
435
0
                ptls_buffer_dispose(&rbuf);
436
0
            } else {
437
0
                sock->input->size += rbuf.off;
438
0
            }
439
0
            if (!(ret == 0 || ret == PTLS_ERROR_IN_PROGRESS))
440
0
                return h2o_socket_error_ssl_decode;
441
0
        }
442
0
        return NULL;
443
0
    }
444
445
0
    while (sock->ssl->input.encrypted->size != 0 || SSL_pending(sock->ssl->ossl)) {
446
0
        int rlen;
447
0
        h2o_iovec_t buf = h2o_buffer_try_reserve(&sock->input, 4096);
448
0
        if (buf.base == NULL)
449
0
            return h2o_socket_error_out_of_memory;
450
0
        { /* call SSL_read (while detecting SSL renegotiation and reporting it as error) */
451
0
            int did_write_in_read = 0;
452
0
            sock->ssl->did_write_in_read = &did_write_in_read;
453
0
            ERR_clear_error();
454
0
            rlen = SSL_read(sock->ssl->ossl, buf.base, (int)buf.len);
455
0
            sock->ssl->did_write_in_read = NULL;
456
0
            if (did_write_in_read)
457
0
                return "ssl renegotiation not supported";
458
0
        }
459
0
        if (rlen == -1) {
460
0
            if (SSL_get_error(sock->ssl->ossl, rlen) != SSL_ERROR_WANT_READ) {
461
0
                return h2o_socket_error_ssl_decode;
462
0
            }
463
0
            break;
464
0
        } else if (rlen == 0) {
465
0
            break;
466
0
        } else {
467
0
            sock->input->size += rlen;
468
0
        }
469
0
    }
470
471
0
    return 0;
472
0
}
473
474
static void flush_pending_ssl(h2o_socket_t *sock, h2o_socket_cb cb)
475
0
{
476
0
    sock->_cb.write = cb;
477
0
    do_write(sock, NULL, 0);
478
0
}
479
480
static void destroy_ssl(struct st_h2o_socket_ssl_t *ssl)
481
0
{
482
0
    assert(!ssl->async.inflight);
483
0
    assert(ssl->async.ptls_wbuf.base == NULL);
484
485
0
    if (ssl->ptls != NULL) {
486
0
        ptls_free(ssl->ptls);
487
0
        ssl->ptls = NULL;
488
0
    }
489
0
    if (ssl->ossl != NULL) {
490
0
        if (!SSL_is_server(ssl->ossl)) {
491
0
            free(ssl->handshake.client.server_name);
492
0
            free(ssl->handshake.client.session_cache_key.base);
493
0
        }
494
0
        SSL_free(ssl->ossl);
495
0
        ssl->ossl = NULL;
496
0
    }
497
0
    h2o_buffer_dispose(&ssl->input.encrypted);
498
0
    if (has_pending_ssl_bytes(ssl))
499
0
        dispose_ssl_output_buffer(ssl);
500
0
    free(ssl);
501
0
}
502
503
static void dispose_socket(h2o_socket_t *sock, const char *err)
504
19.2k
{
505
19.2k
    void (*close_cb)(void *data);
506
19.2k
    void *close_cb_data;
507
508
19.2k
    if (sock->ssl != NULL) {
509
0
        destroy_ssl(sock->ssl);
510
0
        sock->ssl = NULL;
511
0
    }
512
19.2k
    h2o_buffer_dispose(&sock->input);
513
19.2k
    if (sock->_peername != NULL) {
514
1.40k
        free(sock->_peername);
515
1.40k
        sock->_peername = NULL;
516
1.40k
    }
517
19.2k
    if (sock->_sockname != NULL) {
518
0
        free(sock->_sockname);
519
0
        sock->_sockname = NULL;
520
0
    }
521
522
19.2k
    close_cb = sock->on_close.cb;
523
19.2k
    close_cb_data = sock->on_close.data;
524
525
19.2k
    do_dispose_socket(sock);
526
527
19.2k
    if (close_cb != NULL)
528
3.73k
        close_cb(close_cb_data);
529
19.2k
}
530
531
static void shutdown_ssl(h2o_socket_t *sock, const char *err)
532
0
{
533
0
    if (err != NULL)
534
0
        goto Close;
535
536
0
    if (sock->_cb.write != NULL) {
537
        /* note: libuv calls the write callback after the socket is closed by uv_close (with status set to 0 if the write succeeded)
538
         */
539
0
        sock->_cb.write = NULL;
540
0
        goto Close;
541
0
    }
542
543
    /* at the moment, we do not send Close Notify Alert when kTLS is used (TODO) */
544
0
    if (sock->ssl->offload == H2O_SOCKET_SSL_OFFLOAD_ON)
545
0
        goto Close;
546
547
    /* send Close Notify if necessary, depending on each TLS stack being used */
548
0
    if (sock->ssl->ptls != NULL) {
549
0
        ptls_buffer_t wbuf;
550
0
        uint8_t wbuf_small[32];
551
0
        ptls_buffer_init(&wbuf, wbuf_small, sizeof(wbuf_small));
552
0
        if (ptls_send_alert(sock->ssl->ptls, &wbuf, PTLS_ALERT_LEVEL_WARNING, PTLS_ALERT_CLOSE_NOTIFY) != 0)
553
0
            goto Close;
554
0
        write_ssl_bytes(sock, wbuf.base, wbuf.off);
555
0
        ptls_buffer_dispose(&wbuf);
556
0
    } else if (sock->ssl->ossl != NULL) {
557
0
        ERR_clear_error();
558
0
        if (SSL_shutdown(sock->ssl->ossl) == -1)
559
0
            goto Close;
560
0
    } else {
561
0
        goto Close;
562
0
    }
563
564
0
    if (has_pending_ssl_bytes(sock->ssl)) {
565
0
        h2o_socket_read_stop(sock);
566
0
        flush_pending_ssl(sock, dispose_socket);
567
0
        return;
568
0
    }
569
570
0
Close:
571
0
    dispose_socket(sock, err);
572
0
}
573
574
void h2o_socket_dispose_export(h2o_socket_export_t *info)
575
0
{
576
0
    assert(info->fd != -1);
577
0
    if (info->ssl != NULL) {
578
0
        destroy_ssl(info->ssl);
579
0
        info->ssl = NULL;
580
0
    }
581
0
    h2o_buffer_dispose(&info->input);
582
0
    close(info->fd);
583
0
    info->fd = -1;
584
0
}
585
586
int h2o_socket_export(h2o_socket_t *sock, h2o_socket_export_t *info)
587
0
{
588
0
    static h2o_buffer_prototype_t nonpooling_prototype;
589
590
0
    assert(sock->_zerocopy == NULL);
591
0
    assert(!h2o_socket_is_writing(sock));
592
0
    assert(sock->ssl == NULL || !sock->ssl->async.inflight);
593
594
0
    if (do_export(sock, info) == -1)
595
0
        return -1;
596
597
0
    if ((info->ssl = sock->ssl) != NULL) {
598
0
        sock->ssl = NULL;
599
0
        h2o_buffer_set_prototype(&info->ssl->input.encrypted, &nonpooling_prototype);
600
0
    }
601
0
    info->input = sock->input;
602
0
    h2o_buffer_set_prototype(&info->input, &nonpooling_prototype);
603
0
    h2o_buffer_init(&sock->input, &h2o_socket_buffer_prototype);
604
605
0
    h2o_socket_close(sock);
606
607
0
    return 0;
608
0
}
609
610
h2o_socket_t *h2o_socket_import(h2o_loop_t *loop, h2o_socket_export_t *info)
611
0
{
612
0
    h2o_socket_t *sock;
613
614
0
    assert(info->fd != -1);
615
616
0
    sock = do_import(loop, info);
617
0
    info->fd = -1; /* just in case */
618
0
    if ((sock->ssl = info->ssl) != NULL) {
619
0
        setup_bio(sock);
620
0
        h2o_buffer_set_prototype(&sock->ssl->input.encrypted, &h2o_socket_buffer_prototype);
621
0
    }
622
0
    sock->input = info->input;
623
0
    h2o_buffer_set_prototype(&sock->input, &h2o_socket_buffer_prototype);
624
0
    return sock;
625
0
}
626
627
void h2o_socket_close(h2o_socket_t *sock)
628
19.2k
{
629
19.2k
    if (sock->ssl == NULL) {
630
19.2k
        dispose_socket(sock, 0);
631
19.2k
    } else {
632
0
        if (sock->ssl->async.inflight) {
633
0
            sock->ssl->async.sock_is_closed = 1;
634
0
            return;
635
0
        }
636
0
        shutdown_ssl(sock, 0);
637
0
    }
638
19.2k
}
639
640
static uint16_t calc_suggested_tls_payload_size(h2o_socket_t *sock, uint16_t suggested_tls_record_size)
641
0
{
642
0
    uint16_t ps = suggested_tls_record_size;
643
0
    if (sock->ssl != NULL && sock->ssl->record_overhead < ps)
644
0
        ps -= sock->ssl->record_overhead;
645
0
    return ps;
646
0
}
647
648
static void disable_latency_optimized_write(h2o_socket_t *sock, int (*adjust_notsent_lowat)(h2o_socket_t *, unsigned))
649
5.38k
{
650
5.38k
    if (sock->_latency_optimization.notsent_is_minimized) {
651
0
        adjust_notsent_lowat(sock, 0);
652
0
        sock->_latency_optimization.notsent_is_minimized = 0;
653
0
    }
654
5.38k
    sock->_latency_optimization.state = H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_DISABLED;
655
5.38k
    sock->_latency_optimization.suggested_tls_payload_size = SIZE_MAX;
656
5.38k
    sock->_latency_optimization.suggested_write_size = SIZE_MAX;
657
5.38k
}
658
659
static inline void prepare_for_latency_optimized_write(h2o_socket_t *sock,
660
                                                       const h2o_socket_latency_optimization_conditions_t *conditions, uint32_t rtt,
661
                                                       uint32_t mss, uint32_t cwnd_size, uint32_t cwnd_avail, uint64_t loop_time,
662
                                                       int (*adjust_notsent_lowat)(h2o_socket_t *, unsigned))
663
0
{
664
    /* check RTT */
665
0
    if (rtt < conditions->min_rtt * (uint64_t)1000)
666
0
        goto Disable;
667
0
    if (rtt * conditions->max_additional_delay < loop_time * 1000 * 100)
668
0
        goto Disable;
669
670
    /* latency-optimization is enabled */
671
0
    sock->_latency_optimization.state = H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_DETERMINED;
672
673
    /* no need to:
674
     *   1) adjust the write size if single_write_size << cwnd_size
675
     *   2) align TLS record boundary to TCP packet boundary if packet loss-rate is low and BW isn't small (implied by cwnd size)
676
     */
677
0
    if (mss * cwnd_size < conditions->max_cwnd) {
678
0
        if (!sock->_latency_optimization.notsent_is_minimized) {
679
0
            if (adjust_notsent_lowat(sock, 1 /* cannot be set to zero on Linux */) != 0)
680
0
                goto Disable;
681
0
            sock->_latency_optimization.notsent_is_minimized = 1;
682
0
        }
683
0
        sock->_latency_optimization.suggested_tls_payload_size = calc_suggested_tls_payload_size(sock, mss);
684
0
        sock->_latency_optimization.suggested_write_size =
685
0
            cwnd_avail * (size_t)sock->_latency_optimization.suggested_tls_payload_size;
686
0
    } else {
687
0
        if (sock->_latency_optimization.notsent_is_minimized) {
688
0
            if (adjust_notsent_lowat(sock, 0) != 0)
689
0
                goto Disable;
690
0
            sock->_latency_optimization.notsent_is_minimized = 0;
691
0
        }
692
0
        sock->_latency_optimization.suggested_tls_payload_size = SIZE_MAX;
693
0
        sock->_latency_optimization.suggested_write_size = SIZE_MAX;
694
0
    }
695
0
    return;
696
697
0
Disable:
698
0
    disable_latency_optimized_write(sock, adjust_notsent_lowat);
699
0
}
700
701
/**
702
 * Obtains RTT, MSS, size of CWND (in the number of packets).
703
 * Also writes to cwnd_avail minimum number of packets (of MSS size) sufficient to shut up poll-for-write under the precondition
704
 * that TCP_NOTSENT_LOWAT is set to 1.
705
 */
706
static int obtain_tcp_info(int fd, uint32_t *rtt, uint32_t *mss, uint32_t *cwnd_size, uint32_t *cwnd_avail)
707
5.38k
{
708
5.38k
#define CALC_CWND_PAIR_FROM_BYTE_UNITS(cwnd_bytes, inflight_bytes)                                                                 \
709
5.38k
    do {                                                                                                                           \
710
5.38k
        *cwnd_size = (cwnd_bytes + *mss / 2) / *mss;                                                                               \
711
5.38k
        *cwnd_avail = cwnd_bytes > inflight_bytes ? (cwnd_bytes - inflight_bytes) / *mss + 2 : 2;                                  \
712
5.38k
    } while (0)
713
714
5.38k
#if defined(__linux__) && defined(TCP_INFO)
715
716
5.38k
    struct tcp_info tcpi;
717
5.38k
    socklen_t tcpisz = sizeof(tcpi);
718
5.38k
    if (getsockopt(fd, IPPROTO_TCP, TCP_INFO, &tcpi, &tcpisz) != 0)
719
5.38k
        return -1;
720
0
    *rtt = tcpi.tcpi_rtt;
721
0
    *mss = tcpi.tcpi_snd_mss;
722
0
    *cwnd_size = tcpi.tcpi_snd_cwnd;
723
0
    *cwnd_avail = tcpi.tcpi_snd_cwnd > tcpi.tcpi_unacked ? tcpi.tcpi_snd_cwnd - tcpi.tcpi_unacked + 2 : 2;
724
0
    return 0;
725
726
#elif defined(__APPLE__) && defined(TCP_CONNECTION_INFO)
727
728
    struct tcp_connection_info tcpi;
729
    socklen_t tcpisz = sizeof(tcpi);
730
    if (getsockopt(fd, IPPROTO_TCP, TCP_CONNECTION_INFO, &tcpi, &tcpisz) != 0 || tcpi.tcpi_maxseg == 0)
731
        return -1;
732
    *rtt = tcpi.tcpi_srtt * 1000;
733
    *mss = tcpi.tcpi_maxseg;
734
    CALC_CWND_PAIR_FROM_BYTE_UNITS(tcpi.tcpi_snd_cwnd, tcpi.tcpi_snd_sbbytes);
735
    return 0;
736
737
#else
738
739
    /* For other operating systems that do not have TCP_NOTSENT_LOWAT, it is meaningless to return information. Return -1 to disable
740
     * the low latency optimization. */
741
    return -1;
742
743
#endif
744
745
5.38k
#undef CALC_CWND_PAIR_FROM_BYTE_UNITS
746
5.38k
}
747
748
#ifdef TCP_NOTSENT_LOWAT
749
static int adjust_notsent_lowat(h2o_socket_t *sock, unsigned notsent_lowat)
750
0
{
751
0
    return setsockopt(h2o_socket_get_fd(sock), IPPROTO_TCP, TCP_NOTSENT_LOWAT, &notsent_lowat, sizeof(notsent_lowat));
752
0
}
753
#else
754
#define adjust_notsent_lowat NULL
755
#endif
756
757
size_t h2o_socket_do_prepare_for_latency_optimized_write(h2o_socket_t *sock,
758
                                                         const h2o_socket_latency_optimization_conditions_t *conditions)
759
5.38k
{
760
5.38k
    uint32_t rtt = 0, mss = 0, cwnd_size = 0, cwnd_avail = 0;
761
5.38k
    uint64_t loop_time = UINT64_MAX;
762
5.38k
    int can_prepare = 1;
763
764
#if !defined(TCP_NOTSENT_LOWAT)
765
    /* the feature cannot be setup unless TCP_NOTSENT_LOWAT is available */
766
    can_prepare = 0;
767
#endif
768
769
#if H2O_USE_LIBUV
770
    /* poll-then-write is impossible with libuv */
771
    can_prepare = 0;
772
#else
773
5.38k
    if (can_prepare)
774
5.38k
        loop_time = h2o_evloop_get_execution_time_millisec(h2o_socket_get_loop(sock));
775
5.38k
#endif
776
777
    /* obtain TCP states */
778
5.38k
    if (can_prepare && obtain_tcp_info(h2o_socket_get_fd(sock), &rtt, &mss, &cwnd_size, &cwnd_avail) != 0)
779
5.38k
        can_prepare = 0;
780
781
    /* determine suggested_write_size, suggested_tls_record_size and adjust TCP_NOTSENT_LOWAT based on the obtained information */
782
5.38k
    if (can_prepare) {
783
0
        prepare_for_latency_optimized_write(sock, conditions, rtt, mss, cwnd_size, cwnd_avail, loop_time, adjust_notsent_lowat);
784
5.38k
    } else {
785
5.38k
        disable_latency_optimized_write(sock, adjust_notsent_lowat);
786
5.38k
    }
787
788
5.38k
    return sock->_latency_optimization.suggested_write_size;
789
790
5.38k
#undef CALC_CWND_PAIR_FROM_BYTE_UNITS
791
5.38k
}
792
793
static size_t calc_tls_write_size(h2o_socket_t *sock, size_t bufsize)
794
0
{
795
0
    size_t recsize;
796
797
    /* set recsize to the maximum TLS record size by using the latency optimizer, or if the optimizer is not in action, based on the
798
     * number of bytes that have already been sent */
799
0
    switch (sock->_latency_optimization.state) {
800
0
    case H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_TBD:
801
0
    case H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_DISABLED:
802
0
        recsize = sock->bytes_written < 64 * 1024 ? calc_suggested_tls_payload_size(sock, 1400) : SIZE_MAX;
803
0
        break;
804
0
    case H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_DETERMINED:
805
0
        sock->_latency_optimization.state = H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_NEEDS_UPDATE;
806
    /* fallthru */
807
0
    default:
808
0
        recsize = sock->_latency_optimization.suggested_tls_payload_size;
809
0
        break;
810
0
    }
811
812
0
    return recsize < bufsize ? recsize : bufsize;
813
0
}
814
815
/**
816
 * Given a vector, generate at least one TLS record if there's enough space in the buffer, and return the size of application data
817
 * being encrypted. Otherwise, returns zero.
818
 */
819
static size_t generate_tls_records_from_one_vec(h2o_socket_t *sock, const void *input, size_t inlen)
820
0
{
821
0
    static const size_t MAX_RECORD_PAYLOAD_SIZE = 16 * 1024, LARGE_RECORD_OVERHEAD = 5 + 32;
822
823
0
    size_t tls_write_size = calc_tls_write_size(sock, inlen);
824
0
    size_t space_left = sock->ssl->output.buf.capacity - sock->ssl->output.buf.off;
825
826
0
    if (tls_write_size < inlen) {
827
        /* Writing small TLS records, one by one. Bail out if we might fail to do so. */
828
0
        if (space_left < tls_write_size + LARGE_RECORD_OVERHEAD)
829
0
            return 0;
830
0
    } else {
831
        /* Writing full-sized records. Adjust tls_write_size to a multiple of full-sized TLS records, or bail out if we cannot
832
         * write one. */
833
0
        size_t rec_capacity = space_left / (MAX_RECORD_PAYLOAD_SIZE + LARGE_RECORD_OVERHEAD);
834
0
        if (rec_capacity == 0)
835
0
            return 0;
836
0
        tls_write_size = MAX_RECORD_PAYLOAD_SIZE * rec_capacity;
837
0
        if (tls_write_size > inlen)
838
0
            tls_write_size = inlen;
839
0
    }
840
841
    /* Generate TLS record(s). */
842
0
    if (sock->ssl->ptls != NULL) {
843
0
        int ret = ptls_send(sock->ssl->ptls, &sock->ssl->output.buf, input, tls_write_size);
844
0
        assert(ret == 0);
845
0
    } else {
846
0
        int ret = SSL_write(sock->ssl->ossl, input, (int)tls_write_size);
847
        /* The error happens if SSL_write is called after SSL_read returns a fatal error (e.g. due to corrupt TCP packet being
848
         * received). We might be converting more and more TLS records on this side as read errors occur. */
849
0
        if (ret <= 0)
850
0
            return SIZE_MAX;
851
0
        assert(ret == tls_write_size);
852
0
    }
853
854
0
    SOCKET_PROBE(WRITE_TLS_RECORD, sock, tls_write_size, sock->ssl->output.buf.off);
855
0
    H2O_LOG_SOCK(write_tls_record, sock, {
856
0
        PTLS_LOG_ELEMENT_UNSIGNED(write_size, tls_write_size);
857
0
        PTLS_LOG_ELEMENT_UNSIGNED(bytes_buffered, sock->ssl->output.buf.off);
858
0
    });
859
0
    return tls_write_size;
860
0
}
861
862
/**
863
 * Generate as many TLS records as possible, given a list of vectors. Upon return, `*bufs` and `*bufcnt` will be updated to point
864
 * the buffers that still have pending data, and the number of bytes being already written within `(*buf)[0]` will be returned.
865
 */
866
static size_t generate_tls_records(h2o_socket_t *sock, h2o_iovec_t **bufs, size_t *bufcnt, size_t first_buf_written)
867
0
{
868
0
    assert(!has_pending_ssl_bytes(sock->ssl) && "we are filling encrypted bytes from the front, with no existing buffer, always");
869
870
0
    while (*bufcnt != 0) {
871
0
        if ((*bufs)->len == 0) {
872
0
            ++*bufs;
873
0
            --*bufcnt;
874
0
            continue;
875
0
        }
876
0
        if (!has_pending_ssl_bytes(sock->ssl))
877
0
            init_ssl_output_buffer(sock->ssl, sock->_zerocopy != NULL);
878
0
        size_t bytes_newly_written =
879
0
            generate_tls_records_from_one_vec(sock, (*bufs)->base + first_buf_written, (*bufs)->len - first_buf_written);
880
0
        if (bytes_newly_written == SIZE_MAX) {
881
0
            return SIZE_MAX;
882
0
        } else if (bytes_newly_written == 0) {
883
0
            break;
884
0
        }
885
0
        first_buf_written += bytes_newly_written;
886
0
        if ((*bufs)->len == first_buf_written) {
887
0
            first_buf_written = 0;
888
0
            ++*bufs;
889
0
            --*bufcnt;
890
0
        }
891
0
    }
892
893
0
    return first_buf_written;
894
0
}
895
896
size_t flatten_sendvec(h2o_socket_t *sock, h2o_sendvec_t *sendvec)
897
0
{
898
0
    assert(h2o_socket_ssl_buffer_allocator.conf->memsize >= H2O_PULL_SENDVEC_MAX_SIZE);
899
0
    sock->_write_buf.flattened = h2o_mem_alloc_recycle(&h2o_socket_ssl_buffer_allocator);
900
0
    size_t len = sendvec->len;
901
902
0
    if (!sendvec->callbacks->read_(sendvec, sock->_write_buf.flattened, len)) {
903
        /* failed */
904
0
        h2o_mem_free_recycle(&h2o_socket_ssl_buffer_allocator, sock->_write_buf.flattened);
905
0
        sock->_write_buf.flattened = NULL;
906
0
        return SIZE_MAX;
907
0
    }
908
0
    return len;
909
0
}
910
911
void h2o_socket_write(h2o_socket_t *sock, h2o_iovec_t *bufs, size_t bufcnt, h2o_socket_cb cb)
912
18.0k
{
913
18.0k
    SOCKET_PROBE(WRITE, sock, bufs, bufcnt, cb);
914
18.0k
    H2O_LOG_SOCK(write, sock, {
915
18.0k
        size_t num_bytes = 0;
916
18.0k
        for (size_t i = 0; i < bufcnt; ++i)
917
18.0k
            num_bytes += bufs[i].len;
918
18.0k
        PTLS_LOG_ELEMENT_UNSIGNED(num_bytes, num_bytes);
919
18.0k
        PTLS_LOG_ELEMENT_UNSIGNED(bufcnt, bufcnt);
920
18.0k
        PTLS_LOG_ELEMENT_PTR(cb, cb);
921
18.0k
    });
922
923
18.0k
    assert(sock->_cb.write == NULL);
924
18.0k
    assert(sock->_cb.write_flags == 0);
925
18.0k
    sock->_cb.write = cb;
926
927
39.0k
    for (size_t i = 0; i != bufcnt; ++i) {
928
20.9k
        sock->bytes_written += bufs[i].len;
929
#if H2O_SOCKET_DUMP_WRITE
930
        h2o_error_printf("writing %zu bytes to fd:%d\n", bufs[i].len, h2o_socket_get_fd(sock));
931
        h2o_dump_memory(stderr, bufs[i].base, bufs[i].len);
932
#endif
933
20.9k
    }
934
935
18.0k
    do_write(sock, bufs, bufcnt);
936
18.0k
}
937
938
void h2o_socket_sendvec(h2o_socket_t *sock, h2o_sendvec_t *vecs, size_t cnt, unsigned flags, h2o_socket_cb cb)
939
10.3k
{
940
10.3k
    assert(sock->_cb.write == NULL);
941
10.3k
    assert(sock->_cb.write_flags == 0);
942
10.3k
    assert(sock->_write_buf.flattened == NULL);
943
944
10.3k
    sock->_cb.write = cb;
945
10.3k
    sock->_cb.write_flags = flags;
946
947
10.3k
    if (cnt == 0)
948
312
        return do_write(sock, NULL, 0);
949
950
9.99k
    h2o_iovec_t bufs[cnt];
951
9.99k
    size_t pull_index = SIZE_MAX;
952
953
    /* copy vectors to bufs, while looking for one to flatten */
954
31.5k
    for (size_t i = 0; i < cnt; ++i) {
955
21.5k
        sock->bytes_written += vecs[i].len;
956
21.5k
        if (vecs[i].callbacks->read_ == h2o_sendvec_read_raw || vecs[i].len == 0) {
957
21.5k
            bufs[i] = h2o_iovec_init(vecs[i].raw, vecs[i].len);
958
21.5k
        } else {
959
0
            assert(pull_index == SIZE_MAX || !"h2o_socket_sendvec can only handle one pull vector at a time");
960
0
            assert(vecs[i].len <= H2O_PULL_SENDVEC_MAX_SIZE); /* at the moment, this is our size limit */
961
0
            pull_index = i;
962
0
        }
963
21.5k
    }
964
965
9.99k
    if (pull_index != SIZE_MAX) {
966
        /* If the pull vector has a send callback, and if we have the necessary conditions to utilize it, Let it write directly to
967
         * the socket. */
968
0
#if !H2O_USE_LIBUV
969
0
        if (pull_index == cnt - 1 && vecs[pull_index].callbacks != NULL &&
970
0
            do_write_with_sendvec(sock, bufs, cnt - 1, vecs + pull_index))
971
0
            return;
972
0
#endif
973
        /* Load the vector onto memory now. */
974
0
        size_t pulllen = flatten_sendvec(sock, &vecs[pull_index]);
975
0
        if (pulllen == SIZE_MAX) {
976
0
            report_early_write_error(sock);
977
0
            return;
978
0
        }
979
0
        bufs[pull_index] = h2o_iovec_init(sock->_write_buf.flattened, pulllen);
980
0
    }
981
982
9.99k
    do_write(sock, bufs, cnt);
983
9.99k
}
984
985
void on_write_complete(h2o_socket_t *sock, const char *err)
986
32.0k
{
987
32.0k
    h2o_socket_cb cb;
988
989
32.0k
    if (has_pending_ssl_bytes(sock->ssl))
990
0
        dispose_ssl_output_buffer(sock->ssl);
991
992
32.0k
    cb = sock->_cb.write;
993
32.0k
    sock->_cb.write = NULL;
994
32.0k
    sock->_cb.write_flags = 0;
995
32.0k
    cb(sock, err);
996
32.0k
}
997
998
void h2o_socket_read_start(h2o_socket_t *sock, h2o_socket_cb cb)
999
33.0k
{
1000
33.0k
    sock->_cb.read = cb;
1001
33.0k
    do_read_start(sock);
1002
33.0k
}
1003
1004
void h2o_socket_read_stop(h2o_socket_t *sock)
1005
15.5k
{
1006
15.5k
    sock->_cb.read = NULL;
1007
15.5k
    do_read_stop(sock);
1008
15.5k
}
1009
1010
void h2o_socket_setpeername(h2o_socket_t *sock, struct sockaddr *sa, socklen_t len)
1011
1.40k
{
1012
1.40k
    free(sock->_peername);
1013
1.40k
    sock->_peername = h2o_mem_alloc(offsetof(struct st_h2o_socket_addr_t, addr) + len);
1014
1.40k
    sock->_peername->len = len;
1015
1.40k
    memcpy(&sock->_peername->addr, sa, len);
1016
1.40k
}
1017
1018
socklen_t h2o_socket_getpeername(h2o_socket_t *sock, struct sockaddr *sa)
1019
3.23k
{
1020
    /* return cached, if exists */
1021
3.23k
    if (sock->_peername != NULL) {
1022
1.83k
        memcpy(sa, &sock->_peername->addr, sock->_peername->len);
1023
1.83k
        return sock->_peername->len;
1024
1.83k
    }
1025
    /* call, copy to cache, and return */
1026
1.40k
    socklen_t len = get_peername_uncached(sock, sa);
1027
1.40k
    h2o_socket_setpeername(sock, sa, len);
1028
1.40k
    return len;
1029
3.23k
}
1030
1031
socklen_t h2o_socket_getsockname(h2o_socket_t *sock, struct sockaddr *sa)
1032
0
{
1033
    /* return cached, if exists */
1034
0
    if (sock->_sockname != NULL) {
1035
0
        memcpy(sa, &sock->_sockname->addr, sock->_sockname->len);
1036
0
        return sock->_sockname->len;
1037
0
    }
1038
    /* call, copy to cache, and return */
1039
0
    socklen_t len = get_sockname_uncached(sock, sa);
1040
0
    sock->_sockname = h2o_mem_alloc(offsetof(struct st_h2o_socket_addr_t, addr) + len);
1041
0
    sock->_sockname->len = len;
1042
0
    memcpy(&sock->_sockname->addr, sa, len);
1043
0
    return len;
1044
0
}
1045
1046
ptls_t *h2o_socket_get_ptls(h2o_socket_t *sock)
1047
3.23k
{
1048
3.23k
    return sock->ssl != NULL ? sock->ssl->ptls : NULL;
1049
3.23k
}
1050
1051
const char *h2o_socket_get_ssl_protocol_version(h2o_socket_t *sock)
1052
3.65k
{
1053
3.65k
    if (sock->ssl != NULL) {
1054
0
        if (sock->ssl->ptls != NULL) {
1055
0
            switch (ptls_get_protocol_version(sock->ssl->ptls)) {
1056
0
            case PTLS_PROTOCOL_VERSION_TLS12:
1057
0
                return "TLSv1.2";
1058
0
            case PTLS_PROTOCOL_VERSION_TLS13:
1059
0
                return "TLSv1.3";
1060
0
            default:
1061
0
                return "TLSv?";
1062
0
            }
1063
0
        }
1064
0
        if (sock->ssl->ossl != NULL)
1065
0
            return SSL_get_version(sock->ssl->ossl);
1066
0
    }
1067
3.65k
    return NULL;
1068
3.65k
}
1069
1070
int h2o_socket_get_ssl_session_reused(h2o_socket_t *sock)
1071
3.65k
{
1072
3.65k
    if (sock->ssl != NULL) {
1073
0
        if (sock->ssl->ptls != NULL)
1074
0
            return ptls_is_psk_handshake(sock->ssl->ptls);
1075
0
        if (sock->ssl->ossl != NULL)
1076
0
            return (int)SSL_session_reused(sock->ssl->ossl);
1077
0
    }
1078
3.65k
    return -1;
1079
3.65k
}
1080
1081
const char *h2o_socket_get_ssl_cipher(h2o_socket_t *sock)
1082
3.65k
{
1083
3.65k
    if (sock->ssl != NULL) {
1084
0
        if (sock->ssl->ptls != NULL) {
1085
0
            ptls_cipher_suite_t *cipher = ptls_get_cipher(sock->ssl->ptls);
1086
0
            if (cipher != NULL)
1087
0
                return cipher->name;
1088
0
        } else if (sock->ssl->ossl != NULL) {
1089
0
            return SSL_get_cipher_name(sock->ssl->ossl);
1090
0
        }
1091
0
    }
1092
3.65k
    return NULL;
1093
3.65k
}
1094
1095
int h2o_socket_get_ssl_cipher_bits(h2o_socket_t *sock)
1096
3.65k
{
1097
3.65k
    if (sock->ssl != NULL) {
1098
0
        if (sock->ssl->ptls != NULL) {
1099
0
            ptls_cipher_suite_t *cipher = ptls_get_cipher(sock->ssl->ptls);
1100
0
            if (cipher == NULL)
1101
0
                return 0;
1102
0
            return (int)cipher->aead->key_size * 8;
1103
0
        } else if (sock->ssl->ossl != NULL) {
1104
0
            return SSL_get_cipher_bits(sock->ssl->ossl, NULL);
1105
0
        }
1106
0
    }
1107
3.65k
    return 0;
1108
3.65k
}
1109
1110
h2o_iovec_t h2o_socket_get_ssl_session_id(h2o_socket_t *sock)
1111
0
{
1112
0
    if (sock->ssl != NULL) {
1113
0
        if (sock->ssl->ptls != NULL) {
1114
            /* FIXME */
1115
0
        } else if (sock->ssl->ossl != NULL) {
1116
0
            SSL_SESSION *session;
1117
0
            if (sock->ssl->handshake.server.async_resumption.state == ASYNC_RESUMPTION_STATE_COMPLETE &&
1118
0
                (session = SSL_get_session(sock->ssl->ossl)) != NULL) {
1119
0
                unsigned id_len;
1120
0
                const unsigned char *id = SSL_SESSION_get_id(session, &id_len);
1121
0
                return h2o_iovec_init(id, id_len);
1122
0
            }
1123
0
        }
1124
0
    }
1125
1126
0
    return h2o_iovec_init(NULL, 0);
1127
0
}
1128
1129
const char *h2o_socket_get_ssl_server_name(const h2o_socket_t *sock)
1130
0
{
1131
0
    if (sock->ssl != NULL) {
1132
0
        if (sock->ssl->ptls != NULL) {
1133
0
            return ptls_get_server_name(sock->ssl->ptls);
1134
0
        } else if (sock->ssl->ossl != NULL) {
1135
0
            return SSL_get_servername(sock->ssl->ossl, TLSEXT_NAMETYPE_host_name);
1136
0
        }
1137
0
    }
1138
0
    return NULL;
1139
0
}
1140
1141
int h2o_socket_can_tls_offload(h2o_socket_t *sock)
1142
0
{
1143
0
    if (sock->ssl == NULL)
1144
0
        return 0;
1145
1146
#if H2O_USE_LIBUV
1147
    return 0;
1148
#else
1149
0
    return can_tls_offload(sock);
1150
0
#endif
1151
0
}
1152
1153
h2o_iovec_t h2o_socket_log_tcp_congestion_controller(h2o_socket_t *sock, h2o_mem_pool_t *pool)
1154
0
{
1155
0
#if defined(TCP_CONGESTION)
1156
0
    int fd;
1157
0
    if ((fd = h2o_socket_get_fd(sock)) >= 0) {
1158
0
#define CC_BUFSIZE 32
1159
0
        socklen_t buflen = CC_BUFSIZE;
1160
0
        char *buf = pool != NULL ? h2o_mem_alloc_pool(pool, *buf, buflen) : h2o_mem_alloc(buflen);
1161
0
        if (getsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, buf, &buflen) == 0) {
1162
            /* Upon return, linux sets `buflen` to some value greater than the size of the string. Therefore, we apply strlen after
1163
             * making sure that the result does not overrun the buffer. */
1164
0
            buf[CC_BUFSIZE - 1] = '\0';
1165
0
            return h2o_iovec_init(buf, strlen(buf));
1166
0
        }
1167
0
        if (pool == NULL)
1168
0
            free(buf);
1169
0
#undef CC_BUFSIZE
1170
0
    }
1171
0
#endif
1172
0
    return h2o_iovec_init(NULL, 0);
1173
0
}
1174
1175
h2o_iovec_t h2o_socket_log_tcp_delivery_rate(h2o_socket_t *sock, h2o_mem_pool_t *pool)
1176
0
{
1177
0
#if defined(__linux__) && defined(TCP_INFO)
1178
0
    int fd;
1179
0
    if ((fd = h2o_socket_get_fd(sock)) >= 0) {
1180
        /* A copy of `struct tcp_info` found in linux/tcp.h, up to `tcpi_delivery_rate`. Rest of the codebase uses netinet/tcp.h,
1181
         * which does not provide access to `tcpi_delivery_rate`. */
1182
0
        struct {
1183
0
            uint8_t tcpi_state;
1184
0
            uint8_t tcpi_ca_state;
1185
0
            uint8_t tcpi_retransmits;
1186
0
            uint8_t tcpi_probes;
1187
0
            uint8_t tcpi_backoff;
1188
0
            uint8_t tcpi_options;
1189
0
            uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
1190
0
            uint8_t tcpi_delivery_rate_app_limited : 1;
1191
1192
0
            uint32_t tcpi_rto;
1193
0
            uint32_t tcpi_ato;
1194
0
            uint32_t tcpi_snd_mss;
1195
0
            uint32_t tcpi_rcv_mss;
1196
1197
0
            uint32_t tcpi_unacked;
1198
0
            uint32_t tcpi_sacked;
1199
0
            uint32_t tcpi_lost;
1200
0
            uint32_t tcpi_retrans;
1201
0
            uint32_t tcpi_fackets;
1202
1203
            /* Times. */
1204
0
            uint32_t tcpi_last_data_sent;
1205
0
            uint32_t tcpi_last_ack_sent; /* Not remembered, sorry. */
1206
0
            uint32_t tcpi_last_data_recv;
1207
0
            uint32_t tcpi_last_ack_recv;
1208
1209
            /* Metrics. */
1210
0
            uint32_t tcpi_pmtu;
1211
0
            uint32_t tcpi_rcv_ssthresh;
1212
0
            uint32_t tcpi_rtt;
1213
0
            uint32_t tcpi_rttvar;
1214
0
            uint32_t tcpi_snd_ssthresh;
1215
0
            uint32_t tcpi_snd_cwnd;
1216
0
            uint32_t tcpi_advmss;
1217
0
            uint32_t tcpi_reordering;
1218
1219
0
            uint32_t tcpi_rcv_rtt;
1220
0
            uint32_t tcpi_rcv_space;
1221
1222
0
            uint32_t tcpi_total_retrans;
1223
1224
0
            uint64_t tcpi_pacing_rate;
1225
0
            uint64_t tcpi_max_pacing_rate;
1226
0
            uint64_t tcpi_bytes_acked;    /* RFC4898 tcpEStatsAppHCThruOctetsAcked */
1227
0
            uint64_t tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */
1228
0
            uint32_t tcpi_segs_out;       /* RFC4898 tcpEStatsPerfSegsOut */
1229
0
            uint32_t tcpi_segs_in;        /* RFC4898 tcpEStatsPerfSegsIn */
1230
1231
0
            uint32_t tcpi_notsent_bytes;
1232
0
            uint32_t tcpi_min_rtt;
1233
0
            uint32_t tcpi_data_segs_in;  /* RFC4898 tcpEStatsDataSegsIn */
1234
0
            uint32_t tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */
1235
1236
0
            uint64_t tcpi_delivery_rate;
1237
0
        } tcpi;
1238
0
        socklen_t tcpisz = sizeof(tcpi);
1239
0
        if (getsockopt(fd, IPPROTO_TCP, TCP_INFO, &tcpi, &tcpisz) == 0) {
1240
0
            char *buf = (char *)(pool != NULL ? h2o_mem_alloc_pool(pool, char, sizeof(H2O_UINT64_LONGEST_STR))
1241
0
                                              : h2o_mem_alloc(sizeof(H2O_UINT64_LONGEST_STR)));
1242
0
            size_t len = sprintf(buf, "%" PRIu64, (uint64_t)tcpi.tcpi_delivery_rate);
1243
0
            return h2o_iovec_init(buf, len);
1244
0
        }
1245
0
    }
1246
0
#endif
1247
0
    return h2o_iovec_init(NULL, 0);
1248
0
}
1249
1250
h2o_iovec_t h2o_socket_log_ssl_session_id(h2o_socket_t *sock, h2o_mem_pool_t *pool)
1251
0
{
1252
0
    h2o_iovec_t base64id, rawid = h2o_socket_get_ssl_session_id(sock);
1253
1254
0
    if (rawid.base == NULL)
1255
0
        return h2o_iovec_init(NULL, 0);
1256
1257
0
    base64id.base = pool != NULL ? h2o_mem_alloc_pool(pool, char, h2o_base64_encode_capacity(rawid.len))
1258
0
                                 : h2o_mem_alloc(h2o_base64_encode_capacity(rawid.len));
1259
0
    base64id.len = h2o_base64_encode(base64id.base, rawid.base, rawid.len, 1);
1260
0
    return base64id;
1261
0
}
1262
1263
h2o_iovec_t h2o_socket_log_ssl_cipher_bits(h2o_socket_t *sock, h2o_mem_pool_t *pool)
1264
0
{
1265
0
    int bits = h2o_socket_get_ssl_cipher_bits(sock);
1266
0
    if (bits != 0) {
1267
0
        char *s = (char *)(pool != NULL ? h2o_mem_alloc_pool(pool, char, sizeof(H2O_INT16_LONGEST_STR))
1268
0
                                        : h2o_mem_alloc(sizeof(H2O_INT16_LONGEST_STR)));
1269
0
        size_t len = sprintf(s, "%" PRId16, (int16_t)bits);
1270
0
        return h2o_iovec_init(s, len);
1271
0
    } else {
1272
0
        return h2o_iovec_init(NULL, 0);
1273
0
    }
1274
0
}
1275
1276
h2o_iovec_t h2o_socket_log_ssl_ech_config_id(h2o_socket_t *sock, h2o_mem_pool_t *pool)
1277
0
{
1278
0
    uint8_t config_id;
1279
1280
0
    if (sock->ssl != NULL && sock->ssl->ptls != NULL && ptls_is_ech_handshake(sock->ssl->ptls, &config_id, NULL, NULL)) {
1281
0
        char *s = (char *)(pool != NULL ? h2o_mem_alloc_pool(pool, char, sizeof(H2O_UINT8_LONGEST_STR))
1282
0
                                        : h2o_mem_alloc(sizeof(H2O_UINT8_LONGEST_STR)));
1283
0
        size_t len = sprintf(s, "%" PRIu8, config_id);
1284
0
        return h2o_iovec_init(s, len);
1285
0
    } else {
1286
0
        return h2o_iovec_init(NULL, 0);
1287
0
    }
1288
0
}
1289
1290
h2o_iovec_t h2o_socket_log_ssl_ech_kem(h2o_socket_t *sock, h2o_mem_pool_t *pool)
1291
0
{
1292
0
    ptls_hpke_kem_t *kem;
1293
1294
0
    if (sock->ssl != NULL && sock->ssl->ptls != NULL && ptls_is_ech_handshake(sock->ssl->ptls, NULL, &kem, NULL)) {
1295
0
        return h2o_iovec_init(kem->keyex->name, strlen(kem->keyex->name));
1296
0
    } else {
1297
0
        return h2o_iovec_init(NULL, 0);
1298
0
    }
1299
0
}
1300
1301
h2o_iovec_t h2o_socket_log_ssl_ech_cipher(h2o_socket_t *sock, h2o_mem_pool_t *pool)
1302
0
{
1303
0
    ptls_hpke_cipher_suite_t *cipher;
1304
1305
0
    if (sock->ssl != NULL && sock->ssl->ptls != NULL && ptls_is_ech_handshake(sock->ssl->ptls, NULL, NULL, &cipher)) {
1306
0
        return h2o_iovec_init(cipher->name, strlen(cipher->name));
1307
0
    } else {
1308
0
        return h2o_iovec_init(NULL, 0);
1309
0
    }
1310
0
}
1311
1312
h2o_iovec_t h2o_socket_log_ssl_ech_cipher_bits(h2o_socket_t *sock, h2o_mem_pool_t *pool)
1313
0
{
1314
0
    ptls_hpke_cipher_suite_t *cipher;
1315
1316
0
    if (sock->ssl != NULL && sock->ssl->ptls != NULL && ptls_is_ech_handshake(sock->ssl->ptls, NULL, NULL, &cipher)) {
1317
0
        uint16_t bits = (uint16_t)(cipher->aead->key_size * 8);
1318
0
        char *s = (char *)(pool != NULL ? h2o_mem_alloc_pool(pool, char, sizeof(H2O_UINT16_LONGEST_STR))
1319
0
                                        : h2o_mem_alloc(sizeof(H2O_UINT16_LONGEST_STR)));
1320
0
        size_t len = sprintf(s, "%" PRIu16, bits);
1321
0
        return h2o_iovec_init(s, len);
1322
0
    } else {
1323
0
        return h2o_iovec_init(NULL, 0);
1324
0
    }
1325
0
}
1326
1327
h2o_iovec_t h2o_socket_log_ssl_backend(h2o_socket_t *sock, h2o_mem_pool_t *pool)
1328
0
{
1329
0
    if (sock->ssl->ptls != NULL)
1330
0
        return h2o_iovec_init(H2O_STRLIT("picotls"));
1331
0
    if (sock->ssl->ossl != NULL)
1332
0
        return h2o_iovec_init(H2O_STRLIT("openssl"));
1333
0
    return h2o_iovec_init(NULL, 0);
1334
0
}
1335
1336
int h2o_socket_compare_address(struct sockaddr *x, struct sockaddr *y, int check_port)
1337
0
{
1338
0
#define CMP(a, b)                                                                                                                  \
1339
0
    do {                                                                                                                           \
1340
0
        if (a != b)                                                                                                                \
1341
0
            return a < b ? -1 : 1;                                                                                                 \
1342
0
    } while (0)
1343
1344
0
    CMP(x->sa_family, y->sa_family);
1345
1346
0
    if (x->sa_family == AF_UNIX) {
1347
0
        struct sockaddr_un *xun = (void *)x, *yun = (void *)y;
1348
0
        int r = strcmp(xun->sun_path, yun->sun_path);
1349
0
        if (r != 0)
1350
0
            return r;
1351
0
    } else if (x->sa_family == AF_INET) {
1352
0
        struct sockaddr_in *xin = (void *)x, *yin = (void *)y;
1353
0
        CMP(ntohl(xin->sin_addr.s_addr), ntohl(yin->sin_addr.s_addr));
1354
0
        if (check_port)
1355
0
            CMP(ntohs(xin->sin_port), ntohs(yin->sin_port));
1356
0
    } else if (x->sa_family == AF_INET6) {
1357
0
        struct sockaddr_in6 *xin6 = (void *)x, *yin6 = (void *)y;
1358
0
        int r = memcmp(xin6->sin6_addr.s6_addr, yin6->sin6_addr.s6_addr, sizeof(xin6->sin6_addr.s6_addr));
1359
0
        if (r != 0)
1360
0
            return r;
1361
0
        if (check_port)
1362
0
            CMP(ntohs(xin6->sin6_port), ntohs(yin6->sin6_port));
1363
0
        CMP(xin6->sin6_scope_id, yin6->sin6_scope_id);
1364
0
    } else {
1365
0
        assert(!"unknown sa_family");
1366
0
    }
1367
1368
0
#undef CMP
1369
0
    return 0;
1370
0
}
1371
1372
size_t h2o_socket_getnumerichost(const struct sockaddr *sa, socklen_t salen, char *buf)
1373
3.65k
{
1374
3.65k
    if (sa->sa_family == AF_INET) {
1375
        /* fast path for IPv4 addresses */
1376
414
        struct sockaddr_in *sin = (void *)sa;
1377
414
        uint32_t addr;
1378
414
        addr = htonl(sin->sin_addr.s_addr);
1379
414
        return sprintf(buf, "%d.%d.%d.%d", addr >> 24, (addr >> 16) & 255, (addr >> 8) & 255, addr & 255);
1380
414
    }
1381
1382
3.23k
    if (getnameinfo(sa, salen, buf, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0)
1383
0
        return SIZE_MAX;
1384
3.23k
    return strlen(buf);
1385
3.23k
}
1386
1387
int32_t h2o_socket_getport(const struct sockaddr *sa)
1388
0
{
1389
0
    switch (sa->sa_family) {
1390
0
    case AF_INET:
1391
0
        return htons(((struct sockaddr_in *)sa)->sin_port);
1392
0
    case AF_INET6:
1393
0
        return htons(((struct sockaddr_in6 *)sa)->sin6_port);
1394
0
    default:
1395
0
        return -1;
1396
0
    }
1397
0
}
1398
1399
const char *h2o_socket_get_error_string(int errnum, const char *default_err)
1400
0
{
1401
0
    switch (errnum) {
1402
0
    case ECONNREFUSED:
1403
0
        return h2o_socket_error_conn_refused;
1404
0
    case ETIMEDOUT:
1405
0
        return h2o_socket_error_conn_timed_out;
1406
0
    case ENETUNREACH:
1407
0
        return h2o_socket_error_network_unreachable;
1408
0
    case EHOSTUNREACH:
1409
0
        return h2o_socket_error_host_unreachable;
1410
0
    default:
1411
0
        return default_err;
1412
0
    }
1413
0
}
1414
1415
static void create_ossl(h2o_socket_t *sock, int is_server)
1416
0
{
1417
0
    sock->ssl->ossl = SSL_new(sock->ssl->ssl_ctx);
1418
#ifdef OPENSSL_IS_BORINGSSL
1419
    if (is_server) {
1420
        SSL_set_accept_state(sock->ssl->ossl);
1421
    } else {
1422
        SSL_set_connect_state(sock->ssl->ossl);
1423
    }
1424
#else
1425
0
    assert(SSL_is_server(sock->ssl->ossl) == !!is_server);
1426
0
#endif
1427
    /* set app data to be used in h2o_socket_ssl_new_session_cb */
1428
0
    SSL_set_app_data(sock->ssl->ossl, sock);
1429
0
    setup_bio(sock);
1430
0
}
1431
1432
static SSL_SESSION *on_async_resumption_get(SSL *ssl,
1433
#if !defined(LIBRESSL_VERSION_NUMBER) ? OPENSSL_VERSION_NUMBER >= 0x1010000fL : LIBRESSL_VERSION_NUMBER > 0x2070000f
1434
                                            const
1435
#endif
1436
                                            unsigned char *data,
1437
                                            int len, int *copy)
1438
0
{
1439
0
    h2o_socket_t *sock = BIO_get_data(SSL_get_rbio(ssl));
1440
1441
0
    switch (sock->ssl->handshake.server.async_resumption.state) {
1442
0
    case ASYNC_RESUMPTION_STATE_RECORD:
1443
0
#if H2O_USE_OPENSSL_CLIENT_HELLO_CB
1444
0
        h2o_fatal("on_async_resumption_client_hello should have captured this state");
1445
0
#endif
1446
0
        sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_REQUEST_SENT;
1447
0
        resumption_get_async(sock, h2o_iovec_init(data, len));
1448
0
        return NULL;
1449
0
    case ASYNC_RESUMPTION_STATE_COMPLETE:
1450
0
        *copy = 1;
1451
0
        return sock->ssl->handshake.server.async_resumption.session_data;
1452
0
    default:
1453
0
        assert(!"FIXME");
1454
0
        return NULL;
1455
0
    }
1456
0
}
1457
1458
#if H2O_USE_OPENSSL_CLIENT_HELLO_CB
1459
static int on_async_resumption_client_hello(SSL *ssl, int *al, void *arg)
1460
0
{
1461
0
    h2o_socket_t *sock = BIO_get_data(SSL_get_rbio(ssl));
1462
0
    const unsigned char *sess_id;
1463
0
    size_t sess_id_len;
1464
1465
0
    if (sock->ssl->handshake.server.async_resumption.state == ASYNC_RESUMPTION_STATE_RECORD &&
1466
0
        (sess_id_len = SSL_client_hello_get0_session_id(ssl, &sess_id)) != 0) {
1467
0
        sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_REQUEST_SENT;
1468
0
        resumption_get_async(sock, h2o_iovec_init(sess_id, sess_id_len));
1469
0
        return SSL_CLIENT_HELLO_RETRY;
1470
0
    }
1471
1472
0
    return SSL_CLIENT_HELLO_SUCCESS;
1473
0
}
1474
#endif
1475
1476
int h2o_socket_ssl_new_session_cb(SSL *s, SSL_SESSION *sess)
1477
0
{
1478
0
    h2o_socket_t *sock = (h2o_socket_t *)SSL_get_app_data(s);
1479
0
    assert(sock != NULL);
1480
0
    assert(sock->ssl != NULL);
1481
1482
0
    if (!SSL_is_server(s) && sock->ssl->handshake.client.session_cache != NULL
1483
0
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x1010100fL
1484
0
        && SSL_SESSION_is_resumable(sess)
1485
0
#endif
1486
0
    ) {
1487
0
        h2o_cache_set(sock->ssl->handshake.client.session_cache, h2o_now(h2o_socket_get_loop(sock)),
1488
0
                      sock->ssl->handshake.client.session_cache_key, sock->ssl->handshake.client.session_cache_key_hash,
1489
0
                      h2o_iovec_init(sess, 1));
1490
0
        return 1; /* retain ref count */
1491
0
    }
1492
1493
0
    return 0; /* drop ref count */
1494
0
}
1495
1496
static int on_async_resumption_new(SSL *ssl, SSL_SESSION *session)
1497
0
{
1498
0
    h2o_socket_t *sock = BIO_get_data(SSL_get_rbio(ssl));
1499
1500
0
    h2o_iovec_t data;
1501
0
    const unsigned char *id;
1502
0
    unsigned id_len;
1503
0
    unsigned char *p;
1504
1505
    /* build data */
1506
0
    data.len = i2d_SSL_SESSION(session, NULL);
1507
0
    data.base = alloca(data.len);
1508
0
    p = (void *)data.base;
1509
0
    i2d_SSL_SESSION(session, &p);
1510
1511
0
    id = SSL_SESSION_get_id(session, &id_len);
1512
0
    resumption_new(sock, h2o_iovec_init(id, id_len), data);
1513
0
    return 0;
1514
0
}
1515
1516
/**
1517
 * transfer traffic secret to picotls and discard OpenSSL state, if possible
1518
 */
1519
static void switch_to_picotls(h2o_socket_t *sock, uint16_t csid)
1520
0
{
1521
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x1010000fL
1522
    /* Libressl and openssl 1.0.2 does not have SSL_SESSION_get_master_key, or the functions to obtain hello random. Also, they lack
1523
     * the keylog callback that can be used as an alternative. */
1524
    return;
1525
#else
1526
1527
    /* TODO When using boringssl (the only fork of OpenSSL that supports TLS 1.2 False Start), we should probably refuse to switch
1528
     * to picotls when `SSL_in_false_start` returns true, as `SSL_handshake` might signal completion before receiving Finished.
1529
     * This is a issue specific to client-side connections; it does not matter for h2o accepting TLS 1.2 connections. */
1530
1531
    /* skip protocols other than TLS 1.2 */
1532
0
    if (SSL_version(sock->ssl->ossl) != TLS1_2_VERSION)
1533
0
        return;
1534
1535
0
    ptls_context_t *ptls_ctx = h2o_socket_ssl_get_picotls_context(sock->ssl->ssl_ctx);
1536
0
    if (ptls_ctx == NULL)
1537
0
        return;
1538
1539
    /* find the corresponding zerocopy cipher suite, or bail out */
1540
0
    ptls_cipher_suite_t *cs = ptls_find_cipher_suite(ptls_ctx->tls12_cipher_suites, csid);
1541
0
    if (cs == NULL)
1542
0
        return;
1543
1544
    /* The precondition for calling `ptls_build_tl12_export_params` is that we have sent and received only one encrypted record
1545
     * (i.e., next sequence number is 1). Bail out if that expectation is not met (which is very unlikely in practice). At the same
1546
     * time, obtain explicit nonce that has been used, if the underlying AEAD uses one. */
1547
0
    if (!(sock->ssl->tls12_record_layer.last_received[1].type == 20 /* TLS 1.2 ChangeCipherSpec */ &&
1548
0
          sock->ssl->tls12_record_layer.last_received[0].type == 22 /* TLS 1.2 Handshake record */ &&
1549
0
          sock->ssl->tls12_record_layer.last_received[0].length == cs->aead->tls12.record_iv_size + 16 + cs->aead->tag_size))
1550
0
        return;
1551
0
    if (cs->aead->tls12.record_iv_size != 0 && sock->ssl->tls12_record_layer.send_finished_iv == UINT64_MAX)
1552
0
        return;
1553
1554
0
    uint8_t master_secret[PTLS_TLS12_MASTER_SECRET_SIZE], hello_randoms[PTLS_HELLO_RANDOM_SIZE * 2], params_smallbuf[128];
1555
0
    ptls_buffer_t params;
1556
0
    int ret;
1557
1558
0
    ptls_buffer_init(&params, params_smallbuf, sizeof(params_smallbuf));
1559
1560
    /* extract the necessary bits */
1561
0
    if (SSL_SESSION_get_master_key(SSL_get_session(sock->ssl->ossl), master_secret, sizeof(master_secret)) != sizeof(master_secret))
1562
0
        goto Exit;
1563
0
    if (SSL_get_server_random(sock->ssl->ossl, hello_randoms, PTLS_HELLO_RANDOM_SIZE) != PTLS_HELLO_RANDOM_SIZE)
1564
0
        goto Exit;
1565
0
    if (SSL_get_client_random(sock->ssl->ossl, hello_randoms + PTLS_HELLO_RANDOM_SIZE, PTLS_HELLO_RANDOM_SIZE) !=
1566
0
        PTLS_HELLO_RANDOM_SIZE)
1567
0
        goto Exit;
1568
1569
    /* try to create ptls context */
1570
0
    h2o_iovec_t negotiated_protocol = h2o_socket_ssl_get_selected_protocol(sock);
1571
0
    if (ptls_build_tls12_export_params(ptls_ctx, &params, SSL_is_server(sock->ssl->ossl), SSL_session_reused(sock->ssl->ossl), cs,
1572
0
                                       master_secret, hello_randoms, sock->ssl->tls12_record_layer.send_finished_iv + 1,
1573
0
                                       h2o_socket_get_ssl_server_name(sock),
1574
0
                                       ptls_iovec_init(negotiated_protocol.base, negotiated_protocol.len)) != 0)
1575
0
        goto Exit;
1576
0
    ptls_log_conn_state_override = &sock->_log_state;
1577
0
    if ((ret = ptls_import(ptls_ctx, &sock->ssl->ptls, ptls_iovec_init(params.base, params.off))) != 0)
1578
0
        h2o_fatal("failed to import TLS params built using the same context:%d", ret);
1579
0
    ptls_log_conn_state_override = NULL;
1580
1581
0
    if (sock->ssl->ptls != NULL) {
1582
0
        SSL_set_shutdown(sock->ssl->ossl, SSL_SENT_SHUTDOWN); /* close the session so that it can be resumed */
1583
0
        SSL_free(sock->ssl->ossl);
1584
0
        sock->ssl->ossl = NULL;
1585
0
    }
1586
1587
0
Exit:
1588
0
    ptls_clear_memory(master_secret, sizeof(master_secret));
1589
0
    ptls_buffer_dispose(&params);
1590
0
#endif
1591
0
}
1592
1593
static void on_handshake_complete(h2o_socket_t *sock, const char *err)
1594
0
{
1595
0
    assert(sock->ssl->handshake.cb != NULL);
1596
1597
0
    assert(!sock->ssl->async.inflight);
1598
0
    if (sock->ssl->async.sock_is_closed) {
1599
0
        shutdown_ssl(sock, NULL);
1600
0
        return;
1601
0
    }
1602
0
    if (err == NULL) {
1603
        /* Post-handshake setup: set record_overhead, zerocopy, switch to picotls */
1604
0
        if (sock->ssl->ptls == NULL) {
1605
0
            const SSL_CIPHER *cipher = SSL_get_current_cipher(sock->ssl->ossl);
1606
0
            uint32_t cipher_id = SSL_CIPHER_get_id(cipher);
1607
0
            switch (cipher_id) {
1608
0
            case TLS1_CK_RSA_WITH_AES_128_GCM_SHA256:
1609
0
#if defined(TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256)
1610
0
            case TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256:
1611
0
#endif
1612
0
            case TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
1613
0
            case TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
1614
0
                sock->ssl->record_overhead = 5 /* header */ + 8 /* iv (RFC 5288 3) */ + 16 /* tag (RFC 5116 5.1) */;
1615
0
                break;
1616
0
            case TLS1_CK_RSA_WITH_AES_256_GCM_SHA384:
1617
0
#if defined(TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384)
1618
0
            case TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384:
1619
0
#endif
1620
0
            case TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
1621
0
            case TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
1622
0
                sock->ssl->record_overhead = 5 /* header */ + 8 /* iv (RFC 5288 3) */ + 16 /* tag (RFC 5116 5.1) */;
1623
0
                break;
1624
0
#if defined(TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305)
1625
0
            case TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305:
1626
0
            case TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305:
1627
0
            case TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
1628
0
                sock->ssl->record_overhead = 5 /* header */ + 16 /* tag */;
1629
0
                break;
1630
0
#endif
1631
0
            default:
1632
0
                sock->ssl->record_overhead = 32; /* sufficiently large number that can hold most payloads */
1633
0
                break;
1634
0
            }
1635
0
            switch_to_picotls(sock, cipher_id & 0xffff /* obtain IANA cipher-suite ID in a way compatible w. OpenSSL 1.1.0 */);
1636
0
        }
1637
0
        if (sock->ssl->ptls != NULL) {
1638
0
            sock->ssl->record_overhead = ptls_get_record_overhead(sock->ssl->ptls);
1639
0
#if H2O_USE_MSG_ZEROCOPY
1640
0
            assert(sock->_zerocopy == NULL);
1641
0
            ptls_cipher_suite_t *cipher = ptls_get_cipher(sock->ssl->ptls);
1642
0
            if (cipher->aead->non_temporal) {
1643
0
                unsigned one = 1;
1644
0
                if (setsockopt(h2o_socket_get_fd(sock), SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one)) == 0) {
1645
0
                    sock->_zerocopy = h2o_mem_alloc(sizeof(*sock->_zerocopy));
1646
0
                    *sock->_zerocopy = (struct st_h2o_socket_zerocopy_buffers_t){};
1647
0
                }
1648
0
            }
1649
0
#endif
1650
0
        } else {
1651
0
            assert(sock->ssl->ossl != NULL);
1652
0
        }
1653
0
    }
1654
1655
0
    h2o_socket_cb handshake_cb = sock->ssl->handshake.cb;
1656
0
    sock->_cb.write = NULL;
1657
0
    sock->ssl->handshake.cb = NULL;
1658
0
    if (err == NULL)
1659
0
        err = decode_ssl_input(sock);
1660
0
    handshake_cb(sock, err);
1661
0
}
1662
1663
const char *get_handshake_error(struct st_h2o_socket_ssl_t *ssl)
1664
0
{
1665
0
    const char *err = h2o_socket_error_ssl_handshake;
1666
0
    if (ssl->ossl != NULL) {
1667
0
        long verify_result = SSL_get_verify_result(ssl->ossl);
1668
0
        if (verify_result != X509_V_OK) {
1669
0
            err = X509_verify_cert_error_string(verify_result);
1670
0
            assert(err != NULL);
1671
0
        }
1672
0
    }
1673
0
    return err;
1674
0
}
1675
1676
static void on_handshake_fail_complete(h2o_socket_t *sock, const char *err)
1677
0
{
1678
0
    on_handshake_complete(sock, get_handshake_error(sock->ssl));
1679
0
}
1680
1681
static void proceed_handshake(h2o_socket_t *sock, const char *err);
1682
1683
#if H2O_CAN_OSSL_ASYNC
1684
1685
void h2o_socket_start_async_handshake(h2o_loop_t *loop, int async_fd, void *data, h2o_socket_cb cb)
1686
0
{
1687
    /* dup async_fd as h2o socket handling will close it */
1688
0
    if ((async_fd = dup(async_fd)) == -1) {
1689
0
        char errbuf[256];
1690
0
        h2o_fatal("dup failed:%s", h2o_strerror_r(errno, errbuf, sizeof(errbuf)));
1691
0
    }
1692
1693
    /* add async fd to event loop in order to retry when openssl engine is ready */
1694
#if H2O_USE_LIBUV
1695
    h2o_socket_t *async_sock = h2o_uv__poll_create(loop, async_fd, (uv_close_cb)free);
1696
#else
1697
0
    h2o_socket_t *async_sock = h2o_evloop_socket_create(loop, async_fd, H2O_SOCKET_FLAG_DONT_READ);
1698
0
#endif
1699
0
    async_sock->data = data;
1700
0
    h2o_socket_read_start(async_sock, cb);
1701
0
}
1702
1703
void *h2o_socket_async_handshake_on_notify(h2o_socket_t *async_sock, const char *err)
1704
0
{
1705
0
    if (err != NULL)
1706
0
        h2o_fatal("error on internal notification fd:%s", err);
1707
1708
    /* Do we need to handle spurious events for eventfds / pipes used for intra-process communication? If so, maybe we should call
1709
     * select (2) here to assert that the socket is actually readable, and return NULL if it is not. */
1710
1711
0
    void *data = async_sock->data;
1712
1713
0
    h2o_socket_read_stop(async_sock);
1714
0
    dispose_socket(async_sock, NULL);
1715
1716
0
    return data;
1717
0
}
1718
1719
static void on_async_proceed_handshake(h2o_socket_t *async_sock, const char *err)
1720
0
{
1721
0
    h2o_socket_t *sock = h2o_socket_async_handshake_on_notify(async_sock, err);
1722
1723
0
    assert(sock->ssl->async.inflight);
1724
0
    sock->ssl->async.inflight = 0;
1725
1726
0
    proceed_handshake(sock, NULL);
1727
0
}
1728
1729
#endif
1730
1731
static void on_async_job_complete(void *_sock)
1732
0
{
1733
0
    h2o_socket_t *sock = _sock;
1734
1735
0
    assert(sock->ssl->async.inflight);
1736
0
    sock->ssl->async.inflight = 0;
1737
1738
0
    proceed_handshake(sock, NULL);
1739
0
}
1740
1741
static void do_proceed_handshake_async(h2o_socket_t *sock, ptls_buffer_t *ptls_wbuf)
1742
0
{
1743
0
    assert(!sock->ssl->async.inflight);
1744
0
    sock->ssl->async.inflight = 1;
1745
0
    h2o_socket_read_stop(sock);
1746
1747
    /* retain wbuf, wait for notification */
1748
0
    if (sock->ssl->ptls != NULL) {
1749
0
        sock->ssl->async.ptls_wbuf = *ptls_wbuf;
1750
0
        *ptls_wbuf = (ptls_buffer_t){NULL};
1751
0
        ptls_async_job_t *job = ptls_get_async_job(sock->ssl->ptls);
1752
0
        if (job->set_completion_callback != NULL) {
1753
            /* completion is notified via a callback */
1754
0
            job->set_completion_callback(job, on_async_job_complete, sock);
1755
0
        } else {
1756
0
#if H2O_CAN_OSSL_ASYNC
1757
0
            assert(job->get_fd != NULL);
1758
0
            int async_fd = job->get_fd(job);
1759
0
            h2o_socket_start_async_handshake(h2o_socket_get_loop(sock), async_fd, sock, on_async_proceed_handshake);
1760
#else
1761
            h2o_fatal("callback-based approach must have been chosen as the only option when OpenSSL async API is unavailable");
1762
#endif
1763
0
        }
1764
0
    } else {
1765
0
#if H2O_CAN_OSSL_ASYNC
1766
0
        assert(ptls_wbuf == NULL);
1767
0
        int async_fd;
1768
0
        size_t numfds;
1769
0
        SSL_get_all_async_fds(sock->ssl->ossl, NULL, &numfds);
1770
0
        assert(numfds == 1);
1771
0
        SSL_get_all_async_fds(sock->ssl->ossl, &async_fd, &numfds);
1772
0
        h2o_socket_start_async_handshake(h2o_socket_get_loop(sock), async_fd, sock, on_async_proceed_handshake);
1773
#elif defined(OPENSSL_IS_BORINGSSL)
1774
        ptls_async_job_t *job = SSL_get_ex_data(sock->ssl->ossl, h2o_socket_boringssl_get_async_job_index());
1775
        assert(job != NULL);
1776
        assert(job->set_completion_callback != NULL);
1777
        job->set_completion_callback(job, on_async_job_complete, sock);
1778
#else
1779
        h2o_fatal("how can OpenSSL ask async when the async API is unavailable");
1780
#endif
1781
0
    }
1782
0
}
1783
1784
static void proceed_handshake_picotls(h2o_socket_t *sock)
1785
0
{
1786
0
    size_t consumed = sock->ssl->input.encrypted->size;
1787
0
    ptls_buffer_t wbuf;
1788
1789
0
    if (sock->ssl->async.ptls_wbuf.base != NULL) {
1790
0
        wbuf = sock->ssl->async.ptls_wbuf;
1791
0
        sock->ssl->async.ptls_wbuf = (ptls_buffer_t){NULL};
1792
0
    } else {
1793
0
        ptls_buffer_init(&wbuf, "", 0);
1794
0
    }
1795
1796
0
    int ret = ptls_handshake(sock->ssl->ptls, &wbuf, sock->ssl->input.encrypted->bytes, &consumed, NULL);
1797
0
    h2o_buffer_consume(&sock->ssl->input.encrypted, consumed);
1798
1799
0
    if (ret == PTLS_ERROR_ASYNC_OPERATION) {
1800
0
        do_proceed_handshake_async(sock, &wbuf);
1801
0
        return;
1802
0
    }
1803
1804
    /* determine the next action */
1805
0
    h2o_socket_cb next_cb;
1806
0
    switch (ret) {
1807
0
    case 0:
1808
0
        next_cb = on_handshake_complete;
1809
0
        break;
1810
0
    case PTLS_ERROR_IN_PROGRESS:
1811
0
        next_cb = proceed_handshake;
1812
0
        break;
1813
0
    default:
1814
0
        next_cb = on_handshake_fail_complete;
1815
0
        break;
1816
0
    }
1817
1818
    /* When something is to be sent, send it and then take the next action. If there's nothing to be sent and the handshake is still
1819
     * in progress, wait for more bytes to arrive; otherwise, take the action immediately. */
1820
0
    if (wbuf.off != 0) {
1821
0
        h2o_socket_read_stop(sock);
1822
0
        write_ssl_bytes(sock, wbuf.base, wbuf.off);
1823
0
        flush_pending_ssl(sock, next_cb);
1824
0
    } else if (ret == PTLS_ERROR_IN_PROGRESS) {
1825
0
        h2o_socket_read_start(sock, next_cb);
1826
0
    } else {
1827
0
        next_cb(sock, NULL);
1828
0
    }
1829
1830
0
    ptls_buffer_dispose(&wbuf);
1831
0
}
1832
1833
static void proceed_handshake_openssl(h2o_socket_t *sock)
1834
0
{
1835
0
    h2o_iovec_t first_input = {NULL};
1836
0
    int ret = 0;
1837
0
    const char *err = NULL;
1838
1839
0
    assert(sock->ssl->ossl != NULL);
1840
1841
0
    if (SSL_is_server(sock->ssl->ossl) && sock->ssl->handshake.server.async_resumption.state == ASYNC_RESUMPTION_STATE_RECORD) {
1842
0
        if (sock->ssl->input.encrypted->size <= 1024) {
1843
            /* retain a copy of input if performing async resumption */
1844
0
            first_input = h2o_iovec_init(alloca(sock->ssl->input.encrypted->size), sock->ssl->input.encrypted->size);
1845
0
            memcpy(first_input.base, sock->ssl->input.encrypted->bytes, first_input.len);
1846
0
        } else {
1847
0
            sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE;
1848
0
        }
1849
0
    }
1850
1851
0
Redo:
1852
0
    ERR_clear_error();
1853
0
    if (SSL_is_server(sock->ssl->ossl)) {
1854
0
        ret = SSL_accept(sock->ssl->ossl);
1855
0
        switch (sock->ssl->handshake.server.async_resumption.state) {
1856
0
        case ASYNC_RESUMPTION_STATE_COMPLETE:
1857
0
            break;
1858
0
        case ASYNC_RESUMPTION_STATE_RECORD:
1859
            /* async resumption has not been triggered; proceed the state to complete */
1860
0
            sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE;
1861
0
            break;
1862
0
        case ASYNC_RESUMPTION_STATE_REQUEST_SENT: {
1863
            /* sent async request, reset the ssl state, and wait for async response */
1864
0
            assert(ret < 0);
1865
0
#if H2O_CAN_OSSL_ASYNC
1866
0
            assert(SSL_get_error(sock->ssl->ossl, ret) != SSL_ERROR_WANT_ASYNC &&
1867
0
                   "async operation should start only after resumption state is obtained and OpenSSL decides not to resume");
1868
0
#endif
1869
0
            SSL_free(sock->ssl->ossl);
1870
0
            create_ossl(sock, 1);
1871
0
            if (has_pending_ssl_bytes(sock->ssl))
1872
0
                dispose_ssl_output_buffer(sock->ssl);
1873
0
            h2o_buffer_consume(&sock->ssl->input.encrypted, sock->ssl->input.encrypted->size);
1874
0
            h2o_buffer_reserve(&sock->ssl->input.encrypted, first_input.len);
1875
0
            memcpy(sock->ssl->input.encrypted->bytes, first_input.base, first_input.len);
1876
0
            sock->ssl->input.encrypted->size = first_input.len;
1877
0
            h2o_socket_read_stop(sock);
1878
0
            return;
1879
0
        }
1880
0
        default:
1881
0
            h2o_fatal("unexpected async resumption state");
1882
0
            break;
1883
0
        }
1884
0
    } else {
1885
0
        ret = SSL_connect(sock->ssl->ossl);
1886
0
    }
1887
1888
    /* handshake failed either in strict mTLS mode or others */
1889
0
    if (ret == 0 || (ret < 0 && SSL_get_error(sock->ssl->ossl, ret) != SSL_ERROR_WANT_READ)) {
1890
0
        int is_async = 0;
1891
0
#if H2O_CAN_OSSL_ASYNC
1892
0
        is_async = SSL_get_error(sock->ssl->ossl, ret) == SSL_ERROR_WANT_ASYNC;
1893
#elif defined(OPENSSL_IS_BORINGSSL)
1894
        is_async = SSL_get_error(sock->ssl->ossl, ret) == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
1895
#endif
1896
0
        if (is_async) {
1897
0
            do_proceed_handshake_async(sock, NULL);
1898
0
            return;
1899
0
        }
1900
1901
        /* OpenSSL 1.1.0 emits an alert immediately, we  send it now. 1.0.2 emits the error when SSL_shutdown is called in
1902
         * shutdown_ssl. */
1903
0
        if (has_pending_ssl_bytes(sock->ssl)) {
1904
0
            h2o_socket_read_stop(sock);
1905
0
            flush_pending_ssl(sock, on_handshake_fail_complete);
1906
0
            return;
1907
0
        }
1908
0
        err = get_handshake_error(sock->ssl);
1909
0
        goto Complete;
1910
0
    }
1911
1912
0
    if (has_pending_ssl_bytes(sock->ssl)) {
1913
0
        h2o_socket_read_stop(sock);
1914
0
        flush_pending_ssl(sock, ret == 1 ? on_handshake_complete : proceed_handshake);
1915
0
    } else {
1916
0
        if (ret == 1) {
1917
0
            if (!SSL_is_server(sock->ssl->ossl)) {
1918
0
                X509 *cert = SSL_get_peer_certificate(sock->ssl->ossl);
1919
0
                if (cert != NULL) {
1920
0
                    switch (validate_hostname(sock->ssl->handshake.client.server_name, cert)) {
1921
0
                    case MatchFound:
1922
                        /* ok */
1923
0
                        break;
1924
0
                    case MatchNotFound:
1925
0
                        err = h2o_socket_error_ssl_cert_name_mismatch;
1926
0
                        break;
1927
0
                    default:
1928
0
                        err = h2o_socket_error_ssl_cert_invalid;
1929
0
                        break;
1930
0
                    }
1931
0
                    X509_free(cert);
1932
0
                } else {
1933
0
                    err = h2o_socket_error_ssl_no_cert;
1934
0
                }
1935
0
            }
1936
0
            goto Complete;
1937
0
        }
1938
0
        if (sock->ssl->input.encrypted->size != 0) {
1939
0
            goto Redo;
1940
0
        }
1941
0
        h2o_socket_read_start(sock, proceed_handshake);
1942
0
    }
1943
0
    return;
1944
1945
0
Complete:
1946
0
    h2o_socket_read_stop(sock);
1947
0
    on_handshake_complete(sock, err);
1948
0
}
1949
1950
/**
1951
 * Called when it is still uncertain which of the two TLS stacks (picotls or OpenSSL) should handle the handshake.
1952
 * The function first tries picotls without consuming the socket input buffer. Then, if picotls returns PTLS_ALERT_PROTOCOL_VERSION
1953
 * indicating that the client is using TLS 1.2 or below, switches to using OpenSSL.
1954
 */
1955
static void proceed_handshake_undetermined(h2o_socket_t *sock)
1956
0
{
1957
0
    assert(sock->ssl->ossl == NULL && sock->ssl->ptls == NULL);
1958
1959
0
    ptls_context_t *ptls_ctx = h2o_socket_ssl_get_picotls_context(sock->ssl->ssl_ctx);
1960
0
    assert(ptls_ctx != NULL);
1961
1962
0
    size_t consumed = sock->ssl->input.encrypted->size;
1963
0
    ptls_buffer_t wbuf;
1964
0
    ptls_buffer_init(&wbuf, "", 0);
1965
1966
0
    ptls_log_conn_state_override = &sock->_log_state;
1967
0
    ptls_t *ptls = ptls_new(ptls_ctx, 1);
1968
0
    ptls_log_conn_state_override = NULL;
1969
0
    if (ptls == NULL)
1970
0
        h2o_fatal("no memory");
1971
0
    *ptls_get_data_ptr(ptls) = sock;
1972
0
    int ret = ptls_handshake(ptls, &wbuf, sock->ssl->input.encrypted->bytes, &consumed, NULL);
1973
1974
0
    if (ret == PTLS_ERROR_IN_PROGRESS && wbuf.off == 0) {
1975
        /* we aren't sure if the picotls can process the handshake, retain handshake transcript and replay on next occasion */
1976
0
        ptls_free(ptls);
1977
0
    } else if (ret == PTLS_ALERT_PROTOCOL_VERSION) {
1978
        /* the client cannot use tls1.3, fallback to openssl */
1979
0
        ptls_free(ptls);
1980
0
        create_ossl(sock, 1);
1981
0
        proceed_handshake_openssl(sock);
1982
0
    } else {
1983
        /* picotls is responsible for handling the handshake */
1984
0
        sock->ssl->ptls = ptls;
1985
0
        sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE;
1986
0
        h2o_buffer_consume(&sock->ssl->input.encrypted, consumed);
1987
0
        if (ret == PTLS_ERROR_ASYNC_OPERATION) {
1988
0
            do_proceed_handshake_async(sock, &wbuf);
1989
0
            return;
1990
0
        }
1991
        /* stop reading, send response */
1992
0
        h2o_socket_read_stop(sock);
1993
0
        write_ssl_bytes(sock, wbuf.base, wbuf.off);
1994
0
        h2o_socket_cb cb;
1995
0
        switch (ret) {
1996
0
        case 0:
1997
0
            cb = on_handshake_complete;
1998
0
            break;
1999
0
        case PTLS_ERROR_IN_PROGRESS:
2000
0
            cb = proceed_handshake;
2001
0
            break;
2002
0
        default:
2003
0
            assert(ret != PTLS_ERROR_STATELESS_RETRY && "stateless retry is never turned on by us for TCP");
2004
0
            cb = on_handshake_fail_complete;
2005
0
            break;
2006
0
        }
2007
0
        flush_pending_ssl(sock, cb);
2008
0
    }
2009
0
    ptls_buffer_dispose(&wbuf);
2010
0
}
2011
2012
static void proceed_handshake(h2o_socket_t *sock, const char *err)
2013
0
{
2014
0
    assert(!sock->ssl->async.inflight && "while async operation is inflight, the socket should be neither reading nor writing");
2015
2016
0
    sock->_cb.write = NULL;
2017
2018
0
    if (err != NULL) {
2019
0
        h2o_socket_read_stop(sock);
2020
0
        on_handshake_complete(sock, err);
2021
0
        return;
2022
0
    }
2023
2024
0
    if (sock->ssl->ptls != NULL) {
2025
0
        proceed_handshake_picotls(sock);
2026
0
    } else if (sock->ssl->ossl != NULL) {
2027
0
        proceed_handshake_openssl(sock);
2028
0
    } else if (h2o_socket_ssl_get_picotls_context(sock->ssl->ssl_ctx) == NULL) {
2029
0
        create_ossl(sock, 1);
2030
0
        proceed_handshake_openssl(sock);
2031
0
    } else {
2032
0
        proceed_handshake_undetermined(sock);
2033
0
    }
2034
0
}
2035
2036
void h2o_socket_ssl_handshake(h2o_socket_t *sock, SSL_CTX *ssl_ctx, const char *server_name, h2o_iovec_t alpn_protos,
2037
                              h2o_socket_cb handshake_cb)
2038
0
{
2039
0
    sock->ssl = h2o_mem_alloc(sizeof(*sock->ssl));
2040
0
    *sock->ssl = (struct st_h2o_socket_ssl_t){
2041
0
        .ssl_ctx = ssl_ctx, .handshake = {.cb = handshake_cb}, .tls12_record_layer = {.send_finished_iv = UINT64_MAX}};
2042
#if H2O_USE_KTLS
2043
    /* Set offload state to TBD if kTLS is enabled. Otherwise, remains H2O_SOCKET_SSL_OFFLOAD_OFF. */
2044
    if (h2o_socket_use_ktls)
2045
        sock->ssl->offload = H2O_SOCKET_SSL_OFFLOAD_TBD;
2046
#endif
2047
2048
    /* setup the buffers; sock->input should be empty, sock->ssl->input.encrypted should contain the initial input, if any */
2049
0
    h2o_buffer_init(&sock->ssl->input.encrypted, &h2o_socket_buffer_prototype);
2050
0
    if (sock->input->size != 0) {
2051
0
        h2o_buffer_t *tmp = sock->input;
2052
0
        sock->input = sock->ssl->input.encrypted;
2053
0
        sock->ssl->input.encrypted = tmp;
2054
0
    }
2055
2056
0
    if (server_name == NULL) {
2057
        /* is server */
2058
0
        if (SSL_CTX_sess_get_get_cb(sock->ssl->ssl_ctx) != NULL)
2059
0
            sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_RECORD;
2060
0
        if (sock->ssl->input.encrypted->size != 0)
2061
0
            proceed_handshake(sock, 0);
2062
0
        else
2063
0
            h2o_socket_read_start(sock, proceed_handshake);
2064
0
    } else {
2065
0
        create_ossl(sock, 0);
2066
0
        if (alpn_protos.base != NULL)
2067
0
            SSL_set_alpn_protos(sock->ssl->ossl, (const unsigned char *)alpn_protos.base, (unsigned)alpn_protos.len);
2068
0
        h2o_cache_t *session_cache = h2o_socket_ssl_get_session_cache(sock->ssl->ssl_ctx);
2069
0
        if (session_cache != NULL) {
2070
0
            struct sockaddr_storage sa;
2071
0
            int32_t port;
2072
0
            if (h2o_socket_getpeername(sock, (struct sockaddr *)&sa) != 0 &&
2073
0
                (port = h2o_socket_getport((struct sockaddr *)&sa)) != -1) {
2074
                /* session cache is available */
2075
0
                h2o_iovec_t session_cache_key;
2076
0
                session_cache_key.base = h2o_mem_alloc(strlen(server_name) + sizeof(":" H2O_UINT16_LONGEST_STR));
2077
0
                session_cache_key.len = sprintf(session_cache_key.base, "%s:%" PRIu16, server_name, (uint16_t)port);
2078
0
                sock->ssl->handshake.client.session_cache = session_cache;
2079
0
                sock->ssl->handshake.client.session_cache_key = session_cache_key;
2080
0
                sock->ssl->handshake.client.session_cache_key_hash =
2081
0
                    h2o_cache_calchash(session_cache_key.base, session_cache_key.len);
2082
2083
                /* fetch from session cache */
2084
0
                h2o_cache_ref_t *cacheref = h2o_cache_fetch(session_cache, h2o_now(h2o_socket_get_loop(sock)),
2085
0
                                                            sock->ssl->handshake.client.session_cache_key,
2086
0
                                                            sock->ssl->handshake.client.session_cache_key_hash);
2087
0
                if (cacheref != NULL) {
2088
0
                    SSL_set_session(sock->ssl->ossl, (SSL_SESSION *)cacheref->value.base);
2089
0
                    h2o_cache_release(session_cache, cacheref);
2090
0
                }
2091
0
            }
2092
0
        }
2093
0
        sock->ssl->handshake.client.server_name = h2o_strdup(NULL, server_name, SIZE_MAX).base;
2094
0
        SSL_set_tlsext_host_name(sock->ssl->ossl, sock->ssl->handshake.client.server_name);
2095
0
        proceed_handshake(sock, 0);
2096
0
    }
2097
0
}
2098
2099
void h2o_socket_ssl_resume_server_handshake(h2o_socket_t *sock, h2o_iovec_t session_data)
2100
0
{
2101
0
    if (session_data.len != 0) {
2102
0
        const unsigned char *p = (void *)session_data.base;
2103
0
        sock->ssl->handshake.server.async_resumption.session_data = d2i_SSL_SESSION(NULL, &p, (long)session_data.len);
2104
        /* FIXME warn on failure */
2105
0
    }
2106
2107
0
    sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE;
2108
0
    proceed_handshake(sock, 0);
2109
2110
0
    if (sock->ssl->handshake.server.async_resumption.session_data != NULL) {
2111
0
        SSL_SESSION_free(sock->ssl->handshake.server.async_resumption.session_data);
2112
0
        sock->ssl->handshake.server.async_resumption.session_data = NULL;
2113
0
    }
2114
0
}
2115
2116
void h2o_socket_ssl_async_resumption_init(h2o_socket_ssl_resumption_get_async_cb get_async_cb,
2117
                                          h2o_socket_ssl_resumption_new_cb new_cb)
2118
0
{
2119
0
    resumption_get_async = get_async_cb;
2120
0
    resumption_new = new_cb;
2121
0
}
2122
2123
void h2o_socket_ssl_async_resumption_setup_ctx(SSL_CTX *ctx)
2124
0
{
2125
    /**
2126
     * Asynchronous resumption is a feature of libh2o that allows the use of an external session store.
2127
     * The traditional API provided by OpenSSL (`SSL_CTX_sess_set_get_cb`) assumes a blocking operation for the session store
2128
     * lookup. However, on an event-loop-based design, we cannot block while sending a request to and waiting for a response from a
2129
     * remote session store.
2130
     * Our strategy to evade this problem is to run the handshake twice for each TCP connection. When the `SSL_CTX_sess_set_get_cb`
2131
     * callback is called for the first time, asynchronous lookup is initiated. Then, immediately, the TLS handshake state is
2132
     * discarded, while ClientHello (input from TCP to the SSL handshake state machine) is retained. Once the asynchronous lookup is
2133
     * complete, we rerun the TLS handshake from scratch. When the session callback is called again, the result of the asynchronous
2134
     * lookup is supplied.
2135
     * With OpenSSL 1.1.1 and above, `SSL_CTX_set_client_hello_cb` is used to capture the session ID. This is because with the new
2136
     * callback it is possible to stop the SSL handshake state machine from preparing the full handshake response. With the old
2137
     * `SSL_CTX_sess_set_get_cb` callback, it is impossible to stop OpenSSL doing that even in the case of us discarding everything
2138
     * modulo the session ID. That includes private key operation which is very CPU intensive.
2139
     */
2140
0
    SSL_CTX_sess_set_get_cb(ctx, on_async_resumption_get);
2141
0
    SSL_CTX_sess_set_new_cb(ctx, on_async_resumption_new);
2142
0
#if H2O_USE_OPENSSL_CLIENT_HELLO_CB
2143
0
    SSL_CTX_set_client_hello_cb(ctx, on_async_resumption_client_hello, NULL);
2144
0
#endif
2145
2146
    /* if necessary, it is the responsibility of the caller to disable the internal cache */
2147
0
}
2148
2149
static int get_ptls_index(void)
2150
0
{
2151
0
    static volatile int index;
2152
0
    H2O_MULTITHREAD_ONCE({ index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); });
2153
0
    return index;
2154
0
}
2155
2156
ptls_context_t *h2o_socket_ssl_get_picotls_context(SSL_CTX *ossl)
2157
0
{
2158
0
    return SSL_CTX_get_ex_data(ossl, get_ptls_index());
2159
0
}
2160
2161
void h2o_socket_ssl_set_picotls_context(SSL_CTX *ossl, ptls_context_t *ptls)
2162
0
{
2163
0
    SSL_CTX_set_ex_data(ossl, get_ptls_index(), ptls);
2164
0
}
2165
2166
static void on_dispose_ssl_ctx_session_cache(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
2167
0
{
2168
0
    h2o_cache_t *ssl_session_cache = (h2o_cache_t *)ptr;
2169
0
    if (ssl_session_cache != NULL)
2170
0
        h2o_cache_destroy(ssl_session_cache);
2171
0
}
2172
2173
static int get_ssl_session_cache_index(void)
2174
0
{
2175
0
    static volatile int index;
2176
0
    H2O_MULTITHREAD_ONCE({ index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, on_dispose_ssl_ctx_session_cache); });
2177
0
    return index;
2178
0
}
2179
2180
h2o_cache_t *h2o_socket_ssl_get_session_cache(SSL_CTX *ctx)
2181
0
{
2182
0
    return (h2o_cache_t *)SSL_CTX_get_ex_data(ctx, get_ssl_session_cache_index());
2183
0
}
2184
2185
void h2o_socket_ssl_set_session_cache(SSL_CTX *ctx, h2o_cache_t *cache)
2186
0
{
2187
0
    SSL_CTX_set_ex_data(ctx, get_ssl_session_cache_index(), cache);
2188
0
}
2189
2190
void h2o_socket_ssl_destroy_session_cache_entry(h2o_iovec_t value)
2191
0
{
2192
0
    SSL_SESSION *session = (SSL_SESSION *)value.base;
2193
0
    SSL_SESSION_free(session);
2194
0
}
2195
2196
h2o_iovec_t h2o_socket_ssl_get_selected_protocol(h2o_socket_t *sock)
2197
0
{
2198
0
    const unsigned char *data = NULL;
2199
0
    unsigned len = 0;
2200
2201
0
    if (sock->ssl == NULL)
2202
0
        return h2o_iovec_init(NULL, 0);
2203
2204
0
    if (sock->ssl->ptls != NULL) {
2205
0
        const char *proto = ptls_get_negotiated_protocol(sock->ssl->ptls);
2206
0
        return proto != NULL ? h2o_iovec_init(proto, strlen(proto)) : h2o_iovec_init(NULL, 0);
2207
0
    }
2208
2209
0
#if H2O_USE_ALPN
2210
0
    if (len == 0)
2211
0
        SSL_get0_alpn_selected(sock->ssl->ossl, &data, &len);
2212
0
#endif
2213
0
#if H2O_USE_NPN
2214
0
    if (len == 0)
2215
0
        SSL_get0_next_proto_negotiated(sock->ssl->ossl, &data, &len);
2216
0
#endif
2217
2218
0
    return h2o_iovec_init(data, len);
2219
0
}
2220
2221
int h2o_socket_ssl_is_early_data(h2o_socket_t *sock)
2222
0
{
2223
0
    assert(sock->ssl != NULL);
2224
2225
0
    if (sock->ssl->ptls != NULL && !ptls_handshake_is_complete(sock->ssl->ptls))
2226
0
        return 1;
2227
0
    return 0;
2228
0
}
2229
2230
static int on_alpn_select(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *_in, unsigned int inlen,
2231
                          void *_protocols)
2232
0
{
2233
0
    const h2o_iovec_t *protocols = _protocols;
2234
0
    size_t i;
2235
2236
0
    for (i = 0; protocols[i].len != 0; ++i) {
2237
0
        const unsigned char *in = _in, *in_end = in + inlen;
2238
0
        while (in != in_end) {
2239
0
            size_t cand_len = *in++;
2240
0
            if (in_end - in < cand_len) {
2241
                /* broken request */
2242
0
                return SSL_TLSEXT_ERR_NOACK;
2243
0
            }
2244
0
            if (cand_len == protocols[i].len && memcmp(in, protocols[i].base, cand_len) == 0) {
2245
0
                goto Found;
2246
0
            }
2247
0
            in += cand_len;
2248
0
        }
2249
0
    }
2250
    /* not found */
2251
0
    return SSL_TLSEXT_ERR_NOACK;
2252
2253
0
Found:
2254
0
    *out = (const unsigned char *)protocols[i].base;
2255
0
    *outlen = (unsigned char)protocols[i].len;
2256
0
    return SSL_TLSEXT_ERR_OK;
2257
0
}
2258
2259
#if H2O_USE_ALPN
2260
2261
void h2o_ssl_register_alpn_protocols(SSL_CTX *ctx, const h2o_iovec_t *protocols)
2262
0
{
2263
0
    SSL_CTX_set_alpn_select_cb(ctx, on_alpn_select, (void *)protocols);
2264
0
}
2265
2266
#endif
2267
2268
#if H2O_USE_NPN
2269
2270
static int on_npn_advertise(SSL *ssl, const unsigned char **out, unsigned *outlen, void *protocols)
2271
0
{
2272
0
    *out = protocols;
2273
0
    *outlen = (unsigned)strlen(protocols);
2274
0
    return SSL_TLSEXT_ERR_OK;
2275
0
}
2276
2277
void h2o_ssl_register_npn_protocols(SSL_CTX *ctx, const char *protocols)
2278
0
{
2279
0
    SSL_CTX_set_next_protos_advertised_cb(ctx, on_npn_advertise, (void *)protocols);
2280
0
}
2281
2282
#endif
2283
2284
int h2o_socket_set_df_bit(int fd, int domain)
2285
0
{
2286
0
#define SETSOCKOPT(ip, optname, _optvar)                                                                                           \
2287
0
    do {                                                                                                                           \
2288
0
        int optvar = _optvar;                                                                                                      \
2289
0
        if (setsockopt(fd, ip, optname, &optvar, sizeof(optvar)) != 0) {                                                           \
2290
0
            perror("failed to set the DF bit through setsockopt(" H2O_TO_STR(ip) ", " H2O_TO_STR(optname) ")");                    \
2291
0
            return 0;                                                                                                              \
2292
0
        }                                                                                                                          \
2293
0
        return 1;                                                                                                                  \
2294
0
    } while (0)
2295
2296
0
    switch (domain) {
2297
0
    case AF_INET:
2298
0
#if defined(IP_PMTUDISC_DO)
2299
0
        SETSOCKOPT(IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DO);
2300
#elif defined(IP_DONTFRAG)
2301
        SETSOCKOPT(IPPROTO_IP, IP_DONTFRAG, 1);
2302
#endif
2303
0
        break;
2304
0
    case AF_INET6:
2305
0
#if defined(IPV6_PMTUDISC_DO)
2306
0
        SETSOCKOPT(IPPROTO_IPV6, IPV6_MTU_DISCOVER, IPV6_PMTUDISC_DO);
2307
#elif defined(IPV6_DONTFRAG)
2308
        SETSOCKOPT(IPPROTO_IPV6, IPV6_DONTFRAG, 1);
2309
#endif
2310
0
        break;
2311
0
    default:
2312
0
        break;
2313
0
    }
2314
2315
0
    return 1;
2316
2317
0
#undef SETSOCKOPT
2318
0
}
2319
2320
void h2o_sliding_counter_stop(h2o_sliding_counter_t *counter, uint64_t now)
2321
35.3k
{
2322
35.3k
    uint64_t elapsed;
2323
2324
35.3k
    assert(counter->cur.start_at != 0);
2325
2326
    /* calculate the time used, and reset cur */
2327
35.3k
    if (now <= counter->cur.start_at)
2328
4
        elapsed = 0;
2329
35.3k
    else
2330
35.3k
        elapsed = now - counter->cur.start_at;
2331
35.3k
    counter->cur.start_at = 0;
2332
2333
    /* adjust prev */
2334
35.3k
    counter->prev.sum += elapsed;
2335
35.3k
    counter->prev.sum -= counter->prev.slots[counter->prev.index];
2336
35.3k
    counter->prev.slots[counter->prev.index] = elapsed;
2337
35.3k
    if (++counter->prev.index >= sizeof(counter->prev.slots) / sizeof(counter->prev.slots[0]))
2338
4.41k
        counter->prev.index = 0;
2339
2340
    /* recalc average */
2341
35.3k
    counter->average = counter->prev.sum / (sizeof(counter->prev.slots) / sizeof(counter->prev.slots[0]));
2342
35.3k
}
2343
2344
void h2o_sendvec_init_raw(h2o_sendvec_t *vec, const void *base, size_t len)
2345
32.9k
{
2346
32.9k
    static const h2o_sendvec_callbacks_t callbacks = {h2o_sendvec_read_raw};
2347
32.9k
    vec->callbacks = &callbacks;
2348
32.9k
    vec->raw = (char *)base;
2349
32.9k
    vec->len = len;
2350
32.9k
}
2351
2352
int h2o_sendvec_read_raw(h2o_sendvec_t *src, void *dst, size_t len)
2353
5.84k
{
2354
5.84k
    assert(len <= src->len);
2355
5.84k
    memcpy(dst, src->raw, len);
2356
5.84k
    src->raw += len;
2357
5.84k
    src->len -= len;
2358
5.84k
    return 1;
2359
5.84k
}
2360
2361
int zerocopy_buffers_is_empty(struct st_h2o_socket_zerocopy_buffers_t *buffers)
2362
0
{
2363
0
    return buffers->first == buffers->last;
2364
0
}
2365
2366
void zerocopy_buffers_dispose(struct st_h2o_socket_zerocopy_buffers_t *buffers)
2367
0
{
2368
0
    assert(zerocopy_buffers_is_empty(buffers));
2369
0
    if (buffers->bufs != NULL)
2370
0
        free(buffers->bufs);
2371
0
}
2372
2373
void zerocopy_buffers_push(struct st_h2o_socket_zerocopy_buffers_t *buffers, void *p)
2374
0
{
2375
0
    if (buffers->last >= buffers->capacity) {
2376
0
        assert(buffers->last == buffers->capacity);
2377
0
        size_t new_capacity = (buffers->last - buffers->first) * 2;
2378
0
        if (new_capacity < 16)
2379
0
            new_capacity = 16;
2380
0
        if (new_capacity <= buffers->capacity) {
2381
0
            memmove(buffers->bufs, buffers->bufs + buffers->first, sizeof(buffers->bufs[0]) * (buffers->last - buffers->first));
2382
0
        } else {
2383
0
            void **newbufs = h2o_mem_alloc(sizeof(newbufs[0]) * new_capacity);
2384
0
            h2o_memcpy(newbufs, buffers->bufs + buffers->first, sizeof(newbufs[0]) * (buffers->last - buffers->first));
2385
0
            free(buffers->bufs);
2386
0
            buffers->bufs = newbufs;
2387
0
            buffers->capacity = new_capacity;
2388
0
        }
2389
0
        buffers->last -= buffers->first;
2390
0
        buffers->first = 0;
2391
0
    }
2392
0
    buffers->bufs[buffers->last++] = p;
2393
0
}
2394
2395
void *zerocopy_buffers_release(struct st_h2o_socket_zerocopy_buffers_t *buffers, uint64_t counter)
2396
0
{
2397
0
    assert(buffers->first_counter <= counter);
2398
2399
0
    size_t free_slot = buffers->first + (counter - buffers->first_counter);
2400
0
    assert(free_slot < buffers->last);
2401
2402
    /* Determine the address represented by given counter. */
2403
0
    void *free_ptr = buffers->bufs[free_slot];
2404
0
    assert(free_ptr != NULL);
2405
2406
    /* Search for adjacent entries that refer to the same address. If found, the address cannot be freed yet; hence set the return
2407
     * value to NULL. Rationale: when sendmsg returns partial write, one memory block would be registered multiple times in a
2408
     * consecutive manner. Such memory block can be freed only when the last entry is being released. */
2409
0
    for (size_t i = free_slot + 1; i < buffers->last; ++i) {
2410
0
        if (buffers->bufs[i] != NULL) {
2411
0
            if (buffers->bufs[i] == free_ptr)
2412
0
                free_ptr = NULL;
2413
0
            break;
2414
0
        }
2415
0
    }
2416
0
    if (free_ptr != NULL && free_slot > buffers->first) {
2417
0
        size_t i = free_slot - 1;
2418
0
        do {
2419
0
            if (buffers->bufs[i] != NULL) {
2420
0
                if (buffers->bufs[i] == free_ptr)
2421
0
                    free_ptr = NULL;
2422
0
                break;
2423
0
            }
2424
0
        } while (i-- > buffers->first);
2425
0
    }
2426
2427
0
    if (buffers->first_counter == counter) {
2428
        /* Release is in-order. Move `first` and `first_counter` to the next valid entry. */
2429
0
        ++buffers->first;
2430
0
        ++buffers->first_counter;
2431
0
        while (buffers->first != buffers->last) {
2432
0
            if (buffers->bufs[buffers->first] != NULL)
2433
0
                break;
2434
0
            ++buffers->first;
2435
0
            ++buffers->first_counter;
2436
0
        }
2437
0
        if (buffers->first == buffers->last) {
2438
0
            buffers->first = 0;
2439
0
            buffers->last = 0;
2440
0
        }
2441
0
    } else {
2442
        /* Out-of-order: just clear the slot. */
2443
0
        buffers->bufs[free_slot] = NULL;
2444
0
    }
2445
2446
0
    return free_ptr;
2447
0
}
2448
2449
void h2o_socket_clear_recycle(int full)
2450
0
{
2451
0
    h2o_mem_clear_recycle(&h2o_socket_ssl_buffer_allocator, full);
2452
0
    h2o_mem_clear_recycle(&h2o_socket_zerocopy_buffer_allocator, full);
2453
0
}
2454
2455
int h2o_socket_recycle_is_empty(void)
2456
0
{
2457
0
    return h2o_mem_recycle_is_empty(&h2o_socket_ssl_buffer_allocator) &&
2458
0
           h2o_mem_recycle_is_empty(&h2o_socket_zerocopy_buffer_allocator);
2459
0
}
2460
2461
#ifdef OPENSSL_IS_BORINGSSL
2462
2463
int h2o_socket_boringssl_get_async_job_index(void)
2464
{
2465
    static volatile int index;
2466
    H2O_MULTITHREAD_ONCE({ index = SSL_get_ex_new_index(0, 0, NULL, NULL, NULL); });
2467
    return index;
2468
}
2469
2470
int h2o_socket_boringssl_async_resumption_in_flight(SSL *ssl)
2471
{
2472
    h2o_socket_t *sock = BIO_get_data(SSL_get_rbio(ssl));
2473
    return SSL_is_server(ssl) && sock->ssl->handshake.server.async_resumption.state == ASYNC_RESUMPTION_STATE_REQUEST_SENT;
2474
}
2475
2476
#endif