diff options
Diffstat (limited to 'src/vpn/gnunet-helper-vpn.c')
-rw-r--r-- | src/vpn/gnunet-helper-vpn.c | 596 |
1 files changed, 283 insertions, 313 deletions
diff --git a/src/vpn/gnunet-helper-vpn.c b/src/vpn/gnunet-helper-vpn.c index 554019d7c..698c46f1d 100644 --- a/src/vpn/gnunet-helper-vpn.c +++ b/src/vpn/gnunet-helper-vpn.c | |||
@@ -74,23 +74,23 @@ init_tun (char *dev) | |||
74 | int fd; | 74 | int fd; |
75 | 75 | ||
76 | if (NULL == dev) | 76 | if (NULL == dev) |
77 | { | 77 | { |
78 | errno = EINVAL; | 78 | errno = EINVAL; |
79 | return -1; | 79 | return -1; |
80 | } | 80 | } |
81 | 81 | ||
82 | if (-1 == (fd = open ("/dev/net/tun", O_RDWR))) | 82 | if (-1 == (fd = open ("/dev/net/tun", O_RDWR))) |
83 | { | 83 | { |
84 | fprintf (stderr, | 84 | fprintf (stderr, |
85 | "Error opening `%s': %s\n", "/dev/net/tun", strerror (errno)); | 85 | "Error opening `%s': %s\n", "/dev/net/tun", strerror (errno)); |
86 | return -1; | 86 | return -1; |
87 | } | 87 | } |
88 | 88 | ||
89 | if (fd >= FD_SETSIZE) | 89 | if (fd >= FD_SETSIZE) |
90 | { | 90 | { |
91 | fprintf (stderr, "File descriptor to large: %d", fd); | 91 | fprintf (stderr, "File descriptor to large: %d", fd); |
92 | return -1; | 92 | return -1; |
93 | } | 93 | } |
94 | 94 | ||
95 | memset (&ifr, 0, sizeof (ifr)); | 95 | memset (&ifr, 0, sizeof (ifr)); |
96 | ifr.ifr_flags = IFF_TUN; | 96 | ifr.ifr_flags = IFF_TUN; |
@@ -99,13 +99,13 @@ init_tun (char *dev) | |||
99 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); | 99 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); |
100 | 100 | ||
101 | if (-1 == ioctl (fd, TUNSETIFF, (void *) &ifr)) | 101 | if (-1 == ioctl (fd, TUNSETIFF, (void *) &ifr)) |
102 | { | 102 | { |
103 | fprintf (stderr, | 103 | fprintf (stderr, |
104 | "Error with ioctl on `%s': %s\n", | 104 | "Error with ioctl on `%s': %s\n", |
105 | "/dev/net/tun", strerror (errno)); | 105 | "/dev/net/tun", strerror (errno)); |
106 | close (fd); | 106 | close (fd); |
107 | return -1; | 107 | return -1; |
108 | } | 108 | } |
109 | strcpy (dev, ifr.ifr_name); | 109 | strcpy (dev, ifr.ifr_name); |
110 | return fd; | 110 | return fd; |
111 | } | 111 | } |
@@ -119,9 +119,7 @@ init_tun (char *dev) | |||
119 | * @param prefix_len the length of the network-prefix | 119 | * @param prefix_len the length of the network-prefix |
120 | */ | 120 | */ |
121 | static void | 121 | static void |
122 | set_address6 (const char *dev, | 122 | set_address6 (const char *dev, const char *address, unsigned long prefix_len) |
123 | const char *address, | ||
124 | unsigned long prefix_len) | ||
125 | { | 123 | { |
126 | struct ifreq ifr; | 124 | struct ifreq ifr; |
127 | struct in6_ifreq ifr6; | 125 | struct in6_ifreq ifr6; |
@@ -133,25 +131,20 @@ set_address6 (const char *dev, | |||
133 | */ | 131 | */ |
134 | memset (&sa6, 0, sizeof (struct sockaddr_in6)); | 132 | memset (&sa6, 0, sizeof (struct sockaddr_in6)); |
135 | if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) | 133 | if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) |
136 | { | 134 | { |
137 | fprintf (stderr, | 135 | fprintf (stderr, |
138 | "Failed to parse address `%s': %s\n", | 136 | "Failed to parse address `%s': %s\n", address, strerror (errno)); |
139 | address, strerror (errno)); | 137 | exit (1); |
140 | exit (1); | 138 | } |
141 | } | ||
142 | 139 | ||
143 | if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) | 140 | if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) |
144 | { | 141 | { |
145 | fprintf (stderr, | 142 | fprintf (stderr, "Error creating socket: %s\n", strerror (errno)); |
146 | "Error creating socket: %s\n", | 143 | exit (1); |
147 | strerror (errno)); | 144 | } |
148 | exit (1); | ||
149 | } | ||
150 | 145 | ||
151 | sa6.sin6_family = AF_INET6; | 146 | sa6.sin6_family = AF_INET6; |
152 | memcpy (&ifr6.ifr6_addr, | 147 | memcpy (&ifr6.ifr6_addr, &sa6.sin6_addr, sizeof (struct in6_addr)); |
153 | &sa6.sin6_addr, | ||
154 | sizeof (struct in6_addr)); | ||
155 | 148 | ||
156 | 149 | ||
157 | /* | 150 | /* |
@@ -159,13 +152,10 @@ set_address6 (const char *dev, | |||
159 | */ | 152 | */ |
160 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); | 153 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); |
161 | if (-1 == ioctl (fd, SIOGIFINDEX, &ifr)) | 154 | if (-1 == ioctl (fd, SIOGIFINDEX, &ifr)) |
162 | { | 155 | { |
163 | fprintf (stderr, | 156 | fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno)); |
164 | "ioctl failed at %d: %s\n", | 157 | exit (1); |
165 | __LINE__, | 158 | } |
166 | strerror (errno)); | ||
167 | exit (1); | ||
168 | } | ||
169 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; | 159 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; |
170 | 160 | ||
171 | ifr6.ifr6_prefixlen = prefix_len; | 161 | ifr6.ifr6_prefixlen = prefix_len; |
@@ -174,38 +164,38 @@ set_address6 (const char *dev, | |||
174 | * Set the address | 164 | * Set the address |
175 | */ | 165 | */ |
176 | if (-1 == ioctl (fd, SIOCSIFADDR, &ifr6)) | 166 | if (-1 == ioctl (fd, SIOCSIFADDR, &ifr6)) |
177 | { | 167 | { |
178 | fprintf (stderr, | 168 | fprintf (stderr, |
179 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); | 169 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
180 | exit (1); | 170 | exit (1); |
181 | } | 171 | } |
182 | 172 | ||
183 | /* | 173 | /* |
184 | * Get the flags | 174 | * Get the flags |
185 | */ | 175 | */ |
186 | if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) | 176 | if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) |
187 | { | 177 | { |
188 | fprintf (stderr, | 178 | fprintf (stderr, |
189 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); | 179 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
190 | exit (1); | 180 | exit (1); |
191 | } | 181 | } |
192 | 182 | ||
193 | /* | 183 | /* |
194 | * Add the UP and RUNNING flags | 184 | * Add the UP and RUNNING flags |
195 | */ | 185 | */ |
196 | ifr.ifr_flags |= IFF_UP | IFF_RUNNING; | 186 | ifr.ifr_flags |= IFF_UP | IFF_RUNNING; |
197 | if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) | 187 | if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) |
198 | { | 188 | { |
199 | fprintf (stderr, | 189 | fprintf (stderr, |
200 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); | 190 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
201 | exit (1); | 191 | exit (1); |
202 | } | 192 | } |
203 | 193 | ||
204 | if (0 != close (fd)) | 194 | if (0 != close (fd)) |
205 | { | 195 | { |
206 | fprintf (stderr, "close failed: %s\n", strerror (errno)); | 196 | fprintf (stderr, "close failed: %s\n", strerror (errno)); |
207 | exit (1); | 197 | exit (1); |
208 | } | 198 | } |
209 | } | 199 | } |
210 | 200 | ||
211 | 201 | ||
@@ -217,9 +207,7 @@ set_address6 (const char *dev, | |||
217 | * @param mask the netmask | 207 | * @param mask the netmask |
218 | */ | 208 | */ |
219 | static void | 209 | static void |
220 | set_address4 (const char *dev, | 210 | set_address4 (const char *dev, const char *address, const char *mask) |
221 | const char *address, | ||
222 | const char *mask) | ||
223 | { | 211 | { |
224 | int fd; | 212 | int fd; |
225 | struct sockaddr_in *addr; | 213 | struct sockaddr_in *addr; |
@@ -235,21 +223,18 @@ set_address4 (const char *dev, | |||
235 | * Parse the address | 223 | * Parse the address |
236 | */ | 224 | */ |
237 | if (1 != inet_pton (AF_INET, address, &addr->sin_addr.s_addr)) | 225 | if (1 != inet_pton (AF_INET, address, &addr->sin_addr.s_addr)) |
238 | { | 226 | { |
239 | fprintf (stderr, | 227 | fprintf (stderr, |
240 | "Failed to parse address `%s': %s\n", | 228 | "Failed to parse address `%s': %s\n", address, strerror (errno)); |
241 | address, strerror (errno)); | 229 | exit (1); |
242 | exit (1); | 230 | } |
243 | } | 231 | |
244 | 232 | ||
245 | |||
246 | if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0))) | 233 | if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0))) |
247 | { | 234 | { |
248 | fprintf (stderr, | 235 | fprintf (stderr, "Error creating socket: %s\n", strerror (errno)); |
249 | "Error creating socket: %s\n", | 236 | exit (1); |
250 | strerror (errno)); | 237 | } |
251 | exit (1); | ||
252 | } | ||
253 | 238 | ||
254 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); | 239 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); |
255 | 240 | ||
@@ -257,63 +242,58 @@ set_address4 (const char *dev, | |||
257 | * Set the address | 242 | * Set the address |
258 | */ | 243 | */ |
259 | if (-1 == ioctl (fd, SIOCSIFADDR, &ifr)) | 244 | if (-1 == ioctl (fd, SIOCSIFADDR, &ifr)) |
260 | { | 245 | { |
261 | fprintf (stderr, | 246 | fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno)); |
262 | "ioctl failed at %d: %s\n", | 247 | exit (1); |
263 | __LINE__, | 248 | } |
264 | strerror (errno)); | ||
265 | exit (1); | ||
266 | } | ||
267 | 249 | ||
268 | /* | 250 | /* |
269 | * Parse the netmask | 251 | * Parse the netmask |
270 | */ | 252 | */ |
271 | addr = (struct sockaddr_in *) &(ifr.ifr_netmask); | 253 | addr = (struct sockaddr_in *) &(ifr.ifr_netmask); |
272 | if (1 != inet_pton (AF_INET, mask, &addr->sin_addr.s_addr)) | 254 | if (1 != inet_pton (AF_INET, mask, &addr->sin_addr.s_addr)) |
273 | { | 255 | { |
274 | fprintf (stderr, | 256 | fprintf (stderr, |
275 | "Failed to parse address `%s': %s\n", | 257 | "Failed to parse address `%s': %s\n", mask, strerror (errno)); |
276 | mask, | 258 | exit (1); |
277 | strerror (errno)); | 259 | } |
278 | exit (1); | ||
279 | } | ||
280 | 260 | ||
281 | /* | 261 | /* |
282 | * Set the netmask | 262 | * Set the netmask |
283 | */ | 263 | */ |
284 | if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr)) | 264 | if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr)) |
285 | { | 265 | { |
286 | fprintf (stderr, | 266 | fprintf (stderr, |
287 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); | 267 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
288 | exit (1); | 268 | exit (1); |
289 | } | 269 | } |
290 | 270 | ||
291 | /* | 271 | /* |
292 | * Get the flags | 272 | * Get the flags |
293 | */ | 273 | */ |
294 | if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) | 274 | if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) |
295 | { | 275 | { |
296 | fprintf (stderr, | 276 | fprintf (stderr, |
297 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); | 277 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
298 | exit (1); | 278 | exit (1); |
299 | } | 279 | } |
300 | 280 | ||
301 | /* | 281 | /* |
302 | * Add the UP and RUNNING flags | 282 | * Add the UP and RUNNING flags |
303 | */ | 283 | */ |
304 | ifr.ifr_flags |= IFF_UP | IFF_RUNNING; | 284 | ifr.ifr_flags |= IFF_UP | IFF_RUNNING; |
305 | if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) | 285 | if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) |
306 | { | 286 | { |
307 | fprintf (stderr, | 287 | fprintf (stderr, |
308 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); | 288 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
309 | exit (1); | 289 | exit (1); |
310 | } | 290 | } |
311 | 291 | ||
312 | if (0 != close (fd)) | 292 | if (0 != close (fd)) |
313 | { | 293 | { |
314 | fprintf (stderr, "close failed: %s\n", strerror (errno)); | 294 | fprintf (stderr, "close failed: %s\n", strerror (errno)); |
315 | exit (1); | 295 | exit (1); |
316 | } | 296 | } |
317 | } | 297 | } |
318 | 298 | ||
319 | 299 | ||
@@ -340,188 +320,182 @@ run (int fd_tun) | |||
340 | 320 | ||
341 | /* read refers to reading from fd_tun, writing to stdout */ | 321 | /* read refers to reading from fd_tun, writing to stdout */ |
342 | int read_open = 1; | 322 | int read_open = 1; |
323 | |||
343 | /* write refers to reading from stdin, writing to fd_tun */ | 324 | /* write refers to reading from stdin, writing to fd_tun */ |
344 | int write_open = 1; | 325 | int write_open = 1; |
345 | 326 | ||
346 | while ((1 == read_open) || (1 == write_open)) | 327 | while ((1 == read_open) || (1 == write_open)) |
328 | { | ||
329 | FD_ZERO (&fds_w); | ||
330 | FD_ZERO (&fds_r); | ||
331 | |||
332 | /* | ||
333 | * We are supposed to read and the buffer is empty | ||
334 | * -> select on read from tun | ||
335 | */ | ||
336 | if (read_open && (0 == buftun_size)) | ||
337 | FD_SET (fd_tun, &fds_r); | ||
338 | |||
339 | /* | ||
340 | * We are supposed to read and the buffer is not empty | ||
341 | * -> select on write to stdout | ||
342 | */ | ||
343 | if (read_open && (0 != buftun_size)) | ||
344 | FD_SET (1, &fds_w); | ||
345 | |||
346 | /* | ||
347 | * We are supposed to write and the buffer is empty | ||
348 | * -> select on read from stdin | ||
349 | */ | ||
350 | if (write_open && (NULL == bufin_read)) | ||
351 | FD_SET (0, &fds_r); | ||
352 | |||
353 | /* | ||
354 | * We are supposed to write and the buffer is not empty | ||
355 | * -> select on write to tun | ||
356 | */ | ||
357 | if (write_open && (NULL != bufin_read)) | ||
358 | FD_SET (fd_tun, &fds_w); | ||
359 | |||
360 | int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL); | ||
361 | |||
362 | if (-1 == r) | ||
347 | { | 363 | { |
348 | FD_ZERO (&fds_w); | 364 | if (EINTR == errno) |
349 | FD_ZERO (&fds_r); | 365 | continue; |
350 | 366 | fprintf (stderr, "select failed: %s\n", strerror (errno)); | |
351 | /* | 367 | exit (1); |
352 | * We are supposed to read and the buffer is empty | 368 | } |
353 | * -> select on read from tun | 369 | |
354 | */ | 370 | if (r > 0) |
355 | if (read_open && (0 == buftun_size)) | 371 | { |
356 | FD_SET (fd_tun, &fds_r); | 372 | if (FD_ISSET (fd_tun, &fds_r)) |
357 | 373 | { | |
358 | /* | 374 | buftun_size = |
359 | * We are supposed to read and the buffer is not empty | 375 | read (fd_tun, buftun + sizeof (struct GNUNET_MessageHeader), |
360 | * -> select on write to stdout | 376 | MAX_SIZE - sizeof (struct GNUNET_MessageHeader)); |
361 | */ | 377 | if (-1 == buftun_size) |
362 | if (read_open && (0 != buftun_size)) | 378 | { |
363 | FD_SET (1, &fds_w); | 379 | fprintf (stderr, "read-error: %s\n", strerror (errno)); |
364 | 380 | shutdown (fd_tun, SHUT_RD); | |
365 | /* | 381 | shutdown (1, SHUT_WR); |
366 | * We are supposed to write and the buffer is empty | 382 | read_open = 0; |
367 | * -> select on read from stdin | 383 | buftun_size = 0; |
368 | */ | 384 | } |
369 | if (write_open && (NULL == bufin_read)) | 385 | else if (0 == buftun_size) |
370 | FD_SET (0, &fds_r); | 386 | { |
371 | 387 | fprintf (stderr, "EOF on tun\n"); | |
372 | /* | 388 | shutdown (fd_tun, SHUT_RD); |
373 | * We are supposed to write and the buffer is not empty | 389 | shutdown (1, SHUT_WR); |
374 | * -> select on write to tun | 390 | read_open = 0; |
375 | */ | 391 | buftun_size = 0; |
376 | if (write_open && (NULL != bufin_read)) | 392 | } |
377 | FD_SET (fd_tun, &fds_w); | 393 | else |
378 | 394 | { | |
379 | int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL); | 395 | buftun_read = buftun; |
380 | if (-1 == r) | 396 | struct GNUNET_MessageHeader *hdr = |
381 | { | 397 | (struct GNUNET_MessageHeader *) buftun; |
382 | if (EINTR == errno) | 398 | buftun_size += sizeof (struct GNUNET_MessageHeader); |
383 | continue; | 399 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
384 | fprintf (stderr, "select failed: %s\n", strerror (errno)); | 400 | hdr->size = htons (buftun_size); |
385 | exit (1); | 401 | } |
386 | } | 402 | } |
387 | 403 | else if (FD_ISSET (1, &fds_w)) | |
388 | if (r > 0) | 404 | { |
389 | { | 405 | ssize_t written = write (1, buftun_read, buftun_size); |
390 | if (FD_ISSET (fd_tun, &fds_r)) | 406 | |
391 | { | 407 | if (-1 == written) |
392 | buftun_size = | 408 | { |
393 | read (fd_tun, buftun + sizeof (struct GNUNET_MessageHeader), | 409 | fprintf (stderr, "write-error to stdout: %s\n", strerror (errno)); |
394 | MAX_SIZE - sizeof (struct GNUNET_MessageHeader)); | 410 | shutdown (fd_tun, SHUT_RD); |
395 | if (-1 == buftun_size) | 411 | shutdown (1, SHUT_WR); |
396 | { | 412 | read_open = 0; |
397 | fprintf (stderr, "read-error: %s\n", strerror (errno)); | 413 | buftun_size = 0; |
398 | shutdown (fd_tun, SHUT_RD); | 414 | } |
399 | shutdown (1, SHUT_WR); | 415 | else if (0 == written) |
400 | read_open = 0; | 416 | { |
401 | buftun_size = 0; | 417 | fprintf (stderr, "write returned 0!?\n"); |
402 | } | 418 | exit (1); |
403 | else if (0 == buftun_size) | 419 | } |
404 | { | 420 | else |
405 | fprintf (stderr, "EOF on tun\n"); | 421 | { |
406 | shutdown (fd_tun, SHUT_RD); | 422 | buftun_size -= written; |
407 | shutdown (1, SHUT_WR); | 423 | buftun_read += written; |
408 | read_open = 0; | 424 | } |
409 | buftun_size = 0; | 425 | } |
410 | } | 426 | |
411 | else | 427 | if (FD_ISSET (0, &fds_r)) |
412 | { | 428 | { |
413 | buftun_read = buftun; | 429 | bufin_size = read (0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos); |
414 | struct GNUNET_MessageHeader *hdr = | 430 | if (-1 == bufin_size) |
415 | (struct GNUNET_MessageHeader *) buftun; | 431 | { |
416 | buftun_size += sizeof (struct GNUNET_MessageHeader); | 432 | fprintf (stderr, "read-error: %s\n", strerror (errno)); |
417 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | 433 | shutdown (0, SHUT_RD); |
418 | hdr->size = htons (buftun_size); | 434 | shutdown (fd_tun, SHUT_WR); |
419 | } | 435 | write_open = 0; |
420 | } | 436 | bufin_size = 0; |
421 | else if (FD_ISSET (1, &fds_w)) | 437 | } |
422 | { | 438 | else if (0 == bufin_size) |
423 | ssize_t written = write (1, buftun_read, buftun_size); | 439 | { |
424 | if (-1 == written) | 440 | fprintf (stderr, "EOF on stdin\n"); |
425 | { | 441 | shutdown (0, SHUT_RD); |
426 | fprintf (stderr, | 442 | shutdown (fd_tun, SHUT_WR); |
427 | "write-error to stdout: %s\n", | 443 | write_open = 0; |
428 | strerror (errno)); | 444 | bufin_size = 0; |
429 | shutdown (fd_tun, SHUT_RD); | 445 | } |
430 | shutdown (1, SHUT_WR); | 446 | else |
431 | read_open = 0; | 447 | { |
432 | buftun_size = 0; | 448 | struct GNUNET_MessageHeader *hdr; |
433 | } | 449 | |
434 | else if (0 == written) | 450 | PROCESS_BUFFER: |
435 | { | 451 | bufin_rpos += bufin_size; |
436 | fprintf (stderr, | 452 | if (bufin_rpos < sizeof (struct GNUNET_MessageHeader)) |
437 | "write returned 0!?\n"); | 453 | continue; |
438 | exit (1); | 454 | hdr = (struct GNUNET_MessageHeader *) bufin; |
439 | } | 455 | if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) |
440 | else | 456 | { |
441 | { | 457 | fprintf (stderr, "protocol violation!\n"); |
442 | buftun_size -= written; | 458 | exit (1); |
443 | buftun_read += written; | 459 | } |
444 | } | 460 | if (ntohs (hdr->size) > bufin_rpos) |
445 | } | 461 | continue; |
446 | 462 | bufin_read = bufin + sizeof (struct GNUNET_MessageHeader); | |
447 | if (FD_ISSET (0, &fds_r)) | 463 | bufin_size = ntohs (hdr->size) - sizeof (struct GNUNET_MessageHeader); |
448 | { | 464 | bufin_rpos -= bufin_size + sizeof (struct GNUNET_MessageHeader); |
449 | bufin_size = read (0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos); | 465 | } |
450 | if (-1 == bufin_size) | 466 | } |
451 | { | 467 | else if (FD_ISSET (fd_tun, &fds_w)) |
452 | fprintf (stderr, | 468 | { |
453 | "read-error: %s\n", | 469 | ssize_t written = write (fd_tun, bufin_read, bufin_size); |
454 | strerror (errno)); | 470 | |
455 | shutdown (0, SHUT_RD); | 471 | if (-1 == written) |
456 | shutdown (fd_tun, SHUT_WR); | 472 | { |
457 | write_open = 0; | 473 | fprintf (stderr, "write-error to tun: %s\n", strerror (errno)); |
458 | bufin_size = 0; | 474 | shutdown (0, SHUT_RD); |
459 | } | 475 | shutdown (fd_tun, SHUT_WR); |
460 | else if (0 == bufin_size) | 476 | write_open = 0; |
461 | { | 477 | bufin_size = 0; |
462 | fprintf (stderr, | 478 | } |
463 | "EOF on stdin\n"); | 479 | else if (0 == written) |
464 | shutdown (0, SHUT_RD); | 480 | { |
465 | shutdown (fd_tun, SHUT_WR); | 481 | fprintf (stderr, "write returned 0!?\n"); |
466 | write_open = 0; | 482 | exit (1); |
467 | bufin_size = 0; | 483 | } |
468 | } | 484 | else |
469 | else | 485 | { |
470 | { | 486 | bufin_size -= written; |
471 | struct GNUNET_MessageHeader *hdr; | 487 | bufin_read += written; |
472 | 488 | if (0 == bufin_size) | |
473 | PROCESS_BUFFER: | 489 | { |
474 | bufin_rpos += bufin_size; | 490 | memmove (bufin, bufin_read, bufin_rpos); |
475 | if (bufin_rpos < sizeof (struct GNUNET_MessageHeader)) | 491 | bufin_read = NULL; /* start reading again */ |
476 | continue; | 492 | bufin_size = 0; |
477 | hdr = (struct GNUNET_MessageHeader *) bufin; | 493 | goto PROCESS_BUFFER; |
478 | if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) | 494 | } |
479 | { | 495 | } |
480 | fprintf (stderr, "protocol violation!\n"); | 496 | } |
481 | exit (1); | ||
482 | } | ||
483 | if (ntohs (hdr->size) > bufin_rpos) | ||
484 | continue; | ||
485 | bufin_read = bufin + sizeof (struct GNUNET_MessageHeader); | ||
486 | bufin_size = ntohs (hdr->size) - sizeof (struct GNUNET_MessageHeader); | ||
487 | bufin_rpos -= bufin_size + sizeof (struct GNUNET_MessageHeader); | ||
488 | } | ||
489 | } | ||
490 | else if (FD_ISSET (fd_tun, &fds_w)) | ||
491 | { | ||
492 | ssize_t written = write (fd_tun, bufin_read, bufin_size); | ||
493 | if (-1 == written) | ||
494 | { | ||
495 | fprintf (stderr, "write-error to tun: %s\n", | ||
496 | strerror (errno)); | ||
497 | shutdown (0, SHUT_RD); | ||
498 | shutdown (fd_tun, SHUT_WR); | ||
499 | write_open = 0; | ||
500 | bufin_size = 0; | ||
501 | } | ||
502 | else if (0 == written) | ||
503 | { | ||
504 | fprintf (stderr, | ||
505 | "write returned 0!?\n"); | ||
506 | exit (1); | ||
507 | } | ||
508 | else | ||
509 | { | ||
510 | bufin_size -= written; | ||
511 | bufin_read += written; | ||
512 | if (0 == bufin_size) | ||
513 | { | ||
514 | memmove (bufin, | ||
515 | bufin_read, | ||
516 | bufin_rpos); | ||
517 | bufin_read = NULL; /* start reading again */ | ||
518 | bufin_size = 0; | ||
519 | goto PROCESS_BUFFER; | ||
520 | } | ||
521 | } | ||
522 | } | ||
523 | } | ||
524 | } | 497 | } |
498 | } | ||
525 | } | 499 | } |
526 | 500 | ||
527 | 501 | ||
@@ -532,35 +506,33 @@ main (int argc, char **argv) | |||
532 | int fd_tun; | 506 | int fd_tun; |
533 | 507 | ||
534 | if (6 != argc) | 508 | if (6 != argc) |
535 | { | 509 | { |
536 | fprintf (stderr, | 510 | fprintf (stderr, "Fatal: must supply 5 arguments!\n"); |
537 | "Fatal: must supply 5 arguments!\n"); | 511 | return 1; |
538 | return 1; | 512 | } |
539 | } | ||
540 | 513 | ||
541 | strncpy(dev, argv[1], IFNAMSIZ); | 514 | strncpy (dev, argv[1], IFNAMSIZ); |
542 | dev[IFNAMSIZ - 1] = '\0'; | 515 | dev[IFNAMSIZ - 1] = '\0'; |
543 | 516 | ||
544 | if (-1 == (fd_tun = init_tun (dev))) | 517 | if (-1 == (fd_tun = init_tun (dev))) |
545 | { | 518 | { |
546 | fprintf (stderr, | 519 | fprintf (stderr, "Fatal: could not initialize tun-interface\n"); |
547 | "Fatal: could not initialize tun-interface\n"); | 520 | return 1; |
548 | return 1; | 521 | } |
549 | } | ||
550 | 522 | ||
551 | { | 523 | { |
552 | const char *address = argv[2]; | 524 | const char *address = argv[2]; |
553 | long prefix_len = atol(argv[3]); | 525 | long prefix_len = atol (argv[3]); |
554 | 526 | ||
555 | if ( (prefix_len < 1) || (prefix_len > 127) ) | 527 | if ((prefix_len < 1) || (prefix_len > 127)) |
556 | { | 528 | { |
557 | fprintf(stderr, "Fatal: prefix_len out of range\n"); | 529 | fprintf (stderr, "Fatal: prefix_len out of range\n"); |
558 | return 1; | 530 | return 1; |
559 | } | 531 | } |
560 | 532 | ||
561 | set_address6 (dev, address, prefix_len); | 533 | set_address6 (dev, address, prefix_len); |
562 | } | 534 | } |
563 | 535 | ||
564 | { | 536 | { |
565 | const char *address = argv[4]; | 537 | const char *address = argv[4]; |
566 | const char *mask = argv[5]; | 538 | const char *mask = argv[5]; |
@@ -569,14 +541,12 @@ main (int argc, char **argv) | |||
569 | } | 541 | } |
570 | 542 | ||
571 | uid_t uid = getuid (); | 543 | uid_t uid = getuid (); |
544 | |||
572 | if (0 != setresuid (uid, uid, uid)) | 545 | if (0 != setresuid (uid, uid, uid)) |
573 | fprintf (stderr, | 546 | fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); |
574 | "Failed to setresuid: %s\n", | ||
575 | strerror (errno)); | ||
576 | if (SIG_ERR == signal (SIGPIPE, SIG_IGN)) | 547 | if (SIG_ERR == signal (SIGPIPE, SIG_IGN)) |
577 | fprintf (stderr, | 548 | fprintf (stderr, |
578 | "Failed to protect against SIGPIPE: %s\n", | 549 | "Failed to protect against SIGPIPE: %s\n", strerror (errno)); |
579 | strerror (errno)); | ||
580 | run (fd_tun); | 550 | run (fd_tun); |
581 | close (fd_tun); | 551 | close (fd_tun); |
582 | return 0; | 552 | return 0; |