15 # include "../config.h.win"
16 #elif defined( _WIN32_WCE )
17 # include "../config.h.win"
26 # include <sys/types.h>
32 #if !defined( _WIN32 ) && !defined( _WIN32_WCE )
33 # include <netinet/in.h>
34 # include <arpa/nameser.h>
37 # include <arpa/inet.h>
38 # include <sys/socket.h>
45 #elif defined( _WIN32_WCE )
46 # include <winsock2.h>
53 #define SRV_COST (RRFIXEDSZ+0)
54 #define SRV_WEIGHT (RRFIXEDSZ+2)
55 #define SRV_PORT (RRFIXEDSZ+4)
56 #define SRV_SERVER (RRFIXEDSZ+6)
57 #define SRV_FIXEDSZ (RRFIXEDSZ+6)
65 # define DNS_TYPE_SRV 33
72 #ifndef INVALID_SOCKET
73 # define INVALID_SOCKET -1
76 #define XMPP_PORT 5222
81 #if defined( HAVE_RES_QUERYDOMAIN ) && defined( HAVE_DN_SKIPNAME ) && defined( HAVE_RES_QUERY )
83 const std::string& domain,
const LogSink& logInstance )
88 const std::string dname =
"_" + service +
"._" + proto;
91 srvbuf.len = res_querydomain( dname.c_str(),
const_cast<char*
>( domain.c_str() ),
92 C_IN, T_SRV, srvbuf.buf, NS_PACKETSZ );
94 srvbuf.len = res_query( dname.c_str(), C_IN, T_SRV, srvbuf.buf, NS_PACKETSZ );
97 return defaultHostMap( domain, logInstance );
99 HEADER* hdr = (HEADER*)srvbuf.buf;
100 unsigned char* here = srvbuf.buf + NS_HFIXEDSZ;
102 if( ( hdr->tc ) || ( srvbuf.len < NS_HFIXEDSZ ) )
105 if( hdr->rcode >= 1 && hdr->rcode <= 5 )
108 if( ntohs( hdr->ancount ) == 0 )
111 if( ntohs( hdr->ancount ) > NS_PACKETSZ )
115 for( cnt = ntohs( hdr->qdcount ); cnt>0; --cnt )
117 int strlen = dn_skipname( here, srvbuf.buf + srvbuf.len );
118 here += strlen + NS_QFIXEDSZ;
121 unsigned char *srv[NS_PACKETSZ];
123 for( cnt = ntohs( hdr->ancount ); cnt>0; --cnt )
125 int strlen = dn_skipname( here, srvbuf.buf + srvbuf.len );
127 srv[srvnum++] = here;
129 here += dn_skipname( here, srvbuf.buf + srvbuf.len );
134 return defaultHostMap( domain, logInstance );
140 for( cnt=0; cnt<srvnum; ++cnt )
144 if( ns_name_ntop( srv[cnt] + SRV_SERVER, (
char*)srvname, NS_MAXDNAME ) < 0 )
145 printf(
"handle this error!\n" );
147 unsigned char* c = srv[cnt] + SRV_PORT;
149 servers.insert( std::make_pair( (
char*)srvname, ntohs( c[1] << 8 | c[0] ) ) );
155 #elif defined( _WIN32 ) && defined( HAVE_WINDNS_H )
157 const std::string& domain,
const LogSink& logInstance )
159 const std::string dname =
"_" + service +
"._" + proto +
"." + domain;
164 if( DnsQuery( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL ) == ERROR_SUCCESS )
166 DNS_RECORD *pRec = pRecord;
169 if( pRec->wType == DNS_TYPE_SRV )
171 servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort;
175 while( pRec != NULL );
176 DnsRecordListFree( pRecord, DnsFreeRecordList );
181 if( error || !servers.size() )
183 servers = defaultHostMap( domain, logInstance );
191 const std::string& domain,
const LogSink& logInstance )
194 "notice: gloox does not support SRV records on this platform. Using A records instead." );
195 return defaultHostMap( domain, logInstance );
204 +
", using default port." );
206 if( !domain.empty() )
207 server[domain] = XMPP_PORT;
215 if( hosts.size() == 0 )
218 HostMap::const_iterator it = hosts.begin();
219 for( ; it != hosts.end(); ++it )
221 int fd =
DNS::connect( (*it).first, (*it).second, logInstance );
233 if( WSAStartup( MAKEWORD( 1, 1 ), &wsaData ) != 0 )
237 struct protoent* prot;
238 if( ( prot = getprotobyname(
"tcp" ) ) == 0 )
245 if( ( fd = socket( PF_INET, SOCK_STREAM, prot->p_proto ) ) == INVALID_SOCKET )
251 #ifdef HAVE_SETSOCKOPT
253 setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (
char*)&val,
sizeof( val ) );
266 if( ( h = gethostbyname( domain.c_str() ) ) == 0 )
272 struct sockaddr_in target;
273 target.sin_family = AF_INET;
274 target.sin_port = htons( port );
276 if( h->h_length !=
sizeof(
struct in_addr ) )
283 memcpy( &target.sin_addr, h->h_addr,
sizeof(
struct in_addr ) );
287 std::ostringstream oss;
290 memset( target.sin_zero,
'\0', 8 );
291 if( ::
connect( fd, (
struct sockaddr *)&target,
sizeof(
struct sockaddr ) ) == 0 )
294 oss <<
"connecting to " << domain.c_str()
295 <<
" (" << inet_ntoa( target.sin_addr ) <<
":" << port <<
")";
302 oss <<
"connection to " << domain.c_str()
303 <<
" (" << inet_ntoa( target.sin_addr ) <<
":" << port <<
") failed";