iodine 0.7.36 → 0.7.41

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- if (is_open)
340
- fio_max_fd_min(fd);
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
- fio_poll_add_write(fio_uuid2fd(uuid));
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
- fprintf(stderr, "UUID error: %p (%d)\n", (void *)uuid, errno);
3036
- perror("No errno handler");
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
- if (!rw_hooks->read)
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 (fd2uuid(fd) == uuid) {
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
- if (!rw_hooks->read)
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).protocol || (fd_data(fd).active + timeout >= review))
3673
+ if (!fd_data(fd).open || fd_data(fd).active + timeout >= review)
3685
3674
  goto finish;
3686
- tmp = protocol_try_lock(fd, FIO_PR_LOCK_STATE);
3687
- if (!tmp) {
3688
- if (errno == EBADF)
3689
- goto finish;
3690
- goto reschedule;
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).protocol && (fd <= fio_data->max_protocol_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(), fio_data->capa, (int)fio_data->parent);
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) {
@@ -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 3
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
- t->alpn.on_selected((fio_is_valid(t->uuid) ? t->uuid : -1),
194
- t->udata_connection, t->alpn.udata_tls);
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
- return 0;
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
- // fio_force_event(uuid, FIO_EVENT_ON_READY);
667
- return 0;
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
- // fio_force_event(uuid, FIO_EVENT_ON_DATA);
672
- return 0;
691
+ status = FIO_TLS_HANDSHAKE_NEED_READ;
692
+ return status;
673
693
  case SSL_ERROR_SYSCALL:
674
- FIO_LOG_DEBUG(
675
- "SSL_accept/SSL_connect %p error: SSL_ERROR_SYSCALL, errno: %s",
676
- (void *)uuid, strerror(errno));
677
- // fio_force_event(uuid, FIO_EVENT_ON_DATA);
678
- return 0;
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("SSL_accept/SSL_connect %p error: SSL_ERROR_SSL",
681
- (void *)uuid);
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 0;
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 0;
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
- return 1;
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
- if (fio_tls_handshake(uuid, udata))
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
- if (fio_tls_handshake(uuid, udata))
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
- if (fio_tls_handshake(uuid, udata)) {
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 1;
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 */