@@ -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
8991int 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
185188struct 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 */
325355void 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
676706void 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
680711void 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