diff options
author | Philipp Tölke <toelke@in.tum.de> | 2011-01-26 13:15:22 +0000 |
---|---|---|
committer | Philipp Tölke <toelke@in.tum.de> | 2011-01-26 13:15:22 +0000 |
commit | 62c64f683cce5f7521a9a49e6a1055b22da82091 (patch) | |
tree | 64072a06170ab68716322a2a294ca3b6b3647e9b /src/vpn/gnunet-helper-vpn.c | |
parent | ac6f62af65ec1d509efe6ba958ea61c6eacd5f99 (diff) | |
download | gnunet-62c64f683cce5f7521a9a49e6a1055b22da82091.tar.gz gnunet-62c64f683cce5f7521a9a49e6a1055b22da82091.zip |
Documented, cleaned and indented gnunet-helper-vpn
Diffstat (limited to 'src/vpn/gnunet-helper-vpn.c')
-rw-r--r-- | src/vpn/gnunet-helper-vpn.c | 371 |
1 files changed, 219 insertions, 152 deletions
diff --git a/src/vpn/gnunet-helper-vpn.c b/src/vpn/gnunet-helper-vpn.c index 1cee01c71..00eb15c6a 100644 --- a/src/vpn/gnunet-helper-vpn.c +++ b/src/vpn/gnunet-helper-vpn.c | |||
@@ -47,7 +47,7 @@ | |||
47 | /** | 47 | /** |
48 | * This is in linux/include/net/ipv6.h, but not always exported... | 48 | * This is in linux/include/net/ipv6.h, but not always exported... |
49 | */ | 49 | */ |
50 | struct in6_ifreq | 50 | struct in6_ifreq |
51 | { | 51 | { |
52 | struct in6_addr ifr6_addr; | 52 | struct in6_addr ifr6_addr; |
53 | uint32_t ifr6_prefixlen; | 53 | uint32_t ifr6_prefixlen; |
@@ -55,50 +55,52 @@ struct in6_ifreq | |||
55 | }; | 55 | }; |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | |||
59 | /** | 58 | /** |
60 | * Creates a tun-interface called dev; | 59 | * Creates a tun-interface called dev; |
61 | * @param dev is asumed to point to a char[IFNAMSIZ] | 60 | * @param dev is asumed to point to a char[IFNAMSIZ] |
62 | * if *dev == '\\0', uses the name supplied by the kernel | 61 | * if *dev == '\\0', uses the name supplied by the kernel |
63 | * @return the fd to the tun or -1 on error | 62 | * @return the fd to the tun or -1 on error |
64 | */ | 63 | */ |
65 | static int | 64 | static int |
66 | init_tun (char *dev) | 65 | init_tun (char *dev) |
67 | { | 66 | { |
68 | struct ifreq ifr; | 67 | struct ifreq ifr; |
69 | int fd; | 68 | int fd; |
70 | 69 | ||
71 | if (NULL == dev) | 70 | if (NULL == dev) |
72 | { | 71 | { |
73 | errno = EINVAL; | 72 | errno = EINVAL; |
74 | return -1; | 73 | return -1; |
75 | } | 74 | } |
76 | 75 | ||
77 | if (-1 == (fd = open("/dev/net/tun", O_RDWR))) | 76 | if (-1 == (fd = open ("/dev/net/tun", O_RDWR))) |
77 | { | ||
78 | fprintf (stderr, | ||
79 | "Error opening `%s': %s\n", "/dev/net/tun", strerror (errno)); | ||
80 | return -1; | ||
81 | } | ||
82 | |||
83 | if (fd >= FD_SETSIZE) | ||
78 | { | 84 | { |
79 | fprintf (stderr, | 85 | fprintf (stderr, "Filedescriptor to large: %d", fd); |
80 | "Error opening `%s': %s\n", | ||
81 | "/dev/net/tun", | ||
82 | strerror(errno)); | ||
83 | return -1; | 86 | return -1; |
84 | } | 87 | } |
85 | 88 | ||
86 | memset(&ifr, 0, sizeof(ifr)); | 89 | memset (&ifr, 0, sizeof (ifr)); |
87 | ifr.ifr_flags = IFF_TUN; | 90 | ifr.ifr_flags = IFF_TUN; |
88 | 91 | ||
89 | if ('\0' == *dev) | 92 | if ('\0' == *dev) |
90 | strncpy(ifr.ifr_name, dev, IFNAMSIZ); | 93 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); |
91 | 94 | ||
92 | if (-1 == ioctl(fd, TUNSETIFF, (void *) &ifr)) | 95 | if (-1 == ioctl (fd, TUNSETIFF, (void *) &ifr)) |
93 | { | 96 | { |
94 | fprintf (stderr, | 97 | fprintf (stderr, |
95 | "Error with ioctl on `%s': %s\n", | 98 | "Error with ioctl on `%s': %s\n", |
96 | "/dev/net/tun", | 99 | "/dev/net/tun", strerror (errno)); |
97 | strerror(errno)); | ||
98 | close (fd); | 100 | close (fd); |
99 | return -1; | 101 | return -1; |
100 | } | 102 | } |
101 | strcpy(dev, ifr.ifr_name); | 103 | strcpy (dev, ifr.ifr_name); |
102 | return fd; | 104 | return fd; |
103 | } | 105 | } |
104 | 106 | ||
@@ -111,10 +113,8 @@ init_tun (char *dev) | |||
111 | * @param prefix_len the length of the network-prefix | 113 | * @param prefix_len the length of the network-prefix |
112 | */ | 114 | */ |
113 | static void | 115 | static void |
114 | set_address6 (const char *dev, | 116 | set_address6 (const char *dev, const char *address, unsigned long prefix_len) |
115 | const char *address, | 117 | { |
116 | unsigned long prefix_len) | ||
117 | { | ||
118 | struct ifreq ifr; | 118 | struct ifreq ifr; |
119 | struct in6_ifreq ifr6; | 119 | struct in6_ifreq ifr6; |
120 | struct sockaddr_in6 sa6; | 120 | struct sockaddr_in6 sa6; |
@@ -122,70 +122,73 @@ set_address6 (const char *dev, | |||
122 | 122 | ||
123 | if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) | 123 | if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) |
124 | { | 124 | { |
125 | fprintf (stderr, | 125 | fprintf (stderr, "Error creating socket: %s\n", strerror (errno)); |
126 | "Error creating socket: %s\n", | ||
127 | strerror (errno)); | ||
128 | exit (1); | 126 | exit (1); |
129 | } | 127 | } |
130 | memset (&sa6, 0, sizeof (struct sockaddr_in6)); | 128 | memset (&sa6, 0, sizeof (struct sockaddr_in6)); |
131 | sa6.sin6_family = AF_INET6; | 129 | sa6.sin6_family = AF_INET6; |
132 | 130 | ||
131 | /* | ||
132 | * parse the new address | ||
133 | */ | ||
133 | if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) | 134 | if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) |
134 | { | 135 | { |
135 | fprintf (stderr, | 136 | fprintf (stderr, |
136 | "Failed to parse address `%s': %s\n", | 137 | "Failed to parse address `%s': %s\n", |
137 | address, | 138 | address, strerror (errno)); |
138 | strerror (errno)); | ||
139 | exit (1); | 139 | exit (1); |
140 | } | 140 | } |
141 | memcpy (&ifr6.ifr6_addr, &sa6.sin6_addr, sizeof (struct in6_addr)); | ||
142 | |||
141 | 143 | ||
142 | memcpy (&ifr6.ifr6_addr, | 144 | /* |
143 | &sa6.sin6_addr, | 145 | * Get the index of the if |
144 | sizeof (struct in6_addr)); | 146 | */ |
145 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); | 147 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); |
146 | if (-1 == ioctl (fd, SIOGIFINDEX, &ifr)) | 148 | if (-1 == ioctl (fd, SIOGIFINDEX, &ifr)) |
147 | { | 149 | { |
148 | fprintf (stderr, | 150 | fprintf (stderr, |
149 | "ioctl failed at %d: %s\n", | 151 | "ioctl failed at %d: %s\n", __LINE__, strerror (errno)); |
150 | __LINE__, | ||
151 | strerror (errno)); | ||
152 | exit (1); | 152 | exit (1); |
153 | } | 153 | } |
154 | |||
155 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; | 154 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; |
155 | |||
156 | ifr6.ifr6_prefixlen = prefix_len; | 156 | ifr6.ifr6_prefixlen = prefix_len; |
157 | |||
158 | /* | ||
159 | * Set the address | ||
160 | */ | ||
157 | if (-1 == ioctl (fd, SIOCSIFADDR, &ifr6)) | 161 | if (-1 == ioctl (fd, SIOCSIFADDR, &ifr6)) |
158 | { | 162 | { |
159 | fprintf (stderr, | 163 | fprintf (stderr, |
160 | "ioctl failed at line %d: %s\n", | 164 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
161 | __LINE__, | ||
162 | strerror (errno)); | ||
163 | exit (1); | 165 | exit (1); |
164 | } | 166 | } |
165 | 167 | ||
168 | /* | ||
169 | * Get the flags | ||
170 | */ | ||
166 | if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) | 171 | if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) |
167 | { | 172 | { |
168 | fprintf (stderr, | 173 | fprintf (stderr, |
169 | "ioctl failed at line %d: %s\n", | 174 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
170 | __LINE__, | ||
171 | strerror (errno)); | ||
172 | exit (1); | 175 | exit (1); |
173 | } | 176 | } |
177 | |||
178 | /* | ||
179 | * Add the UP and RUNNING flags | ||
180 | */ | ||
174 | ifr.ifr_flags |= IFF_UP | IFF_RUNNING; | 181 | ifr.ifr_flags |= IFF_UP | IFF_RUNNING; |
175 | if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) | 182 | if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) |
176 | { | 183 | { |
177 | fprintf (stderr, | 184 | fprintf (stderr, |
178 | "ioctl failed at line %d: %s\n", | 185 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
179 | __LINE__, | ||
180 | strerror (errno)); | ||
181 | exit (1); | 186 | exit (1); |
182 | } | 187 | } |
183 | 188 | ||
184 | if (0 != close (fd)) | 189 | if (0 != close (fd)) |
185 | { | 190 | { |
186 | fprintf (stderr, | 191 | fprintf (stderr, "close failed: %s\n", strerror (errno)); |
187 | "close failed: %s\n", | ||
188 | strerror (errno)); | ||
189 | exit (1); | 192 | exit (1); |
190 | } | 193 | } |
191 | } | 194 | } |
@@ -211,6 +214,9 @@ set_address4 (char *dev, char *address, char *mask) | |||
211 | addr->sin_family = AF_INET; | 214 | addr->sin_family = AF_INET; |
212 | addr->sin_addr.s_addr = inet_addr (address); | 215 | addr->sin_addr.s_addr = inet_addr (address); |
213 | 216 | ||
217 | /* | ||
218 | * Parse the address | ||
219 | */ | ||
214 | int r = inet_pton (AF_INET, address, &addr->sin_addr.s_addr); | 220 | int r = inet_pton (AF_INET, address, &addr->sin_addr.s_addr); |
215 | if (r < 0) | 221 | if (r < 0) |
216 | { | 222 | { |
@@ -227,6 +233,9 @@ set_address4 (char *dev, char *address, char *mask) | |||
227 | 233 | ||
228 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); | 234 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); |
229 | 235 | ||
236 | /* | ||
237 | * Set the address | ||
238 | */ | ||
230 | if (ioctl (fd, SIOCSIFADDR, &ifr) != 0) | 239 | if (ioctl (fd, SIOCSIFADDR, &ifr) != 0) |
231 | { | 240 | { |
232 | perror ("SIOCSIFADDR"); | 241 | perror ("SIOCSIFADDR"); |
@@ -234,6 +243,9 @@ set_address4 (char *dev, char *address, char *mask) | |||
234 | return; | 243 | return; |
235 | } | 244 | } |
236 | 245 | ||
246 | /* | ||
247 | * Parse the netmask | ||
248 | */ | ||
237 | addr = (struct sockaddr_in *) &(ifr.ifr_netmask); | 249 | addr = (struct sockaddr_in *) &(ifr.ifr_netmask); |
238 | r = inet_pton (AF_INET, mask, &addr->sin_addr.s_addr); | 250 | r = inet_pton (AF_INET, mask, &addr->sin_addr.s_addr); |
239 | if (r < 0) | 251 | if (r < 0) |
@@ -242,6 +254,9 @@ set_address4 (char *dev, char *address, char *mask) | |||
242 | exit (1); | 254 | exit (1); |
243 | } | 255 | } |
244 | 256 | ||
257 | /* | ||
258 | * Set the netmask | ||
259 | */ | ||
245 | if (ioctl (fd, SIOCSIFNETMASK, &ifr) != 0) | 260 | if (ioctl (fd, SIOCSIFNETMASK, &ifr) != 0) |
246 | { | 261 | { |
247 | perror ("SIOCSIFNETMASK"); | 262 | perror ("SIOCSIFNETMASK"); |
@@ -249,156 +264,211 @@ set_address4 (char *dev, char *address, char *mask) | |||
249 | return; | 264 | return; |
250 | } | 265 | } |
251 | 266 | ||
252 | (void) ioctl (fd, SIOCGIFFLAGS, &ifr); | 267 | /* |
268 | * Get the flags | ||
269 | */ | ||
270 | if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) | ||
271 | { | ||
272 | fprintf (stderr, | ||
273 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); | ||
274 | exit (1); | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * Add the UP and RUNNING flags | ||
279 | */ | ||
253 | ifr.ifr_flags |= IFF_UP | IFF_RUNNING; | 280 | ifr.ifr_flags |= IFF_UP | IFF_RUNNING; |
254 | (void) ioctl (fd, SIOCSIFFLAGS, &ifr); | 281 | if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) |
255 | close (fd); | 282 | { |
283 | fprintf (stderr, | ||
284 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); | ||
285 | exit (1); | ||
286 | } | ||
287 | |||
288 | if (0 != close (fd)) | ||
289 | { | ||
290 | fprintf (stderr, "close failed: %s\n", strerror (errno)); | ||
291 | exit (1); | ||
292 | } | ||
256 | } | 293 | } |
257 | 294 | ||
258 | 295 | ||
259 | static void | 296 | static void |
260 | run (int fd_tun) | 297 | run (int fd_tun) |
261 | { | 298 | { |
262 | unsigned char buf[MAX_SIZE]; | 299 | /* |
300 | * The buffer filled by reading from fd_tun | ||
301 | */ | ||
302 | unsigned char buftun[MAX_SIZE]; | ||
303 | ssize_t buftun_size = 0; | ||
304 | unsigned char *buftun_read; | ||
305 | |||
306 | /* | ||
307 | * The buffer filled by reading from stdin | ||
308 | */ | ||
309 | unsigned char bufin[MAX_SIZE]; | ||
310 | ssize_t bufin_size = 0; | ||
311 | unsigned char *bufin_write; | ||
312 | |||
263 | fd_set fds_w; | 313 | fd_set fds_w; |
264 | fd_set fds_r; | 314 | fd_set fds_r; |
315 | |||
265 | int rea = 1; | 316 | int rea = 1; |
266 | int wri = 1; | 317 | int wri = 1; |
267 | int write_fd_possible = 0; | 318 | |
268 | int write_stdout_possible = 0; | ||
269 | ssize_t tin; | ||
270 | outer: | ||
271 | while ((1 == rea) || (1 == wri)) | 319 | while ((1 == rea) || (1 == wri)) |
272 | { | 320 | { |
273 | FD_ZERO (&fds_w); | 321 | FD_ZERO (&fds_w); |
274 | FD_ZERO (&fds_r); | 322 | FD_ZERO (&fds_r); |
275 | 323 | ||
276 | if (rea) | 324 | /* |
325 | * We are supposed to read and the buffer is empty | ||
326 | * -> select on read from tun | ||
327 | */ | ||
328 | if (rea && (0 == buftun_size)) | ||
277 | { | 329 | { |
278 | FD_SET (fd_tun, &fds_r); | 330 | FD_SET (fd_tun, &fds_r); |
279 | if (!write_stdout_possible) | ||
280 | FD_SET (1, &fds_w); | ||
281 | } | 331 | } |
282 | 332 | ||
283 | if (wri) | 333 | /* |
334 | * We are supposed to read and the buffer is not empty | ||
335 | * -> select on write to stdout | ||
336 | */ | ||
337 | if (rea && (0 != buftun_size)) | ||
338 | { | ||
339 | FD_SET (1, &fds_w); | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * We are supposed to write and the buffer is empty | ||
344 | * -> select on read from stdin | ||
345 | */ | ||
346 | if (wri && (0 == bufin_size)) | ||
284 | { | 347 | { |
285 | FD_SET (0, &fds_r); | 348 | FD_SET (0, &fds_r); |
286 | if (!write_fd_possible) | 349 | } |
287 | FD_SET (fd_tun, &fds_w); | 350 | |
351 | /* | ||
352 | * We are supposed to write and the buffer is not empty | ||
353 | * -> select on write to tun | ||
354 | */ | ||
355 | if (wri && (0 != bufin_size)) | ||
356 | { | ||
357 | FD_SET (fd_tun, &fds_w); | ||
288 | } | 358 | } |
289 | 359 | ||
290 | int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL); | 360 | int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL); |
291 | /* FIXME: if error... */ | 361 | if (-1 == r) |
292 | if (r > 0) | ||
293 | { | 362 | { |
294 | if (FD_ISSET (fd_tun, &fds_w)) | 363 | fprintf (stderr, "select failed: %s\n", strerror (errno)); |
295 | write_fd_possible = 1; | 364 | exit (1); |
296 | if (FD_ISSET (1, &fds_w)) | 365 | } |
297 | write_stdout_possible = 1; | ||
298 | 366 | ||
299 | if (FD_ISSET (0, &fds_r) && write_fd_possible) | 367 | if (r > 0) |
368 | { | ||
369 | if (FD_ISSET (fd_tun, &fds_r)) | ||
300 | { | 370 | { |
301 | write_fd_possible = 0; | 371 | buftun_size = |
302 | struct GNUNET_MessageHeader *pkt = ( struct GNUNET_MessageHeader *) buf; | 372 | read (fd_tun, buftun + sizeof (struct GNUNET_MessageHeader), |
303 | tin = read (0, buf, sizeof (struct GNUNET_MessageHeader)); | 373 | MAX_SIZE - sizeof (struct GNUNET_MessageHeader)) + |
304 | if (tin <= 0) | 374 | sizeof (struct GNUNET_MessageHeader); |
375 | if (-1 == buftun_size) | ||
305 | { | 376 | { |
306 | fprintf (stderr, "read-error: %s\n", strerror (errno)); | 377 | fprintf (stderr, "read-error: %s\n", strerror (errno)); |
307 | shutdown (fd_tun, SHUT_WR); | 378 | shutdown (fd_tun, SHUT_RD); |
308 | shutdown (0, SHUT_RD); | 379 | shutdown (1, SHUT_WR); |
309 | wri = 0; | 380 | rea = 0; |
310 | goto outer; | 381 | buftun_size = 0; |
311 | } | 382 | } |
312 | if (pkt->type != ntohs (GNUNET_MESSAGE_TYPE_VPN_HELPER)) | 383 | else if (0 == buftun_size) |
313 | abort (); | ||
314 | while (tin < ntohs (pkt->size)) | ||
315 | { | 384 | { |
316 | ssize_t t = read (0, buf + tin, ntohs (pkt->size) - tin); | 385 | fprintf (stderr, "eof on tun\n"); |
317 | if (t <= 0) | 386 | shutdown (fd_tun, SHUT_RD); |
318 | { | 387 | shutdown (1, SHUT_WR); |
319 | fprintf (stderr, "read-error: %s\n", strerror (errno)); | 388 | rea = 0; |
320 | shutdown (fd_tun, SHUT_WR); | 389 | buftun_size = 0; |
321 | shutdown (0, SHUT_RD); | ||
322 | wri = 0; | ||
323 | goto outer; | ||
324 | } | ||
325 | tin += t; | ||
326 | } | 390 | } |
327 | tin = 0; | 391 | else |
328 | while (tin < | ||
329 | ntohs (pkt->size) - | ||
330 | sizeof (struct GNUNET_MessageHeader)) | ||
331 | { | 392 | { |
332 | ssize_t t = write (fd_tun, &pkt[1], | 393 | buftun_read = buftun; |
333 | ntohs (pkt->size) - | 394 | struct GNUNET_MessageHeader *hdr = |
334 | sizeof (struct GNUNET_MessageHeader) - tin); | 395 | (struct GNUNET_MessageHeader *) buftun; |
335 | if (t <= 0) | 396 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
336 | { | 397 | hdr->size = htons (buftun_size); |
337 | fprintf (stderr, "write-error 3: %s\n", | ||
338 | strerror (errno)); | ||
339 | shutdown (fd_tun, SHUT_WR); | ||
340 | shutdown (0, SHUT_RD); | ||
341 | wri = 0; | ||
342 | goto outer; | ||
343 | } | ||
344 | tin += t; | ||
345 | } | 398 | } |
346 | } | 399 | } |
347 | else if (write_stdout_possible && FD_ISSET (fd_tun, &fds_r)) | 400 | else if (FD_ISSET (1, &fds_w)) |
348 | { | 401 | { |
349 | write_stdout_possible = 0; | 402 | ssize_t written = write (1, buftun_read, buftun_size); |
350 | tin = read (fd_tun, buf, MAX_SIZE); | 403 | if (-1 == written) |
351 | if (tin <= 0) | ||
352 | { | 404 | { |
353 | fprintf (stderr, "read-error: %s\n", strerror (errno)); | 405 | fprintf (stderr, "write-error to stdout: %s\n", |
406 | strerror (errno)); | ||
354 | shutdown (fd_tun, SHUT_RD); | 407 | shutdown (fd_tun, SHUT_RD); |
355 | shutdown (1, SHUT_WR); | 408 | shutdown (1, SHUT_WR); |
356 | rea = 0; | 409 | rea = 0; |
357 | goto outer; | 410 | buftun_size = 0; |
411 | } | ||
412 | buftun_size -= written; | ||
413 | buftun_read += written; | ||
414 | } | ||
415 | |||
416 | if (FD_ISSET (0, &fds_r)) | ||
417 | { | ||
418 | bufin_size = read (0, bufin, MAX_SIZE); | ||
419 | if (-1 == bufin_size) | ||
420 | { | ||
421 | fprintf (stderr, "read-error: %s\n", strerror (errno)); | ||
422 | shutdown (0, SHUT_RD); | ||
423 | shutdown (fd_tun, SHUT_WR); | ||
424 | wri = 0; | ||
425 | bufin_size = 0; | ||
358 | } | 426 | } |
359 | struct GNUNET_MessageHeader hdr = {.size = | 427 | else if (0 == bufin_size) |
360 | htons (r + sizeof (struct GNUNET_MessageHeader)),.type = | ||
361 | htons (GNUNET_MESSAGE_TYPE_VPN_HELPER) | ||
362 | }; | ||
363 | tin = 0; | ||
364 | while (tin < sizeof (struct GNUNET_MessageHeader)) | ||
365 | { | 428 | { |
366 | ssize_t t = | 429 | fprintf (stderr, "eof on stdin\n"); |
367 | write (1, &hdr, sizeof (struct GNUNET_MessageHeader) - tin); | 430 | shutdown (0, SHUT_RD); |
368 | if (t < 0) | 431 | shutdown (fd_tun, SHUT_WR); |
369 | { | 432 | wri = 0; |
370 | fprintf (stderr, "write-error 2: %s\n", | 433 | bufin_size = 0; |
371 | strerror (errno)); | ||
372 | shutdown (fd_tun, SHUT_RD); | ||
373 | shutdown (1, SHUT_WR); | ||
374 | rea = 0; | ||
375 | goto outer; | ||
376 | } | ||
377 | tin += t; | ||
378 | } | 434 | } |
379 | while (tin < ntohs (hdr.size)) | 435 | else |
380 | { | 436 | { |
381 | size_t t = write (1, buf, ntohs (hdr.size) - tin); | 437 | struct GNUNET_MessageHeader *hdr = |
382 | if (t < 0) | 438 | (struct GNUNET_MessageHeader *) bufin; |
439 | if ((bufin_size < sizeof (struct GNUNET_MessageHeader)) | ||
440 | || (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) | ||
441 | || (ntohs (hdr->size) != bufin_size)) | ||
383 | { | 442 | { |
384 | fprintf (stderr, "write-error 1: %s, written %d/%d\n", | 443 | fprintf (stderr, "protocol violation!\n"); |
385 | strerror (errno), r, ntohs (hdr.size)); | 444 | exit (1); |
386 | shutdown (fd_tun, SHUT_RD); | ||
387 | shutdown (1, SHUT_WR); | ||
388 | rea = 0; | ||
389 | goto outer; | ||
390 | } | 445 | } |
391 | tin += t; | 446 | bufin_write = bufin + sizeof (struct GNUNET_MessageHeader); |
447 | bufin_size -= sizeof (struct GNUNET_MessageHeader); | ||
448 | } | ||
449 | } | ||
450 | else if (FD_ISSET (fd_tun, &fds_w)) | ||
451 | { | ||
452 | ssize_t written = write (fd_tun, bufin_write, bufin_size); | ||
453 | if (-1 == written) | ||
454 | { | ||
455 | fprintf (stderr, "write-error to tun: %s\n", | ||
456 | strerror (errno)); | ||
457 | shutdown (0, SHUT_RD); | ||
458 | shutdown (fd_tun, SHUT_WR); | ||
459 | wri = 0; | ||
460 | bufin_size = 0; | ||
392 | } | 461 | } |
462 | bufin_size -= written; | ||
463 | bufin_write += written; | ||
393 | } | 464 | } |
394 | } | 465 | } |
395 | } | 466 | } |
396 | } | 467 | } |
397 | 468 | ||
398 | 469 | ||
399 | int | 470 | int |
400 | main (int argc, | 471 | main (int argc, char **argv) |
401 | char** argv) | ||
402 | { | 472 | { |
403 | char dev[IFNAMSIZ]; | 473 | char dev[IFNAMSIZ]; |
404 | int fd_tun; | 474 | int fd_tun; |
@@ -406,8 +476,7 @@ main (int argc, | |||
406 | memset (dev, 0, IFNAMSIZ); | 476 | memset (dev, 0, IFNAMSIZ); |
407 | if (-1 == (fd_tun = init_tun (dev))) | 477 | if (-1 == (fd_tun = init_tun (dev))) |
408 | { | 478 | { |
409 | fprintf (stderr, | 479 | fprintf (stderr, "Fatal: could not initialize tun-interface\n"); |
410 | "Fatal: could not initialize tun-interface\n"); | ||
411 | return 1; | 480 | return 1; |
412 | } | 481 | } |
413 | 482 | ||
@@ -428,9 +497,7 @@ main (int argc, | |||
428 | 497 | ||
429 | uid_t uid = getuid (); | 498 | uid_t uid = getuid (); |
430 | if (0 != setresuid (uid, uid, uid)) | 499 | if (0 != setresuid (uid, uid, uid)) |
431 | fprintf (stderr, | 500 | fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); |
432 | "Failed to setresuid: %s\n", | ||
433 | strerror (errno)); | ||
434 | run (fd_tun); | 501 | run (fd_tun); |
435 | close (fd_tun); | 502 | close (fd_tun); |
436 | return 0; | 503 | return 0; |