static gboolean initiate_resolving(gpointer data) { PurpleDnsQueryData *query_data; PurpleProxyType proxy_type; query_data = data; query_data->timeout = 0; if (resolve_ip(query_data)) /* resolve_ip calls purple_dnsquery_resolved */ return FALSE; proxy_type = purple_proxy_info_get_type( purple_proxy_get_setup(query_data->account)); if (proxy_type == PURPLE_PROXY_TOR) { purple_dnsquery_failed(query_data, _("Aborting DNS lookup in Tor Proxy mode.")); return FALSE; } if (purple_dnsquery_ui_resolve(query_data)) /* The UI is handling the resolve; we're done */ return FALSE; resolve_host(query_data); return FALSE; }
static gboolean resolve_host(gpointer data) { PurpleDnsQueryData *query_data; struct sockaddr_in sin; GError *err = NULL; query_data = data; query_data->timeout = 0; if (purple_dnsquery_ui_resolve(query_data)) { /* The UI is handling the resolve; we're done */ return FALSE; } if (inet_aton(query_data->hostname, &sin.sin_addr)) { /* * The given "hostname" is actually an IP address, so we * don't need to do anything. */ GSList *hosts = NULL; sin.sin_family = AF_INET; sin.sin_port = htons(query_data->port); hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin))); hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin))); purple_dnsquery_resolved(query_data, hosts); } else { /* * Spin off a separate thread to perform the DNS lookup so * that we don't block the UI. */ query_data->resolver = g_thread_create(dns_thread, query_data, FALSE, &err); if (query_data->resolver == NULL) { char message[1024]; g_snprintf(message, sizeof(message), _("Thread creation failure: %s"), (err && err->message) ? err->message : _("Unknown reason")); g_error_free(err); purple_dnsquery_failed(query_data, message); } } return FALSE; }
static gboolean resolve_host(gpointer data) { PurpleDnsQueryData *query_data; struct sockaddr_in sin; GSList *hosts = NULL; query_data = data; query_data->timeout = 0; if (purple_dnsquery_ui_resolve(query_data)) { /* The UI is handling the resolve; we're done */ return FALSE; } if (!inet_aton(query_data->hostname, &sin.sin_addr)) { struct hostent *hp; if(!(hp = gethostbyname(query_data->hostname))) { char message[1024]; g_snprintf(message, sizeof(message), _("Error resolving %s: %d"), query_data->hostname, h_errno); purple_dnsquery_failed(query_data, message); return FALSE; } memset(&sin, 0, sizeof(struct sockaddr_in)); memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); sin.sin_family = hp->h_addrtype; } else sin.sin_family = AF_INET; sin.sin_port = htons(query_data->port); hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin))); hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin))); purple_dnsquery_resolved(query_data, hosts); return FALSE; }
static void handle_next_queued_request() { PurpleDnsQueryData *query_data; PurpleDnsQueryResolverProcess *resolver; if (queued_requests == NULL) /* No more DNS queries, yay! */ return; query_data = queued_requests->data; queued_requests = g_slist_delete_link(queued_requests, queued_requests); if (purple_dnsquery_ui_resolve(query_data)) { /* The UI is handling the resolve; we're done */ handle_next_queued_request(); return; } /* * If we have any children, attempt to have them perform the DNS * query. If we're able to send the query then resolver will be * set to the PurpleDnsQueryResolverProcess. Otherwise, resolver * will be NULL and we'll need to create a new DNS request child. */ while (free_dns_children != NULL) { resolver = free_dns_children->data; free_dns_children = g_slist_remove(free_dns_children, resolver); if (send_dns_request_to_child(query_data, resolver)) /* We found an acceptable child, yay */ break; } /* We need to create a new DNS request child */ if (query_data->resolver == NULL) { if (number_of_dns_children >= MAX_DNS_CHILDREN) { /* Apparently all our children are busy */ queued_requests = g_slist_prepend(queued_requests, query_data); return; } resolver = purple_dnsquery_resolver_new(purple_debug_is_enabled()); if (resolver == NULL) { purple_dnsquery_failed(query_data, _("Unable to create new resolver process\n")); return; } if (!send_dns_request_to_child(query_data, resolver)) { purple_dnsquery_failed(query_data, _("Unable to send request to resolver process\n")); return; } } query_data->resolver->inpa = purple_input_add(query_data->resolver->fd_out, PURPLE_INPUT_READ, host_resolved, query_data); }