BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * Copyright (C) Ambroz Bizjak <ambrop7@gmail.com>
3 * Contributions:
4 * Transparent DNS: Copyright (C) Kerem Hadimli <kerem.hadimli@gmail.com>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28  
29 #include <misc/debug.h>
30 #include <base/BLog.h>
31  
32 #include <tun2socks/SocksUdpGwClient.h>
33  
34 #include <generated/blog_channel_SocksUdpGwClient.h>
35  
36 static void free_socks (SocksUdpGwClient *o);
37 static void try_connect (SocksUdpGwClient *o);
38 static void reconnect_timer_handler (SocksUdpGwClient *o);
39 static void socks_client_handler (SocksUdpGwClient *o, int event);
40 static void udpgw_handler_servererror (SocksUdpGwClient *o);
41 static void udpgw_handler_received (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len);
42  
43 static void free_socks (SocksUdpGwClient *o)
44 {
45 ASSERT(o->have_socks)
46  
47 // disconnect udpgw client from SOCKS
48 if (o->socks_up) {
49 UdpGwClient_DisconnectServer(&o->udpgw_client);
50 }
51  
52 // free SOCKS client
53 BSocksClient_Free(&o->socks_client);
54  
55 // set have no SOCKS
56 o->have_socks = 0;
57 }
58  
59 static void try_connect (SocksUdpGwClient *o)
60 {
61 ASSERT(!o->have_socks)
62 ASSERT(!BTimer_IsRunning(&o->reconnect_timer))
63  
64 // init SOCKS client
65 if (!BSocksClient_Init(&o->socks_client, o->socks_server_addr,
66 o->auth_info, o->num_auth_info, o->remote_udpgw_addr, /*udp=*/false,
67 (BSocksClient_handler)socks_client_handler, o, o->reactor))
68 {
69 BLog(BLOG_ERROR, "BSocksClient_Init failed");
70 goto fail0;
71 }
72  
73 // set have SOCKS
74 o->have_socks = 1;
75  
76 // set SOCKS not up
77 o->socks_up = 0;
78  
79 return;
80  
81 fail0:
82 // set reconnect timer
83 BReactor_SetTimer(o->reactor, &o->reconnect_timer);
84 }
85  
86 static void reconnect_timer_handler (SocksUdpGwClient *o)
87 {
88 DebugObject_Access(&o->d_obj);
89 ASSERT(!o->have_socks)
90  
91 // try connecting
92 try_connect(o);
93 }
94  
95 static void socks_client_handler (SocksUdpGwClient *o, int event)
96 {
97 DebugObject_Access(&o->d_obj);
98 ASSERT(o->have_socks)
99  
100 switch (event) {
101 case BSOCKSCLIENT_EVENT_UP: {
102 ASSERT(!o->socks_up)
103  
104 BLog(BLOG_INFO, "SOCKS up");
105  
106 // connect udpgw client to SOCKS
107 if (!UdpGwClient_ConnectServer(&o->udpgw_client, BSocksClient_GetSendInterface(&o->socks_client), BSocksClient_GetRecvInterface(&o->socks_client))) {
108 BLog(BLOG_ERROR, "UdpGwClient_ConnectServer failed");
109 goto fail0;
110 }
111  
112 // set SOCKS up
113 o->socks_up = 1;
114  
115 return;
116  
117 fail0:
118 // free SOCKS
119 free_socks(o);
120  
121 // set reconnect timer
122 BReactor_SetTimer(o->reactor, &o->reconnect_timer);
123 } break;
124  
125 case BSOCKSCLIENT_EVENT_ERROR:
126 case BSOCKSCLIENT_EVENT_ERROR_CLOSED: {
127 BLog(BLOG_INFO, "SOCKS error");
128  
129 // free SOCKS
130 free_socks(o);
131  
132 // set reconnect timer
133 BReactor_SetTimer(o->reactor, &o->reconnect_timer);
134 } break;
135 }
136 }
137  
138 static void udpgw_handler_servererror (SocksUdpGwClient *o)
139 {
140 DebugObject_Access(&o->d_obj);
141 ASSERT(o->have_socks)
142 ASSERT(o->socks_up)
143  
144 BLog(BLOG_ERROR, "client reports server error");
145  
146 // free SOCKS
147 free_socks(o);
148  
149 // set reconnect timer
150 BReactor_SetTimer(o->reactor, &o->reconnect_timer);
151 }
152  
153 static void udpgw_handler_received (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len)
154 {
155 DebugObject_Access(&o->d_obj);
156  
157 // submit to user
158 o->handler_received(o->user, local_addr, remote_addr, data, data_len);
159 return;
160 }
161  
162 int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time,
163 BAddr socks_server_addr, const struct BSocksClient_auth_info *auth_info, size_t num_auth_info,
164 BAddr remote_udpgw_addr, btime_t reconnect_time, BReactor *reactor, void *user,
165 SocksUdpGwClient_handler_received handler_received)
166 {
167 // see asserts in UdpGwClient_Init
168 ASSERT(!BAddr_IsInvalid(&socks_server_addr))
169 ASSERT(remote_udpgw_addr.type == BADDR_TYPE_IPV4 || remote_udpgw_addr.type == BADDR_TYPE_IPV6)
170  
171 // init arguments
172 o->udp_mtu = udp_mtu;
173 o->socks_server_addr = socks_server_addr;
174 o->auth_info = auth_info;
175 o->num_auth_info = num_auth_info;
176 o->remote_udpgw_addr = remote_udpgw_addr;
177 o->reactor = reactor;
178 o->user = user;
179 o->handler_received = handler_received;
180  
181 // init udpgw client
182 if (!UdpGwClient_Init(&o->udpgw_client, udp_mtu, max_connections, send_buffer_size, keepalive_time, o->reactor, o,
183 (UdpGwClient_handler_servererror)udpgw_handler_servererror,
184 (UdpGwClient_handler_received)udpgw_handler_received
185 )) {
186 goto fail0;
187 }
188  
189 // init reconnect timer
190 BTimer_Init(&o->reconnect_timer, reconnect_time, (BTimer_handler)reconnect_timer_handler, o);
191  
192 // set have no SOCKS
193 o->have_socks = 0;
194  
195 // try connecting
196 try_connect(o);
197  
198 DebugObject_Init(&o->d_obj);
199 return 1;
200  
201 fail0:
202 return 0;
203 }
204  
205 void SocksUdpGwClient_Free (SocksUdpGwClient *o)
206 {
207 DebugObject_Free(&o->d_obj);
208  
209 // free SOCKS
210 if (o->have_socks) {
211 free_socks(o);
212 }
213  
214 // free reconnect timer
215 BReactor_RemoveTimer(o->reactor, &o->reconnect_timer);
216  
217 // free udpgw client
218 UdpGwClient_Free(&o->udpgw_client);
219 }
220  
221 void SocksUdpGwClient_SubmitPacket (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, int is_dns, const uint8_t *data, int data_len)
222 {
223 DebugObject_Access(&o->d_obj);
224 // see asserts in UdpGwClient_SubmitPacket
225  
226 // submit to udpgw client
227 UdpGwClient_SubmitPacket(&o->udpgw_client, local_addr, remote_addr, is_dns, data, data_len);
228 }
229