// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "proxy_resolver_js_bindings.h" #include "proxy_resolver_v8.h" #include <arpa/inet.h> #include <netdb.h> #include <unistd.h> #include <cstddef> #include <memory> #include <string> #include "net_util.h" namespace net { // ProxyResolverJSBindings implementation. class DefaultJSBindings : public ProxyResolverJSBindings { public: DefaultJSBindings() { } // Handler for "myIpAddress()". // TODO: Perhaps enumerate the interfaces directly, using // getifaddrs(). virtual bool MyIpAddress(std::string* first_ip_address) { return MyIpAddressImpl(first_ip_address); } // Handler for "myIpAddressEx()". virtual bool MyIpAddressEx(std::string* ip_address_list) { return MyIpAddressExImpl(ip_address_list); } // Handler for "dnsResolve(host)". virtual bool DnsResolve(const std::string& host, std::string* first_ip_address) { return DnsResolveImpl(host, first_ip_address); } // Handler for "dnsResolveEx(host)". virtual bool DnsResolveEx(const std::string& host, std::string* ip_address_list) { return DnsResolveExImpl(host, ip_address_list); } private: bool MyIpAddressImpl(std::string* first_ip_address) { std::string my_hostname = GetHostName(); if (my_hostname.empty()) return false; return DnsResolveImpl(my_hostname, first_ip_address); } bool MyIpAddressExImpl(std::string* ip_address_list) { std::string my_hostname = GetHostName(); if (my_hostname.empty()) return false; return DnsResolveExImpl(my_hostname, ip_address_list); } bool DnsResolveImpl(const std::string& host, std::string* first_ip_address) { struct hostent* he = gethostbyname(host.c_str()); if (he == NULL || he->h_addr == NULL || he->h_addrtype != AF_INET) { return false; } char tmp[INET_ADDRSTRLEN]; if (inet_ntop(he->h_addrtype, he->h_addr, tmp, sizeof(tmp)) == NULL) { return false; } *first_ip_address = std::string(tmp); return true; } bool DnsResolveExImpl(const std::string& host, std::string* ip_address_list) { struct hostent* he = gethostbyname(host.c_str()); if (he == NULL) { return false; } std::string address_list_str; for (char** addr = &he->h_addr; *addr != NULL; ++addr) { if (!address_list_str.empty()) address_list_str += ";"; const std::string address_string = std::string(*addr); if (address_string.empty()) return false; address_list_str += address_string; } *ip_address_list = std::string(he->h_addr); return true; } std::string GetHostName() { char buffer[256]; if (gethostname(buffer, 256) != 0) { buffer[0] = '\0'; } return std::string(buffer); } }; // static ProxyResolverJSBindings* ProxyResolverJSBindings::CreateDefault() { return new DefaultJSBindings(); } } // namespace net