BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file PacketPassInterface.h
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * @section DESCRIPTION
30 *
31 * Interface allowing a packet sender to pass data packets to a packet receiver.
32 */
33  
34 #ifndef BADVPN_FLOW_PACKETPASSINTERFACE_H
35 #define BADVPN_FLOW_PACKETPASSINTERFACE_H
36  
37 #include <stdint.h>
38 #include <stddef.h>
39  
40 #include <misc/debug.h>
41 #include <base/DebugObject.h>
42 #include <base/BPending.h>
43  
44 #define PPI_STATE_NONE 1
45 #define PPI_STATE_OPERATION_PENDING 2
46 #define PPI_STATE_BUSY 3
47 #define PPI_STATE_DONE_PENDING 4
48  
49 typedef void (*PacketPassInterface_handler_send) (void *user, uint8_t *data, int data_len);
50  
51 typedef void (*PacketPassInterface_handler_requestcancel) (void *user);
52  
53 typedef void (*PacketPassInterface_handler_done) (void *user);
54  
55 typedef struct {
56 // provider data
57 int mtu;
58 PacketPassInterface_handler_send handler_operation;
59 PacketPassInterface_handler_requestcancel handler_requestcancel;
60 void *user_provider;
61  
62 // user data
63 PacketPassInterface_handler_done handler_done;
64 void *user_user;
65  
66 // operation job
67 BPending job_operation;
68 uint8_t *job_operation_data;
69 int job_operation_len;
70  
71 // requestcancel job
72 BPending job_requestcancel;
73  
74 // done job
75 BPending job_done;
76  
77 // state
78 int state;
79 int cancel_requested;
80  
81 DebugObject d_obj;
82 } PacketPassInterface;
83  
84 static void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg);
85  
86 static void PacketPassInterface_Free (PacketPassInterface *i);
87  
88 static void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_requestcancel handler_requestcancel);
89  
90 static void PacketPassInterface_Done (PacketPassInterface *i);
91  
92 static int PacketPassInterface_GetMTU (PacketPassInterface *i);
93  
94 static void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user);
95  
96 static void PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len);
97  
98 static void PacketPassInterface_Sender_RequestCancel (PacketPassInterface *i);
99  
100 static int PacketPassInterface_HasCancel (PacketPassInterface *i);
101  
102 void _PacketPassInterface_job_operation (PacketPassInterface *i);
103 void _PacketPassInterface_job_requestcancel (PacketPassInterface *i);
104 void _PacketPassInterface_job_done (PacketPassInterface *i);
105  
106 void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_operation, void *user, BPendingGroup *pg)
107 {
108 ASSERT(mtu >= 0)
109  
110 // init arguments
111 i->mtu = mtu;
112 i->handler_operation = handler_operation;
113 i->handler_requestcancel = NULL;
114 i->user_provider = user;
115  
116 // set no user
117 i->handler_done = NULL;
118  
119 // init jobs
120 BPending_Init(&i->job_operation, pg, (BPending_handler)_PacketPassInterface_job_operation, i);
121 BPending_Init(&i->job_requestcancel, pg, (BPending_handler)_PacketPassInterface_job_requestcancel, i);
122 BPending_Init(&i->job_done, pg, (BPending_handler)_PacketPassInterface_job_done, i);
123  
124 // set state
125 i->state = PPI_STATE_NONE;
126  
127 DebugObject_Init(&i->d_obj);
128 }
129  
130 void PacketPassInterface_Free (PacketPassInterface *i)
131 {
132 DebugObject_Free(&i->d_obj);
133  
134 // free jobs
135 BPending_Free(&i->job_done);
136 BPending_Free(&i->job_requestcancel);
137 BPending_Free(&i->job_operation);
138 }
139  
140 void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_requestcancel handler_requestcancel)
141 {
142 ASSERT(!i->handler_requestcancel)
143 ASSERT(!i->handler_done)
144 ASSERT(handler_requestcancel)
145  
146 i->handler_requestcancel = handler_requestcancel;
147 }
148  
149 void PacketPassInterface_Done (PacketPassInterface *i)
150 {
151 ASSERT(i->state == PPI_STATE_BUSY)
152 DebugObject_Access(&i->d_obj);
153  
154 // unset requestcancel job
155 BPending_Unset(&i->job_requestcancel);
156  
157 // schedule done
158 BPending_Set(&i->job_done);
159  
160 // set state
161 i->state = PPI_STATE_DONE_PENDING;
162 }
163  
164 int PacketPassInterface_GetMTU (PacketPassInterface *i)
165 {
166 DebugObject_Access(&i->d_obj);
167  
168 return i->mtu;
169 }
170  
171 void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user)
172 {
173 ASSERT(handler_done)
174 ASSERT(!i->handler_done)
175 DebugObject_Access(&i->d_obj);
176  
177 i->handler_done = handler_done;
178 i->user_user = user;
179 }
180  
181 void PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len)
182 {
183 ASSERT(data_len >= 0)
184 ASSERT(data_len <= i->mtu)
185 ASSERT(!(data_len > 0) || data)
186 ASSERT(i->state == PPI_STATE_NONE)
187 ASSERT(i->handler_done)
188 DebugObject_Access(&i->d_obj);
189  
190 // schedule operation
191 i->job_operation_data = data;
192 i->job_operation_len = data_len;
193 BPending_Set(&i->job_operation);
194  
195 // set state
196 i->state = PPI_STATE_OPERATION_PENDING;
197 i->cancel_requested = 0;
198 }
199  
200 void PacketPassInterface_Sender_RequestCancel (PacketPassInterface *i)
201 {
202 ASSERT(i->state == PPI_STATE_OPERATION_PENDING || i->state == PPI_STATE_BUSY || i->state == PPI_STATE_DONE_PENDING)
203 ASSERT(i->handler_requestcancel)
204 DebugObject_Access(&i->d_obj);
205  
206 // ignore multiple cancel requests
207 if (i->cancel_requested) {
208 return;
209 }
210  
211 // remember we requested cancel
212 i->cancel_requested = 1;
213  
214 if (i->state == PPI_STATE_OPERATION_PENDING) {
215 // unset operation job
216 BPending_Unset(&i->job_operation);
217  
218 // set done job
219 BPending_Set(&i->job_done);
220  
221 // set state
222 i->state = PPI_STATE_DONE_PENDING;
223 } else if (i->state == PPI_STATE_BUSY) {
224 // set requestcancel job
225 BPending_Set(&i->job_requestcancel);
226 }
227 }
228  
229 int PacketPassInterface_HasCancel (PacketPassInterface *i)
230 {
231 DebugObject_Access(&i->d_obj);
232  
233 return !!i->handler_requestcancel;
234 }
235  
236 #endif