BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file PacketProtoDecoder.c
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  
30 #include <stdlib.h>
31 #include <string.h>
32  
33 #include <misc/debug.h>
34 #include <misc/byteorder.h>
35 #include <misc/minmax.h>
36 #include <base/BLog.h>
37  
38 #include <flow/PacketProtoDecoder.h>
39  
40 #include <generated/blog_channel_PacketProtoDecoder.h>
41  
42 static void process_data (PacketProtoDecoder *enc);
43 static void input_handler_done (PacketProtoDecoder *enc, int data_len);
44 static void output_handler_done (PacketProtoDecoder *enc);
45  
46 void process_data (PacketProtoDecoder *enc)
47 {
48 int was_error = 0;
49  
50 do {
51 uint8_t *data = enc->buf + enc->buf_start;
52 int left = enc->buf_used;
53  
54 // check if header was received
55 if (left < sizeof(struct packetproto_header)) {
56 break;
57 }
58 struct packetproto_header header;
59 memcpy(&header, data, sizeof(header));
60 data += sizeof(struct packetproto_header);
61 left -= sizeof(struct packetproto_header);
62 int data_len = ltoh16(header.len);
63  
64 // check data length
65 if (data_len > enc->output_mtu) {
66 BLog(BLOG_NOTICE, "error: packet too large");
67 was_error = 1;
68 break;
69 }
70  
71 // check if whole packet was received
72 if (left < data_len) {
73 break;
74 }
75  
76 // update buffer
77 enc->buf_start += sizeof(struct packetproto_header) + data_len;
78 enc->buf_used -= sizeof(struct packetproto_header) + data_len;
79  
80 // submit packet
81 PacketPassInterface_Sender_Send(enc->output, data, data_len);
82 return;
83 } while (0);
84  
85 if (was_error) {
86 // reset buffer
87 enc->buf_start = 0;
88 enc->buf_used = 0;
89 } else {
90 // if we reached the end of the buffer, wrap around to allow more data to be received
91 if (enc->buf_start + enc->buf_used == enc->buf_size) {
92 memmove(enc->buf, enc->buf + enc->buf_start, enc->buf_used);
93 enc->buf_start = 0;
94 }
95 }
96  
97 // receive data
98 StreamRecvInterface_Receiver_Recv(enc->input, enc->buf + (enc->buf_start + enc->buf_used), enc->buf_size - (enc->buf_start + enc->buf_used));
99  
100 // if we had error, report it
101 if (was_error) {
102 enc->handler_error(enc->user);
103 return;
104 }
105 }
106  
107 static void input_handler_done (PacketProtoDecoder *enc, int data_len)
108 {
109 ASSERT(data_len > 0)
110 ASSERT(data_len <= enc->buf_size - (enc->buf_start + enc->buf_used))
111 DebugObject_Access(&enc->d_obj);
112  
113 // update buffer
114 enc->buf_used += data_len;
115  
116 // process data
117 process_data(enc);
118 return;
119 }
120  
121 void output_handler_done (PacketProtoDecoder *enc)
122 {
123 DebugObject_Access(&enc->d_obj);
124  
125 // process data
126 process_data(enc);
127 return;
128 }
129  
130 int PacketProtoDecoder_Init (PacketProtoDecoder *enc, StreamRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg, void *user, PacketProtoDecoder_handler_error handler_error)
131 {
132 // init arguments
133 enc->input = input;
134 enc->output = output;
135 enc->user = user;
136 enc->handler_error = handler_error;
137  
138 // init input
139 StreamRecvInterface_Receiver_Init(enc->input, (StreamRecvInterface_handler_done)input_handler_done, enc);
140  
141 // init output
142 PacketPassInterface_Sender_Init(enc->output, (PacketPassInterface_handler_done)output_handler_done, enc);
143  
144 // set output MTU, limit by maximum payload size
145 enc->output_mtu = bmin_int(PacketPassInterface_GetMTU(enc->output), PACKETPROTO_MAXPAYLOAD);
146  
147 // init buffer state
148 enc->buf_size = PACKETPROTO_ENCLEN(enc->output_mtu);
149 enc->buf_start = 0;
150 enc->buf_used = 0;
151  
152 // allocate buffer
153 if (!(enc->buf = (uint8_t *)malloc(enc->buf_size))) {
154 goto fail0;
155 }
156  
157 // start receiving
158 StreamRecvInterface_Receiver_Recv(enc->input, enc->buf, enc->buf_size);
159  
160 DebugObject_Init(&enc->d_obj);
161  
162 return 1;
163  
164 fail0:
165 return 0;
166 }
167  
168 void PacketProtoDecoder_Free (PacketProtoDecoder *enc)
169 {
170 DebugObject_Free(&enc->d_obj);
171  
172 // free buffer
173 free(enc->buf);
174 }
175  
176 void PacketProtoDecoder_Reset (PacketProtoDecoder *enc)
177 {
178 DebugObject_Access(&enc->d_obj);
179  
180 enc->buf_start += enc->buf_used;
181 enc->buf_used = 0;
182 }