char *
ldap_host_connected_to( Sockbuf *sb )
{
- struct hostent *hp;
socklen_t len;
#ifdef LDAP_PF_INET6
struct sockaddr_storage sabuf;
struct sockaddr sabuf;
#endif
struct sockaddr *sa = (struct sockaddr *) &sabuf;
- char *addr;
- char *host;
-
- /* buffers for gethostbyaddr_r */
- struct hostent he_buf;
- int local_h_errno;
- char *ha_buf=NULL;
+ char *host = NULL, *herr;
+ char hbuf[NI_MAXHOST];
+ int rc;
ber_socket_t sd;
(void)memset( (char *)sa, '\0', sizeof sabuf );
#endif
#ifdef LDAP_PF_INET6
case AF_INET6:
- addr = (char *) &((struct sockaddr_in6 *)sa)->sin6_addr;
- len = sizeof( struct in6_addr );
+ {
+ struct in6_addr localhost = IN6ADDR_LOOPBACK_INIT;
+ if( memcmp ( &((struct sockaddr_in6 *)sa)->sin6_addr,
+ &localhost, sizeof(localhost)) == 0 )
+ {
+ return LDAP_STRDUP( ldap_int_hostname );
+ }
+ }
break;
#endif
case AF_INET:
- addr = (char *) &((struct sockaddr_in *)sa)->sin_addr;
- len = sizeof( struct in_addr );
-
{
- struct sockaddr_in localhost;
- localhost.sin_addr.s_addr = htonl( INADDR_ANY );
+ struct in_addr localhost;
+ localhost.s_addr = htonl( INADDR_ANY );
- if( memcmp ( &localhost.sin_addr,
- &((struct sockaddr_in *)sa)->sin_addr,
- sizeof(localhost.sin_addr) ) == 0 )
+ if( memcmp ( &((struct sockaddr_in *)sa)->sin_addr,
+ &localhost, sizeof(localhost) ) == 0 )
{
return LDAP_STRDUP( ldap_int_hostname );
}
#ifdef INADDR_LOOPBACK
- localhost.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
+ localhost.s_addr = htonl( INADDR_LOOPBACK );
- if( memcmp ( &localhost.sin_addr,
- &((struct sockaddr_in *)sa)->sin_addr,
- sizeof(localhost.sin_addr) ) == 0 )
+ if( memcmp ( &((struct sockaddr_in *)sa)->sin_addr,
+ &localhost, sizeof(localhost) ) == 0 )
{
return LDAP_STRDUP( ldap_int_hostname );
}
break;
}
- host = NULL;
- if ((ldap_pvt_gethostbyaddr_a( addr, len, sa->sa_family,
- &he_buf, &ha_buf, &hp, &local_h_errno ) == 0 ) &&
- (hp != NULL) && ( hp->h_name != NULL ) )
+ hbuf[0] = 0;
+ if (ldap_pvt_get_hname( sa, len, hbuf, sizeof(hbuf), &herr ) == 0 &&
+ hbuf[0] )
{
- host = LDAP_STRDUP( hp->h_name );
+ host = LDAP_STRDUP( hbuf );
}
- LDAP_FREE( ha_buf );
return host;
}
#endif
return -1;
#endif
}
-
+
+#ifndef GETNAMEINFO
+static const char *
+hp_strerror( int err )
+{
+ switch (err) {
+ case HOST_NOT_FOUND: return "Host not found (authoritative)";
+ case TRY_AGAIN: return "Host not found (server fail?)";
+ case NO_RECOVERY: return "Non-recoverable failure";
+ case NO_DATA: return "No data of requested type";
+#ifdef NETDB_INTERNAL
+ case NETDB_INTERNAL: return STRERROR( errno );
+#endif
+ default: break;
+ }
+ return "Unknown resolver error";
+}
+#endif
+
+int ldap_pvt_get_hname(
+ const struct sockaddr *sa,
+ int len,
+ char *name,
+ int namelen,
+ char **err )
+{
+ int rc;
+#if defined( HAVE_GETNAMEINFO )
+
+#if defined( LDAP_R_COMPILE )
+ ldap_pvt_thread_mutex_lock( &ldap_int_resolv_mutex );
+#endif
+ rc = getnameinfo( sa, len, name, namelen, NULL, 0, 0 );
+#if defined( LDAP_R_COMPILE )
+ ldap_pvt_thread_mutex_unlock( &ldap_int_resolv_mutex );
+#endif
+ if ( rc ) *err = AC_GAI_STRERROR( rc );
+ return rc;
+
+#else /* !HAVE_GETNAMEINFO */
+ char *addr;
+ int alen;
+ struct hostent *hp = NULL;
+#ifdef HAVE_GETHOSTBYADDR_R
+ struct hostent hb;
+ int buflen=BUFSTART, h_errno;
+ char *buf=NULL;
+#endif
+
+#ifdef LDAP_PF_INET6
+ if (sa->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
+ addr = (char *)&sin->sin6_addr;
+ alen = sizeof(sin->sin6_addr);
+ } else
+#endif
+ if (sa->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ addr = (char *)&sin->sin_addr;
+ alen = sizeof(sin->sin_addr);
+ } else {
+ rc = NO_RECOVERY;
+ *err = hp_strerror( rc );
+ return rc;
+ }
+#if defined( HAVE_GETHOSTBYADDR_R )
+ for(;buflen<BUFMAX;) {
+ if (safe_realloc( &buf, buflen )==NULL) {
+ *err = STRERROR( ENOMEM );
+ return ENOMEM;
+ }
+#if (GETHOSTBYADDR_R_NARGS < 8)
+ hp=gethostbyaddr_r( addr, alen, sa->sa_family,
+ &hb, buf, buflen, &h_errno );
+ rc = (hp == NULL) ? -1 : 0;
+#else
+ rc = gethostbyaddr_r( addr, alen, sa->sa_family,
+ &hb, buf, buflen,
+ &hp, &h_errno );
+#endif
+#ifdef NETDB_INTERNAL
+ if ((rc<0) &&
+ (h_errno==NETDB_INTERNAL) &&
+ (errno==ERANGE))
+ {
+ buflen*=2;
+ continue;
+ }
+#endif
+ break;
+ }
+ if (hp) {
+ strncpy( name, hp->h_name, namelen );
+ } else {
+ *err = hp_strerror( h_errno );
+ }
+ LDAP_FREE(buf);
+#else /* HAVE_GETHOSTBYADDR_R */
+
+#if defined( LDAP_R_COMPILE )
+ ldap_pvt_thread_mutex_lock( &ldap_int_resolv_mutex );
+#endif
+ hp = gethostbyaddr( addr, alen, sa->sa_family );
+ if (hp) {
+ strncpy( name, hp->h_name, namelen );
+ rc = 0;
+ } else {
+ rc = h_errno;
+ *err = hp_strerror( h_errno );
+ }
+#if defined( LDAP_R_COMPILE )
+ ldap_pvt_thread_mutex_unlock( &ldap_int_resolv_mutex );
+#endif
+
+#endif /* !HAVE_GETHOSTBYADDR_R */
+ return rc;
+#endif /* !HAVE_GETNAMEINFO */
+}
+
int ldap_pvt_gethostbyaddr_a(
const char *addr,
int len,