示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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);
}