]> git.sur5r.net Git - openldap/commitdiff
Added ldap_pvt_get_hname. Use instead of ldap_pvt_gethostbyaddr_a when
authorHoward Chu <hyc@openldap.org>
Wed, 5 Mar 2003 01:35:39 +0000 (01:35 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 5 Mar 2003 01:35:39 +0000 (01:35 +0000)
all you want is the hostname. Supports IPv6 addresses.

libraries/libldap/os-ip.c
libraries/libldap/util-int.c

index fc705e9f3320c52d345d2eecd6f7aecabd1daf8a..738e97f930ed903ef16a9dce65a04476d669ce7e 100644 (file)
@@ -499,7 +499,6 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
 char *
 ldap_host_connected_to( Sockbuf *sb )
 {
-       struct hostent  *hp;
        socklen_t               len;
 #ifdef LDAP_PF_INET6
        struct sockaddr_storage sabuf;
@@ -507,13 +506,9 @@ ldap_host_connected_to( Sockbuf *sb )
        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 );
@@ -537,31 +532,32 @@ ldap_host_connected_to( Sockbuf *sb )
 #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 );
                        }
@@ -574,15 +570,13 @@ ldap_host_connected_to( Sockbuf *sb )
                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
index 59c3db48156f14dee6b5bdbad71c12dd9497f70a..6d5886d3654428fb43797175e33f7438d09f514a 100644 (file)
@@ -178,7 +178,125 @@ int ldap_pvt_gethostbyname_a(
        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,