OpenSSL
1.0.1c
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
demos
tunala
sm.c
Go to the documentation of this file.
1
#include "
tunala.h
"
2
3
#ifndef NO_TUNALA
4
5
void
state_machine_init
(
state_machine_t
*machine)
6
{
7
machine->
ssl
= NULL;
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
);
13
}
14
15
void
state_machine_close
(
state_machine_t
*machine)
16
{
17
if
(machine->
ssl
)
18
SSL_free
(machine->
ssl
);
19
/* SSL_free seems to decrement the reference counts already so doing this goes
20
* kaboom. */
21
#if 0
22
if
(machine->
bio_intossl
)
23
BIO_free
(machine->
bio_intossl
);
24
if
(machine->
bio_fromssl
)
25
BIO_free
(machine->
bio_fromssl
);
26
#endif
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);
32
}
33
34
buffer_t
*
state_machine_get_buffer
(
state_machine_t
*machine,
sm_buffer_t
type
)
35
{
36
switch
(type) {
37
case
SM_CLEAN_IN
:
38
return
&machine->
clean_in
;
39
case
SM_CLEAN_OUT
:
40
return
&machine->
clean_out
;
41
case
SM_DIRTY_IN
:
42
return
&machine->
dirty_in
;
43
case
SM_DIRTY_OUT
:
44
return
&machine->
dirty_out
;
45
default
:
46
break
;
47
}
48
/* Should never get here */
49
abort();
50
return
NULL;
51
}
52
53
SSL
*
state_machine_get_SSL
(
state_machine_t
*machine)
54
{
55
return
machine->
ssl
;
56
}
57
58
int
state_machine_set_SSL
(
state_machine_t
*machine,
SSL
*ssl,
int
is_server)
59
{
60
if
(machine->
ssl
)
61
/* Shouldn't ever be set twice */
62
abort();
63
machine->
ssl
= ssl;
64
/* Create the BIOs to handle the dirty side of the SSL */
65
if
((machine->
bio_intossl
=
BIO_new
(
BIO_s_mem
())) == NULL)
66
abort();
67
if
((machine->
bio_fromssl
=
BIO_new
(
BIO_s_mem
())) == NULL)
68
abort();
69
/* Hook up the BIOs on the dirty side of the SSL */
70
SSL_set_bio
(machine->
ssl
, machine->
bio_intossl
, machine->
bio_fromssl
);
71
if
(is_server)
72
SSL_set_accept_state
(machine->
ssl
);
73
else
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
return
state_machine_churn
(machine);
79
}
80
81
/* Performs the data-IO loop and returns zero if the machine should close */
82
int
state_machine_churn
(
state_machine_t
*machine)
83
{
84
unsigned
int
loop;
85
if
(machine->
ssl
== NULL) {
86
if
(
buffer_empty
(&machine->
clean_out
))
87
/* Time to close this state-machine altogether */
88
return
0;
89
else
90
/* Still buffered data on the clean side to go out */
91
return
1;
92
}
93
/* Do this loop twice to cover any dependencies about which precise
94
* order of reads and writes is required. */
95
for
(loop = 0; loop < 2; loop++) {
96
buffer_to_SSL
(&machine->
clean_in
, machine->
ssl
);
97
buffer_to_BIO
(&machine->
dirty_in
, machine->
bio_intossl
);
98
buffer_from_SSL
(&machine->
clean_out
, machine->
ssl
);
99
buffer_from_BIO
(&machine->
dirty_out
, machine->
bio_fromssl
);
100
}
101
/* We close on the SSL side if the info callback noticed some problems
102
* or an SSL shutdown was underway and shutdown traffic had all been
103
* sent. */
104
if
(
SSL_get_app_data
(machine->
ssl
) || (
SSL_get_shutdown
(machine->
ssl
) &&
105
buffer_empty
(&machine->
dirty_out
))) {
106
/* Great, we can seal off the dirty side completely */
107
if
(!
state_machine_close_dirty
(machine))
108
return
0;
109
}
110
/* Either the SSL is alive and well, or the closing process still has
111
* outgoing data waiting to be sent */
112
return
1;
113
}
114
115
/* Called when the clean side of the SSL has lost its connection */
116
int
state_machine_close_clean
(
state_machine_t
*machine)
117
{
118
/* Well, first thing to do is null out the clean-side buffers - they're
119
* no use any more. */
120
buffer_close
(&machine->
clean_in
);
121
buffer_close
(&machine->
clean_out
);
122
/* And start an SSL shutdown */
123
if
(machine->
ssl
)
124
SSL_shutdown
(machine->
ssl
);
125
/* This is an "event", so flush the SSL of any generated traffic */
126
state_machine_churn
(machine);
127
if
(
buffer_empty
(&machine->
dirty_in
) &&
128
buffer_empty
(&machine->
dirty_out
))
129
return
0;
130
return
1;
131
}
132
133
/* Called when the dirty side of the SSL has lost its connection. This is pretty
134
* terminal as all that can be left to do is send any buffered output on the
135
* clean side - after that, we're done. */
136
int
state_machine_close_dirty
(
state_machine_t
*machine)
137
{
138
buffer_close
(&machine->
dirty_in
);
139
buffer_close
(&machine->
dirty_out
);
140
buffer_close
(&machine->
clean_in
);
141
if
(machine->
ssl
)
142
SSL_free
(machine->
ssl
);
143
machine->
ssl
= NULL;
144
machine->
bio_intossl
= machine->
bio_fromssl
= NULL;
145
if
(
buffer_empty
(&machine->
clean_out
))
146
return
0;
147
return
1;
148
}
149
150
#endif
/* !defined(NO_TUNALA) */
151
Generated on Thu Jan 10 2013 09:53:41 for OpenSSL by
1.8.2