diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-07 20:41:38 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-07 20:41:38 +0000 |
commit | 75bfc02cd9753b664e4799b2f837c1de9ab2e2dc (patch) | |
tree | 748a86e230511cf4ce4ae191260204f4fbace726 /src/vpn/gnunet-vpn.c | |
parent | b89c033494de27537c6b936e2effdea975d75075 (diff) | |
download | gnunet-75bfc02cd9753b664e4799b2f837c1de9ab2e2dc.tar.gz gnunet-75bfc02cd9753b664e4799b2f837c1de9ab2e2dc.zip |
-finishing gnunet-vpn tool and man page
Diffstat (limited to 'src/vpn/gnunet-vpn.c')
-rw-r--r-- | src/vpn/gnunet-vpn.c | 188 |
1 files changed, 186 insertions, 2 deletions
diff --git a/src/vpn/gnunet-vpn.c b/src/vpn/gnunet-vpn.c index 3be830a6a..74c9956e2 100644 --- a/src/vpn/gnunet-vpn.c +++ b/src/vpn/gnunet-vpn.c | |||
@@ -65,15 +65,35 @@ static int ipv4; | |||
65 | static int ipv6; | 65 | static int ipv6; |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * Option -t: TCP requested. | ||
69 | */ | ||
70 | static int tcp; | ||
71 | |||
72 | /** | ||
73 | * Option -u: UDP requested. | ||
74 | */ | ||
75 | static int udp; | ||
76 | |||
77 | /** | ||
68 | * Selected level of verbosity. | 78 | * Selected level of verbosity. |
69 | */ | 79 | */ |
70 | static int verbosity; | 80 | static int verbosity; |
71 | 81 | ||
72 | /** | 82 | /** |
83 | * Option '-a': Notify only once the tunnel is connected? | ||
84 | */ | ||
85 | static int nac; | ||
86 | |||
87 | /** | ||
73 | * Global return value. | 88 | * Global return value. |
74 | */ | 89 | */ |
75 | static int ret; | 90 | static int ret; |
76 | 91 | ||
92 | /** | ||
93 | * Option '-d': duration of the mapping | ||
94 | */ | ||
95 | static unsigned long long duration = 5 * 60; | ||
96 | |||
77 | 97 | ||
78 | /** | 98 | /** |
79 | * Shutdown. | 99 | * Shutdown. |
@@ -98,6 +118,46 @@ do_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
98 | 118 | ||
99 | 119 | ||
100 | /** | 120 | /** |
121 | * Callback invoked from the VPN service once a redirection is | ||
122 | * available. Provides the IP address that can now be used to | ||
123 | * reach the requested destination. | ||
124 | * | ||
125 | * @param cls closure | ||
126 | * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error; | ||
127 | * will match 'result_af' from the request | ||
128 | * @param address IP address (struct in_addr or struct in_addr6, depending on 'af') | ||
129 | * that the VPN allocated for the redirection; | ||
130 | * traffic to this IP will now be redirected to the | ||
131 | * specified target peer; NULL on error | ||
132 | */ | ||
133 | static void | ||
134 | allocation_cb (void *cls, | ||
135 | int af, | ||
136 | const void *address) | ||
137 | { | ||
138 | char buf[INET6_ADDRSTRLEN]; | ||
139 | |||
140 | switch (af) | ||
141 | { | ||
142 | case AF_INET6: | ||
143 | case AF_INET: | ||
144 | FPRINTF (stdout, | ||
145 | "%s", | ||
146 | inet_ntop (af, address, buf, sizeof (buf))); | ||
147 | break; | ||
148 | case AF_UNSPEC: | ||
149 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
150 | _("Error creating tunnel\n")); | ||
151 | ret = 1; | ||
152 | break; | ||
153 | default: | ||
154 | break; | ||
155 | } | ||
156 | GNUNET_SCHEDULER_shutdown (); | ||
157 | } | ||
158 | |||
159 | |||
160 | /** | ||
101 | * Main function that will be run by the scheduler. | 161 | * Main function that will be run by the scheduler. |
102 | * | 162 | * |
103 | * @param cls closure | 163 | * @param cls closure |
@@ -109,10 +169,121 @@ static void | |||
109 | run (void *cls, char *const *args, const char *cfgfile, | 169 | run (void *cls, char *const *args, const char *cfgfile, |
110 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 170 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
111 | { | 171 | { |
112 | handle = GNUNET_VPN_connect (cfg); | 172 | int dst_af; |
113 | 173 | int req_af; | |
174 | struct GNUNET_PeerIdentity peer; | ||
175 | GNUNET_HashCode sd; | ||
176 | const void *addr; | ||
177 | struct in_addr v4; | ||
178 | struct in6_addr v6; | ||
179 | uint8_t protocol; | ||
180 | struct GNUNET_TIME_Absolute etime; | ||
181 | |||
182 | etime = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, | ||
183 | (unsigned int) duration)); | ||
114 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | 184 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
115 | &do_disconnect, NULL); | 185 | &do_disconnect, NULL); |
186 | handle = GNUNET_VPN_connect (cfg); | ||
187 | if (NULL == handle) | ||
188 | goto error; | ||
189 | req_af = AF_UNSPEC; | ||
190 | if (ipv4) | ||
191 | { | ||
192 | if (ipv6) | ||
193 | { | ||
194 | FPRINTF (stderr, _("Option `%s' makes no sense with option `%s'.\n"), | ||
195 | "-4", "-6"); | ||
196 | goto error; | ||
197 | } | ||
198 | req_af = AF_INET; | ||
199 | } | ||
200 | if (ipv6) | ||
201 | req_af = AF_INET6; | ||
202 | |||
203 | if (NULL == target_ip) | ||
204 | { | ||
205 | if (NULL == service_name) | ||
206 | { | ||
207 | FPRINTF (stderr, _("Option `%s' or `%s' is required.\n"), | ||
208 | "-i", "-s"); | ||
209 | goto error; | ||
210 | } | ||
211 | if (NULL == peer_id) | ||
212 | { | ||
213 | FPRINTF (stderr, _("Option `%s' is required when using option `%s'.\n"), | ||
214 | "-p", "-s"); | ||
215 | goto error; | ||
216 | } | ||
217 | if (! (tcp | udp) ) | ||
218 | { | ||
219 | FPRINTF (stderr, _("Option `%s' or `%s' is required when using option `%s'.\n"), | ||
220 | "-t", "-u", "-s"); | ||
221 | goto error; | ||
222 | } | ||
223 | if (tcp & udp) | ||
224 | { | ||
225 | FPRINTF (stderr, _("Option `%s' makes no sense with option `%s'.\n"), | ||
226 | "-t", "-u"); | ||
227 | goto error; | ||
228 | } | ||
229 | if (tcp) | ||
230 | protocol = IPPROTO_TCP; | ||
231 | if (udp) | ||
232 | protocol = IPPROTO_UDP; | ||
233 | if (GNUNET_OK != | ||
234 | GNUNET_CRYPTO_hash_from_string (peer_id, | ||
235 | &peer.hashPubKey)) | ||
236 | { | ||
237 | FPRINTF (stderr, _("`%s' is not a valid peer identifier.\n"), | ||
238 | peer_id); | ||
239 | goto error; | ||
240 | } | ||
241 | GNUNET_CRYPTO_hash (service_name, | ||
242 | strlen (service_name), | ||
243 | &sd); | ||
244 | request = GNUNET_VPN_redirect_to_peer (handle, | ||
245 | req_af, | ||
246 | protocol, | ||
247 | &peer, | ||
248 | &sd, | ||
249 | nac, | ||
250 | etime, | ||
251 | &allocation_cb, NULL); | ||
252 | } | ||
253 | else | ||
254 | { | ||
255 | if (1 != inet_pton (AF_INET6, target_ip, &v6)) | ||
256 | { | ||
257 | if (1 != inet_pton (AF_INET, target_ip, &v4)) | ||
258 | { | ||
259 | FPRINTF (stderr, _("`%s' is not a valid IP address.\n"), | ||
260 | target_ip); | ||
261 | goto error; | ||
262 | } | ||
263 | else | ||
264 | { | ||
265 | dst_af = AF_INET; | ||
266 | addr = &v4; | ||
267 | } | ||
268 | } | ||
269 | else | ||
270 | { | ||
271 | dst_af = AF_INET6; | ||
272 | addr = &v6; | ||
273 | } | ||
274 | request = GNUNET_VPN_redirect_to_ip (handle, | ||
275 | req_af, | ||
276 | dst_af, | ||
277 | addr, | ||
278 | nac, | ||
279 | etime, | ||
280 | &allocation_cb, NULL); | ||
281 | } | ||
282 | return; | ||
283 | |||
284 | error: | ||
285 | GNUNET_SCHEDULER_shutdown (); | ||
286 | ret = 1; | ||
116 | } | 287 | } |
117 | 288 | ||
118 | 289 | ||
@@ -126,6 +297,12 @@ main (int argc, char *const *argv) | |||
126 | {'6', "ipv6", NULL, | 297 | {'6', "ipv6", NULL, |
127 | gettext_noop ("request that result should be an IPv6 address"), | 298 | gettext_noop ("request that result should be an IPv6 address"), |
128 | 0, &GNUNET_GETOPT_set_one, &ipv6}, | 299 | 0, &GNUNET_GETOPT_set_one, &ipv6}, |
300 | {'a', "after-connect", NULL, | ||
301 | gettext_noop ("print IP address only after mesh tunnel has been created"), | ||
302 | 0, &GNUNET_GETOPT_set_one, &ipv6}, | ||
303 | {'d', "duration", "SECONDS", | ||
304 | gettext_noop ("how long should the mapping be valid for new tunnels?"), | ||
305 | 1, &GNUNET_GETOPT_set_ulong, &duration}, | ||
129 | {'i', "ip", "IP", | 306 | {'i', "ip", "IP", |
130 | gettext_noop ("destination IP for the tunnel"), | 307 | gettext_noop ("destination IP for the tunnel"), |
131 | 1, &GNUNET_GETOPT_set_string, &target_ip}, | 308 | 1, &GNUNET_GETOPT_set_string, &target_ip}, |
@@ -135,6 +312,13 @@ main (int argc, char *const *argv) | |||
135 | {'s', "service", "NAME", | 312 | {'s', "service", "NAME", |
136 | gettext_noop ("name of the service we would like to access"), | 313 | gettext_noop ("name of the service we would like to access"), |
137 | 1, &GNUNET_GETOPT_set_string, &peer_id}, | 314 | 1, &GNUNET_GETOPT_set_string, &peer_id}, |
315 | {'t', "tcp", NULL, | ||
316 | gettext_noop ("service is offered via TCP"), | ||
317 | 0, &GNUNET_GETOPT_set_one, &tcp}, | ||
318 | {'u', "udp", NULL, | ||
319 | gettext_noop ("service is offered via UDP"), | ||
320 | 0, &GNUNET_GETOPT_set_one, &udp}, | ||
321 | |||
138 | GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), | 322 | GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), |
139 | GNUNET_GETOPT_OPTION_END | 323 | GNUNET_GETOPT_OPTION_END |
140 | }; | 324 | }; |