forked from ambrop72/badvpn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DatagramPeerIO.h
266 lines (242 loc) · 8.81 KB
/
DatagramPeerIO.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/**
* @file DatagramPeerIO.h
* @author Ambroz Bizjak <[email protected]>
*
* @section LICENSE
*
* This file is part of BadVPN.
*
* BadVPN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* BadVPN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* @section DESCRIPTION
*
* Object for comminicating with a peer using a datagram socket.
*/
#ifndef BADVPN_CLIENT_DATAGRAMPEERIO_H
#define BADVPN_CLIENT_DATAGRAMPEERIO_H
#include <stdint.h>
#include <misc/debug.h>
#include <protocol/spproto.h>
#include <protocol/fragmentproto.h>
#include <base/DebugObject.h>
#include <system/BReactor.h>
#include <system/BAddr.h>
#include <system/BDatagram.h>
#include <system/BTime.h>
#include <flow/PacketPassInterface.h>
#include <flow/PacketPassConnector.h>
#include <flow/SinglePacketBuffer.h>
#include <flow/PacketRecvConnector.h>
#include <flow/PacketPassNotifier.h>
#include <client/FragmentProtoDisassembler.h>
#include <client/FragmentProtoAssembler.h>
#include <client/SPProtoEncoder.h>
#include <client/SPProtoDecoder.h>
typedef void (*DatagramPeerIO_logfunc) (void *user);
/**
* Callback function invoked when an error occurs with the peer connection.
* The object has entered default state.
* May be called from within a sending Send call.
*
* @param user as in {@link DatagramPeerIO_SetHandlers}
*/
typedef void (*DatagramPeerIO_handler_error) (void *user);
/**
* Handler function invoked when the number of used OTPs has reached
* the specified warning number in {@link DatagramPeerIO_SetOTPWarningHandler}.
* May be called from within a sending Send call.
*
* @param user as in {@link DatagramPeerIO_SetHandlers}
*/
typedef void (*DatagramPeerIO_handler_otp_warning) (void *user);
/**
* Handler called when OTP generation for a new receive seed is finished.
*
* @param user as in {@link DatagramPeerIO_SetHandlers}
*/
typedef void (*DatagramPeerIO_handler_otp_ready) (void *user);
/**
* Object for comminicating with a peer using a datagram socket.
*
* The user provides data for sending to the peer through {@link PacketPassInterface}.
* Received data is provided to the user through {@link PacketPassInterface}.
*
* The object has a logical state called a mode, which is one of the following:
* - default - nothing is send or received
* - connecting - an address was provided by the user for sending datagrams to.
* Datagrams are being sent to that address through a socket,
* and datagrams are being received on the same socket.
* - binding - an address was provided by the user to bind a socket to.
* Datagrams are being received on the socket. Datagrams are not being
* sent initially. When a datagram is received, its source address is
* used as a destination address for sending datagrams.
*/
typedef struct {
DebugObject d_obj;
BReactor *reactor;
int payload_mtu;
struct spproto_security_params sp_params;
void *user;
DatagramPeerIO_logfunc logfunc;
DatagramPeerIO_handler_error handler_error;
int spproto_payload_mtu;
int effective_socket_mtu;
// sending base
FragmentProtoDisassembler send_disassembler;
SPProtoEncoder send_encoder;
SinglePacketBuffer send_buffer;
PacketPassConnector send_connector;
// receiving
PacketRecvConnector recv_connector;
SinglePacketBuffer recv_buffer;
SPProtoDecoder recv_decoder;
PacketPassNotifier recv_notifier;
FragmentProtoAssembler recv_assembler;
// mode
int mode;
// datagram object
BDatagram dgram;
} DatagramPeerIO;
/**
* Initializes the object.
* The interface is initialized in default mode.
* {@link BLog_Init} must have been done.
* {@link BNetwork_GlobalInit} must have been done.
* {@link BSecurity_GlobalInitThreadSafe} must have been done if
* {@link BThreadWorkDispatcher_UsingThreads}(twd) = 1.
*
* @param o the object
* @param reactor {@link BReactor} we live in
* @param payload_mtu maximum payload size. Must be >=0.
* @param socket_mtu maximum datagram size for the socket. Must be >=0. Must be large enough so it is possible to
* send a FragmentProto chunk with one byte of data over SPProto, i.e. the following has to hold:
* spproto_payload_mtu_for_carrier_mtu(sp_params, socket_mtu) > sizeof(struct fragmentproto_chunk_header)
* @param sp_params SPProto security parameters
* @param latency latency parameter to {@link FragmentProtoDisassembler_Init}.
* @param num_frames num_frames parameter to {@link FragmentProtoAssembler_Init}. Must be >0.
* @param recv_userif interface to pass received packets to the user. Its MTU must be >=payload_mtu.
* @param otp_warning_count If using OTPs, after how many encoded packets to call the handler.
* In this case, must be >0 and <=sp_params.otp_num.
* @param twd thread work dispatcher
* @param user value to pass to handlers
* @param logfunc function which prepends the log prefix using {@link BLog_Append}
* @param handler_error error handler
* @param handler_otp_warning OTP warning handler
* @param handler_otp_ready handler called when OTP generation for a new receive seed is finished
* @return 1 on success, 0 on failure
*/
int DatagramPeerIO_Init (
DatagramPeerIO *o,
BReactor *reactor,
int payload_mtu,
int socket_mtu,
struct spproto_security_params sp_params,
btime_t latency,
int num_frames,
PacketPassInterface *recv_userif,
int otp_warning_count,
BThreadWorkDispatcher *twd,
void *user,
DatagramPeerIO_logfunc logfunc,
DatagramPeerIO_handler_error handler_error,
DatagramPeerIO_handler_otp_warning handler_otp_warning,
DatagramPeerIO_handler_otp_ready handler_otp_ready
) WARN_UNUSED;
/**
* Frees the object.
*
* @param o the object
*/
void DatagramPeerIO_Free (DatagramPeerIO *o);
/**
* Returns an interface the user should use to send packets.
* The OTP warning handler may be called from within Send calls
* to the interface.
*
* @param o the object
* @return sending interface
*/
PacketPassInterface * DatagramPeerIO_GetSendInput (DatagramPeerIO *o);
/**
* Attempts to establish connection to the peer which has bound to an address.
* On success, the interface enters connecting mode.
* On failure, the interface enters default mode.
*
* @param o the object
* @param addr address to send packets to. Must be supported according to
* {@link BDatagram_AddressFamilySupported}.
* @return 1 on success, 0 on failure
*/
int DatagramPeerIO_Connect (DatagramPeerIO *o, BAddr addr) WARN_UNUSED;
/**
* Attempts to establish connection to the peer by binding to an address.
* On success, the interface enters connecting mode.
* On failure, the interface enters default mode.
*
* @param o the object
* @param addr address to bind to. Must be supported according to
* {@link BDatagram_AddressFamilySupported}.
* @return 1 on success, 0 on failure
*/
int DatagramPeerIO_Bind (DatagramPeerIO *o, BAddr addr) WARN_UNUSED;
/**
* Sets the encryption key to use for sending and receiving.
* Encryption must be enabled.
*
* @param o the object
* @param encryption_key key to use
*/
void DatagramPeerIO_SetEncryptionKey (DatagramPeerIO *o, uint8_t *encryption_key);
/**
* Removed the encryption key to use for sending and receiving.
* Encryption must be enabled.
*
* @param o the object
*/
void DatagramPeerIO_RemoveEncryptionKey (DatagramPeerIO *o);
/**
* Sets the OTP seed for sending.
* OTPs must be enabled.
*
* @param o the object
* @param seed_id seed identifier
* @param key OTP encryption key
* @param iv OTP initialization vector
*/
void DatagramPeerIO_SetOTPSendSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv);
/**
* Removes the OTP seed for sending of one is configured.
* OTPs must be enabled.
*
* @param o the object
*/
void DatagramPeerIO_RemoveOTPSendSeed (DatagramPeerIO *o);
/**
* Adds an OTP seed for reciving.
* OTPs must be enabled.
*
* @param o the object
* @param seed_id seed identifier
* @param key OTP encryption key
* @param iv OTP initialization vector
*/
void DatagramPeerIO_AddOTPRecvSeed (DatagramPeerIO *o, uint16_t seed_id, uint8_t *key, uint8_t *iv);
/**
* Removes all OTP seeds for reciving.
* OTPs must be enabled.
*
* @param o the object
*/
void DatagramPeerIO_RemoveOTPRecvSeeds (DatagramPeerIO *o);
#endif