mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-05 13:40:08 +08:00
Add 1st libldap IPv6 patch (ITS#594) from Stig Venass.
Copyright 2000 Stig Venaas, UNINETT All rights reserved. Redistribution and use in source and binary forms are permitted without restriction or fee of any kind as long as this notice is preserved. The name of UNINETT may not be used to endorse or promote products derived from this software without specific prior written permission. This software is provided ``as is'' without express or implied warranty.
This commit is contained in:
parent
73b9ffc3e5
commit
ac659e20d3
@ -95,9 +95,9 @@ ldap_pvt_ndelay_off(LDAP *ld, int fd)
|
||||
}
|
||||
|
||||
static ber_socket_t
|
||||
ldap_pvt_socket(LDAP *ld)
|
||||
ldap_pvt_socket(LDAP *ld, int family)
|
||||
{
|
||||
ber_socket_t s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
ber_socket_t s = socket(family, SOCK_STREAM, 0);
|
||||
osip_debug(ld, "ldap_new_socket: %d\n",s,0,0);
|
||||
return ( s );
|
||||
}
|
||||
@ -183,7 +183,7 @@ ldap_pvt_is_socket_ready(LDAP *ld, int s)
|
||||
#undef TRACE
|
||||
|
||||
static int
|
||||
ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_in *sin, int async)
|
||||
ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr *sin, socklen_t addrlen, int async)
|
||||
{
|
||||
struct timeval tv, *opt_tv=NULL;
|
||||
fd_set wfds, *z=NULL;
|
||||
@ -202,7 +202,7 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_in *sin, int async)
|
||||
if ( ldap_pvt_ndelay_on(ld, s) == -1 )
|
||||
return ( -1 );
|
||||
|
||||
if ( connect(s, (struct sockaddr *) sin, sizeof(struct sockaddr_in)) == 0 )
|
||||
if ( connect(s, sin, addrlen) == 0 )
|
||||
{
|
||||
if ( ldap_pvt_ndelay_off(ld, s) == -1 )
|
||||
return ( -1 );
|
||||
@ -289,13 +289,61 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
|
||||
osip_debug(ld, "ldap_connect_to_host\n",0,0,0);
|
||||
|
||||
if (host != NULL) {
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
char serv[7];
|
||||
struct addrinfo hints, *res, *sai;
|
||||
|
||||
memset( &hints, '\0', sizeof(hints) );
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
snprintf(serv, sizeof serv, "%d", ntohs(port));
|
||||
if ( getaddrinfo(host, serv, &hints, &res) ) {
|
||||
osip_debug(ld, "ldap_connect_to_host:getaddrinfo failed\n",0,0,0);
|
||||
return -1;
|
||||
}
|
||||
sai = res;
|
||||
rc = -1;
|
||||
do {
|
||||
s = ldap_pvt_socket( ld, sai->ai_family, ld );
|
||||
if ( s == -1 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (sai->ai_family) {
|
||||
#ifdef LDAP_PF_INET6
|
||||
case AF_INET6: {
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
inet_ntop( AF_INET6,
|
||||
&((struct sockaddr_in6 *)sai->ai_addr)->sin6_addr,
|
||||
addr, sizeof addr);
|
||||
osip_debug(ld, "ldap_connect_to_host: Trying %s %s\n",
|
||||
addr, serv, 0);
|
||||
} break;
|
||||
#endif
|
||||
case AF_INET: {
|
||||
char addr[INET_ADDRSTRLEN];
|
||||
inet_ntop( AF_INET,
|
||||
&((struct sockaddr_in *)sai->ai_addr)->sin_addr,
|
||||
addr, sizeof addr);
|
||||
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);
|
||||
} while ((sai = sai->ai_next) != NULL);
|
||||
freeaddrinfo(res);
|
||||
return rc;
|
||||
#else
|
||||
if (! inet_aton( host, &in) ) {
|
||||
rc = ldap_pvt_gethostbyname_a(host, &he_buf, &ha_buf,
|
||||
&hp, &local_h_errno);
|
||||
|
||||
if ( rc < 0 )
|
||||
; /*XXX NO MEMORY? */
|
||||
|
||||
if ( (rc < 0) || (hp == NULL) ) {
|
||||
#ifdef HAVE_WINSOCK
|
||||
ldap_pvt_set_errno( WSAGetLastError() );
|
||||
@ -309,14 +357,17 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
|
||||
use_hp = 1;
|
||||
}
|
||||
address = in.s_addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
rc = s = -1;
|
||||
for ( i = 0; !use_hp || (hp->h_addr_list[i] != 0); ++i, rc = -1 ) {
|
||||
|
||||
if ( (s = ldap_pvt_socket( ld )) == -1 )
|
||||
s = ldap_pvt_socket( ld, AF_INET );
|
||||
if ( s == -1 ) {
|
||||
/* use_hp ? continue : break; */
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ldap_pvt_prepare_socket(ld, s) == -1 ) {
|
||||
ldap_pvt_close_socket(ld, s);
|
||||
@ -334,7 +385,7 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
|
||||
osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n",
|
||||
inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),0);
|
||||
|
||||
rc = ldap_pvt_connect(ld, s, &sin, async);
|
||||
rc = ldap_pvt_connect(ld, s, (struct sockaddr *)&sin, sizeof(struct sockaddr_in), async);
|
||||
|
||||
if ( (rc == 0) || (rc == -2) ) {
|
||||
ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
|
||||
@ -356,7 +407,8 @@ ldap_host_connected_to( Sockbuf *sb )
|
||||
{
|
||||
struct hostent *hp;
|
||||
socklen_t len;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr sa;
|
||||
char *addr;
|
||||
|
||||
/* buffers for gethostbyaddr_r */
|
||||
struct hostent he_buf;
|
||||
@ -365,11 +417,11 @@ ldap_host_connected_to( Sockbuf *sb )
|
||||
ber_socket_t sd;
|
||||
#define DO_RETURN(x) if (ha_buf) LDAP_FREE(ha_buf); return (x);
|
||||
|
||||
(void)memset( (char *)&sin, '\0', sizeof( struct sockaddr_in ));
|
||||
len = sizeof( sin );
|
||||
(void)memset( (char *)&sa, '\0', sizeof( struct sockaddr ));
|
||||
len = sizeof( sa );
|
||||
|
||||
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
|
||||
if ( getpeername( sd, (struct sockaddr *)&sin, &len ) == -1 ) {
|
||||
if ( getpeername( sd, (struct sockaddr *)&sa, &len ) == -1 ) {
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
@ -378,9 +430,24 @@ ldap_host_connected_to( Sockbuf *sb )
|
||||
* this is necessary for kerberos to work right, since the official
|
||||
* hostname is used as the kerberos instance.
|
||||
*/
|
||||
if ((ldap_pvt_gethostbyaddr_a( (char *) &sin.sin_addr,
|
||||
sizeof( sin.sin_addr ),
|
||||
AF_INET, &he_buf, &ha_buf,
|
||||
|
||||
switch (sa.sa_family) {
|
||||
#ifdef LDAP_PF_INET6
|
||||
case AF_INET6:
|
||||
addr = (char *) &((struct sockaddr_in6 *)&sa)->sin6_addr;
|
||||
len = sizeof( struct in6_addr );
|
||||
break;
|
||||
#endif
|
||||
case AF_INET:
|
||||
addr = (char *) &((struct sockaddr_in *)&sa)->sin_addr;
|
||||
len = sizeof( struct in_addr );
|
||||
break;
|
||||
default:
|
||||
return( NULL );
|
||||
break;
|
||||
}
|
||||
if ((ldap_pvt_gethostbyaddr_a( addr, len,
|
||||
sa.sa_family, &he_buf, &ha_buf,
|
||||
&hp,&local_h_errno ) ==0 ) && (hp != NULL) )
|
||||
{
|
||||
if ( hp->h_name != NULL ) {
|
||||
|
Loading…
Reference in New Issue
Block a user