5 void state_machine_init(state_machine_t *machine)
8 machine->bio_intossl = machine->bio_fromssl = NULL;
9 buffer_init(&machine->clean_in);
10 buffer_init(&machine->clean_out);
11 buffer_init(&machine->dirty_in);
12 buffer_init(&machine->dirty_out);
15 void state_machine_close(state_machine_t *machine)
18 SSL_free(machine->ssl);
19 /* SSL_free seems to decrement the reference counts already so doing this goes
22 if(machine->bio_intossl)
23 BIO_free(machine->bio_intossl);
24 if(machine->bio_fromssl)
25 BIO_free(machine->bio_fromssl);
27 buffer_close(&machine->clean_in);
28 buffer_close(&machine->clean_out);
29 buffer_close(&machine->dirty_in);
30 buffer_close(&machine->dirty_out);
31 state_machine_init(machine);
34 buffer_t *state_machine_get_buffer(state_machine_t *machine, sm_buffer_t type)
38 return &machine->clean_in;
40 return &machine->clean_out;
42 return &machine->dirty_in;
44 return &machine->dirty_out;
48 /* Should never get here */
53 SSL *state_machine_get_SSL(state_machine_t *machine)
58 void state_machine_set_SSL(state_machine_t *machine, SSL *ssl, int is_server)
61 /* Shouldn't ever be set twice */
64 /* Create the BIOs to handle the dirty side of the SSL */
65 if((machine->bio_intossl = BIO_new(BIO_s_mem())) == NULL)
67 if((machine->bio_fromssl = BIO_new(BIO_s_mem())) == NULL)
69 /* Hook up the BIOs on the dirty side of the SSL */
70 SSL_set_bio(machine->ssl, machine->bio_intossl, machine->bio_fromssl);
72 SSL_set_accept_state(machine->ssl);
74 SSL_set_connect_state(machine->ssl);
75 /* If we're the first one to generate traffic - do it now otherwise we
76 * go into the next select empty-handed and our peer will not send data
77 * but will similarly wait for us. */
78 state_machine_churn(machine);
81 /* Performs the data-IO loop and returns zero if the machine should close */
82 int state_machine_churn(state_machine_t *machine)
85 /* Do this loop twice to cover any dependencies about which precise
86 * order of reads and writes is required. */
87 for(loop = 0; loop < 2; loop++) {
88 buffer_to_SSL(&machine->clean_in, machine->ssl);
89 buffer_to_BIO(&machine->dirty_in, machine->bio_intossl);
90 buffer_from_SSL(&machine->clean_out, machine->ssl);
91 buffer_from_BIO(&machine->dirty_out, machine->bio_fromssl);
93 if(machine->ssl == NULL) {
94 if(buffer_empty(&machine->clean_out))
95 /* Time to close this state-machine altogether */
98 /* Still buffered data on the clean side to go out */
101 if(SSL_get_shutdown(machine->ssl)) {
102 /* An SSL shutdown was underway */
103 if(buffer_empty(&machine->dirty_out)) {
104 /* Great, we can seal off the dirty side completely */
105 if(!state_machine_close_dirty(machine))
109 /* Either the SSL is alive and well, or the closing process still has
110 * outgoing data waiting to be sent */
114 /* Called when the clean side of the SSL has lost its connection */
115 int state_machine_close_clean(state_machine_t *machine)
117 /* Well, first thing to do is null out the clean-side buffers - they're
118 * no use any more. */
119 buffer_close(&machine->clean_in);
120 buffer_close(&machine->clean_out);
121 /* And start an SSL shutdown */
122 SSL_shutdown(machine->ssl);
123 /* This is an "event", so flush the SSL of any generated traffic */
124 state_machine_churn(machine);
125 if(buffer_empty(&machine->dirty_in) &&
126 buffer_empty(&machine->dirty_out))
131 /* Called when the dirty side of the SSL has lost its connection. This is pretty
132 * terminal as all that can be left to do is send any buffered output on the
133 * clean side - after that, we're done. */
134 int state_machine_close_dirty(state_machine_t *machine)
136 buffer_close(&machine->dirty_in);
137 buffer_close(&machine->dirty_out);
138 buffer_close(&machine->clean_in);
140 SSL_free(machine->ssl);
142 machine->bio_intossl = machine->bio_fromssl = NULL;
143 if(buffer_empty(&machine->clean_out))
148 #endif /* !defined(NO_TUNALA) */