Ejemplo n.º 1
0
String NameConfig::getHostName(bool prefer_loopback) {
    // try to pick a good host identifier

    ConstString result = "127.0.0.1";
    bool loopback = true;

    // Pick an IPv4 address.
    // Prefer non-local addresses, then shorter addresses.
    // Avoid IPv6.
#ifdef YARP_HAS_ACE
    ACE_INET_Addr *ips = NULL;
    size_t count = 0;
    if (ACE::get_ip_interfaces(count,ips)>=0) {
        for (size_t i=0; i<count; i++) {
            ConstString ip = ips[i].get_host_addr();
#else
    int family, s;
    char hostname[NI_MAXHOST]; hostname[NI_MAXHOST-1] = '\0';
    ConstString ip;
    struct ifaddrs *ifaddr, *ifa;
    if (getifaddrs(&ifaddr) == -1) {
    	perror("getifaddrs in getIps");
    	exit(EXIT_FAILURE);
    }
    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    	if (ifa->ifa_addr == NULL) continue;
    	family = ifa->ifa_addr->sa_family;
    	if (family == AF_INET || family == AF_INET6) {
    		s = getnameinfo(ifa->ifa_addr,
    				(family == AF_INET) ? sizeof(struct sockaddr_in) :
    						sizeof(struct sockaddr_in6),
    						hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
    		if (s != 0) {
    			printf("getnameinfo() failed: %s\n", gai_strerror(s));
    			exit(EXIT_FAILURE);
    		}
    		ip = ConstString(hostname);
#endif

            YARP_DEBUG(Logger::get(), String("scanning network interface ") +
                       ip.c_str());
            bool take = prefer_loopback;
            if (ip.find(":")!=ConstString::npos) continue;
            if (!take) {
                if (result=="localhost") {
                    take = true; // can't be worse
                }
                if (loopback) {
                    take = true; // can't be worse
                } else if (ip.length()<result.length()) {
                    take = true;
                }
            }
            if (take) {
                if (!prefer_loopback) result = ip;
                loopback = false;
                if (ip == "127.0.0.1" || ip == "127.1.0.1" ||
                    ip == "127.0.1.1") {
                    loopback = true;
                }
#ifdef YARP_HAS_ACE
#ifdef YARP_ACE_ADDR_HAS_LOOPBACK_METHOD
                loopback = ips[i].is_loopback();
#endif
#endif

                if (prefer_loopback && loopback) {
                    result = ip;
                }
            }
        }
#ifdef YARP_HAS_ACE
        delete[] ips;
#endif
    }

    return result.c_str();
}


bool NameConfig::isLocalName(const String& name) {
    bool result = false;

#ifdef YARP_HAS_ACE
    ACE_INET_Addr *ips = NULL;
    size_t count = 0;
    if (ACE::get_ip_interfaces(count,ips)>=0) {
        for (size_t i=0; i<count; i++) {
            String ip = ips[i].get_host_addr();
            if (ip==name) {
                result = true;
                break;
            }
        }
        delete[] ips;
    }
#else
    /**
     * If this does not work properly, use a more sophisticated way
     * instead of just gethostname.
     */
    char hostname[NI_MAXHOST]; hostname[NI_MAXHOST-1] = '\0';
    gethostname(hostname, NI_MAXHOST);
    if (strcmp(hostname, name.c_str()) == 0) result = true;
#endif

    // just in case
    if (name=="localhost"||name=="127.0.0.1") { result = true; }

    return result;
}

yarp::os::Bottle NameConfig::getIpsAsBottle() {
    yarp::os::Bottle result;

#ifdef YARP_HAS_ACE
    ACE_INET_Addr *ips = NULL;
    size_t count = 0;
    if (ACE::get_ip_interfaces(count,ips)>=0) {
        for (size_t i=0; i<count; i++) {
            String ip = ips[i].get_host_addr();
            result.addString(ip.c_str());
        }
        delete[] ips;
    }
#else
   int family, s;
    char host[NI_MAXHOST];
    struct ifaddrs *ifaddr, *ifa;
    if (getifaddrs(&ifaddr) == -1) {
    	perror("getifaddrs in getIpsAsBottle");
    	exit(EXIT_FAILURE);
    }
    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    	if (ifa->ifa_addr == NULL) continue;
    	family = ifa->ifa_addr->sa_family;
    	if (family == AF_INET || family == AF_INET6) {
    		s = getnameinfo(ifa->ifa_addr,
    				(family == AF_INET) ? sizeof(struct sockaddr_in) :
    						sizeof(struct sockaddr_in6),
    						host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
    		if (s != 0) {
    			printf("getnameinfo() failed: %s\n", gai_strerror(s));
    			exit(EXIT_FAILURE);
    		}
    		result.addString(host);
    	}
    }
#endif

    return result;
}


String NameConfig::getIps() {
    yarp::os::Bottle bot = getIpsAsBottle();
    ConstString result = "";
    for (int i=0; i<bot.size(); i++) {
        ConstString ip = bot.get(i).asString();
        if (i>0) {
            result += " ";
        }
        result += ip;
    }
    return result.c_str();
}



void NameConfig::setAddress(const Address& address) {
    this->address = address;
}


void NameConfig::setNamespace(const String& ns) {
    space = ns;
}

String NameConfig::getNamespace(bool refresh) {
    if (space==""||refresh) {
        ConstString senv = NetworkBase::getEnvironment("YARP_NAMESPACE");
        if (senv!="") {
            spaces.fromString(senv.c_str());
        } else {
            String fname = getConfigFileName(YARP_CONFIG_NAMESPACE_FILENAME);
            spaces.fromString(readConfig(fname).c_str());
        }
        space = spaces.get(0).asString().c_str();
        if (space=="") {
            space = "/root";
        }
        if (spaces.size()==0) {
            spaces.addString("/root");
        }
    }
    return space;
}

Bottle NameConfig::getNamespaces(bool refresh) {
    getNamespace(refresh);
    return spaces;
}