Skip to content

Commit 5440dba

Browse files
committed
Apply read-wants-write patch
1 parent be4a19f commit 5440dba

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

src/crypto/openssl.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct us_internal_ssl_socket_context_t {
7070
/* These decorate the base implementation */
7171
struct us_internal_ssl_socket_t *(*on_open)(struct us_internal_ssl_socket_t *, int is_client, char *ip, int ip_length);
7272
struct us_internal_ssl_socket_t *(*on_data)(struct us_internal_ssl_socket_t *, char *data, int length);
73+
struct us_internal_ssl_socket_t *(*on_writable)(struct us_internal_ssl_socket_t *);
7374
struct us_internal_ssl_socket_t *(*on_close)(struct us_internal_ssl_socket_t *, int code, void *reason);
7475

7576
/* Called for missing SNI hostnames, if not NULL */
@@ -84,6 +85,7 @@ struct us_internal_ssl_socket_t {
8485
struct us_socket_t s;
8586
SSL *ssl;
8687
int ssl_write_wants_read; // we use this for now
88+
int ssl_read_wants_write;
8789
};
8890

8991
int passphrase_cb(char *buf, int size, int rwflag, void *u) {
@@ -155,6 +157,7 @@ struct us_internal_ssl_socket_t *ssl_on_open(struct us_internal_ssl_socket_t *s,
155157

156158
s->ssl = SSL_new(context->ssl_context);
157159
s->ssl_write_wants_read = 0;
160+
s->ssl_read_wants_write = 0;
158161
SSL_set_bio(s->ssl, loop_ssl_data->shared_rbio, loop_ssl_data->shared_wbio);
159162

160163
BIO_up_ref(loop_ssl_data->shared_rbio);
@@ -183,7 +186,7 @@ struct us_internal_ssl_socket_t *ssl_on_close(struct us_internal_ssl_socket_t *s
183186
}
184187

185188
struct us_internal_ssl_socket_t *ssl_on_end(struct us_internal_ssl_socket_t *s) {
186-
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
189+
// struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
187190

188191
// whatever state we are in, a TCP FIN is always an answered shutdown
189192

@@ -252,6 +255,11 @@ struct us_internal_ssl_socket_t *ssl_on_data(struct us_internal_ssl_socket_t *s,
252255
} else {
253256
// emit the data we have and exit
254257

258+
if (err == SSL_ERROR_WANT_WRITE) {
259+
// here we need to trigger writable event next ssl_read!
260+
s->ssl_read_wants_write = 1;
261+
}
262+
255263
// assume we emptied the input buffer fully or error here as well!
256264
if (loop_ssl_data->ssl_read_input_length) {
257265
return us_internal_ssl_socket_close(s, 0, NULL);
@@ -321,6 +329,28 @@ struct us_internal_ssl_socket_t *ssl_on_data(struct us_internal_ssl_socket_t *s,
321329
return s;
322330
}
323331

332+
struct us_internal_ssl_socket_t *ssl_on_writable(struct us_internal_ssl_socket_t *s) {
333+
334+
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
335+
336+
// todo: cork here so that we efficiently output both from reading and from writing?
337+
338+
if (s->ssl_read_wants_write) {
339+
s->ssl_read_wants_write = 0;
340+
341+
// make sure to update context before we call (context can change if the user adopts the socket!)
342+
context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
343+
344+
// if this one fails to write data, it sets ssl_read_wants_write again
345+
s = (struct us_internal_ssl_socket_t *) context->sc.on_data(&s->s, 0, 0); // cast here!
346+
}
347+
348+
// should this one come before we have read? should it come always? spurious on_writable is okay
349+
s = context->on_writable(s);
350+
351+
return s;
352+
}
353+
324354
/* Lazily inits loop ssl data first time */
325355
void us_internal_init_loop_ssl_data(struct us_loop_t *loop) {
326356
if (!loop->data.ssl_data) {
@@ -674,7 +704,8 @@ void us_internal_ssl_socket_context_on_data(struct us_internal_ssl_socket_contex
674704
}
675705

676706
void us_internal_ssl_socket_context_on_writable(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_writable)(struct us_internal_ssl_socket_t *s)) {
677-
us_socket_context_on_writable(0, (struct us_socket_context_t *) context, (struct us_socket_t *(*)(struct us_socket_t *)) on_writable);
707+
us_socket_context_on_writable(0, (struct us_socket_context_t *) context, (struct us_socket_t *(*)(struct us_socket_t *)) ssl_on_writable);
708+
context->on_writable = on_writable;
678709
}
679710

680711
void us_internal_ssl_socket_context_on_timeout(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_timeout)(struct us_internal_ssl_socket_t *s)) {

0 commit comments

Comments
 (0)