X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fos-ip.c;h=57195918db1ef1a4f12fa1161cd68ada0155658a;hb=afa2cd1893875266c58677cc640514c1d9eef41f;hp=5e4391178a735f74eecbd35d969ee034c4fe966d;hpb=ca5aa3b615e5b521c30625a81195d103e6fb67f7;p=openldap diff --git a/libraries/libldap/os-ip.c b/libraries/libldap/os-ip.c index 5e4391178a..57195918db 100644 --- a/libraries/libldap/os-ip.c +++ b/libraries/libldap/os-ip.c @@ -1,6 +1,6 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* Portions @@ -52,11 +52,19 @@ int ldap_int_inet4or6 = AF_INET; * ftp://koobera.math.uic.edu/www/docs/connect.html. */ +#ifdef LDAP_DEBUG + #define osip_debug(ld,fmt,arg1,arg2,arg3) \ do { \ ldap_log_printf(NULL, LDAP_DEBUG_TRACE, fmt, arg1, arg2, arg3); \ } while(0) +#else + +#define osip_debug(ld,fmt,arg1,arg2,arg3) ((void)0) + +#endif /* LDAP_DEBUG */ + static void ldap_pvt_set_errno(int err) { @@ -322,67 +330,88 @@ ldap_pvt_inet_aton( const char *host, struct in_addr *in) int ldap_connect_to_host(LDAP *ld, Sockbuf *sb, int proto, - const char *host, - unsigned long address, int port, int async ) + const char *host, int port, + int async ) { + int rc; + int socktype; ber_socket_t s = AC_SOCKET_INVALID; - int rc, i, use_hp = 0; - struct hostent *hp = NULL; - char *ha_buf=NULL, *p, *q; - int socktype; +#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) + char serv[7]; + int err; + struct addrinfo hints, *res, *sai; +#else + int i; + int use_hp = 0; + struct hostent *hp = NULL; + struct hostent he_buf; + struct in_addr in; + char *ha_buf=NULL; +#endif + + if( host == NULL ) host = "localhost"; switch(proto) { case LDAP_PROTO_TCP: socktype = SOCK_STREAM; - osip_debug(ld, "ldap_connect_to_host: TCP %s:%d\n",host,port,0); + osip_debug( ld, + "ldap_connect_to_host: TCP %s:%d\n", + host, port, 0); break; case LDAP_PROTO_UDP: socktype = SOCK_DGRAM; - osip_debug(ld, "ldap_connect_to_host: TCP %s:%d\n",host,port,0); + osip_debug( ld, + "ldap_connect_to_host: UDP %s:%d\n", + host, port, 0); break; - default: - osip_debug(ld, "ldap_connect_to_host: unknown proto: %d\n", - proto, 0, 0); + osip_debug( ld, "ldap_connect_to_host: unknown proto: %d\n", + proto, 0, 0 ); return -1; } - if (host != NULL) { #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) - char serv[7]; - int err; - struct addrinfo hints, *res, *sai; - - memset( &hints, '\0', sizeof(hints) ); - hints.ai_family = ldap_int_inet4or6; - hints.ai_socktype = socktype; - - snprintf(serv, sizeof serv, "%d", port ); - if ( ( err = getaddrinfo(host, serv, &hints, &res) ) ) { - osip_debug(ld, "ldap_connect_to_host: getaddrinfo failed: %s\n", - AC_GAI_STRERROR(err), 0, 0); - return -1; - } - rc = -1; + memset( &hints, '\0', sizeof(hints) ); + hints.ai_family = ldap_int_inet4or6; + hints.ai_socktype = socktype; + snprintf(serv, sizeof serv, "%d", port ); + +#ifdef LDAP_R_COMPILE + /* most getaddrinfo(3) use non-threadsafe resolver libraries */ + ldap_pvt_thread_mutex_lock(&ldap_int_resolv_mutex); +#endif - for( sai=res; sai != NULL; sai=sai->ai_next) { - if( sai->ai_addr == NULL ) { - osip_debug(ld, "ldap_connect_to_host: getaddrinfo " - "ai_addr is NULL?\n", 0, 0, 0); - continue; - } + err = getaddrinfo( host, serv, &hints, &res ); - /* we assume AF_x and PF_x are equal for all x */ - s = ldap_int_socket( ld, sai->ai_family, socktype ); - if ( s == AC_SOCKET_INVALID ) { - continue; - } +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_unlock(&ldap_int_resolv_mutex); +#endif - if ( ldap_int_prepare_socket(ld, s, proto ) == -1 ) { - ldap_pvt_close_socket(ld, s); - break; - } + if ( err != 0 ) { + osip_debug(ld, "ldap_connect_to_host: getaddrinfo failed: %s\n", + AC_GAI_STRERROR(err), 0, 0); + return -1; + } + rc = -1; - switch (sai->ai_family) { + for( sai=res; sai != NULL; sai=sai->ai_next) { + if( sai->ai_addr == NULL ) { + osip_debug(ld, "ldap_connect_to_host: getaddrinfo " + "ai_addr is NULL?\n", 0, 0, 0); + continue; + } + + /* we assume AF_x and PF_x are equal for all x */ + s = ldap_int_socket( ld, sai->ai_family, socktype ); + if ( s == AC_SOCKET_INVALID ) { + continue; + } + + if ( ldap_int_prepare_socket(ld, s, proto ) == -1 ) { + ldap_pvt_close_socket(ld, s); + break; + } + + switch (sai->ai_family) { #ifdef LDAP_PF_INET6 case AF_INET6: { char addr[INET6_ADDRSTRLEN]; @@ -401,40 +430,36 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, osip_debug(ld, "ldap_connect_to_host: Trying %s:%s\n", addr, serv, 0); } break; - } + } - rc = ldap_pvt_connect(ld, s, sai->ai_addr, sai->ai_addrlen, async); - if ( (rc == 0) || (rc == -2) ) { - ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s ); - break; - } - ldap_pvt_close_socket(ld, s); + rc = ldap_pvt_connect( ld, s, + sai->ai_addr, sai->ai_addrlen, async ); + if ( (rc == 0) || (rc == -2) ) { + ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s ); + break; } - freeaddrinfo(res); - return rc; + ldap_pvt_close_socket(ld, s); + } + freeaddrinfo(res); #else - struct in_addr in; - if (! inet_aton( host, &in) ) { - int local_h_errno; - struct hostent he_buf; - rc = ldap_pvt_gethostbyname_a(host, &he_buf, &ha_buf, - &hp, &local_h_errno); - - if ( (rc < 0) || (hp == NULL) ) { + if (! inet_aton( host, &in ) ) { + int local_h_errno; + rc = ldap_pvt_gethostbyname_a( host, &he_buf, &ha_buf, + &hp, &local_h_errno ); + + if ( (rc < 0) || (hp == NULL) ) { #ifdef HAVE_WINSOCK - ldap_pvt_set_errno( WSAGetLastError() ); + ldap_pvt_set_errno( WSAGetLastError() ); #else - /* not exactly right, but... */ - ldap_pvt_set_errno( EHOSTUNREACH ); + /* not exactly right, but... */ + ldap_pvt_set_errno( EHOSTUNREACH ); #endif - if (ha_buf) LDAP_FREE(ha_buf); - return -1; - } - use_hp = 1; + if (ha_buf) LDAP_FREE(ha_buf); + return -1; } - address = in.s_addr; -#endif + + use_hp = 1; } rc = s = -1; @@ -455,15 +480,20 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, (void)memset((char *)&sin, '\0', sizeof sin); sin.sin_family = AF_INET; sin.sin_port = htons((short) port); - p = (char *)&sin.sin_addr; - q = use_hp ? (char *)hp->h_addr_list[i] : (char *)&address; - AC_MEMCPY(p, q, sizeof(sin.sin_addr) ); + + if( use_hp ) { + AC_MEMCPY( &sin.sin_addr, hp->h_addr_list[i], + sizeof(sin.sin_addr) ); + } else { + AC_MEMCPY( &sin.sin_addr, &in.s_addr, + sizeof(sin.sin_addr) ); + } osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n", - inet_ntoa(sin.sin_addr),port,0); + inet_ntoa(sin.sin_addr), port, 0); rc = ldap_pvt_connect(ld, s, - (struct sockaddr *)&sin, sizeof(struct sockaddr_in), + (struct sockaddr *)&sin, sizeof(sin), async); if ( (rc == 0) || (rc == -2) ) { @@ -473,19 +503,19 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, ldap_pvt_close_socket(ld, s); - if (!use_hp) - break; + if (!use_hp) break; } if (ha_buf) LDAP_FREE(ha_buf); +#endif + return rc; } #if defined( LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND ) || \ defined( HAVE_CYRUS_SASL ) char * -ldap_host_connected_to( Sockbuf *sb ) +ldap_host_connected_to( Sockbuf *sb, const char *host ) { - struct hostent *hp; socklen_t len; #ifdef LDAP_PF_INET6 struct sockaddr_storage sabuf; @@ -493,13 +523,7 @@ 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; + int rc; ber_socket_t sd; (void)memset( (char *)sa, '\0', sizeof sabuf ); @@ -523,31 +547,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 ); } @@ -560,16 +585,21 @@ 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 ) ) +#if 0 { - host = LDAP_STRDUP( hp->h_name ); + char *herr; + char hbuf[NI_MAXHOST]; + hbuf[0] = 0; + + if (ldap_pvt_get_hname( sa, len, hbuf, sizeof(hbuf), &herr ) == 0 + && hbuf[0] ) + { + return LDAP_STRDUP( hbuf ); + } } +#endif - LDAP_FREE( ha_buf ); - return host; + return host ? LDAP_STRDUP( host ) : NULL; } #endif