Beispiel #1
0
static void
host_resolved(gpointer data, gint source, PurpleInputCondition cond)
{
	PurpleDnsQueryData *query_data;
	int rc, err;
	GSList *hosts = NULL;
	struct sockaddr *addr = NULL;
	size_t addrlen;
	char message[1024];

	query_data = data;

	purple_debug_info("dns", "Got response for '%s'\n", query_data->hostname);
	purple_input_remove(query_data->resolver->inpa);
	query_data->resolver->inpa = 0;

	rc = read(query_data->resolver->fd_out, &err, sizeof(err));
	if ((rc == 4) && (err != 0))
	{
#ifdef HAVE_GETADDRINFO
		g_snprintf(message, sizeof(message), _("Error resolving %s:\n%s"),
				query_data->hostname, purple_gai_strerror(err));
#else
		g_snprintf(message, sizeof(message), _("Error resolving %s: %d"),
				query_data->hostname, err);
#endif
		/* Re-read resolv.conf and friends in case DNS servers have changed */
		res_init();

		purple_dnsquery_failed(query_data, message);
	} else if (rc > 0) {
		/* Success! */
		while (rc > 0) {
			rc = read(query_data->resolver->fd_out, &addrlen, sizeof(addrlen));
			if (rc > 0 && addrlen > 0 && addrlen < MAX_ADDR_RESPONSE_LEN) {
				addr = g_malloc(addrlen);
				rc = read(query_data->resolver->fd_out, addr, addrlen);
				hosts = g_slist_append(hosts, GINT_TO_POINTER(addrlen));
				hosts = g_slist_append(hosts, addr);
			} else {
				break;
			}
		}
		/*	wait4(resolver->dns_pid, NULL, WNOHANG, NULL); */
		purple_dnsquery_resolved(query_data, hosts);

	} else if (rc == -1) {
		g_snprintf(message, sizeof(message), _("Error reading from resolver process:\n%s"), g_strerror(errno));
		purple_dnsquery_failed(query_data, message);

	} else if (rc == 0) {
		g_snprintf(message, sizeof(message), _("Resolver process exited without answering our request"));
		purple_dnsquery_failed(query_data, message);
	}

	handle_next_queued_request();
}
Beispiel #2
0
static gboolean
resolve_ip(PurpleDnsQueryData *query_data)
{
#if defined(HAVE_GETADDRINFO) && defined(AI_NUMERICHOST)
	struct addrinfo hints, *res;
	char servname[20];

	g_snprintf(servname, sizeof(servname), "%d", query_data->port);
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_flags |= AI_NUMERICHOST;

	if (0 == getaddrinfo(query_data->hostname, servname, &hints, &res))
	{
		GSList *hosts = NULL;
		hosts = g_slist_append(hosts, GINT_TO_POINTER(res->ai_addrlen));
		hosts = g_slist_append(hosts, g_memdup(res->ai_addr, res->ai_addrlen));
		purple_dnsquery_resolved(query_data, hosts);

		freeaddrinfo(res);
		return TRUE;
	}
#else /* defined(HAVE_GETADDRINFO) && defined(AI_NUMERICHOST) */
	struct sockaddr_in sin;
	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);

		return TRUE;
	}
#endif

	return FALSE;
}
Beispiel #3
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;
}
Beispiel #4
0
static void
resolve_host(PurpleDnsQueryData *query_data)
{
	struct sockaddr_in sin;
	GSList *hosts = NULL;
	struct hostent *hp;
	gchar *hostname;
#ifdef USE_IDN
	if (!dns_str_is_ascii(query_data->hostname)) {
		int ret = purple_network_convert_idn_to_ascii(query_data->hostname,
				&hostname);
		if (ret != 0) {
			char message[1024];
			g_snprintf(message, sizeof(message), _("Error resolving %s: %d"),
					query_data->hostname, ret);
			purple_dnsquery_failed(query_data, message);
			return;
		}
	} else /* fallthrough is intentional to the g_strdup */
#endif
	hostname = g_strdup(query_data->hostname);

	if(!(hp = gethostbyname(hostname))) {
		char message[1024];
		g_snprintf(message, sizeof(message), _("Error resolving %s: %d"),
				query_data->hostname, h_errno);
		purple_dnsquery_failed(query_data, message);
		g_free(hostname);
		return;
	}
	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;
	g_free(hostname);
	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);
}
Beispiel #5
0
static gboolean
dns_main_thread_cb(gpointer data)
{
	PurpleDnsQueryData *query_data;

	query_data = data;

	if (query_data->error_message != NULL)
		purple_dnsquery_failed(query_data, query_data->error_message);
	else
	{
		GSList *hosts;

		/* We don't want purple_dns_query_resolved() to free(hosts) */
		hosts = query_data->hosts;
		query_data->hosts = NULL;
		purple_dnsquery_resolved(query_data, hosts);
	}

	return FALSE;
}
Beispiel #6
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;
}
Beispiel #7
0
static gboolean
dns_main_thread_cb(gpointer data)
{
	PurpleDnsQueryData *query_data = data;

	/* We're done, so purple_dnsquery_destroy() shouldn't think it is canceling an in-progress lookup */
	query_data->resolver = NULL;

	if (query_data->error_message != NULL)
		purple_dnsquery_failed(query_data, query_data->error_message);
	else
	{
		GSList *hosts;

		/* We don't want purple_dns_query_resolved() to free(hosts) */
		hosts = query_data->hosts;
		query_data->hosts = NULL;
		purple_dnsquery_resolved(query_data, hosts);
	}

	return FALSE;
}