11
22#include "bio_frag.h"
3+ #include <openssl/bio.h>
34
45static int bwrite (BIO * bio , const char * buf , int len );
56static int bread (BIO * bio , char * buf , int len );
@@ -8,23 +9,16 @@ static int create(BIO *bio);
89static int destroy (BIO * bio );
910static long callback_ctrl (BIO * bio , int cmd , BIO_info_cb * fp );
1011
11- // static const BIO_METHOD bio_methods = {
12- // BIO_TYPE_BIO,
13- // "DTLS fragmentation for mem BIO",
14- // bwrite_conv,
15- // bwrite,
16- // bread_conv,
17- // bread,
18- // NULL,
19- // NULL,
20- // ctrl,
21- // create,
22- // destroy,
23- // callback_ctrl
24- // };
25-
2612static BIO_METHOD * bio_methods = NULL ;
2713
14+ #define MAX_FRAGS 100
15+
16+ struct Ctx {
17+ int frag_sizes [MAX_FRAGS ];
18+ int witer ;
19+ int riter ;
20+ };
21+
2822const BIO_METHOD * BIO_f_frag (void ) {
2923 bio_methods = BIO_meth_new (BIO_TYPE_FILTER , "DTLS fragmentation for mem BIO" );
3024
@@ -39,50 +33,99 @@ const BIO_METHOD *BIO_f_frag(void) {
3933}
4034
4135static int create (BIO * bio ) {
42- DEBUG ("BIO frag create" );
43- // indicate that BIO initialization is complete
36+ struct Ctx * ctx = calloc (1 , sizeof (struct Ctx ));
37+ for (int i = 0 ; i < MAX_FRAGS ; i ++ ) {
38+ ctx -> frag_sizes [i ] = 0 ;
39+ }
40+ ctx -> witer = 0 ;
41+ ctx -> riter = 0 ;
42+
43+ BIO_set_data (bio , ctx );
4444 BIO_set_init (bio , 1 );
4545 return 1 ;
4646}
4747
4848static int destroy (BIO * bio ) {
49- DEBUG ("BIO frag destroy" );
5049 if (bio == NULL ) {
5150 return 0 ;
5251 }
5352
53+ struct Ctx * ctx = BIO_get_data (bio );
54+ free (ctx );
55+ BIO_set_data (bio , NULL );
5456 BIO_set_init (bio , 0 );
5557 return 1 ;
5658}
5759
5860static int bread (BIO * bio , char * buf , int len ) {
59- DEBUG ("BIO frag bread" );
6061 BIO * next = BIO_next (bio );
6162 if (next == NULL ) {
6263 return 0 ;
6364 }
6465
65- return BIO_read (next , buf , len );
66+ struct Ctx * ctx = BIO_get_data (bio );
67+
68+ if (len != ctx -> frag_sizes [ctx -> riter ]) {
69+ return 0 ;
70+ }
71+
72+ int ret = BIO_read (next , buf , len );
73+
74+ if (ret > 0 ) {
75+ if (ret == ctx -> frag_sizes [ctx -> riter ]) {
76+ ctx -> frag_sizes [ctx -> riter ] = 0 ;
77+ ctx -> riter ++ ;
78+
79+ if (ctx -> riter == ctx -> witer && ctx -> frag_sizes [ctx -> riter ] == 0 ) {
80+ // reset iterators
81+ ctx -> riter = 0 ;
82+ ctx -> witer = 0 ;
83+ }
84+
85+ } else if (ret < ctx -> frag_sizes [ctx -> riter ]) {
86+ ctx -> frag_sizes [ctx -> riter ] -= ret ;
87+ } else {
88+ // This should never happen
89+ return 0 ;
90+ }
91+ };
92+
93+ return ret ;
6694}
6795
6896static int bwrite (BIO * bio , const char * buf , int len ) {
69- DEBUG ("BIO frag bwrite %d" , len );
7097 BIO * next = BIO_next (bio );
7198 if (next == NULL ) {
7299 return 0 ;
73100 }
74101
75- return BIO_write (next , buf , len );
102+ struct Ctx * ctx = BIO_get_data (bio );
103+
104+ if (ctx -> witer >= MAX_FRAGS ) {
105+ return 0 ;
106+ }
107+
108+ int ret = BIO_write (next , buf , len );
109+ if (ret > 0 ) {
110+ ctx -> frag_sizes [ctx -> witer ] = ret ;
111+ ctx -> witer ++ ;
112+ }
113+
114+ return ret ;
76115}
77116
78117static long ctrl (BIO * bio , int cmd , long num , void * ptr ) {
79- DEBUG ("BIO frag ctrl" );
80-
81118 BIO * next = BIO_next (bio );
82119 if (next == NULL ) {
83120 return 0 ;
84121 }
85122
123+ struct Ctx * ctx = BIO_get_data (bio );
124+
125+ if (cmd == BIO_CTRL_PENDING ) {
126+ return ctx -> frag_sizes [ctx -> riter ];
127+ }
128+
86129 return BIO_ctrl (next , cmd , num , ptr );
87130}
88131
@@ -94,5 +137,3 @@ static long callback_ctrl(BIO *bio, int cmd, BIO_info_cb *fp) {
94137
95138 return BIO_callback_ctrl (next , cmd , fp );
96139}
97-
98-
0 commit comments