iodine 0.7.36 → 0.7.41
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
- data/.travis.yml +10 -8
- data/CHANGELOG.md +28 -0
- data/README.md +55 -48
- data/Rakefile +3 -1
- data/examples/shootout.ru +8 -0
- data/exe/iodine +1 -0
- data/ext/iodine/extconf.rb +0 -34
- data/ext/iodine/fio.c +65 -65
- data/ext/iodine/fio.h +1 -1
- data/ext/iodine/fio_tls_missing.c +6 -0
- data/ext/iodine/fio_tls_openssl.c +64 -28
- data/ext/iodine/http.c +87 -100
- data/ext/iodine/http1.c +6 -15
- data/ext/iodine/http1_parser.h +806 -63
- data/ext/iodine/iodine.c +12 -0
- data/ext/iodine/iodine_defer.c +1 -0
- data/ext/iodine/iodine_http.c +11 -0
- data/ext/iodine/iodine_http.h +2 -0
- data/ext/iodine/iodine_rack_io.c +1 -5
- data/ext/iodine/iodine_tls.c +2 -16
- data/iodine.gemspec +2 -2
- data/lib/iodine.rb +2 -1
- data/lib/iodine/connection.rb +12 -0
- data/lib/iodine/version.rb +1 -1
- metadata +7 -7
- data/ext/iodine/http1_parser.c +0 -458
data/ext/iodine/fio.c
CHANGED
@@ -36,6 +36,12 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
36
36
|
|
37
37
|
#include <arpa/inet.h>
|
38
38
|
|
39
|
+
#if HAVE_OPENSSL
|
40
|
+
#include <openssl/bio.h>
|
41
|
+
#include <openssl/err.h>
|
42
|
+
#include <openssl/ssl.h>
|
43
|
+
#endif
|
44
|
+
|
39
45
|
/* force poll for testing? */
|
40
46
|
#ifndef FIO_ENGINE_POLL
|
41
47
|
#define FIO_ENGINE_POLL 0
|
@@ -277,26 +283,6 @@ static inline fio_packet_s *fio_packet_alloc(void) {
|
|
277
283
|
Core Connection Data Clearing
|
278
284
|
***************************************************************************** */
|
279
285
|
|
280
|
-
/* set the minimal max_protocol_fd */
|
281
|
-
static void fio_max_fd_min(uint32_t fd) {
|
282
|
-
if (fio_data->max_protocol_fd > fd)
|
283
|
-
return;
|
284
|
-
fio_lock(&fio_data->lock);
|
285
|
-
if (fio_data->max_protocol_fd < fd)
|
286
|
-
fio_data->max_protocol_fd = fd;
|
287
|
-
fio_unlock(&fio_data->lock);
|
288
|
-
}
|
289
|
-
|
290
|
-
/* set the minimal max_protocol_fd */
|
291
|
-
static void fio_max_fd_shrink(void) {
|
292
|
-
fio_lock(&fio_data->lock);
|
293
|
-
uint32_t fd = fio_data->max_protocol_fd;
|
294
|
-
while (fd && fd_data(fd).protocol == NULL)
|
295
|
-
--fd;
|
296
|
-
fio_data->max_protocol_fd = fd;
|
297
|
-
fio_unlock(&fio_data->lock);
|
298
|
-
}
|
299
|
-
|
300
286
|
/* resets connection data, marking it as either open or closed. */
|
301
287
|
static inline int fio_clear_fd(intptr_t fd, uint8_t is_open) {
|
302
288
|
fio_packet_s *packet;
|
@@ -318,6 +304,13 @@ static inline int fio_clear_fd(intptr_t fd, uint8_t is_open) {
|
|
318
304
|
.counter = fd_data(fd).counter + 1,
|
319
305
|
.packet_last = &fd_data(fd).packet,
|
320
306
|
};
|
307
|
+
if (fio_data->max_protocol_fd < fd) {
|
308
|
+
fio_data->max_protocol_fd = fd;
|
309
|
+
} else {
|
310
|
+
while (fio_data->max_protocol_fd &&
|
311
|
+
!fd_data(fio_data->max_protocol_fd).open)
|
312
|
+
--fio_data->max_protocol_fd;
|
313
|
+
}
|
321
314
|
fio_unlock(&(fd_data(fd).sock_lock));
|
322
315
|
if (rw_hooks && rw_hooks->cleanup)
|
323
316
|
rw_hooks->cleanup(rw_udata);
|
@@ -336,8 +329,8 @@ static inline int fio_clear_fd(intptr_t fd, uint8_t is_open) {
|
|
336
329
|
if (protocol && protocol->on_close) {
|
337
330
|
fio_defer(deferred_on_close, (void *)fd2uuid(fd), protocol);
|
338
331
|
}
|
339
|
-
|
340
|
-
|
332
|
+
FIO_LOG_DEBUG("FD %d re-initialized (state: %p-%s).", (int)fd,
|
333
|
+
(void *)fd2uuid(fd), (is_open ? "open" : "closed"));
|
341
334
|
return 0;
|
342
335
|
}
|
343
336
|
|
@@ -2887,7 +2880,7 @@ void fio_close(intptr_t uuid) {
|
|
2887
2880
|
}
|
2888
2881
|
if (uuid_data(uuid).packet || uuid_data(uuid).sock_lock) {
|
2889
2882
|
uuid_data(uuid).close = 1;
|
2890
|
-
|
2883
|
+
fio_force_event(uuid, FIO_EVENT_ON_READY);
|
2891
2884
|
return;
|
2892
2885
|
}
|
2893
2886
|
fio_force_close(uuid);
|
@@ -3019,6 +3012,7 @@ test_errno:
|
|
3019
3012
|
case ENOSPC: /* fallthrough */
|
3020
3013
|
case EADDRNOTAVAIL: /* fallthrough */
|
3021
3014
|
case EINTR:
|
3015
|
+
case 0:
|
3022
3016
|
return 1;
|
3023
3017
|
case EFAULT:
|
3024
3018
|
FIO_LOG_ERROR("fio_flush EFAULT - possible memory address error sent to "
|
@@ -3032,8 +3026,8 @@ test_errno:
|
|
3032
3026
|
fio_force_close(uuid);
|
3033
3027
|
return -1;
|
3034
3028
|
}
|
3035
|
-
|
3036
|
-
|
3029
|
+
FIO_LOG_DEBUG("UUID error: %p (%d): %s\n", (void *)uuid, errno,
|
3030
|
+
strerror(errno));
|
3037
3031
|
return 0;
|
3038
3032
|
|
3039
3033
|
invalid:
|
@@ -3099,6 +3093,19 @@ const fio_rw_hook_s FIO_DEFAULT_RW_HOOKS = {
|
|
3099
3093
|
.cleanup = fio_hooks_default_cleanup,
|
3100
3094
|
};
|
3101
3095
|
|
3096
|
+
static inline void fio_rw_hook_validate(fio_rw_hook_s *rw_hooks) {
|
3097
|
+
if (!rw_hooks->read)
|
3098
|
+
rw_hooks->read = fio_hooks_default_read;
|
3099
|
+
if (!rw_hooks->write)
|
3100
|
+
rw_hooks->write = fio_hooks_default_write;
|
3101
|
+
if (!rw_hooks->flush)
|
3102
|
+
rw_hooks->flush = fio_hooks_default_flush;
|
3103
|
+
if (!rw_hooks->before_close)
|
3104
|
+
rw_hooks->before_close = fio_hooks_default_before_close;
|
3105
|
+
if (!rw_hooks->cleanup)
|
3106
|
+
rw_hooks->cleanup = fio_hooks_default_cleanup;
|
3107
|
+
}
|
3108
|
+
|
3102
3109
|
/**
|
3103
3110
|
* Replaces an existing read/write hook with another from within a read/write
|
3104
3111
|
* hook callback.
|
@@ -3112,19 +3119,10 @@ int fio_rw_hook_replace_unsafe(intptr_t uuid, fio_rw_hook_s *rw_hooks,
|
|
3112
3119
|
int replaced = -1;
|
3113
3120
|
uint8_t was_locked;
|
3114
3121
|
intptr_t fd = fio_uuid2fd(uuid);
|
3115
|
-
|
3116
|
-
rw_hooks->read = fio_hooks_default_read;
|
3117
|
-
if (!rw_hooks->write)
|
3118
|
-
rw_hooks->write = fio_hooks_default_write;
|
3119
|
-
if (!rw_hooks->flush)
|
3120
|
-
rw_hooks->flush = fio_hooks_default_flush;
|
3121
|
-
if (!rw_hooks->before_close)
|
3122
|
-
rw_hooks->before_close = fio_hooks_default_before_close;
|
3123
|
-
if (!rw_hooks->cleanup)
|
3124
|
-
rw_hooks->cleanup = fio_hooks_default_cleanup;
|
3122
|
+
fio_rw_hook_validate(rw_hooks);
|
3125
3123
|
/* protect against some fulishness... but not all of it. */
|
3126
3124
|
was_locked = fio_trylock(&fd_data(fd).sock_lock);
|
3127
|
-
if (
|
3125
|
+
if (uuid_is_valid(uuid)) {
|
3128
3126
|
fd_data(fd).rw_hooks = rw_hooks;
|
3129
3127
|
fd_data(fd).rw_udata = udata;
|
3130
3128
|
replaced = 0;
|
@@ -3138,16 +3136,7 @@ int fio_rw_hook_replace_unsafe(intptr_t uuid, fio_rw_hook_s *rw_hooks,
|
|
3138
3136
|
int fio_rw_hook_set(intptr_t uuid, fio_rw_hook_s *rw_hooks, void *udata) {
|
3139
3137
|
if (fio_is_closed(uuid))
|
3140
3138
|
goto invalid_uuid;
|
3141
|
-
|
3142
|
-
rw_hooks->read = fio_hooks_default_read;
|
3143
|
-
if (!rw_hooks->write)
|
3144
|
-
rw_hooks->write = fio_hooks_default_write;
|
3145
|
-
if (!rw_hooks->flush)
|
3146
|
-
rw_hooks->flush = fio_hooks_default_flush;
|
3147
|
-
if (!rw_hooks->before_close)
|
3148
|
-
rw_hooks->before_close = fio_hooks_default_before_close;
|
3149
|
-
if (!rw_hooks->cleanup)
|
3150
|
-
rw_hooks->cleanup = fio_hooks_default_cleanup;
|
3139
|
+
fio_rw_hook_validate(rw_hooks);
|
3151
3140
|
intptr_t fd = fio_uuid2fd(uuid);
|
3152
3141
|
fio_rw_hook_s *old_rw_hooks;
|
3153
3142
|
void *old_udata;
|
@@ -3249,7 +3238,6 @@ static int fio_attach__internal(void *uuid_, void *protocol_) {
|
|
3249
3238
|
/* adding a new uuid to the reactor */
|
3250
3239
|
fio_poll_add(fio_uuid2fd(uuid));
|
3251
3240
|
}
|
3252
|
-
fio_max_fd_min(fio_uuid2fd(uuid));
|
3253
3241
|
return 0;
|
3254
3242
|
|
3255
3243
|
invalid_uuid:
|
@@ -3510,18 +3498,19 @@ static void fio_on_fork(void) {
|
|
3510
3498
|
fio_poll_init();
|
3511
3499
|
fio_state_callback_on_fork();
|
3512
3500
|
|
3501
|
+
/* don't pass open connections belonging to the parent onto the child. */
|
3513
3502
|
const size_t limit = fio_data->capa;
|
3514
3503
|
for (size_t i = 0; i < limit; ++i) {
|
3515
3504
|
fd_data(i).sock_lock = FIO_LOCK_INIT;
|
3516
3505
|
fd_data(i).protocol_lock = FIO_LOCK_INIT;
|
3517
|
-
if (fd_data(i).protocol) {
|
3506
|
+
if (fd_data(i).protocol && fd_data(i).open) {
|
3507
|
+
/* open without protocol might be waiting for the child (listening) */
|
3518
3508
|
fd_data(i).protocol->rsv = 0;
|
3519
3509
|
fio_force_close(fd2uuid(i));
|
3520
3510
|
}
|
3521
3511
|
}
|
3522
3512
|
|
3523
3513
|
fio_pubsub_on_fork();
|
3524
|
-
fio_max_fd_shrink();
|
3525
3514
|
uint16_t old_active = fio_data->active;
|
3526
3515
|
fio_data->active = 0;
|
3527
3516
|
fio_defer_perform();
|
@@ -3681,24 +3670,30 @@ static void fio_review_timeout(void *arg, void *ignr) {
|
|
3681
3670
|
uint16_t timeout = fd_data(fd).timeout;
|
3682
3671
|
if (!timeout)
|
3683
3672
|
timeout = 300; /* enforced timout settings */
|
3684
|
-
if (!fd_data(fd).
|
3673
|
+
if (!fd_data(fd).open || fd_data(fd).active + timeout >= review)
|
3685
3674
|
goto finish;
|
3686
|
-
|
3687
|
-
|
3688
|
-
if (
|
3689
|
-
|
3690
|
-
|
3675
|
+
if (fd_data(fd).protocol) {
|
3676
|
+
tmp = protocol_try_lock(fd, FIO_PR_LOCK_STATE);
|
3677
|
+
if (!tmp) {
|
3678
|
+
if (errno == EBADF)
|
3679
|
+
goto finish;
|
3680
|
+
goto reschedule;
|
3681
|
+
}
|
3682
|
+
if (prt_meta(tmp).locks[FIO_PR_LOCK_TASK] ||
|
3683
|
+
prt_meta(tmp).locks[FIO_PR_LOCK_WRITE])
|
3684
|
+
goto unlock;
|
3685
|
+
fio_defer_push_task(deferred_ping, (void *)fio_fd2uuid((int)fd), NULL);
|
3686
|
+
unlock:
|
3687
|
+
protocol_unlock(tmp, FIO_PR_LOCK_STATE);
|
3688
|
+
} else {
|
3689
|
+
/* open FD but no protocol? RW hook thing or listening sockets? */
|
3690
|
+
if (fd_data(fd).rw_hooks != &FIO_DEFAULT_RW_HOOKS)
|
3691
|
+
fio_close(fd2uuid(fd));
|
3691
3692
|
}
|
3692
|
-
if (prt_meta(tmp).locks[FIO_PR_LOCK_TASK] ||
|
3693
|
-
prt_meta(tmp).locks[FIO_PR_LOCK_WRITE])
|
3694
|
-
goto unlock;
|
3695
|
-
fio_defer_push_task(deferred_ping, (void *)fio_fd2uuid((int)fd), NULL);
|
3696
|
-
unlock:
|
3697
|
-
protocol_unlock(tmp, FIO_PR_LOCK_STATE);
|
3698
3693
|
finish:
|
3699
3694
|
do {
|
3700
3695
|
fd++;
|
3701
|
-
} while (!fd_data(fd).
|
3696
|
+
} while (!fd_data(fd).open && (fd <= fio_data->max_protocol_fd));
|
3702
3697
|
|
3703
3698
|
if (fio_data->max_protocol_fd < fd) {
|
3704
3699
|
fio_data->need_review = 1;
|
@@ -3714,7 +3709,6 @@ static void fio_cycle_schedule_events(void) {
|
|
3714
3709
|
static time_t last_to_review = 0;
|
3715
3710
|
fio_mark_time();
|
3716
3711
|
fio_timer_schedule();
|
3717
|
-
fio_max_fd_shrink();
|
3718
3712
|
if (fio_signal_children_flag) {
|
3719
3713
|
/* hot restart support */
|
3720
3714
|
fio_signal_children_flag = 0;
|
@@ -3923,16 +3917,22 @@ void fio_start FIO_IGNORE_MACRO(struct fio_start_args args) {
|
|
3923
3917
|
fio_data->is_worker = 0;
|
3924
3918
|
|
3925
3919
|
fio_state_callback_force(FIO_CALL_PRE_START);
|
3926
|
-
|
3927
3920
|
FIO_LOG_INFO(
|
3928
3921
|
"Server is running %u %s X %u %s with facil.io " FIO_VERSION_STRING
|
3929
3922
|
" (%s)\n"
|
3923
|
+
#if HAVE_OPENSSL
|
3924
|
+
"* Linked to %s\n"
|
3925
|
+
#endif
|
3930
3926
|
"* Detected capacity: %d open file limit\n"
|
3931
3927
|
"* Root pid: %d\n"
|
3932
3928
|
"* Press ^C to stop\n",
|
3933
3929
|
fio_data->workers, fio_data->workers > 1 ? "workers" : "worker",
|
3934
3930
|
fio_data->threads, fio_data->threads > 1 ? "threads" : "thread",
|
3935
|
-
fio_engine(),
|
3931
|
+
fio_engine(),
|
3932
|
+
#if HAVE_OPENSSL
|
3933
|
+
OpenSSL_version(0),
|
3934
|
+
#endif
|
3935
|
+
fio_data->capa, (int)fio_data->parent);
|
3936
3936
|
|
3937
3937
|
if (args.workers > 1) {
|
3938
3938
|
for (int i = 0; i < args.workers && fio_data->active; ++i) {
|
data/ext/iodine/fio.h
CHANGED
@@ -109,7 +109,7 @@ Version and helper macros
|
|
109
109
|
|
110
110
|
#define FIO_VERSION_MAJOR 0
|
111
111
|
#define FIO_VERSION_MINOR 7
|
112
|
-
#define FIO_VERSION_PATCH
|
112
|
+
#define FIO_VERSION_PATCH 4
|
113
113
|
#define FIO_VERSION_BETA 0
|
114
114
|
|
115
115
|
/* Automatically convert version data to a string constant - ignore these two */
|
@@ -33,6 +33,11 @@ Feel free to copy, use and enjoy according to the license provided.
|
|
33
33
|
FIO_LOG_FATAL("No supported SSL/TLS library available."); \
|
34
34
|
exit(-1);
|
35
35
|
#endif
|
36
|
+
|
37
|
+
#ifndef FIO_TLS_TIMEOUT
|
38
|
+
#define FIO_TLS_TIMEOUT 4
|
39
|
+
#endif
|
40
|
+
|
36
41
|
/* STOP deleting after this line */
|
37
42
|
|
38
43
|
/* *****************************************************************************
|
@@ -590,6 +595,7 @@ file_missing:
|
|
590
595
|
*/
|
591
596
|
void FIO_TLS_WEAK fio_tls_accept(intptr_t uuid, fio_tls_s *tls, void *udata) {
|
592
597
|
REQUIRE_LIBRARY();
|
598
|
+
fio_timeout_set(uuid, FIO_TLS_TIMEOUT);
|
593
599
|
fio_tls_attach2uuid(uuid, tls, udata, 1);
|
594
600
|
}
|
595
601
|
|
@@ -29,6 +29,10 @@ The SSL/TLS helper data types (can be left as is)
|
|
29
29
|
#define FIO_FORCE_MALLOC_TMP 1
|
30
30
|
#include <fio.h>
|
31
31
|
|
32
|
+
#ifndef FIO_TLS_TIMEOUT
|
33
|
+
#define FIO_TLS_TIMEOUT 4
|
34
|
+
#endif
|
35
|
+
|
32
36
|
typedef struct {
|
33
37
|
fio_str_s private_key;
|
34
38
|
fio_str_s public_key;
|
@@ -190,8 +194,12 @@ typedef struct {
|
|
190
194
|
|
191
195
|
FIO_FUNC inline void alpn_select___task(void *t_, void *ignr_) {
|
192
196
|
alpn_task_s *t = t_;
|
193
|
-
|
194
|
-
|
197
|
+
if (fio_is_valid(t->uuid)) {
|
198
|
+
fio_timeout_set(t->uuid, 0); // remove TLS timeout
|
199
|
+
t->alpn.on_selected(t->uuid, t->udata_connection, t->alpn.udata_tls);
|
200
|
+
} else {
|
201
|
+
t->alpn.on_selected(-1, t->udata_connection, t->alpn.udata_tls);
|
202
|
+
}
|
195
203
|
fio_free(t);
|
196
204
|
(void)ignr_;
|
197
205
|
}
|
@@ -537,19 +545,21 @@ static ssize_t fio_tls_read(intptr_t uuid, void *udata, void *buf,
|
|
537
545
|
case SSL_ERROR_SSL: /* overflow */
|
538
546
|
case SSL_ERROR_ZERO_RETURN:
|
539
547
|
return 0; /* EOF */
|
548
|
+
case SSL_ERROR_SYSCALL: /* allow errno to inform us */
|
549
|
+
break; /* return -1 */
|
540
550
|
case SSL_ERROR_NONE: /* overflow */
|
541
551
|
case SSL_ERROR_WANT_CONNECT: /* overflow */
|
542
552
|
case SSL_ERROR_WANT_ACCEPT: /* overflow */
|
543
553
|
case SSL_ERROR_WANT_X509_LOOKUP: /* overflow */
|
554
|
+
case SSL_ERROR_WANT_WRITE: /* overflow */
|
555
|
+
case SSL_ERROR_WANT_READ: /* overflow */
|
544
556
|
#ifdef SSL_ERROR_WANT_ASYNC
|
545
557
|
case SSL_ERROR_WANT_ASYNC: /* overflow */
|
546
558
|
#endif
|
547
|
-
case SSL_ERROR_WANT_WRITE: /* overflow */
|
548
|
-
case SSL_ERROR_WANT_READ:
|
549
559
|
default:
|
560
|
+
errno = EWOULDBLOCK;
|
550
561
|
break;
|
551
562
|
}
|
552
|
-
errno = EWOULDBLOCK;
|
553
563
|
return -1;
|
554
564
|
(void)uuid;
|
555
565
|
}
|
@@ -591,19 +601,21 @@ static ssize_t fio_tls_write(intptr_t uuid, void *udata, const void *buf,
|
|
591
601
|
case SSL_ERROR_SSL: /* overflow */
|
592
602
|
case SSL_ERROR_ZERO_RETURN:
|
593
603
|
return 0; /* EOF */
|
604
|
+
case SSL_ERROR_SYSCALL: /* allow errno to inform us */
|
605
|
+
break; /* return -1 */
|
594
606
|
case SSL_ERROR_NONE: /* overflow */
|
595
607
|
case SSL_ERROR_WANT_CONNECT: /* overflow */
|
596
608
|
case SSL_ERROR_WANT_ACCEPT: /* overflow */
|
597
609
|
case SSL_ERROR_WANT_X509_LOOKUP: /* overflow */
|
610
|
+
case SSL_ERROR_WANT_WRITE: /* overflow */
|
611
|
+
case SSL_ERROR_WANT_READ: /* overflow */
|
598
612
|
#ifdef SSL_ERROR_WANT_ASYNC
|
599
613
|
case SSL_ERROR_WANT_ASYNC: /* overflow */
|
600
614
|
#endif
|
601
|
-
case SSL_ERROR_WANT_WRITE: /* overflow */
|
602
|
-
case SSL_ERROR_WANT_READ:
|
603
615
|
default:
|
616
|
+
errno = EWOULDBLOCK;
|
604
617
|
break;
|
605
618
|
}
|
606
|
-
errno = EWOULDBLOCK;
|
607
619
|
return -1;
|
608
620
|
(void)uuid;
|
609
621
|
}
|
@@ -640,13 +652,20 @@ static void fio_tls_cleanup(void *udata) {
|
|
640
652
|
static fio_rw_hook_s FIO_TLS_HOOKS = {
|
641
653
|
.read = fio_tls_read,
|
642
654
|
.write = fio_tls_write,
|
643
|
-
.before_close = fio_tls_before_close,
|
644
655
|
.flush = fio_tls_flush,
|
656
|
+
.before_close = fio_tls_before_close,
|
645
657
|
.cleanup = fio_tls_cleanup,
|
646
658
|
};
|
647
659
|
|
660
|
+
#define FIO_TLS_HANDSHAKE_ERROR 0
|
661
|
+
#define FIO_TLS_HANDSHAKE_OK 1
|
662
|
+
#define FIO_TLS_HANDSHAKE_NEED_READ 2
|
663
|
+
#define FIO_TLS_HANDSHAKE_NEED_WRITE 4
|
664
|
+
|
648
665
|
static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
666
|
+
size_t status = FIO_TLS_HANDSHAKE_ERROR;
|
649
667
|
fio_tls_connection_s *c = udata;
|
668
|
+
|
650
669
|
int ri;
|
651
670
|
if (c->is_server) {
|
652
671
|
ri = SSL_accept(c->ssl);
|
@@ -659,26 +678,29 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
659
678
|
case SSL_ERROR_NONE:
|
660
679
|
// FIO_LOG_DEBUG("SSL_accept/SSL_connect %p state: SSL_ERROR_NONE",
|
661
680
|
// (void *)uuid);
|
662
|
-
|
681
|
+
status = FIO_TLS_HANDSHAKE_NEED_READ | FIO_TLS_HANDSHAKE_NEED_WRITE;
|
682
|
+
return status;
|
663
683
|
case SSL_ERROR_WANT_WRITE:
|
664
684
|
// FIO_LOG_DEBUG("SSL_accept/SSL_connect %p state: SSL_ERROR_WANT_WRITE",
|
665
685
|
// (void *)uuid);
|
666
|
-
|
667
|
-
return
|
686
|
+
status = FIO_TLS_HANDSHAKE_NEED_WRITE;
|
687
|
+
return status;
|
668
688
|
case SSL_ERROR_WANT_READ:
|
669
689
|
// FIO_LOG_DEBUG("SSL_accept/SSL_connect %p state: SSL_ERROR_WANT_READ",
|
670
690
|
// (void *)uuid);
|
671
|
-
|
672
|
-
return
|
691
|
+
status = FIO_TLS_HANDSHAKE_NEED_READ;
|
692
|
+
return status;
|
673
693
|
case SSL_ERROR_SYSCALL:
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
694
|
+
if (errno) {
|
695
|
+
FIO_LOG_DEBUG(
|
696
|
+
"SSL_accept/SSL_connect %p error: SSL_ERROR_SYSCALL, errno: %s",
|
697
|
+
(void *)uuid, strerror(errno));
|
698
|
+
}
|
699
|
+
break;
|
679
700
|
case SSL_ERROR_SSL:
|
680
|
-
FIO_LOG_DEBUG(
|
681
|
-
|
701
|
+
FIO_LOG_DEBUG(
|
702
|
+
"SSL_accept/SSL_connect %p error: SSL_ERROR_SSL (non SSL attempt?)",
|
703
|
+
(void *)uuid);
|
682
704
|
break;
|
683
705
|
case SSL_ERROR_ZERO_RETURN:
|
684
706
|
FIO_LOG_DEBUG("SSL_accept/SSL_connect %p error: SSL_ERROR_ZERO_RETURN",
|
@@ -715,8 +737,9 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
715
737
|
(void *)uuid, ri);
|
716
738
|
break;
|
717
739
|
}
|
740
|
+
fio_rw_hook_replace_unsafe(uuid, &FIO_TLS_HOOKS, udata);
|
718
741
|
fio_defer(fio_tls_delayed_close, (void *)uuid, NULL);
|
719
|
-
return
|
742
|
+
return status;
|
720
743
|
}
|
721
744
|
if (!c->alpn_ok) {
|
722
745
|
c->alpn_ok = 1;
|
@@ -745,7 +768,7 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
745
768
|
} else {
|
746
769
|
FIO_LOG_DEBUG("Something went wrong during TLS handshake for %p",
|
747
770
|
(void *)uuid);
|
748
|
-
return
|
771
|
+
return status;
|
749
772
|
}
|
750
773
|
/* make sure the connection is re-added to the reactor */
|
751
774
|
fio_force_event(uuid, FIO_EVENT_ON_DATA);
|
@@ -768,14 +791,18 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
768
791
|
buff2);
|
769
792
|
}
|
770
793
|
#endif
|
771
|
-
|
794
|
+
status = FIO_TLS_HANDSHAKE_OK;
|
795
|
+
return status;
|
772
796
|
}
|
773
797
|
|
774
798
|
static ssize_t fio_tls_read4handshake(intptr_t uuid, void *udata, void *buf,
|
775
799
|
size_t count) {
|
776
800
|
// FIO_LOG_DEBUG("TLS handshake from read %p", (void *)uuid);
|
777
|
-
|
801
|
+
size_t s = fio_tls_handshake(uuid, udata);
|
802
|
+
if (s == FIO_TLS_HANDSHAKE_OK)
|
778
803
|
return fio_tls_read(uuid, udata, buf, count);
|
804
|
+
if (!s)
|
805
|
+
return 0;
|
779
806
|
errno = EWOULDBLOCK;
|
780
807
|
return -1;
|
781
808
|
}
|
@@ -783,20 +810,27 @@ static ssize_t fio_tls_read4handshake(intptr_t uuid, void *udata, void *buf,
|
|
783
810
|
static ssize_t fio_tls_write4handshake(intptr_t uuid, void *udata,
|
784
811
|
const void *buf, size_t count) {
|
785
812
|
// FIO_LOG_DEBUG("TLS handshake from write %p", (void *)uuid);
|
786
|
-
|
813
|
+
size_t s = fio_tls_handshake(uuid, udata);
|
814
|
+
if (s == FIO_TLS_HANDSHAKE_OK)
|
787
815
|
return fio_tls_write(uuid, udata, buf, count);
|
816
|
+
if (!s)
|
817
|
+
return 0;
|
788
818
|
errno = EWOULDBLOCK;
|
789
819
|
return -1;
|
790
820
|
}
|
791
821
|
|
792
822
|
static ssize_t fio_tls_flush4handshake(intptr_t uuid, void *udata) {
|
793
823
|
// FIO_LOG_DEBUG("TLS handshake from flush %p", (void *)uuid);
|
794
|
-
|
824
|
+
size_t s = fio_tls_handshake(uuid, udata);
|
825
|
+
if (s == FIO_TLS_HANDSHAKE_OK) {
|
795
826
|
return fio_tls_flush(uuid, udata);
|
796
827
|
}
|
828
|
+
if (!s)
|
829
|
+
return 0;
|
797
830
|
errno = 0;
|
798
|
-
return
|
831
|
+
return s | FIO_TLS_HANDSHAKE_NEED_WRITE;
|
799
832
|
}
|
833
|
+
|
800
834
|
static fio_rw_hook_s FIO_TLS_HANDSHAKE_HOOKS = {
|
801
835
|
.read = fio_tls_read4handshake,
|
802
836
|
.write = fio_tls_write4handshake,
|
@@ -967,6 +1001,7 @@ file_missing:
|
|
967
1001
|
*/
|
968
1002
|
void FIO_TLS_WEAK fio_tls_accept(intptr_t uuid, fio_tls_s *tls, void *udata) {
|
969
1003
|
REQUIRE_LIBRARY();
|
1004
|
+
fio_timeout_set(uuid, FIO_TLS_TIMEOUT);
|
970
1005
|
fio_tls_attach2uuid(uuid, tls, udata, 1);
|
971
1006
|
}
|
972
1007
|
|
@@ -1007,6 +1042,7 @@ void FIO_TLS_WEAK fio_tls_destroy(fio_tls_s *tls) {
|
|
1007
1042
|
cert_ary_free(&tls->sni);
|
1008
1043
|
trust_ary_free(&tls->trust);
|
1009
1044
|
free(tls);
|
1045
|
+
FIO_LOG_DEBUG("freed TLS context %p", (void *)tls);
|
1010
1046
|
}
|
1011
1047
|
|
1012
1048
|
#endif /* Library compiler flags */
|