Пример #1
0
static gboolean resolve_ip(ResolverData *data) {
	PurpleDnsQueryData *query_data = (PurpleDnsQueryData *) data->query_data;
	struct sockaddr_in sin;
	if (inet_aton(purple_dnsquery_get_host(query_data), &sin.sin_addr)) {
		// The given "hostname" is actually an IP address, so we don't need to do anything.
		Log("DNSResolver", "Resolving " << purple_dnsquery_get_host(query_data) << ": It's IP, don't do anything.");
		GSList *hosts = NULL;
		sin.sin_family = AF_INET;
		sin.sin_port = htons(purple_dnsquery_get_port(query_data));
		hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin)));
		hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin)));
		data->resolved_cb(query_data, hosts);
		delete data;
		return TRUE;
	}

	return FALSE;
}
Пример #2
0
nsresult purpleDNSRequest::OnLookupComplete(nsICancelable *request,
                                            nsIDNSRecord *record,
                                            nsresult status)
{
  NS_ASSERTION(NS_IsMainThread(), "wrong thread");
  NS_ASSERTION(request == asyncResolv, "wrong request");

  purpleAccountScoper scoper(mAccountId);

  if (NS_FAILED(status)) {
    Failed("DNS query failed\n");
    return NS_OK;
  }

  GSList *hosts = NULL;
  bool more;
  record->HasMore(&more);
  if (!more) {
    Failed("Not found\n");
    return NS_OK;
  }

  if (NS_FAILED(purpleDNS::Remove(query_data))) {
    LOG(("DNS resolution completed but result discarded because it was cancelled"));
    return NS_OK;
  }

  mozilla::net::NetAddr netAddr;
  for (; more; record->HasMore(&more))
  {
    unsigned short port = purple_dnsquery_get_port(query_data);
    if (NS_FAILED(record->GetNextAddr(port, &netAddr))) {
      Failed("GetNextAddr failed\n");
      return NS_OK;
    }

    socklen_t addrlen;
    struct sockaddr *addr;

    if (netAddr.raw.family == AF_INET) {
      addrlen = sizeof(struct sockaddr_in);
      struct sockaddr_in *s_in = (struct sockaddr_in *)g_malloc0(addrlen);
      s_in->sin_port = netAddr.inet.port;
      memcpy(&s_in->sin_addr, &netAddr.inet.ip, sizeof(netAddr.inet.ip));
      addr = (struct sockaddr *)s_in;
      LOG(("Found ip v4 address"));
    }
    else if (netAddr.raw.family == AF_INET6) {
      addrlen = sizeof(struct sockaddr_in6);
      struct sockaddr_in6 *s_in6 = (struct sockaddr_in6 *)g_malloc0(addrlen);
      s_in6->sin6_port = netAddr.inet6.port;
      s_in6->sin6_flowinfo = netAddr.inet6.flowinfo;
      memcpy(&s_in6->sin6_addr, &netAddr.inet6.ip, sizeof(netAddr.inet6.ip.u8));
      s_in6->sin6_scope_id = netAddr.inet6.scope_id;
      addr = (struct sockaddr *)s_in6;
      LOG(("Found ip v6 address"));
    }
#ifndef XP_WIN
    else if (netAddr.raw.family == AF_LOCAL) {
      addrlen = sizeof(struct sockaddr_un);
      struct sockaddr_un *s_un = (struct sockaddr_un *)g_malloc0(addrlen);
      memcpy(&s_un->sun_path, netAddr.local.path, sizeof(netAddr.local.path));
      addr = (struct sockaddr *)s_un;
      LOG(("Found local address"));
    }
#endif
    else {
      NS_NOTREACHED("Unknown address type...");
      continue;
    }

    addr->sa_family = netAddr.raw.family;

    hosts = g_slist_append(hosts, GINT_TO_POINTER(addrlen));
    hosts = g_slist_append(hosts, addr);
  }
  LOG(("DNS resolution done"));
  resolved_cb(query_data, hosts);
  return NS_OK;
}
Пример #3
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;
}