iodine 0.7.57 → 0.7.58
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +10 -10
- data/ext/iodine/fio_tls_openssl.c +140 -90
- data/ext/iodine/iodine_caller.c +25 -13
- data/lib/iodine/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 322c256e46337fbbb04715a5076984dda9e00ffa35e75bac7882fb8e95b17dea
|
4
|
+
data.tar.gz: 91390ce111e21fbf39f40e010bc059acab48d13a92b90f04d0a1a4b5738b87f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78c783b0457ff798146af5c3040ccf86e3449dc33c53677986d58b7cd585745288bffcbf19f2427b8353c51507140b307209f33df2b4598d21d875c5203ab3a5
|
7
|
+
data.tar.gz: 257bbacb1c902bfa2202cd649b0d842f366963a528a00e115bc923a381d47bbe93e7c38c42cc21976f839d7a042873b107dc2fa8dd7ecc3703a61cecbe65e301
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,12 @@ Please notice that this change log contains changes for upcoming releases as wel
|
|
6
6
|
|
7
7
|
## Changes:
|
8
8
|
|
9
|
+
#### Change log v.0.7.58 (2024-04-28)
|
10
|
+
|
11
|
+
**Fix**: possible fix for compilation issues on Fedora. Credit to @garytaylor for opening issue #155.
|
12
|
+
|
13
|
+
**Fix**: possible fix for an OpenSSL certificate chain import issue that would cause certificate chains to be imported incorrectly. Credit to @dwolrdcojp for opening the facil.io repo PR #151.
|
14
|
+
|
9
15
|
#### Change log v.0.7.57 (2023-09-04)
|
10
16
|
|
11
17
|
**Fix**: Fixes possible name collision when loading gem (`.rb` vs. `.so` loading). Credit to @noraj (Alexandre ZANNI) for opening issue #148. Credit to @janbiedermann (Jan Biedermann) for discovering the root cause and offering a solution.
|
data/README.md
CHANGED
@@ -10,28 +10,28 @@
|
|
10
10
|
|
11
11
|
Iodine is a fast concurrent web application server for real-time Ruby applications, with native support for WebSockets and Pub/Sub services - but it's also so much more.
|
12
12
|
|
13
|
-
Iodine is a Ruby wrapper for
|
13
|
+
Iodine is a Ruby wrapper for much of the [facil.io](https://facil.io) C framework, leveraging the speed of C for many common web application tasks. In addition, iodine abstracts away all network concerns, so you never need to worry about the transport layer, leaving you free to concentrate on your application logic.
|
14
14
|
|
15
15
|
Iodine includes native support for:
|
16
16
|
|
17
17
|
* HTTP, WebSockets and EventSource (SSE) Services (server);
|
18
18
|
* WebSocket connections (server / client);
|
19
19
|
* Pub/Sub (with optional Redis Pub/Sub scaling);
|
20
|
-
* Fast(!) builtin Mustache
|
20
|
+
* Fast(!) builtin Mustache templating;
|
21
21
|
* Static file service (with automatic `gzip` support for pre-compressed assets);
|
22
|
-
* Optimized Logging to `stderr
|
22
|
+
* Optimized Logging to `stderr`;
|
23
23
|
* Asynchronous event scheduling and timers;
|
24
24
|
* HTTP/1.1 keep-alive and pipelining;
|
25
|
-
* Heap Fragmentation Protection
|
26
|
-
* TLS 1.2 and above (
|
25
|
+
* Heap Fragmentation Protection;
|
26
|
+
* TLS 1.2 and above (Requiring OpenSSL >= 1.1.0);
|
27
27
|
* TCP/IP server and client connectivity;
|
28
28
|
* Unix Socket server and client connectivity;
|
29
|
-
* Hot
|
29
|
+
* Hot Restarts (using the USR1 signal and without hot deployment);
|
30
30
|
* Custom protocol authoring;
|
31
|
-
* [Sequel](https://github.com/jeremyevans/sequel) and ActiveRecord forking protection
|
31
|
+
* [Sequel](https://github.com/jeremyevans/sequel) and ActiveRecord forking protection;
|
32
32
|
* and more!
|
33
33
|
|
34
|
-
Since iodine wraps much of the [C facil.io framework](https://github.com/boazsegev/facil.io)
|
34
|
+
Since iodine wraps much of the [C facil.io framework](https://github.com/boazsegev/facil.io) for Ruby:
|
35
35
|
|
36
36
|
* Iodine can handle **thousands of concurrent connections** (tested with more then 20K connections on Linux)!
|
37
37
|
|
@@ -39,13 +39,13 @@ Since iodine wraps much of the [C facil.io framework](https://github.com/boazseg
|
|
39
39
|
|
40
40
|
Iodine is a C extension for Ruby, developed and optimized for Ruby MRI 2.3 and up... it should support the whole Ruby 2.x and 3.x MRI family, but CI tests start at Ruby 2.3.
|
41
41
|
|
42
|
-
**Note**: iodine does **not** support streaming when using Rack. It's recommended to avoid blocking the server when using `body.each` since the `each` loop will block
|
42
|
+
**Note**: iodine does **not** support streaming when using Rack. It's recommended to avoid blocking the server when using `body.each` since the `each` loop will block iodine's thread until it's finished and iodine won't send any data before the loop is done.
|
43
43
|
|
44
44
|
## Iodine - a fast & powerful HTTP + WebSockets server with native Pub/Sub
|
45
45
|
|
46
46
|
Iodine includes a light and fast HTTP and Websocket server written in C that was written according to the [Rack interface specifications](http://www.rubydoc.info/github/rack/rack/master/file/SPEC) and the [Websocket draft extension](./SPEC-Websocket-Draft.md).
|
47
47
|
|
48
|
-
With `Iodine.listen service: :http` it's possible to run multiple HTTP applications (please remember not to set more than a single application on a single TCP/IP port).
|
48
|
+
With `Iodine.listen service: :http` it's possible to run multiple HTTP applications (but please remember not to set more than a single application on a single TCP/IP port).
|
49
49
|
|
50
50
|
Iodine also supports native process cluster Pub/Sub and a native RedisEngine to easily scale iodine's Pub/Sub horizontally.
|
51
51
|
|
@@ -32,7 +32,7 @@ typedef struct {
|
|
32
32
|
/* *****************************************************************************
|
33
33
|
The SSL/TLS helper data types (can be left as is)
|
34
34
|
***************************************************************************** */
|
35
|
-
#define FIO_INCLUDE_STR
|
35
|
+
#define FIO_INCLUDE_STR 1
|
36
36
|
#define FIO_FORCE_MALLOC_TMP 1
|
37
37
|
#include <fio.h>
|
38
38
|
|
@@ -65,12 +65,12 @@ static inline void fio_tls_cert_destroy(cert_s *obj) {
|
|
65
65
|
fio_str_free(&obj->password);
|
66
66
|
}
|
67
67
|
|
68
|
-
#define FIO_ARY_NAME
|
69
|
-
#define FIO_ARY_TYPE
|
68
|
+
#define FIO_ARY_NAME cert_ary
|
69
|
+
#define FIO_ARY_TYPE cert_s
|
70
70
|
#define FIO_ARY_COMPARE(k1, k2) (fio_tls_cert_cmp(&(k1), &(k2)))
|
71
71
|
#define FIO_ARY_COPY(dest, obj) fio_tls_cert_copy(&(dest), &(obj))
|
72
|
-
#define FIO_ARY_DESTROY(key)
|
73
|
-
#define FIO_FORCE_MALLOC_TMP
|
72
|
+
#define FIO_ARY_DESTROY(key) fio_tls_cert_destroy(&(key))
|
73
|
+
#define FIO_FORCE_MALLOC_TMP 1
|
74
74
|
#include <fio.h>
|
75
75
|
|
76
76
|
typedef struct {
|
@@ -90,12 +90,12 @@ static inline void fio_tls_trust_destroy(trust_s *obj) {
|
|
90
90
|
fio_str_free(&obj->pem);
|
91
91
|
}
|
92
92
|
|
93
|
-
#define FIO_ARY_NAME
|
94
|
-
#define FIO_ARY_TYPE
|
93
|
+
#define FIO_ARY_NAME trust_ary
|
94
|
+
#define FIO_ARY_TYPE trust_s
|
95
95
|
#define FIO_ARY_COMPARE(k1, k2) (fio_tls_trust_cmp(&(k1), &(k2)))
|
96
96
|
#define FIO_ARY_COPY(dest, obj) fio_tls_trust_copy(&(dest), &(obj))
|
97
|
-
#define FIO_ARY_DESTROY(key)
|
98
|
-
#define FIO_FORCE_MALLOC_TMP
|
97
|
+
#define FIO_ARY_DESTROY(key) fio_tls_trust_destroy(&(key))
|
98
|
+
#define FIO_FORCE_MALLOC_TMP 1
|
99
99
|
#include <fio.h>
|
100
100
|
|
101
101
|
typedef struct {
|
@@ -123,12 +123,12 @@ static inline void fio_alpn_destroy(alpn_s *obj) {
|
|
123
123
|
fio_str_free(&obj->name);
|
124
124
|
}
|
125
125
|
|
126
|
-
#define FIO_SET_NAME
|
127
|
-
#define FIO_SET_OBJ_TYPE
|
126
|
+
#define FIO_SET_NAME alpn_list
|
127
|
+
#define FIO_SET_OBJ_TYPE alpn_s
|
128
128
|
#define FIO_SET_OBJ_COMPARE(k1, k2) fio_alpn_cmp(&(k1), &(k2))
|
129
129
|
#define FIO_SET_OBJ_COPY(dest, obj) fio_alpn_copy(&(dest), &(obj))
|
130
|
-
#define FIO_SET_OBJ_DESTROY(key)
|
131
|
-
#define FIO_FORCE_MALLOC_TMP
|
130
|
+
#define FIO_SET_OBJ_DESTROY(key) fio_alpn_destroy(&(key))
|
131
|
+
#define FIO_FORCE_MALLOC_TMP 1
|
132
132
|
#include <fio.h>
|
133
133
|
|
134
134
|
/* *****************************************************************************
|
@@ -167,10 +167,13 @@ FIO_FUNC inline alpn_s *alpn_find(fio_tls_s *tls, char *name, size_t len) {
|
|
167
167
|
}
|
168
168
|
|
169
169
|
/** Adds an ALPN data object to the ALPN "list" (set) */
|
170
|
-
FIO_FUNC inline void alpn_add(
|
171
|
-
|
172
|
-
|
173
|
-
|
170
|
+
FIO_FUNC inline void alpn_add(fio_tls_s *tls,
|
171
|
+
const char *protocol_name,
|
172
|
+
void (*on_selected)(intptr_t uuid,
|
173
|
+
void *udata_connection,
|
174
|
+
void *udata_tls),
|
175
|
+
void *udata_tls,
|
176
|
+
void (*on_cleanup)(void *udata_tls)) {
|
174
177
|
alpn_s tmp = {
|
175
178
|
.name = FIO_STR_INIT_STATIC(protocol_name),
|
176
179
|
.on_selected = on_selected,
|
@@ -212,7 +215,8 @@ FIO_FUNC inline void alpn_select___task(void *t_, void *ignr_) {
|
|
212
215
|
}
|
213
216
|
|
214
217
|
/** Schedules the ALPN protocol callback. */
|
215
|
-
FIO_FUNC inline void alpn_select(alpn_s *alpn,
|
218
|
+
FIO_FUNC inline void alpn_select(alpn_s *alpn,
|
219
|
+
intptr_t uuid,
|
216
220
|
void *udata_connection) {
|
217
221
|
if (!alpn || !alpn->on_selected)
|
218
222
|
return;
|
@@ -257,7 +261,8 @@ static void fio_tls_make_root_key(void) {
|
|
257
261
|
"OpenSSL failed to create RSA key.");
|
258
262
|
BN_free(e);
|
259
263
|
EVP_PKEY_assign_RSA(fio_tls_pkey, rsa);
|
260
|
-
fio_state_callback_add(FIO_CALL_AT_EXIT,
|
264
|
+
fio_state_callback_add(FIO_CALL_AT_EXIT,
|
265
|
+
fio_tls_clear_root_key,
|
261
266
|
fio_tls_pkey);
|
262
267
|
finish:
|
263
268
|
fio_unlock(&lock);
|
@@ -284,12 +289,27 @@ static X509 *fio_tls_create_self_signed(char *server_name) {
|
|
284
289
|
/* set identity details */
|
285
290
|
X509_NAME *s = X509_get_subject_name(cert);
|
286
291
|
size_t srv_name_len = strlen(server_name);
|
287
|
-
X509_NAME_add_entry_by_txt(s,
|
288
|
-
|
289
|
-
|
290
|
-
(unsigned char *)server_name,
|
291
|
-
|
292
|
-
|
292
|
+
X509_NAME_add_entry_by_txt(s,
|
293
|
+
"O",
|
294
|
+
MBSTRING_ASC,
|
295
|
+
(unsigned char *)server_name,
|
296
|
+
srv_name_len,
|
297
|
+
-1,
|
298
|
+
0);
|
299
|
+
X509_NAME_add_entry_by_txt(s,
|
300
|
+
"CN",
|
301
|
+
MBSTRING_ASC,
|
302
|
+
(unsigned char *)server_name,
|
303
|
+
srv_name_len,
|
304
|
+
-1,
|
305
|
+
0);
|
306
|
+
X509_NAME_add_entry_by_txt(s,
|
307
|
+
"CA",
|
308
|
+
MBSTRING_ASC,
|
309
|
+
(unsigned char *)server_name,
|
310
|
+
srv_name_len,
|
311
|
+
-1,
|
312
|
+
0);
|
293
313
|
X509_set_issuer_name(cert, s);
|
294
314
|
|
295
315
|
/* sign certificate */
|
@@ -324,12 +344,15 @@ static void fio_tls_alpn_fallback(fio_tls_connection_s *c) {
|
|
324
344
|
return;
|
325
345
|
/* set protocol to default protocol */
|
326
346
|
FIO_LOG_DEBUG("TLS ALPN handshake missing, falling back on %s for %p",
|
327
|
-
fio_str_info(&alpn->name).data,
|
347
|
+
fio_str_info(&alpn->name).data,
|
348
|
+
(void *)c->uuid);
|
328
349
|
alpn_select(alpn, c->uuid, c->alpn_arg);
|
329
350
|
}
|
330
|
-
static int fio_tls_alpn_selector_cb(SSL *ssl,
|
351
|
+
static int fio_tls_alpn_selector_cb(SSL *ssl,
|
352
|
+
const unsigned char **out,
|
331
353
|
unsigned char *outlen,
|
332
|
-
const unsigned char *in,
|
354
|
+
const unsigned char *in,
|
355
|
+
unsigned int inlen,
|
333
356
|
void *tls_) {
|
334
357
|
fio_tls_s *tls = tls_;
|
335
358
|
alpn_s *alpn;
|
@@ -358,7 +381,8 @@ static int fio_tls_alpn_selector_cb(SSL *ssl, const unsigned char **out,
|
|
358
381
|
alpn_select(alpn, c->uuid, c->alpn_arg);
|
359
382
|
FIO_LOG_DEBUG(
|
360
383
|
"TLS ALPN handshake failed, falling back on default (%s) for %p",
|
361
|
-
fio_str_data(&alpn->name),
|
384
|
+
fio_str_data(&alpn->name),
|
385
|
+
(void *)c->uuid);
|
362
386
|
return SSL_TLSEXT_ERR_NOACK;
|
363
387
|
(void)ssl;
|
364
388
|
(void)out;
|
@@ -380,7 +404,9 @@ static void fio_tls_destroy_context(fio_tls_s *tls) {
|
|
380
404
|
FIO_LOG_DEBUG("destroyed TLS context for OpenSSL %p", (void *)tls);
|
381
405
|
}
|
382
406
|
|
383
|
-
static int fio_tls_pem_passwd_cb(char *buf,
|
407
|
+
static int fio_tls_pem_passwd_cb(char *buf,
|
408
|
+
int size,
|
409
|
+
int rwflag,
|
384
410
|
void *password) {
|
385
411
|
fio_str_info_s *p = password;
|
386
412
|
if (!p || !p->len || !size)
|
@@ -407,7 +433,8 @@ static void fio_tls_build_context(fio_tls_s *tls) {
|
|
407
433
|
/* attach certificates */
|
408
434
|
FIO_ARY_FOR(&tls->sni, pos) {
|
409
435
|
fio_str_info_s keys[4] = {
|
410
|
-
fio_str_info(&pos->private_key),
|
436
|
+
fio_str_info(&pos->private_key),
|
437
|
+
fio_str_info(&pos->public_key),
|
411
438
|
fio_str_info(&pos->password),
|
412
439
|
/* empty password slot for public key */
|
413
440
|
};
|
@@ -416,8 +443,10 @@ static void fio_tls_build_context(fio_tls_s *tls) {
|
|
416
443
|
/* Extract private key from private key file */
|
417
444
|
BIO *bio = BIO_new_mem_buf(keys[0].data, keys[0].len);
|
418
445
|
if (bio) {
|
419
|
-
EVP_PKEY *k = PEM_read_bio_PrivateKey(
|
420
|
-
|
446
|
+
EVP_PKEY *k = PEM_read_bio_PrivateKey(bio,
|
447
|
+
NULL,
|
448
|
+
fio_tls_pem_passwd_cb,
|
449
|
+
keys + 2);
|
421
450
|
if (k) {
|
422
451
|
FIO_LOG_DEBUG("TLS read private key from PEM file.");
|
423
452
|
SSL_CTX_use_PrivateKey(tls->ctx, k);
|
@@ -430,15 +459,21 @@ static void fio_tls_build_context(fio_tls_s *tls) {
|
|
430
459
|
/* Extract as much data as possible from each file */
|
431
460
|
BIO *bio = BIO_new_mem_buf(keys[ki].data, keys[ki].len);
|
432
461
|
FIO_ASSERT(bio, "OpenSSL error allocating BIO.");
|
433
|
-
STACK_OF(X509_INFO) *inf = PEM_X509_INFO_read_bio(
|
434
|
-
|
462
|
+
STACK_OF(X509_INFO) *inf = PEM_X509_INFO_read_bio(bio,
|
463
|
+
NULL,
|
464
|
+
fio_tls_pem_passwd_cb,
|
465
|
+
keys + ki + 2);
|
435
466
|
if (inf) {
|
436
467
|
for (int i = 0; i < sk_X509_INFO_num(inf); ++i) {
|
437
468
|
/* for each element in PEM */
|
438
469
|
X509_INFO *tmp = sk_X509_INFO_value(inf, i);
|
439
470
|
if (tmp->x509) {
|
440
471
|
FIO_LOG_DEBUG("TLS adding certificate from PEM file.");
|
441
|
-
|
472
|
+
if (i == 0) {
|
473
|
+
SSL_CTX_use_certificate(tls->ctx, tmp->x509);
|
474
|
+
} else {
|
475
|
+
SSL_CTX_add1_chain_cert(tls->ctx, tmp->x509);
|
476
|
+
}
|
442
477
|
}
|
443
478
|
if (tmp->x_pkey) {
|
444
479
|
FIO_LOG_DEBUG("TLS adding private key from PEM file.");
|
@@ -541,7 +576,9 @@ static void fio_tls_delayed_close(void *uuid, void *ignr_) {
|
|
541
576
|
* Note: facil.io library functions MUST NEVER be called by any r/w hook, or a
|
542
577
|
* deadlock might occur.
|
543
578
|
*/
|
544
|
-
static ssize_t fio_tls_read(intptr_t uuid,
|
579
|
+
static ssize_t fio_tls_read(intptr_t uuid,
|
580
|
+
void *udata,
|
581
|
+
void *buf,
|
545
582
|
size_t count) {
|
546
583
|
fio_tls_connection_s *c = udata;
|
547
584
|
ssize_t ret = SSL_read(c->ssl, buf, count);
|
@@ -549,23 +586,19 @@ static ssize_t fio_tls_read(intptr_t uuid, void *udata, void *buf,
|
|
549
586
|
return ret;
|
550
587
|
ret = SSL_get_error(c->ssl, ret);
|
551
588
|
switch (ret) {
|
552
|
-
case SSL_ERROR_SSL:
|
553
|
-
case SSL_ERROR_ZERO_RETURN:
|
554
|
-
|
555
|
-
case
|
556
|
-
|
557
|
-
case
|
558
|
-
case
|
559
|
-
case
|
560
|
-
case
|
561
|
-
case SSL_ERROR_WANT_WRITE: /* overflow */
|
562
|
-
case SSL_ERROR_WANT_READ: /* overflow */
|
589
|
+
case SSL_ERROR_SSL: /* overflow */
|
590
|
+
case SSL_ERROR_ZERO_RETURN: return 0; /* EOF */
|
591
|
+
case SSL_ERROR_SYSCALL: /* allow errno to inform us */ break; /* return -1 */
|
592
|
+
case SSL_ERROR_NONE: /* overflow */
|
593
|
+
case SSL_ERROR_WANT_CONNECT: /* overflow */
|
594
|
+
case SSL_ERROR_WANT_ACCEPT: /* overflow */
|
595
|
+
case SSL_ERROR_WANT_X509_LOOKUP: /* overflow */
|
596
|
+
case SSL_ERROR_WANT_WRITE: /* overflow */
|
597
|
+
case SSL_ERROR_WANT_READ: /* overflow */
|
563
598
|
#ifdef SSL_ERROR_WANT_ASYNC
|
564
|
-
case SSL_ERROR_WANT_ASYNC:
|
599
|
+
case SSL_ERROR_WANT_ASYNC: /* overflow */
|
565
600
|
#endif
|
566
|
-
default:
|
567
|
-
errno = EWOULDBLOCK;
|
568
|
-
break;
|
601
|
+
default: errno = EWOULDBLOCK; break;
|
569
602
|
}
|
570
603
|
return -1;
|
571
604
|
(void)uuid;
|
@@ -597,7 +630,9 @@ static ssize_t fio_tls_flush(intptr_t uuid, void *udata) {
|
|
597
630
|
* Note: facil.io library functions MUST NEVER be called by any r/w hook, or a
|
598
631
|
* deadlock might occur.
|
599
632
|
*/
|
600
|
-
static ssize_t fio_tls_write(intptr_t uuid,
|
633
|
+
static ssize_t fio_tls_write(intptr_t uuid,
|
634
|
+
void *udata,
|
635
|
+
const void *buf,
|
601
636
|
size_t count) {
|
602
637
|
fio_tls_connection_s *c = udata;
|
603
638
|
ssize_t ret = SSL_write(c->ssl, buf, count);
|
@@ -605,23 +640,19 @@ static ssize_t fio_tls_write(intptr_t uuid, void *udata, const void *buf,
|
|
605
640
|
return ret;
|
606
641
|
ret = SSL_get_error(c->ssl, ret);
|
607
642
|
switch (ret) {
|
608
|
-
case SSL_ERROR_SSL:
|
609
|
-
case SSL_ERROR_ZERO_RETURN:
|
610
|
-
|
611
|
-
case
|
612
|
-
|
613
|
-
case
|
614
|
-
case
|
615
|
-
case
|
616
|
-
case
|
617
|
-
case SSL_ERROR_WANT_WRITE: /* overflow */
|
618
|
-
case SSL_ERROR_WANT_READ: /* overflow */
|
643
|
+
case SSL_ERROR_SSL: /* overflow */
|
644
|
+
case SSL_ERROR_ZERO_RETURN: return 0; /* EOF */
|
645
|
+
case SSL_ERROR_SYSCALL: /* allow errno to inform us */ break; /* return -1 */
|
646
|
+
case SSL_ERROR_NONE: /* overflow */
|
647
|
+
case SSL_ERROR_WANT_CONNECT: /* overflow */
|
648
|
+
case SSL_ERROR_WANT_ACCEPT: /* overflow */
|
649
|
+
case SSL_ERROR_WANT_X509_LOOKUP: /* overflow */
|
650
|
+
case SSL_ERROR_WANT_WRITE: /* overflow */
|
651
|
+
case SSL_ERROR_WANT_READ: /* overflow */
|
619
652
|
#ifdef SSL_ERROR_WANT_ASYNC
|
620
|
-
case SSL_ERROR_WANT_ASYNC:
|
653
|
+
case SSL_ERROR_WANT_ASYNC: /* overflow */
|
621
654
|
#endif
|
622
|
-
default:
|
623
|
-
errno = EWOULDBLOCK;
|
624
|
-
break;
|
655
|
+
default: errno = EWOULDBLOCK; break;
|
625
656
|
}
|
626
657
|
return -1;
|
627
658
|
(void)uuid;
|
@@ -664,9 +695,9 @@ static fio_rw_hook_s FIO_TLS_HOOKS = {
|
|
664
695
|
.cleanup = fio_tls_cleanup,
|
665
696
|
};
|
666
697
|
|
667
|
-
#define FIO_TLS_HANDSHAKE_ERROR
|
668
|
-
#define FIO_TLS_HANDSHAKE_OK
|
669
|
-
#define FIO_TLS_HANDSHAKE_NEED_READ
|
698
|
+
#define FIO_TLS_HANDSHAKE_ERROR 0
|
699
|
+
#define FIO_TLS_HANDSHAKE_OK 1
|
700
|
+
#define FIO_TLS_HANDSHAKE_NEED_READ 2
|
670
701
|
#define FIO_TLS_HANDSHAKE_NEED_WRITE 4
|
671
702
|
|
672
703
|
static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
@@ -701,7 +732,8 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
701
732
|
if (errno) {
|
702
733
|
FIO_LOG_DEBUG(
|
703
734
|
"SSL_accept/SSL_connect %p error: SSL_ERROR_SYSCALL, errno: %s",
|
704
|
-
(void *)uuid,
|
735
|
+
(void *)uuid,
|
736
|
+
strerror(errno));
|
705
737
|
}
|
706
738
|
break;
|
707
739
|
case SSL_ERROR_SSL:
|
@@ -741,7 +773,8 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
741
773
|
#endif
|
742
774
|
default:
|
743
775
|
FIO_LOG_DEBUG("SSL_accept/SSL_connect %p error: unknown (%d).",
|
744
|
-
(void *)uuid,
|
776
|
+
(void *)uuid,
|
777
|
+
ri);
|
745
778
|
break;
|
746
779
|
}
|
747
780
|
fio_rw_hook_replace_unsafe(uuid, &FIO_TLS_HOOKS, udata);
|
@@ -766,7 +799,8 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
766
799
|
}
|
767
800
|
if (alpn)
|
768
801
|
FIO_LOG_DEBUG("setting ALPN %s for TLS client %p",
|
769
|
-
fio_str_data(&alpn->name),
|
802
|
+
fio_str_data(&alpn->name),
|
803
|
+
(void *)uuid);
|
770
804
|
alpn_select(alpn, c->uuid, c->alpn_arg);
|
771
805
|
}
|
772
806
|
}
|
@@ -783,7 +817,8 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
783
817
|
#if FIO_TLS_PRINT_SECRET
|
784
818
|
if (FIO_LOG_LEVEL >= FIO_LOG_LEVEL_DEBUG) {
|
785
819
|
unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH + 2];
|
786
|
-
size_t ret = SSL_SESSION_get_master_key(SSL_get_session(c->ssl),
|
820
|
+
size_t ret = SSL_SESSION_get_master_key(SSL_get_session(c->ssl),
|
821
|
+
buff,
|
787
822
|
SSL_MAX_MASTER_KEY_LENGTH + 1);
|
788
823
|
buff[ret] = 0;
|
789
824
|
unsigned char buff2[(SSL_MAX_MASTER_KEY_LENGTH + 2) << 1];
|
@@ -794,7 +829,8 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
794
829
|
: ('0' + (buff[i] & 15));
|
795
830
|
}
|
796
831
|
buff2[(ret << 1)] = 0;
|
797
|
-
FIO_LOG_DEBUG("OpenSSL Master Key for uuid %p:\n\t\t%s",
|
832
|
+
FIO_LOG_DEBUG("OpenSSL Master Key for uuid %p:\n\t\t%s",
|
833
|
+
(void *)uuid,
|
798
834
|
buff2);
|
799
835
|
}
|
800
836
|
#endif
|
@@ -802,7 +838,9 @@ static size_t fio_tls_handshake(intptr_t uuid, void *udata) {
|
|
802
838
|
return status;
|
803
839
|
}
|
804
840
|
|
805
|
-
static ssize_t fio_tls_read4handshake(intptr_t uuid,
|
841
|
+
static ssize_t fio_tls_read4handshake(intptr_t uuid,
|
842
|
+
void *udata,
|
843
|
+
void *buf,
|
806
844
|
size_t count) {
|
807
845
|
// FIO_LOG_DEBUG("TLS handshake from read %p", (void *)uuid);
|
808
846
|
size_t s = fio_tls_handshake(uuid, udata);
|
@@ -814,8 +852,10 @@ static ssize_t fio_tls_read4handshake(intptr_t uuid, void *udata, void *buf,
|
|
814
852
|
return -1;
|
815
853
|
}
|
816
854
|
|
817
|
-
static ssize_t fio_tls_write4handshake(intptr_t uuid,
|
818
|
-
|
855
|
+
static ssize_t fio_tls_write4handshake(intptr_t uuid,
|
856
|
+
void *udata,
|
857
|
+
const void *buf,
|
858
|
+
size_t count) {
|
819
859
|
// FIO_LOG_DEBUG("TLS handshake from write %p", (void *)uuid);
|
820
860
|
size_t s = fio_tls_handshake(uuid, udata);
|
821
861
|
if (s == FIO_TLS_HANDSHAKE_OK)
|
@@ -845,8 +885,10 @@ static fio_rw_hook_s FIO_TLS_HANDSHAKE_HOOKS = {
|
|
845
885
|
.flush = fio_tls_flush4handshake,
|
846
886
|
.cleanup = fio_tls_cleanup,
|
847
887
|
};
|
848
|
-
static inline void fio_tls_attach2uuid(intptr_t uuid,
|
849
|
-
|
888
|
+
static inline void fio_tls_attach2uuid(intptr_t uuid,
|
889
|
+
fio_tls_s *tls,
|
890
|
+
void *udata,
|
891
|
+
uint8_t is_server) {
|
850
892
|
fio_atomic_add(&tls->ref, 1);
|
851
893
|
/* create SSL connection context from global context */
|
852
894
|
fio_tls_connection_s *c = malloc(sizeof(*c));
|
@@ -891,8 +933,10 @@ SSL/TLS API implementation - this can be pretty much used as is...
|
|
891
933
|
* Creates a new SSL/TLS context / settings object with a default certificate
|
892
934
|
* (if any).
|
893
935
|
*/
|
894
|
-
fio_tls_s *FIO_TLS_WEAK fio_tls_new(const char *server_name,
|
895
|
-
const char *
|
936
|
+
fio_tls_s *FIO_TLS_WEAK fio_tls_new(const char *server_name,
|
937
|
+
const char *cert,
|
938
|
+
const char *key,
|
939
|
+
const char *pk_password) {
|
896
940
|
REQUIRE_LIBRARY();
|
897
941
|
fio_tls_s *tls = calloc(sizeof(*tls), 1);
|
898
942
|
tls->ref = 1;
|
@@ -903,8 +947,10 @@ fio_tls_s *FIO_TLS_WEAK fio_tls_new(const char *server_name, const char *cert,
|
|
903
947
|
/**
|
904
948
|
* Adds a certificate a new SSL/TLS context / settings object.
|
905
949
|
*/
|
906
|
-
void FIO_TLS_WEAK fio_tls_cert_add(fio_tls_s *tls,
|
907
|
-
const char *
|
950
|
+
void FIO_TLS_WEAK fio_tls_cert_add(fio_tls_s *tls,
|
951
|
+
const char *server_name,
|
952
|
+
const char *cert,
|
953
|
+
const char *key,
|
908
954
|
const char *pk_password) {
|
909
955
|
REQUIRE_LIBRARY();
|
910
956
|
cert_s c = {
|
@@ -929,7 +975,8 @@ void FIO_TLS_WEAK fio_tls_cert_add(fio_tls_s *tls, const char *server_name,
|
|
929
975
|
return;
|
930
976
|
file_missing:
|
931
977
|
FIO_LOG_FATAL("TLS certificate file missing for either %s or %s or both.",
|
932
|
-
key,
|
978
|
+
key,
|
979
|
+
cert);
|
933
980
|
exit(-1);
|
934
981
|
}
|
935
982
|
|
@@ -950,10 +997,13 @@ file_missing:
|
|
950
997
|
* Except for the `tls` and `protocol_name` arguments, all arguments can be
|
951
998
|
* NULL.
|
952
999
|
*/
|
953
|
-
void FIO_TLS_WEAK fio_tls_alpn_add(
|
954
|
-
|
955
|
-
|
956
|
-
|
1000
|
+
void FIO_TLS_WEAK fio_tls_alpn_add(fio_tls_s *tls,
|
1001
|
+
const char *protocol_name,
|
1002
|
+
void (*on_selected)(intptr_t uuid,
|
1003
|
+
void *udata_connection,
|
1004
|
+
void *udata_tls),
|
1005
|
+
void *udata_tls,
|
1006
|
+
void (*on_cleanup)(void *udata_tls)) {
|
957
1007
|
REQUIRE_LIBRARY();
|
958
1008
|
alpn_add(tls, protocol_name, on_selected, udata_tls, on_cleanup);
|
959
1009
|
fio_tls_build_context(tls);
|
data/ext/iodine/iodine_caller.c
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
static pthread_key_t iodine_GVL_state_key;
|
11
11
|
static pthread_once_t iodine_GVL_state_once = PTHREAD_ONCE_INIT;
|
12
12
|
static void init_iodine_GVL_state_key(void) {
|
13
|
-
pthread_key_create(&iodine_GVL_state_key, NULL);
|
13
|
+
pthread_key_create(&iodine_GVL_state_key, NULL);
|
14
14
|
}
|
15
15
|
static void init_iodine_GVL_state_init(void) {
|
16
16
|
uint8_t *gvl = malloc(sizeof(uint8_t));
|
@@ -47,14 +47,18 @@ static void *iodine_handle_exception(void *ignr) {
|
|
47
47
|
if (TYPE(bt) == T_ARRAY) {
|
48
48
|
bt = rb_ary_join(bt, rb_str_new_literal("\n"));
|
49
49
|
FIO_LOG_ERROR("Iodine caught an unprotected exception - %.*s: %.*s\n%s",
|
50
|
-
(int)RSTRING_LEN(exc_class),
|
51
|
-
|
50
|
+
(int)RSTRING_LEN(exc_class),
|
51
|
+
RSTRING_PTR(exc_class),
|
52
|
+
(int)RSTRING_LEN(msg),
|
53
|
+
RSTRING_PTR(msg),
|
52
54
|
StringValueCStr(bt));
|
53
55
|
} else {
|
54
56
|
FIO_LOG_ERROR("Iodine caught an unprotected exception - %.*s: %.*s\n"
|
55
57
|
"No backtrace available.\n",
|
56
|
-
(int)RSTRING_LEN(exc_class),
|
57
|
-
(
|
58
|
+
(int)RSTRING_LEN(exc_class),
|
59
|
+
RSTRING_PTR(exc_class),
|
60
|
+
(int)RSTRING_LEN(msg),
|
61
|
+
RSTRING_PTR(msg));
|
58
62
|
}
|
59
63
|
rb_backtrace();
|
60
64
|
FIO_LOG_ERROR("\n");
|
@@ -69,8 +73,12 @@ static void *iodine_handle_exception(void *ignr) {
|
|
69
73
|
/* calls the Ruby each method within the protection block */
|
70
74
|
static VALUE iodine_ruby_caller_perform_block(VALUE tsk_) {
|
71
75
|
iodine_rb_task_s *task = (void *)tsk_;
|
72
|
-
return rb_block_call(task->obj,
|
73
|
-
task->
|
76
|
+
return rb_block_call(task->obj,
|
77
|
+
task->method,
|
78
|
+
task->argc,
|
79
|
+
task->argv,
|
80
|
+
(rb_block_call_func_t)(task->each_func),
|
81
|
+
task->each_udata);
|
74
82
|
}
|
75
83
|
|
76
84
|
/* calls the Ruby method within the protection block */
|
@@ -83,7 +91,8 @@ static VALUE iodine_ruby_caller_perform(VALUE tsk_) {
|
|
83
91
|
static void *iodine_protect_ruby_call(void *task_) {
|
84
92
|
int state = 0;
|
85
93
|
VALUE ret = rb_protect(((iodine_rb_task_s *)task_)->protected_task,
|
86
|
-
(VALUE)(task_),
|
94
|
+
(VALUE)(task_),
|
95
|
+
&state);
|
87
96
|
if (state) {
|
88
97
|
iodine_handle_exception(NULL);
|
89
98
|
}
|
@@ -157,10 +166,13 @@ static VALUE iodine_call2(VALUE obj, ID method, int argc, VALUE *argv) {
|
|
157
166
|
}
|
158
167
|
|
159
168
|
/** Calls a Ruby method on a given object, protecting against exceptions. */
|
160
|
-
static VALUE iodine_call_block(
|
161
|
-
|
162
|
-
|
163
|
-
|
169
|
+
static VALUE iodine_call_block(
|
170
|
+
VALUE obj,
|
171
|
+
ID method,
|
172
|
+
int argc,
|
173
|
+
VALUE *argv,
|
174
|
+
VALUE udata,
|
175
|
+
VALUE(each_func)(VALUE block_arg, VALUE udata, int argc, VALUE *argv)) {
|
164
176
|
iodine_rb_task_s task = {
|
165
177
|
.obj = obj,
|
166
178
|
.argc = argc,
|
@@ -186,7 +198,7 @@ static uint8_t iodine_in_GVL(void) {
|
|
186
198
|
}
|
187
199
|
|
188
200
|
/** Forces the GVL state flag. */
|
189
|
-
static void iodine_set_GVL(uint8_t state) {
|
201
|
+
static void iodine_set_GVL(uint8_t state) {
|
190
202
|
pthread_once(&iodine_GVL_state_once, init_iodine_GVL_state_key);
|
191
203
|
uint8_t *iodine_GVL_state = pthread_getspecific(iodine_GVL_state_key);
|
192
204
|
if (!iodine_GVL_state) {
|
data/lib/iodine/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iodine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.58
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -251,7 +251,7 @@ licenses:
|
|
251
251
|
metadata:
|
252
252
|
allowed_push_host: https://rubygems.org
|
253
253
|
post_install_message: |-
|
254
|
-
Thank you for installing Iodine 0.7.
|
254
|
+
Thank you for installing Iodine 0.7.58.
|
255
255
|
Remember: if iodine supports your business, it's only fair to give value back (code contributions / donations).
|
256
256
|
rdoc_options: []
|
257
257
|
require_paths:
|