void TokenAwarePolicy::init(const SharedRefPtr<Host>& connected_host, const HostMap& hosts, Random* random) { if (random != NULL) { index_ = random->next(std::max(static_cast<size_t>(1), hosts.size())); } ChainedLoadBalancingPolicy::init(connected_host, hosts, random); }
int DNS::connect( const std::string& domain, const LogSink& logInstance ) { HostMap hosts = resolve( domain ); if( hosts.size() == 0 ) return -DNS_NO_HOSTS_FOUND; struct protoent* prot; if( ( prot = getprotobyname( "tcp" ) ) == 0) return -DNS_COULD_NOT_RESOLVE; int fd; if( ( fd = socket( PF_INET, SOCK_STREAM, prot->p_proto ) ) == -1 ) return -DNS_COULD_NOT_RESOLVE; struct hostent *h; struct sockaddr_in target; target.sin_family = AF_INET; int ret = 0; HostMap::const_iterator it = hosts.begin(); for( ; it != hosts.end(); ++it ) { int port; if( (*it).second == 0 ) port = XMPP_PORT; else port = (*it).second; target.sin_port = htons( port ); if( ( h = gethostbyname( (*it).first.c_str() ) ) == 0 ) { ret = -DNS_COULD_NOT_RESOLVE; continue; } in_addr *addr = (in_addr*)malloc( sizeof( in_addr ) ); memcpy( addr, h->h_addr, sizeof( in_addr ) ); char *tmp = inet_ntoa( *addr ); free( addr ); std::ostringstream oss; oss << "resolved " << (*it).first.c_str() << " to: " << tmp << ":" << port; logInstance.log( LogLevelDebug, LogAreaClassDns, oss.str() ); if( inet_aton( tmp, &(target.sin_addr) ) == 0 ) continue; memset( target.sin_zero, '\0', 8 ); if( ::connect( fd, (struct sockaddr *)&target, sizeof( struct sockaddr ) ) == 0 ) return fd; close( fd ); } if( ret ) return ret; return -DNS_COULD_NOT_CONNECT; }
void LatencyAwarePolicy::init(const Host::Ptr& connected_host, const HostMap& hosts, Random* random) { hosts_->reserve(hosts.size()); std::transform(hosts.begin(), hosts.end(), std::back_inserter(*hosts_), GetHost()); for (HostMap::const_iterator i = hosts.begin(), end = hosts.end(); i != end; ++i) { i->second->enable_latency_tracking(settings_.scale_ns, settings_.min_measured); } ChainedLoadBalancingPolicy::init(connected_host, hosts, random); }
int DNS::connect( const std::string& host, const LogSink& logInstance ) { HostMap hosts = resolve( host, logInstance ); if( hosts.size() == 0 ) return -ConnDnsError; HostMap::const_iterator it = hosts.begin(); for( ; it != hosts.end(); ++it ) { int fd = DNS::connect( (*it).first, (*it).second, logInstance ); if( fd >= 0 ) return fd; } return -ConnConnectionRefused; }
DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto, const std::string& domain, const LogSink& logInstance ) { buffer srvbuf; bool error = false; const std::string dname = "_" + service + "._" + proto; if( !domain.empty() ) srvbuf.len = res_querydomain( dname.c_str(), const_cast<char*>( domain.c_str() ), C_IN, T_SRV, srvbuf.buf, NS_PACKETSZ ); else srvbuf.len = res_query( dname.c_str(), C_IN, T_SRV, srvbuf.buf, NS_PACKETSZ ); if( srvbuf.len < 0 ) return defaultHostMap( domain, logInstance ); HEADER* hdr = (HEADER*)srvbuf.buf; unsigned char* here = srvbuf.buf + NS_HFIXEDSZ; if( srvbuf.len < NS_HFIXEDSZ ) error = true; if( hdr->rcode >= 1 && hdr->rcode <= 5 ) error = true; if( ntohs( hdr->ancount ) == 0 ) error = true; if( ntohs( hdr->ancount ) > NS_PACKETSZ ) error = true; int cnt; for( cnt = ntohs( hdr->qdcount ); cnt > 0; --cnt ) { int strlen = dn_skipname( here, srvbuf.buf + srvbuf.len ); here += strlen + NS_QFIXEDSZ; } unsigned char* srv[NS_PACKETSZ]; int srvnum = 0; for( cnt = ntohs( hdr->ancount ); cnt > 0; --cnt ) { int strlen = dn_skipname( here, srvbuf.buf + srvbuf.len ); here += strlen; srv[srvnum++] = here; here += SRV_FIXEDSZ; here += dn_skipname( here, srvbuf.buf + srvbuf.len ); } if( error ) { return defaultHostMap( domain, logInstance ); } // (q)sort here HostMap servers; for( cnt = 0; cnt < srvnum; ++cnt ) { char srvname[NS_MAXDNAME]; srvname[0] = '\0'; if( dn_expand( srvbuf.buf, srvbuf.buf + NS_PACKETSZ, srv[cnt] + SRV_SERVER, srvname, NS_MAXDNAME ) < 0 || !(*srvname) ) continue; unsigned char* c = srv[cnt] + SRV_PORT; servers.insert( std::make_pair( (char*)srvname, ntohs( c[1] << 8 | c[0] ) ) ); } if( !servers.size() ) return defaultHostMap( domain, logInstance ); return servers; }