Exemplo n.º 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();
}
Exemplo n.º 2
0
static gpointer dns_thread(gpointer d) {
	ResolverData *data = (ResolverData *) d;
	PurpleDnsQueryData *query_data;
// #ifdef HAVE_GETADDRINFO
	int rc;
	struct addrinfo hints, *res, *tmp;
	char servname[20];
// #else
// 	struct sockaddr_in sin;
// 	struct hostent *hp;
// #endif
	char *hostname;

	query_data = data->query_data;

// Currently we don't support IDN

// #ifdef USE_IDN
// 	if (!dns_str_is_ascii(purple_dnsquery_get_host(query_data))) {
// 		rc = purple_network_convert_idn_to_ascii(purple_dnsquery_get_host(query_data), &hostname);
// 		if (rc != 0) {
// 			data->error_message = g_strdup_printf(_("Error converting %s "
// 					"to punycode: %d"), purple_dnsquery_get_host(query_data), rc);
// 			/* back to main thread */
// 			purple_timeout_add(0, dns_main_thread_cb, query_data);
// 			return 0;
// 		}
// 	} else /* intentional fallthru */
// #endif
	hostname = g_strdup(purple_dnsquery_get_host(query_data));

// #ifdef HAVE_GETADDRINFO
	g_snprintf(servname, sizeof(servname), "%d", purple_dnsquery_get_port(query_data));
	memset(&hints,0,sizeof(hints));

	/*
	 * This is only used to convert a service
	 * name to a port number. As we know we are
	 * passing a number already, we know this
	 * value will not be really used by the C
	 * library.
	 */
	hints.ai_socktype = SOCK_STREAM;
// #ifdef AI_ADDRCONFIG
// 	hints.ai_flags |= AI_ADDRCONFIG;
// #endif /* AI_ADDRCONFIG */
	if ((rc = getaddrinfo(hostname, servname, &hints, &res)) == 0) {
		tmp = res;
		while(res) {
			data->hosts = g_slist_append(data->hosts,
				GSIZE_TO_POINTER(res->ai_addrlen));
			data->hosts = g_slist_append(data->hosts,
				g_memdup(res->ai_addr, res->ai_addrlen));
			res = res->ai_next;
		}
		freeaddrinfo(tmp);
	} else {
		g_mutex_lock(data->mutex);
		bool destroyed = data->destroyed;
		g_mutex_unlock(data->mutex);
		if (!destroyed) {
			data->error_message = g_strdup_printf("Error resolving %s:\n%s", purple_dnsquery_get_host(query_data), purple_gai_strerror(rc));
		}
	}
// #else
// 	if ((hp = gethostbyname(hostname))) {
// 		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;
// 		sin.sin_port = htons(purple_dnsquery_get_port(query_data));
// 
// 		data->hosts = g_slist_append(data->hosts,
// 				GSIZE_TO_POINTER(sizeof(sin)));
// 		data->hosts = g_slist_append(data->hosts,
// 				g_memdup(&sin, sizeof(sin)));
// 	} else {
// 		data->error_message = g_strdup_printf("Error resolving %s: %d", purple_dnsquery_get_host(query_data), h_errno);
// 	}
// #endif
	g_free(hostname);

	/* back to main thread */
	purple_timeout_add(0, dns_main_thread_cb, data);

	return 0;
}
Exemplo n.º 3
0
static gpointer
dns_thread(gpointer data)
{
	PurpleDnsQueryData *query_data;
#ifdef HAVE_GETADDRINFO
	int rc;
	struct addrinfo hints, *res, *tmp;
	char servname[20];
#else
	struct sockaddr_in sin;
	struct hostent *hp;
#endif
	char *hostname;

	query_data = data;

#ifdef USE_IDN
	if (!dns_str_is_ascii(query_data->hostname)) {
		rc = purple_network_convert_idn_to_ascii(query_data->hostname, &hostname);
		if (rc != 0) {
			query_data->error_message = g_strdup_printf(_("Error converting %s "
					"to punycode: %d"), query_data->hostname, rc);
			/* back to main thread */
			purple_timeout_add(0, dns_main_thread_cb, query_data);
			return 0;
		}
	} else /* intentional fallthru */
#endif
	hostname = g_strdup(query_data->hostname);

#ifdef HAVE_GETADDRINFO
	g_snprintf(servname, sizeof(servname), "%d", query_data->port);
	memset(&hints,0,sizeof(hints));

	/*
	 * This is only used to convert a service
	 * name to a port number. As we know we are
	 * passing a number already, we know this
	 * value will not be really used by the C
	 * library.
	 */
	hints.ai_socktype = SOCK_STREAM;
#ifdef AI_ADDRCONFIG
	hints.ai_flags |= AI_ADDRCONFIG;
#endif /* AI_ADDRCONFIG */
	if ((rc = getaddrinfo(hostname, servname, &hints, &res)) == 0) {
		tmp = res;
		while(res) {
			query_data->hosts = g_slist_append(query_data->hosts,
				GSIZE_TO_POINTER(res->ai_addrlen));
			query_data->hosts = g_slist_append(query_data->hosts,
				g_memdup(res->ai_addr, res->ai_addrlen));
			res = res->ai_next;
		}
		freeaddrinfo(tmp);
	} else {
		query_data->error_message = g_strdup_printf(_("Error resolving %s:\n%s"), query_data->hostname, purple_gai_strerror(rc));
	}
#else
	if ((hp = gethostbyname(hostname))) {
		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;
		sin.sin_port = htons(query_data->port);

		query_data->hosts = g_slist_append(query_data->hosts,
				GSIZE_TO_POINTER(sizeof(sin)));
		query_data->hosts = g_slist_append(query_data->hosts,
				g_memdup(&sin, sizeof(sin)));
	} else {
		query_data->error_message = g_strdup_printf(_("Error resolving %s: %d"), query_data->hostname, h_errno);
	}
#endif
	g_free(hostname);

	/* back to main thread */
	purple_timeout_add(0, dns_main_thread_cb, query_data);

	return 0;
}