diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-09-20 10:57:07 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-09-20 10:57:07 +0000 |
commit | 2a53d025446c993ccb516e2d7005169b26950a29 (patch) | |
tree | c865a25db5ca07dd8605314e038da96232cbac4d /src | |
parent | 1aa42a97fb4310dd72a31aad114b6ebe26aebd8a (diff) | |
download | gnunet-2a53d025446c993ccb516e2d7005169b26950a29.tar.gz gnunet-2a53d025446c993ccb516e2d7005169b26950a29.zip |
tot tot
Diffstat (limited to 'src')
-rw-r--r-- | src/gns/gnocksy/gnocksy.c | 860 | ||||
-rw-r--r-- | src/gns/gnocksy/gns_glue.c | 144 | ||||
-rw-r--r-- | src/gns/gnocksy/gns_glue.h | 34 | ||||
-rw-r--r-- | src/gns/gnocksy/protocol.h | 87 |
4 files changed, 0 insertions, 1125 deletions
diff --git a/src/gns/gnocksy/gnocksy.c b/src/gns/gnocksy/gnocksy.c deleted file mode 100644 index df5f06940..000000000 --- a/src/gns/gnocksy/gnocksy.c +++ /dev/null | |||
@@ -1,860 +0,0 @@ | |||
1 | /* | ||
2 | * The GNS Socks5 Proxy | ||
3 | */ | ||
4 | |||
5 | #include <stdio.h> | ||
6 | /** | ||
7 | * | ||
8 | * Note: Only supports addr type 3 (domain) for now. | ||
9 | * Chrome uses it automatically | ||
10 | * For FF: about:config -> network.proxy.socks_remote_dns true | ||
11 | * | ||
12 | * TODO | ||
13 | * - zkey shorten | ||
14 | * - LEHO replacement and glue | ||
15 | * - SSL | ||
16 | */ | ||
17 | |||
18 | #include <stdlib.h> | ||
19 | #include <string.h> | ||
20 | #include <unistd.h> | ||
21 | #include <sys/types.h> | ||
22 | #include <sys/socket.h> | ||
23 | #include <netinet/in.h> | ||
24 | #include <sys/epoll.h> | ||
25 | #include <errno.h> | ||
26 | #include <fcntl.h> | ||
27 | #include <netdb.h> | ||
28 | #include <arpa/inet.h> | ||
29 | #include <microhttpd.h> | ||
30 | #include <curl/curl.h> | ||
31 | #include <regex.h> | ||
32 | |||
33 | #include "protocol.h" | ||
34 | #include "gns_glue.h" | ||
35 | |||
36 | #define MAXEVENTS 64 | ||
37 | |||
38 | #define DEBUG 0 | ||
39 | #define VERBOSE 1 | ||
40 | |||
41 | #define HTML_HDR_CONTENT "Content-Type: text/html\r\n" | ||
42 | |||
43 | #define RE_DOTPLUS "<a href=\"http://(([A-Za-z]+[.])+)([+])" | ||
44 | |||
45 | #define RE_N_MATCHES 4 | ||
46 | |||
47 | #define HTTP_PORT 80 | ||
48 | #define HTTPS_PORT 443 | ||
49 | |||
50 | static struct MHD_Daemon *mhd_daemon; | ||
51 | static regex_t re_dotplus; | ||
52 | |||
53 | static size_t | ||
54 | curl_write_data (void *buffer, size_t size, size_t nmemb, void* cls) | ||
55 | { | ||
56 | const char* page = buffer; | ||
57 | uint64_t bytes = size * nmemb; | ||
58 | struct socks5_bridge* br = cls; | ||
59 | int ret; | ||
60 | |||
61 | int nomatch; | ||
62 | regmatch_t m[RE_N_MATCHES]; | ||
63 | char* hostptr; | ||
64 | char* plusptr; | ||
65 | char* p; | ||
66 | char new_host[256]; | ||
67 | char to_exp[256]; | ||
68 | uint64_t bytes_copied = 0; | ||
69 | |||
70 | char new_buf[CURL_MAX_WRITE_SIZE+1]; | ||
71 | p = new_buf; | ||
72 | |||
73 | pthread_mutex_lock ( &br->m_buf ); | ||
74 | if (br->MHD_CURL_BUF_STATUS == BUF_WAIT_FOR_MHD) | ||
75 | { | ||
76 | pthread_mutex_unlock ( &br->m_buf ); | ||
77 | return CURL_WRITEFUNC_PAUSE; | ||
78 | } | ||
79 | |||
80 | /* do regex magic */ | ||
81 | if ( br->res_is_html ) | ||
82 | { | ||
83 | printf ("result is html text\n"); | ||
84 | memset (new_buf, 0, sizeof(new_buf)); | ||
85 | memcpy (new_buf, page, bytes); | ||
86 | |||
87 | |||
88 | while (1) | ||
89 | { | ||
90 | nomatch = regexec ( &re_dotplus, p, RE_N_MATCHES, m, 0); | ||
91 | |||
92 | if (nomatch) | ||
93 | { | ||
94 | if (DEBUG) | ||
95 | printf ("No more matches\n"); | ||
96 | if ((p-new_buf) < 0) | ||
97 | { | ||
98 | if (DEBUG) | ||
99 | printf ("Error p<buf!\n"); | ||
100 | break; | ||
101 | } | ||
102 | memcpy ( br->MHD_CURL_BUF+bytes_copied, p, bytes-(p-new_buf)); | ||
103 | bytes_copied += bytes-(p-new_buf); | ||
104 | break; | ||
105 | } | ||
106 | |||
107 | if (DEBUG) | ||
108 | printf ("Got match\n"); | ||
109 | |||
110 | if (m[1].rm_so != -1) | ||
111 | { | ||
112 | hostptr = p+m[1].rm_so; | ||
113 | if (DEBUG) | ||
114 | printf ("Copying %d bytes.\n", (hostptr-p)); | ||
115 | memcpy (br->MHD_CURL_BUF+bytes_copied, p, (hostptr-p)); | ||
116 | bytes_copied += (hostptr-p); | ||
117 | memset (new_host, 0, sizeof(new_host)); | ||
118 | memset (to_exp, 0, sizeof (to_exp)); | ||
119 | memcpy (to_exp, hostptr, (m[1].rm_eo-m[1].rm_so)); | ||
120 | |||
121 | gns_glue_expand_and_shorten ( to_exp, | ||
122 | br->host, | ||
123 | new_host ); | ||
124 | if (DEBUG) | ||
125 | { | ||
126 | printf ("Glue fin\n"); | ||
127 | printf ("Copying new name %s \n", new_host); | ||
128 | } | ||
129 | memcpy ( br->MHD_CURL_BUF+bytes_copied, new_host, | ||
130 | strlen (new_host) ); | ||
131 | bytes_copied += strlen (new_host); | ||
132 | p += m[3].rm_so+1; | ||
133 | |||
134 | if (DEBUG) | ||
135 | printf ("Done. Next in %d bytes\n", m[3].rm_so); | ||
136 | |||
137 | //TODO check buf lenghts! | ||
138 | } | ||
139 | } | ||
140 | br->MHD_CURL_BUF_SIZE = bytes_copied; | ||
141 | } | ||
142 | else | ||
143 | { | ||
144 | memcpy (br->MHD_CURL_BUF, buffer, bytes); | ||
145 | br->MHD_CURL_BUF_SIZE = bytes; | ||
146 | } | ||
147 | |||
148 | br->MHD_CURL_BUF_STATUS = BUF_WAIT_FOR_MHD; | ||
149 | |||
150 | pthread_mutex_unlock ( &br->m_buf ); | ||
151 | |||
152 | |||
153 | //MHD_destroy_response (response); | ||
154 | if (DEBUG) | ||
155 | printf( "buffer:\n%s\n", (char*)br->MHD_CURL_BUF ); | ||
156 | return bytes; | ||
157 | } | ||
158 | |||
159 | static size_t | ||
160 | curl_check_hdr (void *buffer, size_t size, size_t nmemb, void* cls) | ||
161 | { | ||
162 | size_t bytes = size * nmemb; | ||
163 | struct socks5_bridge* br = cls; | ||
164 | char hdr[bytes+1]; | ||
165 | |||
166 | memcpy(hdr, buffer, bytes); | ||
167 | hdr[bytes] = '\0'; | ||
168 | |||
169 | if (DEBUG) | ||
170 | printf ("got hdr: %s", hdr); | ||
171 | |||
172 | if (0 == strcmp(hdr, HTML_HDR_CONTENT)) | ||
173 | br->res_is_html = 1; | ||
174 | |||
175 | return bytes; | ||
176 | } | ||
177 | |||
178 | |||
179 | /* | ||
180 | * Create an ipv4/6 tcp socket for a given port | ||
181 | * | ||
182 | * @param port the port to bind to | ||
183 | * @return the file descriptor of the socket or -1 | ||
184 | */ | ||
185 | static int | ||
186 | create_socket (char *port) | ||
187 | { | ||
188 | struct addrinfo hints; | ||
189 | struct addrinfo *result, *rp; | ||
190 | int s, sfd; | ||
191 | |||
192 | memset (&hints, 0, sizeof (struct addrinfo)); | ||
193 | hints.ai_family = AF_UNSPEC; | ||
194 | hints.ai_socktype = SOCK_STREAM; | ||
195 | hints.ai_flags = AI_PASSIVE; | ||
196 | |||
197 | s = getaddrinfo (NULL, port, &hints, &result); | ||
198 | if (s != 0) | ||
199 | { | ||
200 | fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (s)); | ||
201 | return -1; | ||
202 | } | ||
203 | |||
204 | for (rp = result; rp != NULL; rp = rp->ai_next) | ||
205 | { | ||
206 | sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol); | ||
207 | if (sfd == -1) | ||
208 | continue; | ||
209 | |||
210 | s = bind (sfd, rp->ai_addr, rp->ai_addrlen); | ||
211 | if (s == 0) | ||
212 | { | ||
213 | break; | ||
214 | } | ||
215 | close(sfd); | ||
216 | } | ||
217 | |||
218 | if (rp == NULL) | ||
219 | { | ||
220 | fprintf (stderr, "Could not bind\n"); | ||
221 | return -1; | ||
222 | } | ||
223 | |||
224 | freeaddrinfo (result); | ||
225 | |||
226 | return sfd; | ||
227 | } | ||
228 | |||
229 | |||
230 | /* | ||
231 | * Make socket with fd non blocking | ||
232 | * | ||
233 | * @param fd the file descriptor of the socket | ||
234 | * @return -1 on error | ||
235 | */ | ||
236 | static int | ||
237 | setnonblocking (int fd) | ||
238 | { | ||
239 | int flags, s; | ||
240 | |||
241 | flags = fcntl (fd, F_GETFL, 0); | ||
242 | if (flags == -1) | ||
243 | { | ||
244 | perror ("fcntl"); | ||
245 | return -1; | ||
246 | } | ||
247 | |||
248 | flags |= O_NONBLOCK; | ||
249 | s = fcntl (fd, F_SETFL, flags); | ||
250 | if (s == -1) | ||
251 | { | ||
252 | perror ("fcntl"); | ||
253 | return -1; | ||
254 | } | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | /** | ||
260 | * Checks if name is in tld | ||
261 | * | ||
262 | * @param name the name to check | ||
263 | * @param tld the TLD to check for | ||
264 | * @return -1 if name not in tld | ||
265 | */ | ||
266 | static int | ||
267 | is_tld (const char* name, const char* tld) | ||
268 | { | ||
269 | int offset = 0; | ||
270 | |||
271 | if (strlen (name) <= strlen (tld)) | ||
272 | return -1; | ||
273 | |||
274 | offset = strlen (name) - strlen (tld); | ||
275 | if (strcmp (name+offset, tld) != 0) | ||
276 | return -1; | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | |||
282 | /* | ||
283 | * Connect to host specified in phost | ||
284 | * | ||
285 | * @param phost the hostentry containing the IP | ||
286 | * @return fd to the connection or -1 on error | ||
287 | */ | ||
288 | static int | ||
289 | connect_to_domain (struct hostent* phost, uint16_t srv_port) | ||
290 | { | ||
291 | uint32_t srv_ip; | ||
292 | struct sockaddr_in srv_addr; | ||
293 | struct in_addr *sin_addr; | ||
294 | int conn_fd; | ||
295 | |||
296 | |||
297 | sin_addr = (struct in_addr*)(phost->h_addr); | ||
298 | srv_ip = sin_addr->s_addr; | ||
299 | conn_fd = socket(AF_INET, SOCK_STREAM, 0); | ||
300 | memset(&srv_addr, 0, sizeof(srv_addr)); | ||
301 | srv_addr.sin_family = AF_INET; | ||
302 | srv_addr.sin_addr.s_addr = srv_ip; | ||
303 | srv_addr.sin_port = srv_port; | ||
304 | if (DEBUG) | ||
305 | printf("target server: %s:%u\n", inet_ntoa(srv_addr.sin_addr), | ||
306 | ntohs(srv_port)); | ||
307 | |||
308 | if (connect (conn_fd, (struct sockaddr*)&srv_addr, | ||
309 | sizeof (struct sockaddr)) < 0) | ||
310 | { | ||
311 | printf("socket request error...\n"); | ||
312 | close(conn_fd); | ||
313 | return -1; | ||
314 | } | ||
315 | |||
316 | setnonblocking(conn_fd); | ||
317 | |||
318 | return conn_fd; | ||
319 | } | ||
320 | |||
321 | static int | ||
322 | access_cb (void* cls, | ||
323 | const struct sockaddr *addr, | ||
324 | socklen_t addrlen) | ||
325 | { | ||
326 | printf ("access cb called\n"); | ||
327 | return MHD_YES; | ||
328 | } | ||
329 | |||
330 | static void | ||
331 | fetch_url (struct socks5_bridge* br) | ||
332 | { | ||
333 | |||
334 | CURLcode ret; | ||
335 | |||
336 | br->curl = curl_easy_init(); | ||
337 | |||
338 | /* TODO optionally do LEHO stuff here */ | ||
339 | |||
340 | if (br->curl) | ||
341 | { | ||
342 | curl_easy_setopt (br->curl, CURLOPT_URL, br->full_url); | ||
343 | curl_easy_setopt (br->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr); | ||
344 | curl_easy_setopt (br->curl, CURLOPT_HEADERDATA, br); | ||
345 | curl_easy_setopt (br->curl, CURLOPT_WRITEFUNCTION, &curl_write_data); | ||
346 | curl_easy_setopt (br->curl, CURLOPT_WRITEDATA, br); | ||
347 | ret = curl_easy_perform (br->curl); | ||
348 | free (br->full_url); | ||
349 | pthread_mutex_lock ( &br->m_done ); | ||
350 | br->is_done = 1; | ||
351 | pthread_mutex_unlock ( &br->m_done ); | ||
352 | |||
353 | curl_easy_cleanup (br->curl); | ||
354 | |||
355 | if (ret == CURLE_OK) | ||
356 | { | ||
357 | printf("all good on the curl end\n"); | ||
358 | return; | ||
359 | } | ||
360 | printf("error on the curl end %s\n", curl_easy_strerror(ret)); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | static ssize_t | ||
365 | mhd_content_cb (void* cls, | ||
366 | uint64_t pos, | ||
367 | char* buf, | ||
368 | size_t max) | ||
369 | { | ||
370 | struct socks5_bridge* br = cls; | ||
371 | |||
372 | pthread_mutex_lock ( &br->m_done ); | ||
373 | /* if done and buf empty */ | ||
374 | if ( (br->is_done == 1) && | ||
375 | (br->MHD_CURL_BUF_STATUS == BUF_WAIT_FOR_CURL) ) | ||
376 | { | ||
377 | printf("done. sending response...\n"); | ||
378 | br->is_done = 0; | ||
379 | pthread_mutex_unlock ( &br->m_done ); | ||
380 | return MHD_CONTENT_READER_END_OF_STREAM; | ||
381 | } | ||
382 | pthread_mutex_unlock ( &br->m_done ); | ||
383 | |||
384 | pthread_mutex_lock ( &br->m_buf ); | ||
385 | if ( br->MHD_CURL_BUF_STATUS == BUF_WAIT_FOR_CURL ) | ||
386 | { | ||
387 | pthread_mutex_unlock ( &br->m_buf ); | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | |||
392 | |||
393 | if ( br->MHD_CURL_BUF_SIZE > max ) | ||
394 | { | ||
395 | printf("buffer in mhd response too small!\n"); | ||
396 | pthread_mutex_unlock ( &br->m_buf ); | ||
397 | return MHD_CONTENT_READER_END_WITH_ERROR; | ||
398 | } | ||
399 | |||
400 | if (0 != br->MHD_CURL_BUF_SIZE) | ||
401 | { | ||
402 | printf("copying %d bytes to mhd response at offset %d\n", | ||
403 | br->MHD_CURL_BUF_SIZE, pos); | ||
404 | memcpy ( buf, br->MHD_CURL_BUF, br->MHD_CURL_BUF_SIZE ); | ||
405 | } | ||
406 | br->MHD_CURL_BUF_STATUS = BUF_WAIT_FOR_CURL; | ||
407 | curl_easy_pause (br->curl, CURLPAUSE_CONT); | ||
408 | pthread_mutex_unlock ( &br->m_buf ); | ||
409 | |||
410 | return br->MHD_CURL_BUF_SIZE; | ||
411 | } | ||
412 | |||
413 | static int | ||
414 | accept_cb (void *cls, | ||
415 | struct MHD_Connection *con, | ||
416 | const char *url, | ||
417 | const char *meth, | ||
418 | const char *ver, | ||
419 | const char *upload_data, | ||
420 | size_t *upload_data_size, | ||
421 | void **con_cls) | ||
422 | { | ||
423 | static int dummy; | ||
424 | const char* page = "<html><head><title>gnoxy</title>"\ | ||
425 | "</head><body>gnoxy demo</body></html>"; | ||
426 | struct MHD_Response *response; | ||
427 | struct socks5_bridge *br = cls; | ||
428 | int ret; | ||
429 | char* full_url; | ||
430 | |||
431 | if (0 != strcmp (meth, "GET")) | ||
432 | return MHD_NO; | ||
433 | if (&dummy != *con_cls) | ||
434 | { | ||
435 | *con_cls = &dummy; | ||
436 | return MHD_YES; | ||
437 | } | ||
438 | |||
439 | if (0 != *upload_data_size) | ||
440 | return MHD_NO; | ||
441 | |||
442 | *con_cls = NULL; | ||
443 | |||
444 | if (-1 == asprintf (&br->full_url, "%s%s", br->host, url)) | ||
445 | { | ||
446 | printf ("error building url!\n"); | ||
447 | return MHD_NO; | ||
448 | } | ||
449 | printf ("url %s\n", br->full_url); | ||
450 | |||
451 | pthread_mutex_lock ( &br->m_done ); | ||
452 | br->is_done = 0; | ||
453 | pthread_mutex_unlock ( &br->m_done ); | ||
454 | |||
455 | br->MHD_CURL_BUF_STATUS = BUF_WAIT_FOR_CURL; | ||
456 | br->res_is_html = 0; | ||
457 | |||
458 | response = MHD_create_response_from_callback (-1, -1, | ||
459 | &mhd_content_cb, | ||
460 | br, | ||
461 | NULL); //TODO destroy resp here | ||
462 | |||
463 | ret = MHD_queue_response (con, MHD_HTTP_OK, response); | ||
464 | pthread_create ( &br->thread, NULL, &fetch_url, br ); | ||
465 | |||
466 | return MHD_YES; | ||
467 | |||
468 | |||
469 | } | ||
470 | |||
471 | static int | ||
472 | compile_regex (regex_t *re, const char* rt) | ||
473 | { | ||
474 | int status; | ||
475 | char err[1024]; | ||
476 | |||
477 | status = regcomp (re, rt, REG_EXTENDED|REG_NEWLINE); | ||
478 | if (status) | ||
479 | { | ||
480 | regerror (status, re, err, 1024); | ||
481 | printf ("Regex error compiling '%s': %s\n", rt, err); | ||
482 | return 1; | ||
483 | } | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | |||
488 | int main ( int argc, char *argv[] ) | ||
489 | { | ||
490 | int sfd, s; | ||
491 | int efd; | ||
492 | struct epoll_event event; | ||
493 | struct epoll_event *events; | ||
494 | int ev_states[MAXEVENTS]; | ||
495 | int n, i, j; | ||
496 | struct socks5_bridge* br; | ||
497 | |||
498 | struct sockaddr in_addr; | ||
499 | socklen_t in_len; | ||
500 | int infd; | ||
501 | char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; | ||
502 | |||
503 | /* port offset for ssl daemons */ | ||
504 | int i_ssl = 1; | ||
505 | |||
506 | int done; | ||
507 | ssize_t count; | ||
508 | char buf[512]; | ||
509 | struct socks5_server_hello hello; | ||
510 | struct socks5_server_response resp; | ||
511 | struct socks5_client_request *req; | ||
512 | struct socks5_bridge* new_br; | ||
513 | char domain[256]; | ||
514 | uint8_t dom_len; | ||
515 | uint16_t req_port; | ||
516 | int conn_fd; | ||
517 | struct hostent *phost; | ||
518 | |||
519 | mhd_daemon = NULL; | ||
520 | curl_global_init(CURL_GLOBAL_ALL); | ||
521 | |||
522 | //compile_regex ( &re_htmlhdr, RE_HTML ); | ||
523 | compile_regex( &re_dotplus, (char*)RE_DOTPLUS ); | ||
524 | |||
525 | for (j = 0; j < MAXEVENTS; j++) | ||
526 | ev_states[j] = SOCKS5_INIT; | ||
527 | |||
528 | if (argc != 2) | ||
529 | { | ||
530 | fprintf (stderr, "Usage: %s [port]\n", argv[0]); | ||
531 | exit (EXIT_FAILURE); | ||
532 | } | ||
533 | |||
534 | sfd = create_socket(argv[1]); | ||
535 | if (s == -1) | ||
536 | abort (); | ||
537 | |||
538 | s = setnonblocking (sfd); | ||
539 | if (s == -1) | ||
540 | abort (); | ||
541 | |||
542 | s = listen (sfd, SOMAXCONN); | ||
543 | if (s == -1) | ||
544 | { | ||
545 | perror ("listen"); | ||
546 | abort (); | ||
547 | } | ||
548 | |||
549 | efd = epoll_create1 (0); | ||
550 | if (efd == -1) | ||
551 | { | ||
552 | perror ("epoll create"); | ||
553 | abort (); | ||
554 | } | ||
555 | |||
556 | br = malloc(sizeof (struct socks5_bridge)); | ||
557 | event.data.ptr = br; | ||
558 | br->fd = sfd; | ||
559 | br->remote_end = NULL; | ||
560 | |||
561 | event.events = EPOLLIN | EPOLLET; | ||
562 | s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event); | ||
563 | if (s == -1) | ||
564 | { | ||
565 | perror ("epoll ctl"); | ||
566 | abort (); | ||
567 | } | ||
568 | |||
569 | events = calloc (MAXEVENTS, sizeof event); | ||
570 | |||
571 | while (1) | ||
572 | { | ||
573 | n = epoll_wait (efd, events, MAXEVENTS, -1); | ||
574 | for (i = 0; i < n; i++) | ||
575 | { | ||
576 | br = (struct socks5_bridge*)(events[i].data.ptr); | ||
577 | |||
578 | if ((events[i].events & EPOLLERR) || | ||
579 | (events[i].events & EPOLLHUP) || | ||
580 | (!(events[i].events & EPOLLIN))) | ||
581 | { | ||
582 | fprintf (stderr, "epoll error %d\n", events[i].events); | ||
583 | fprintf (stderr, "closing fd %d\n", br->fd); | ||
584 | close (br->fd); | ||
585 | continue; | ||
586 | } | ||
587 | else if (sfd == br->fd) | ||
588 | { | ||
589 | /* New connection(s) */ | ||
590 | while (1) | ||
591 | { | ||
592 | |||
593 | in_len = sizeof (in_addr); | ||
594 | infd = accept (sfd, &in_addr, &in_len); | ||
595 | if (infd == -1) | ||
596 | { | ||
597 | if ((errno == EAGAIN) || | ||
598 | (errno == EWOULDBLOCK)) | ||
599 | { | ||
600 | break; | ||
601 | } | ||
602 | else | ||
603 | { | ||
604 | perror ("accept"); | ||
605 | break; | ||
606 | } | ||
607 | } | ||
608 | |||
609 | s = getnameinfo (&in_addr, in_len, | ||
610 | hbuf, sizeof (hbuf), | ||
611 | sbuf, sizeof (sbuf), | ||
612 | NI_NUMERICHOST | NI_NUMERICSERV); | ||
613 | if (s == -1) | ||
614 | abort (); | ||
615 | |||
616 | s = setnonblocking (infd); | ||
617 | if (s == -1) | ||
618 | abort (); | ||
619 | |||
620 | event.events = EPOLLIN | EPOLLET; | ||
621 | br = malloc (sizeof (struct socks5_bridge)); | ||
622 | br->fd = infd; | ||
623 | br->addr = in_addr; | ||
624 | br->addr_len = in_len; | ||
625 | br->remote_end = NULL; | ||
626 | br->status = SOCKS5_INIT; | ||
627 | event.data.ptr = br; | ||
628 | |||
629 | s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event); | ||
630 | if (s == -1) | ||
631 | { | ||
632 | perror ("epoll ctl"); | ||
633 | abort (); | ||
634 | } | ||
635 | } | ||
636 | continue; | ||
637 | } | ||
638 | else | ||
639 | { | ||
640 | /* Incoming data */ | ||
641 | done = 0; | ||
642 | |||
643 | while (1) | ||
644 | { | ||
645 | |||
646 | memset (buf, 0, sizeof (buf)); | ||
647 | |||
648 | count = read (br->fd, buf, sizeof (buf)); | ||
649 | |||
650 | if (count == -1) | ||
651 | { | ||
652 | if (errno != EAGAIN) | ||
653 | { | ||
654 | perror ("read"); | ||
655 | done = 1; | ||
656 | } | ||
657 | break; | ||
658 | } | ||
659 | else if (count == 0) | ||
660 | { | ||
661 | done = 1; | ||
662 | break; | ||
663 | } | ||
664 | |||
665 | if (br->status == SOCKS5_DATA_TRANSFER) | ||
666 | { | ||
667 | if (DEBUG) | ||
668 | { | ||
669 | printf ("Trying to fwd %d bytes from %d to %d!\n" , | ||
670 | count, br->fd, br->remote_end->fd ); | ||
671 | } | ||
672 | if (br->remote_end) | ||
673 | s = write (br->remote_end->fd, buf, count); | ||
674 | if (DEBUG) | ||
675 | printf ("%d bytes written\n", s); | ||
676 | } | ||
677 | |||
678 | if (br->status == SOCKS5_INIT) | ||
679 | { | ||
680 | if (DEBUG) | ||
681 | printf ("SOCKS5 init for %d\n", br->fd); | ||
682 | hello.version = 0x05; | ||
683 | hello.auth_method = 0; | ||
684 | write (br->fd, &hello, sizeof (hello)); | ||
685 | br->status = SOCKS5_REQUEST; | ||
686 | } | ||
687 | if (br->status == SOCKS5_REQUEST) | ||
688 | { | ||
689 | req = (struct socks5_client_request*)buf; | ||
690 | |||
691 | memset(&resp, 0, sizeof(resp)); | ||
692 | |||
693 | if (req->addr_type == 3) | ||
694 | { | ||
695 | dom_len = *((uint8_t*)(&(req->addr_type) + 1)); | ||
696 | memset(domain, 0, sizeof(domain)); | ||
697 | strncpy(domain, (char*)(&(req->addr_type) + 2), dom_len); | ||
698 | req_port = *((uint16_t*)(&(req->addr_type) + 2 + dom_len)); | ||
699 | |||
700 | if (DEBUG) | ||
701 | printf ("Requested connection is %s:%d\n", | ||
702 | domain, | ||
703 | ntohs(req_port)); | ||
704 | |||
705 | phost = (struct hostent*)gethostbyname (domain); | ||
706 | if (phost == NULL) | ||
707 | { | ||
708 | if (VERBOSE) | ||
709 | printf ("Resolve %s error!\n" , domain ); | ||
710 | resp.version = 0x05; | ||
711 | resp.reply = 0x01; | ||
712 | write (br->fd, &resp, sizeof (struct socks5_server_response)); | ||
713 | break; | ||
714 | } | ||
715 | |||
716 | if (DEBUG) | ||
717 | printf ("trying to add %d to MHD\n", br->fd); | ||
718 | |||
719 | if ( -1 != is_tld (domain, ".gnunet") ) | ||
720 | { | ||
721 | strcpy (br->host, domain); | ||
722 | if (HTTP_PORT == ntohs(req_port)) | ||
723 | { | ||
724 | br->use_ssl = 0; | ||
725 | if (NULL == mhd_daemon) | ||
726 | { | ||
727 | mhd_daemon = | ||
728 | MHD_start_daemon( MHD_USE_THREAD_PER_CONNECTION, | ||
729 | 8080, | ||
730 | &access_cb, br, | ||
731 | &accept_cb, br, | ||
732 | MHD_OPTION_END); | ||
733 | } | ||
734 | |||
735 | if (MHD_YES != MHD_add_connection (mhd_daemon, | ||
736 | br->fd, | ||
737 | &br->addr, | ||
738 | br->addr_len)) | ||
739 | { | ||
740 | if (VERBOSE) | ||
741 | printf ("Error adding %d to mhd\n", br->fd); | ||
742 | } | ||
743 | } | ||
744 | |||
745 | if (HTTPS_PORT == ntohs(req_port)) | ||
746 | { | ||
747 | /* | ||
748 | * custom daemon for SSL requests | ||
749 | * TODO make more efficient with | ||
750 | * per name SSL daemons? | ||
751 | */ | ||
752 | br->use_ssl = 1; | ||
753 | br->ssl_daemon = | ||
754 | MHD_start_daemon( MHD_USE_THREAD_PER_CONNECTION | | ||
755 | MHD_USE_SSL, | ||
756 | 8080+i_ssl, | ||
757 | NULL, NULL, | ||
758 | &accept_cb, br, | ||
759 | MHD_OPTION_HTTPS_MEM_KEY, NULL, | ||
760 | MHD_OPTION_HTTPS_MEM_CERT, NULL, | ||
761 | MHD_OPTION_END); | ||
762 | |||
763 | i_ssl++; | ||
764 | |||
765 | if (MHD_YES != MHD_add_connection (br->ssl_daemon, | ||
766 | br->fd, | ||
767 | &br->addr, | ||
768 | br->addr_len)) | ||
769 | { | ||
770 | if (VERBOSE) | ||
771 | printf ("Error adding %d to mhd\n", br->fd); | ||
772 | } | ||
773 | } | ||
774 | |||
775 | |||
776 | event.events = EPOLLIN | EPOLLET; | ||
777 | epoll_ctl (efd, EPOLL_CTL_DEL, br->fd, &event); | ||
778 | resp.version = 0x05; | ||
779 | resp.reply = 0x00; | ||
780 | resp.reserved = 0x00; | ||
781 | resp.addr_type = 0x01; | ||
782 | write (br->fd, &resp, 10); | ||
783 | } | ||
784 | else | ||
785 | { | ||
786 | |||
787 | conn_fd = connect_to_domain (phost, req_port); | ||
788 | |||
789 | if (-1 == conn_fd) | ||
790 | { | ||
791 | if (VERBOSE) | ||
792 | printf("cannot create remote connection from %d to %s:%d\n", | ||
793 | br->fd, domain, ntohs(req_port)); | ||
794 | resp.version = 0x05; | ||
795 | resp.reply = 0x01; | ||
796 | write (br->fd, &resp, 10); | ||
797 | } | ||
798 | else | ||
799 | { | ||
800 | if (VERBOSE) | ||
801 | printf("new remote connection %d to %d\n", br->fd, conn_fd); | ||
802 | resp.version = 0x05; | ||
803 | resp.reply = 0x00; | ||
804 | resp.reserved = 0x00; | ||
805 | resp.addr_type = 0x01; | ||
806 | |||
807 | new_br = malloc (sizeof (struct socks5_bridge)); | ||
808 | if (br->remote_end != NULL) | ||
809 | printf ("WARNING remote end was not NULL!\n"); | ||
810 | br->remote_end = new_br; | ||
811 | br->status = SOCKS5_DATA_TRANSFER; | ||
812 | new_br->fd = conn_fd; | ||
813 | new_br->remote_end = br; | ||
814 | new_br->status = SOCKS5_DATA_TRANSFER; | ||
815 | |||
816 | event.data.ptr = new_br; | ||
817 | event.events = EPOLLIN | EPOLLET; | ||
818 | epoll_ctl (efd, EPOLL_CTL_ADD, conn_fd, &event); | ||
819 | write (br->fd, &resp, 10); | ||
820 | } | ||
821 | } | ||
822 | |||
823 | } | ||
824 | else | ||
825 | { | ||
826 | if (DEBUG) | ||
827 | printf("not implemented address type %02X\n", (int)req->addr_type); | ||
828 | } | ||
829 | } | ||
830 | |||
831 | |||
832 | if (s == -1) | ||
833 | { | ||
834 | perror ("write"); | ||
835 | abort (); | ||
836 | } | ||
837 | } | ||
838 | |||
839 | if (done) | ||
840 | { | ||
841 | //close (br->fd); | ||
842 | |||
843 | if (br->remote_end) | ||
844 | { | ||
845 | //close (br->remote_end->fd); | ||
846 | //free(br->remote_end); | ||
847 | } | ||
848 | //free(br); | ||
849 | } | ||
850 | } | ||
851 | } | ||
852 | } | ||
853 | |||
854 | free (events); | ||
855 | MHD_stop_daemon (mhd_daemon); | ||
856 | regfree ( &re_dotplus ); | ||
857 | close (sfd); | ||
858 | |||
859 | return EXIT_SUCCESS; | ||
860 | } | ||
diff --git a/src/gns/gnocksy/gns_glue.c b/src/gns/gnocksy/gns_glue.c deleted file mode 100644 index 54e6916fc..000000000 --- a/src/gns/gnocksy/gns_glue.c +++ /dev/null | |||
@@ -1,144 +0,0 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
3 | |||
4 | /* | ||
5 | * Glue function to return the authoritative part | ||
6 | * of a name. i.e. the site of origin | ||
7 | * | ||
8 | * @param name the name to process | ||
9 | * @param auth pointer where the result is stored | ||
10 | * @return 0 on success < 0 on failure | ||
11 | */ | ||
12 | int | ||
13 | gns_glue_get_auth ( char* name, char* auth ) | ||
14 | { | ||
15 | char cmd[1024]; | ||
16 | char line[1024]; | ||
17 | FILE *p; | ||
18 | |||
19 | sprintf (cmd, "%s %s", "gnunet-gns -a", name); | ||
20 | |||
21 | p = popen(cmd, "r"); | ||
22 | |||
23 | if (p != NULL) | ||
24 | { | ||
25 | while (fgets (line, sizeof(line), p) != NULL) | ||
26 | { | ||
27 | if (line[strlen(line)-1] == '\n') | ||
28 | { | ||
29 | line[strlen(line)-1] = '\0'; | ||
30 | strcpy (auth, line); | ||
31 | return 0; | ||
32 | } | ||
33 | } | ||
34 | |||
35 | } | ||
36 | |||
37 | fclose (p); | ||
38 | |||
39 | return -1; | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | * Glue function to return the short version of | ||
44 | * a given name | ||
45 | * | ||
46 | * @param name the name to shorten | ||
47 | * @param shortened pointer where the result will be stored | ||
48 | * @return 0 on success < 0 on failure | ||
49 | */ | ||
50 | int | ||
51 | gns_glue_shorten ( char* name, char* shortened ) | ||
52 | { | ||
53 | char cmd[1024]; | ||
54 | char line[1024]; | ||
55 | FILE *p; | ||
56 | |||
57 | sprintf (cmd, "%s %s", "gnunet-gns -r -s", name); | ||
58 | |||
59 | p = popen(cmd, "r"); | ||
60 | |||
61 | if (p != NULL) | ||
62 | { | ||
63 | while (fgets (line, sizeof(line), p) != NULL) | ||
64 | { | ||
65 | if (line[strlen(line)-1] == '\n') | ||
66 | { | ||
67 | line[strlen(line)-1] = '\0'; | ||
68 | strcpy (shortened, line); | ||
69 | return 0; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | } | ||
74 | |||
75 | fclose (p); | ||
76 | |||
77 | return -1; | ||
78 | } | ||
79 | |||
80 | |||
81 | /* | ||
82 | * Glue function to expand .+ urls and shorted the | ||
83 | * resulting name | ||
84 | * | ||
85 | * @param to_expand the .+ name to expand | ||
86 | * @param host the site of origin | ||
87 | * @param shortened the expanded and shortened result pointer | ||
88 | */ | ||
89 | int | ||
90 | gns_glue_expand_and_shorten( char* to_expand, char* host, char* shortened ) | ||
91 | { | ||
92 | char cmd[1024]; | ||
93 | char line[1024]; | ||
94 | FILE *p; | ||
95 | char sorig[256]; | ||
96 | char expanded[256]; | ||
97 | |||
98 | sprintf (shortened, "%s%s", to_expand, host); //TODO this is a mockup | ||
99 | return 0; | ||
100 | |||
101 | sprintf (cmd, "%s %s", "gnunet-gns -a", host); | ||
102 | |||
103 | p = popen(cmd, "r"); | ||
104 | |||
105 | if (p != NULL) | ||
106 | { | ||
107 | while (fgets (line, sizeof(line), p) != NULL) | ||
108 | { | ||
109 | if (line[strlen(line)-1] == '\n') | ||
110 | { | ||
111 | line[strlen(line)-1] = '\0'; | ||
112 | strcpy (sorig, line); | ||
113 | return 0; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | } | ||
118 | |||
119 | fclose (p); | ||
120 | |||
121 | sprintf (expanded, "%s.%s", to_expand, sorig); | ||
122 | |||
123 | sprintf (cmd, "%s %s", "gnunet-gns -r -s", expanded); | ||
124 | |||
125 | p = popen(cmd, "r"); | ||
126 | |||
127 | if (p != NULL) | ||
128 | { | ||
129 | while (fgets (line, sizeof(line), p) != NULL) | ||
130 | { | ||
131 | if (line[strlen(line)-1] == '\n') | ||
132 | { | ||
133 | line[strlen(line)-1] = '\0'; | ||
134 | strcpy (shortened, line); | ||
135 | return 0; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | } | ||
140 | |||
141 | fclose (p); | ||
142 | |||
143 | return -1; | ||
144 | } | ||
diff --git a/src/gns/gnocksy/gns_glue.h b/src/gns/gnocksy/gns_glue.h deleted file mode 100644 index 7a872d683..000000000 --- a/src/gns/gnocksy/gns_glue.h +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | /* | ||
2 | * Glue function to return the authoritative part | ||
3 | * of a name. i.e. the site of origin | ||
4 | * | ||
5 | * @param name the name to process | ||
6 | * @param auth pointer where the result is stored | ||
7 | * @return 0 on success < 0 on failure | ||
8 | */ | ||
9 | int | ||
10 | gns_glue_get_auth ( char* name, char* auth ); | ||
11 | |||
12 | /* | ||
13 | * Glue function to return the short version of | ||
14 | * a given name | ||
15 | * | ||
16 | * @param name the name to shorten | ||
17 | * @param shortened pointer where the result will be stored | ||
18 | * @return 0 on success < 0 on failure | ||
19 | */ | ||
20 | int | ||
21 | gns_glue_shorten ( char* name, char* shortened); | ||
22 | |||
23 | /* | ||
24 | * Glue function to expand .+ urls and shorted the | ||
25 | * resulting name | ||
26 | * | ||
27 | * @param to_expand the .+ name to expand | ||
28 | * @param host the site of origin | ||
29 | * @param shortened the expanded and shortened result pointer | ||
30 | */ | ||
31 | int | ||
32 | gns_glue_expand_and_shorten (char* to_expand, | ||
33 | char* host, | ||
34 | char* shortened); | ||
diff --git a/src/gns/gnocksy/protocol.h b/src/gns/gnocksy/protocol.h deleted file mode 100644 index a6f22a64b..000000000 --- a/src/gns/gnocksy/protocol.h +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | |||
2 | |||
3 | /* The socks phases */ | ||
4 | enum | ||
5 | { | ||
6 | SOCKS5_INIT, | ||
7 | SOCKS5_REQUEST, | ||
8 | SOCKS5_DATA_TRANSFER | ||
9 | }; | ||
10 | |||
11 | /* Client hello */ | ||
12 | struct socks5_client_hello | ||
13 | { | ||
14 | uint8_t version; | ||
15 | uint8_t num_auth_methods; | ||
16 | char* auth_methods; | ||
17 | }; | ||
18 | |||
19 | /* Client socks request */ | ||
20 | struct socks5_client_request | ||
21 | { | ||
22 | uint8_t version; | ||
23 | uint8_t command; | ||
24 | uint8_t resvd; | ||
25 | uint8_t addr_type; | ||
26 | /* | ||
27 | * followed by either an ip4/ipv6 address | ||
28 | * or a domain name with a length field in front | ||
29 | */ | ||
30 | }; | ||
31 | |||
32 | /* Server hello */ | ||
33 | struct socks5_server_hello | ||
34 | { | ||
35 | uint8_t version; | ||
36 | uint8_t auth_method; | ||
37 | }; | ||
38 | |||
39 | #define BUF_WAIT_FOR_CURL 0 | ||
40 | #define BUF_WAIT_FOR_MHD 1 | ||
41 | |||
42 | /* Struct used to store connection | ||
43 | * information | ||
44 | */ | ||
45 | struct socks5_bridge | ||
46 | { | ||
47 | int fd; | ||
48 | struct socks5_bridge* remote_end; | ||
49 | struct sockaddr addr; | ||
50 | socklen_t addr_len; | ||
51 | char host[256]; | ||
52 | int status; | ||
53 | |||
54 | /* This is an ssl bridge? */ | ||
55 | int use_ssl; | ||
56 | |||
57 | /* if use_ssl=1 we have a daemon associated */ | ||
58 | struct MHD_Daemon *ssl_daemon; | ||
59 | |||
60 | /* http url + host */ | ||
61 | char* full_url; | ||
62 | |||
63 | /* handle to curl */ | ||
64 | CURL* curl; | ||
65 | |||
66 | /* is response html? */ | ||
67 | int res_is_html; | ||
68 | |||
69 | /* buffer structures */ | ||
70 | pthread_t thread; | ||
71 | pthread_mutex_t m_done; | ||
72 | int is_done; | ||
73 | pthread_mutex_t m_buf; | ||
74 | char MHD_CURL_BUF[CURL_MAX_WRITE_SIZE]; | ||
75 | size_t MHD_CURL_BUF_SIZE; | ||
76 | int MHD_CURL_BUF_STATUS; | ||
77 | }; | ||
78 | |||
79 | /* Server response to client requests */ | ||
80 | struct socks5_server_response | ||
81 | { | ||
82 | uint8_t version; | ||
83 | uint8_t reply; | ||
84 | uint8_t reserved; | ||
85 | uint8_t addr_type; | ||
86 | uint8_t add_port[18]; | ||
87 | }; | ||