77#include "dyn_buff.h"
88#include "native.h"
99
10+ struct Datagram {
11+ UnifexPayload * packet ;
12+ struct Datagram * next ;
13+ };
14+
1015static void ssl_info_cb (const SSL * ssl , int where , int ret );
1116static int verify_cb (int preverify_ok , X509_STORE_CTX * ctx );
12- static int read_pending_data (UnifexPayload * gen_packets , int pending_data_len ,
13- State * state );
17+ static void read_pending_data (UnifexPayload * * * payloads , int * size ,
18+ State * state );
1419static void cert_to_payload (UnifexEnv * env , X509 * x509 , UnifexPayload * payload );
1520static void pkey_to_payload (UnifexEnv * env , EVP_PKEY * pkey ,
1621 UnifexPayload * payload );
@@ -21,6 +26,7 @@ UNIFEX_TERM handle_regular_read(State *state, char data[], int ret);
2126UNIFEX_TERM handle_read_error (State * state , int ret );
2227UNIFEX_TERM handle_handshake_in_progress (State * state , int ret );
2328UNIFEX_TERM handle_handshake_finished (State * state );
29+ static UnifexPayload * * to_payload_array (struct Datagram * dgram_list , int len );
2430
2531int handle_load (UnifexEnv * env , void * * priv_data ) {
2632 UNIFEX_UNUSED (env );
@@ -242,23 +248,19 @@ UNIFEX_TERM do_handshake(UnifexEnv *env, State *state) {
242248 if (pending_data_len > 0 ) {
243249 DEBUG ("WBIO: pending data: %ld bytes" , pending_data_len );
244250
245- char * pending_data = (char * )malloc (pending_data_len * sizeof (char ));
246- memset (pending_data , 0 , pending_data_len );
247- BIO * wbio = SSL_get_wbio (state -> ssl );
248- int read_bytes = BIO_read (wbio , pending_data , pending_data_len );
249- if (read_bytes <= 0 ) {
250- DEBUG ("WBIO: read error" );
251+ UnifexPayload * * gen_packets ;
252+ int gen_packets_size ;
253+ read_pending_data (& gen_packets , & gen_packets_size , state );
254+
255+ if (gen_packets == NULL ) {
251256 return unifex_raise (state -> env , "Handshake failed: write BIO error" );
252257 } else {
253- DEBUG ("WBIO: read: %d bytes" , read_bytes );
254- UnifexPayload gen_packets ;
255- unifex_payload_alloc (env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
256- & gen_packets );
257- memcpy (gen_packets .data , pending_data , pending_data_len );
258- gen_packets .size = (unsigned int )pending_data_len ;
259258 int timeout = get_timeout (state -> ssl );
260- UNIFEX_TERM res_term = do_handshake_result (env , & gen_packets , timeout );
261- unifex_payload_release (& gen_packets );
259+ UNIFEX_TERM res_term =
260+ do_handshake_result (env , gen_packets , gen_packets_size , timeout );
261+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
262+ unifex_payload_release (gen_packets [i ]);
263+ }
262264 return res_term ;
263265 }
264266 }
@@ -285,19 +287,21 @@ UNIFEX_TERM write_data(UnifexEnv *env, State *state, UnifexPayload *payload) {
285287 return unifex_raise (env , "No data to read from BIO after writing" );
286288 }
287289
288- UnifexPayload res_payload ;
289- unifex_payload_alloc (env , UNIFEX_PAYLOAD_BINARY , pending_data_len , & res_payload );
290-
291- int read_bytes = BIO_read (wbio , res_payload .data , pending_data_len );
292- if (read_bytes <= 0 || (size_t ) read_bytes != pending_data_len ) {
290+ UnifexPayload * * gen_packets = NULL ;
291+ int gen_packets_size = 0 ;
292+ read_pending_data (& gen_packets , & gen_packets_size , state );
293+ if (gen_packets == NULL ) {
293294 DEBUG ("Unable to read data from BIO after writing" );
294295 return unifex_raise (env , "Unable to read data from BIO after writing" );
295296 }
296297
297- DEBUG ("Wrote %d bytes of data" , read_bytes );
298- res_payload .size = (unsigned int ) pending_data_len ;
299- UNIFEX_TERM res_term = write_data_result_ok (env , & res_payload );
300- unifex_payload_release (& res_payload );
298+ UNIFEX_TERM res_term =
299+ write_data_result_ok (env , gen_packets , gen_packets_size );
300+
301+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
302+ unifex_payload_release (gen_packets [i ]);
303+ }
304+
301305 return res_term ;
302306}
303307
@@ -333,12 +337,14 @@ UNIFEX_TERM handle_data(UnifexEnv *env, State *state, UnifexPayload *payload) {
333337
334338UNIFEX_TERM handle_regular_read (State * state , char data [], int ret ) {
335339 if (ret > 0 ) {
336- UnifexPayload packets ;
337- unifex_payload_alloc (state -> env , UNIFEX_PAYLOAD_BINARY , ret , & packets );
338- memcpy (packets .data , data , ret );
339- packets .size = (unsigned int )ret ;
340- UNIFEX_TERM res_term = handle_data_result_ok (state -> env , & packets );
341- unifex_payload_release (& packets );
340+ UnifexPayload * * packets = calloc (1 , sizeof (UnifexPayload * ));
341+ UnifexPayload packet ;
342+ packets [0 ] = & packet ;
343+ unifex_payload_alloc (state -> env , UNIFEX_PAYLOAD_BINARY , ret , packets [0 ]);
344+ memcpy (packets [0 ]-> data , data , ret );
345+ packets [0 ]-> size = (unsigned int )ret ;
346+ UNIFEX_TERM res_term = handle_data_result_ok (state -> env , packets , 1 );
347+ unifex_payload_release (packets [0 ]);
342348 return res_term ;
343349 }
344350
@@ -369,7 +375,8 @@ UNIFEX_TERM handle_read_error(State *state, int ret) {
369375
370376UNIFEX_TERM handle_handshake_finished (State * state ) {
371377 UNIFEX_TERM res_term ;
372- UnifexPayload gen_packets ;
378+ UnifexPayload * * gen_packets = NULL ;
379+ int gen_packets_size = 0 ;
373380 KeyingMaterial * keying_material = export_keying_material (state -> ssl );
374381 if (keying_material == NULL ) {
375382 DEBUG ("Cannot export keying material" );
@@ -393,10 +400,9 @@ UNIFEX_TERM handle_handshake_finished(State *state) {
393400 size_t pending_data_len = BIO_ctrl_pending (SSL_get_wbio (state -> ssl ));
394401 DEBUG ("WBIO: pending data: %ld bytes" , pending_data_len );
395402
396- unifex_payload_alloc (state -> env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
397- & gen_packets );
398403 if (pending_data_len > 0 ) {
399- if (read_pending_data (& gen_packets , pending_data_len , state ) < 0 ) {
404+ read_pending_data (& gen_packets , & gen_packets_size , state );
405+ if (gen_packets == NULL ) {
400406 res_term = unifex_raise (state -> env , "Handshake failed: write BIO error" );
401407 goto cleanup ;
402408 }
@@ -416,10 +422,14 @@ UNIFEX_TERM handle_handshake_finished(State *state) {
416422
417423 res_term = handle_data_result_handshake_finished (
418424 state -> env , local_keying_material , remote_keying_material ,
419- keying_material -> protection_profile , & gen_packets );
425+ keying_material -> protection_profile , gen_packets , gen_packets_size );
420426
421427cleanup :
422- unifex_payload_release (& gen_packets );
428+
429+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
430+ unifex_payload_release (gen_packets [i ]);
431+ }
432+
423433 unifex_payload_release (& client_keying_material );
424434 unifex_payload_release (& server_keying_material );
425435 return res_term ;
@@ -434,16 +444,20 @@ UNIFEX_TERM handle_handshake_in_progress(State *state, int ret) {
434444 DEBUG ("WBIO: pending data: %ld bytes" , pending_data_len );
435445
436446 if (pending_data_len > 0 ) {
437- UnifexPayload gen_packets ;
438- unifex_payload_alloc ( state -> env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
439- & gen_packets );
440- if (read_pending_data ( & gen_packets , pending_data_len , state ) < 0 ) {
447+ UnifexPayload * * gen_packets = NULL ;
448+ int gen_packets_size = 0 ;
449+ read_pending_data ( & gen_packets , & gen_packets_size , state );
450+ if (gen_packets == NULL ) {
441451 return unifex_raise (state -> env , "Handshake failed: write BIO error" );
442452 }
443453 int timeout = get_timeout (state -> ssl );
444454 UNIFEX_TERM res_term = handle_data_result_handshake_packets (
445- state -> env , & gen_packets , timeout );
446- unifex_payload_release (& gen_packets );
455+ state -> env , gen_packets , gen_packets_size , timeout );
456+
457+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
458+ unifex_payload_release (gen_packets [i ]);
459+ }
460+
447461 return res_term ;
448462 } else {
449463 return handle_data_result_handshake_want_read (state -> env );
@@ -458,20 +472,22 @@ UNIFEX_TERM handle_timeout(UnifexEnv *env, State *state) {
458472 if (result != 1 )
459473 return handle_timeout_result_ok (env );
460474
461- BIO * wbio = SSL_get_wbio (state -> ssl );
462- size_t pending_data_len = BIO_ctrl_pending (wbio );
463- UnifexPayload gen_packets ;
464- unifex_payload_alloc (env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
465- & gen_packets );
475+ UnifexPayload * * gen_packets = NULL ;
476+ int gen_packets_size = 0 ;
477+ read_pending_data (& gen_packets , & gen_packets_size , state );
466478
467- if (read_pending_data ( & gen_packets , pending_data_len , state ) < 0 ) {
479+ if (gen_packets == NULL ) {
468480 return unifex_raise (state -> env ,
469481 "Retransmit handshake failed: write BIO error" );
470482 } else {
471483 int timeout = get_timeout (state -> ssl );
472- UNIFEX_TERM res_term =
473- handle_timeout_result_retransmit (env , & gen_packets , timeout );
474- unifex_payload_release (& gen_packets );
484+ UNIFEX_TERM res_term = handle_timeout_result_retransmit (
485+ env , gen_packets , gen_packets_size , timeout );
486+
487+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
488+ unifex_payload_release (gen_packets [i ]);
489+ }
490+
475491 return res_term ;
476492 }
477493}
@@ -511,22 +527,84 @@ static int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) {
511527 }
512528}
513529
514- static int read_pending_data (UnifexPayload * gen_packets , int pending_data_len ,
515- State * state ) {
516- char * pending_data = (char * )malloc (pending_data_len * sizeof (char ));
517- memset (pending_data , 0 , pending_data_len );
518- BIO * wbio = SSL_get_wbio (state -> ssl );
519- int read_bytes = BIO_read (wbio , pending_data , pending_data_len );
520- if (read_bytes <= 0 ) {
521- DEBUG ("WBIO: read error" );
522- } else {
523- DEBUG ("WBIO: read: %d bytes" , read_bytes );
524- memcpy (gen_packets -> data , pending_data , pending_data_len );
525- gen_packets -> size = (unsigned int )pending_data_len ;
530+ static UnifexPayload * * to_payload_array (struct Datagram * dgram_list , int len ) {
531+
532+ UnifexPayload * * payloads = calloc (len , sizeof (UnifexPayload * ));
533+
534+ for (int i = 0 ; i < len ; i ++ ) {
535+ DEBUG ("%d" , i );
536+ payloads [i ] = NULL ;
537+ }
538+
539+ struct Datagram * itr = dgram_list ;
540+
541+ for (int i = 0 ; i < len ; i ++ ) {
542+ DEBUG ("size, %d" , itr -> packet -> size );
543+ itr = itr -> next ;
544+ }
545+
546+ itr = dgram_list ;
547+ for (int i = 0 ; i < len ; i ++ ) {
548+ DEBUG ("to payload array 3, %d" , len );
549+ payloads [i ] = itr -> packet ;
550+ itr = itr -> next ;
551+ }
552+
553+ DEBUG ("to payload array" );
554+
555+ // itr = dgram_list;
556+ // struct Datagram *next = dgram_list->next;
557+
558+ // for (int i = 0; i < len; i++) {
559+ // free(itr);
560+ // itr = next;
561+ // next = itr->next;
562+ // DEBUG("dupa2");
563+ // }
564+
565+ return payloads ;
566+ }
567+
568+ static void read_pending_data (UnifexPayload * * * payloads , int * size ,
569+ State * state ) {
570+
571+ struct Datagram * dgram_list = NULL ;
572+ struct Datagram * itr = NULL ;
573+ * size = 0 ;
574+
575+ size_t pending_data_len = 0 ;
576+ while ((pending_data_len = BIO_ctrl_pending (SSL_get_wbio (state -> ssl ))) > 0 ) {
577+ struct Datagram * dgram = calloc (1 , sizeof (struct Datagram ));
578+ UnifexPayload * payload = calloc (1 , sizeof (UnifexPayload ));
579+ unifex_payload_alloc (state -> env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
580+ payload );
581+ dgram -> packet = payload ;
582+ dgram -> next = NULL ;
583+
584+ BIO * wbio = SSL_get_wbio (state -> ssl );
585+ int read_bytes = BIO_read (wbio , payload -> data , pending_data_len );
586+ if (read_bytes <= 0 ) {
587+ DEBUG ("WBIO: read error" );
588+ // TODO cleanup
589+ * size = 0 ;
590+ return ;
591+ } else {
592+ DEBUG ("WBIO: read: %d bytes" , read_bytes );
593+ dgram -> packet -> size = (unsigned int )pending_data_len ;
594+ }
595+
596+ if (dgram_list == NULL ) {
597+ dgram_list = dgram ;
598+ itr = dgram_list ;
599+ } else {
600+ itr -> next = dgram ;
601+ itr = itr -> next ;
602+ }
603+
604+ (* size )++ ;
526605 }
527- free (pending_data );
528606
529- return read_bytes ;
607+ * payloads = to_payload_array ( dgram_list , * size ) ;
530608}
531609
532610static void cert_to_payload (UnifexEnv * env , X509 * x509 ,
0 commit comments