| 33 |
33 |
| 34 /************************************************************************** |
34 /************************************************************************** |
| 35 * DNS query API |
35 * DNS query API |
| 36 **************************************************************************/ |
36 **************************************************************************/ |
| 37 |
37 |
| |
38 struct _GaimDnsQueryData { |
| |
39 }; |
| |
40 |
| 38 #if defined(__unix__) || defined(__APPLE__) |
41 #if defined(__unix__) || defined(__APPLE__) |
| 39 |
42 |
| 40 #define MAX_DNS_CHILDREN 4 |
43 #define MAX_DNS_CHILDREN 4 |
| 41 |
44 |
| 42 /* |
45 /* |
| 471 } |
474 } |
| 472 /* |
475 /* |
| 473 * End the functions for dealing with the DNS child processes. |
476 * End the functions for dealing with the DNS child processes. |
| 474 */ |
477 */ |
| 475 |
478 |
| 476 int |
479 GaimDnsQueryData * |
| 477 gaim_gethostbyname_async(const char *hostname, int port, GaimProxyDnsConnectFunction callback, gpointer data) |
480 gaim_dnsquery_a(const char *hostname, int port, GaimDnsQueryConnectFunction callback, gpointer data) |
| 478 { |
481 { |
| 479 pending_dns_request_t *req = NULL; |
482 pending_dns_request_t *req = NULL; |
| 480 dns_params_t dns_params; |
483 dns_params_t dns_params; |
| 481 gchar *host_temp; |
484 gchar *host_temp; |
| 482 gboolean show_debug; |
485 gboolean show_debug; |
| 519 g_queue_push_tail(queued_requests, r); |
522 g_queue_push_tail(queued_requests, r); |
| 520 |
523 |
| 521 gaim_debug_info("dns", |
524 gaim_debug_info("dns", |
| 522 "DNS query for '%s' queued\n", dns_params.hostname); |
525 "DNS query for '%s' queued\n", dns_params.hostname); |
| 523 |
526 |
| 524 return 0; |
527 return (GaimDnsQueryData *)1; |
| 525 } |
528 } |
| 526 |
529 |
| 527 req = gaim_dns_new_resolverthread(show_debug); |
530 req = gaim_dns_new_resolverthread(show_debug); |
| 528 if (req == NULL) |
531 if (req == NULL) |
| 529 { |
532 { |
| 530 gaim_debug_error("proxy", "oh dear, this is going to explode, I give up\n"); |
533 gaim_debug_error("proxy", "oh dear, this is going to explode, I give up\n"); |
| 531 return -1; |
534 return NULL; |
| 532 } |
535 } |
| 533 send_dns_request_to_child(req, &dns_params); |
536 send_dns_request_to_child(req, &dns_params); |
| 534 } |
537 } |
| 535 |
538 |
| 536 req->host = g_strdup(hostname); |
539 req->host = g_strdup(hostname); |
| 537 req->port = port; |
540 req->port = port; |
| 538 req->callback = callback; |
541 req->callback = callback; |
| 539 req->data = data; |
542 req->data = data; |
| 540 req->inpa = gaim_input_add(req->fd_out, GAIM_INPUT_READ, host_resolved, req); |
543 req->inpa = gaim_input_add(req->fd_out, GAIM_INPUT_READ, host_resolved, req); |
| 541 |
544 |
| 542 return 0; |
545 return (GaimDnsQueryData *)1; |
| 543 } |
546 } |
| 544 |
547 |
| 545 #elif defined _WIN32 /* end __unix__ || __APPLE__ */ |
548 #elif defined _WIN32 /* end __unix__ || __APPLE__ */ |
| 546 |
549 |
| 547 typedef struct _dns_tdata { |
550 typedef struct _dns_tdata { |
| 548 char *hostname; |
551 char *hostname; |
| 549 int port; |
552 int port; |
| 550 GaimProxyDnsConnectFunction callback; |
553 GaimDnsQueryConnectFunction callback; |
| 551 gpointer data; |
554 gpointer data; |
| 552 GSList *hosts; |
555 GSList *hosts; |
| 553 char *errmsg; |
556 char *errmsg; |
| 554 } dns_tdata; |
557 } dns_tdata; |
| 555 |
558 |
| 619 /* back to main thread */ |
622 /* back to main thread */ |
| 620 g_idle_add(dns_main_thread_cb, td); |
623 g_idle_add(dns_main_thread_cb, td); |
| 621 return 0; |
624 return 0; |
| 622 } |
625 } |
| 623 |
626 |
| 624 int |
627 GaimDnsQueryData * |
| 625 gaim_gethostbyname_async(const char *hostname, int port, |
628 gaim_dnsquery_a(const char *hostname, int port, |
| 626 GaimProxyDnsConnectFunction callback, gpointer data) |
629 GaimDnsQueryConnectFunction callback, gpointer data) |
| 627 { |
630 { |
| 628 dns_tdata *td; |
631 dns_tdata *td; |
| 629 struct sockaddr_in sin; |
632 struct sockaddr_in sin; |
| 630 GError* err = NULL; |
633 GError* err = NULL; |
| 631 |
634 |
| 634 sin.sin_family = AF_INET; |
637 sin.sin_family = AF_INET; |
| 635 sin.sin_port = htons(port); |
638 sin.sin_port = htons(port); |
| 636 hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin))); |
639 hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin))); |
| 637 hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin))); |
640 hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin))); |
| 638 callback(hosts, data, NULL); |
641 callback(hosts, data, NULL); |
| 639 return 0; |
642 return (GaimDnsQueryData *)1; |
| 640 } |
643 } |
| 641 |
644 |
| 642 gaim_debug_info("dns", "DNS Lookup for: %s\n", hostname); |
645 gaim_debug_info("dns", "DNS Lookup for: %s\n", hostname); |
| 643 td = g_new0(dns_tdata, 1); |
646 td = g_new0(dns_tdata, 1); |
| 644 td->hostname = g_strdup(hostname); |
647 td->hostname = g_strdup(hostname); |
| 649 if(!g_thread_create(dns_thread, td, FALSE, &err)) { |
652 if(!g_thread_create(dns_thread, td, FALSE, &err)) { |
| 650 gaim_debug_error("dns", "DNS thread create failure: %s\n", err?err->message:""); |
653 gaim_debug_error("dns", "DNS thread create failure: %s\n", err?err->message:""); |
| 651 g_error_free(err); |
654 g_error_free(err); |
| 652 g_free(td->hostname); |
655 g_free(td->hostname); |
| 653 g_free(td); |
656 g_free(td); |
| 654 return -1; |
657 return NULL; |
| 655 } |
658 } |
| 656 return 0; |
659 return (GaimDnsQueryData *)1; |
| 657 } |
660 } |
| 658 |
661 |
| 659 #else /* not __unix__ or __APPLE__ or _WIN32 */ |
662 #else /* not __unix__ or __APPLE__ or _WIN32 */ |
| 660 |
663 |
| 661 typedef struct { |
664 typedef struct { |
| 662 gpointer data; |
665 gpointer data; |
| 663 size_t addrlen; |
666 size_t addrlen; |
| 664 struct sockaddr *addr; |
667 struct sockaddr *addr; |
| 665 GaimProxyDnsConnectFunction callback; |
668 GaimDnsQueryConnectFunction callback; |
| 666 } pending_dns_request_t; |
669 } pending_dns_request_t; |
| 667 |
670 |
| 668 static gboolean host_resolved(gpointer data) |
671 static gboolean host_resolved(gpointer data) |
| 669 { |
672 { |
| 670 pending_dns_request_t *req = (pending_dns_request_t*)data; |
673 pending_dns_request_t *req = (pending_dns_request_t*)data; |
| 674 req->callback(hosts, req->data, NULL); |
677 req->callback(hosts, req->data, NULL); |
| 675 g_free(req); |
678 g_free(req); |
| 676 return FALSE; |
679 return FALSE; |
| 677 } |
680 } |
| 678 |
681 |
| 679 int |
682 GaimDnsQueryData * |
| 680 gaim_gethostbyname_async(const char *hostname, int port, |
683 gaim_dnsquery_a(const char *hostname, int port, |
| 681 GaimProxyDnsConnectFunction callback, gpointer data) |
684 GaimDnsQueryConnectFunction callback, gpointer data) |
| 682 { |
685 { |
| 683 struct sockaddr_in sin; |
686 struct sockaddr_in sin; |
| 684 pending_dns_request_t *req; |
687 pending_dns_request_t *req; |
| 685 |
688 |
| 686 if (!inet_aton(hostname, &sin.sin_addr)) { |
689 if (!inet_aton(hostname, &sin.sin_addr)) { |
| 687 struct hostent *hp; |
690 struct hostent *hp; |
| 688 if(!(hp = gethostbyname(hostname))) { |
691 if(!(hp = gethostbyname(hostname))) { |
| 689 gaim_debug_error("dns", |
692 gaim_debug_error("dns", |
| 690 "gaim_gethostbyname(\"%s\", %d) failed: %d\n", |
693 "gaim_gethostbyname(\"%s\", %d) failed: %d\n", |
| 691 hostname, port, h_errno); |
694 hostname, port, h_errno); |
| 692 return -1; |
695 return NULL; |
| 693 } |
696 } |
| 694 memset(&sin, 0, sizeof(struct sockaddr_in)); |
697 memset(&sin, 0, sizeof(struct sockaddr_in)); |
| 695 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); |
698 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); |
| 696 sin.sin_family = hp->h_addrtype; |
699 sin.sin_family = hp->h_addrtype; |
| 697 } else |
700 } else |
| 702 req->addr = (struct sockaddr*) g_memdup(&sin, sizeof(sin)); |
705 req->addr = (struct sockaddr*) g_memdup(&sin, sizeof(sin)); |
| 703 req->addrlen = sizeof(sin); |
706 req->addrlen = sizeof(sin); |
| 704 req->data = data; |
707 req->data = data; |
| 705 req->callback = callback; |
708 req->callback = callback; |
| 706 gaim_timeout_add(10, host_resolved, req); |
709 gaim_timeout_add(10, host_resolved, req); |
| 707 return 0; |
710 return (GaimDnsQueryData *)1; |
| 708 } |
711 } |
| 709 |
712 |
| 710 #endif /* not __unix__ or __APPLE__ or _WIN32 */ |
713 #endif /* not __unix__ or __APPLE__ or _WIN32 */ |