int DNS::connect( const std::string& domain, const LogSink& logInstance ) { logInstance.log( LogLevelWarning, LogAreaClassDns, "note: gloox does not support SRV records on this platform." ); return DNS::connect( domain, XMPP_PORT, logInstance ); }
int DNS::connect( const std::string& domain, int port, const LogSink& logInstance ) { #ifdef WIN32 WSADATA wsaData; if( WSAStartup( MAKEWORD( 1, 1 ), &wsaData ) != 0 ) return -DNS_COULD_NOT_RESOLVE; #endif struct protoent* prot; if( ( prot = getprotobyname( "tcp" ) ) == 0 ) { cleanup(); return -DNS_COULD_NOT_RESOLVE; } int fd; if( ( fd = socket( PF_INET, SOCK_STREAM, prot->p_proto ) ) == -1 ) { cleanup(); return -DNS_COULD_NOT_CONNECT; } struct hostent *h; if( ( h = gethostbyname( domain.c_str() ) ) == 0 ) { cleanup(); return -DNS_COULD_NOT_RESOLVE; } struct sockaddr_in target; target.sin_family = AF_INET; target.sin_port = htons( port ); if( h->h_length != sizeof( struct in_addr ) ) { cleanup(); return -DNS_COULD_NOT_RESOLVE; } else { memcpy( &target.sin_addr, h->h_addr, sizeof( struct in_addr ) ); } std::ostringstream oss; oss << "resolved " << domain.c_str() << " to: " << inet_ntoa( target.sin_addr ); logInstance.log( LogLevelDebug, LogAreaClassDns, oss.str() ); memset( target.sin_zero, '\0', 8 ); if( ::connect( fd, (struct sockaddr *)&target, sizeof( struct sockaddr ) ) == 0 ) return fd; #ifndef WIN32 close( fd ); #else closesocket( fd ); cleanup(); #endif return -DNS_COULD_NOT_CONNECT; }
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; }