aboutsummaryrefslogtreecommitdiff
path: root/src/vpn/gnunet-vpn.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-07 20:41:38 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-07 20:41:38 +0000
commit75bfc02cd9753b664e4799b2f837c1de9ab2e2dc (patch)
tree748a86e230511cf4ce4ae191260204f4fbace726 /src/vpn/gnunet-vpn.c
parentb89c033494de27537c6b936e2effdea975d75075 (diff)
downloadgnunet-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.c188
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;
65static int ipv6; 65static int ipv6;
66 66
67/** 67/**
68 * Option -t: TCP requested.
69 */
70static int tcp;
71
72/**
73 * Option -u: UDP requested.
74 */
75static int udp;
76
77/**
68 * Selected level of verbosity. 78 * Selected level of verbosity.
69 */ 79 */
70static int verbosity; 80static int verbosity;
71 81
72/** 82/**
83 * Option '-a': Notify only once the tunnel is connected?
84 */
85static int nac;
86
87/**
73 * Global return value. 88 * Global return value.
74 */ 89 */
75static int ret; 90static int ret;
76 91
92/**
93 * Option '-d': duration of the mapping
94 */
95static 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 */
133static void
134allocation_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
109run (void *cls, char *const *args, const char *cfgfile, 169run (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 };