1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright (c) 1995-2001 by Sun Microsystems, Inc. 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate /* 9*0Sstevel@tonic-gate * Copyright (c) 1995 Regents of the University of Michigan. 10*0Sstevel@tonic-gate * All rights reserved. 11*0Sstevel@tonic-gate * 12*0Sstevel@tonic-gate * os-ip.c -- platform-specific TCP & UDP related code 13*0Sstevel@tonic-gate */ 14*0Sstevel@tonic-gate 15*0Sstevel@tonic-gate #ifndef lint 16*0Sstevel@tonic-gate static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n"; 17*0Sstevel@tonic-gate #endif 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gate #include <stdio.h> 20*0Sstevel@tonic-gate #include <string.h> 21*0Sstevel@tonic-gate #include <errno.h> 22*0Sstevel@tonic-gate #include <arpa/inet.h> 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate #ifdef _WIN32 25*0Sstevel@tonic-gate #include <io.h> 26*0Sstevel@tonic-gate #include "msdos.h" 27*0Sstevel@tonic-gate #else /* _WIN32 */ 28*0Sstevel@tonic-gate #include <sys/time.h> 29*0Sstevel@tonic-gate #include <sys/types.h> 30*0Sstevel@tonic-gate #include <sys/socket.h> 31*0Sstevel@tonic-gate #include <netinet/in.h> 32*0Sstevel@tonic-gate #include <netdb.h> 33*0Sstevel@tonic-gate #endif /* _WIN32 */ 34*0Sstevel@tonic-gate #ifdef _AIX 35*0Sstevel@tonic-gate #include <sys/select.h> 36*0Sstevel@tonic-gate #endif /* _AIX */ 37*0Sstevel@tonic-gate #ifdef VMS 38*0Sstevel@tonic-gate #include "ucx_select.h" 39*0Sstevel@tonic-gate #endif /* VMS */ 40*0Sstevel@tonic-gate #include "portable.h" 41*0Sstevel@tonic-gate #include "lber.h" 42*0Sstevel@tonic-gate #include "ldap.h" 43*0Sstevel@tonic-gate #include "ldap-private.h" 44*0Sstevel@tonic-gate #include "ldap-int.h" 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 47*0Sstevel@tonic-gate #ifdef USE_SYSCONF 48*0Sstevel@tonic-gate #include <unistd.h> 49*0Sstevel@tonic-gate #endif /* USE_SYSCONF */ 50*0Sstevel@tonic-gate #ifdef notyet 51*0Sstevel@tonic-gate #ifdef NEED_FILIO 52*0Sstevel@tonic-gate #include <sys/filio.h> 53*0Sstevel@tonic-gate #else /* NEED_FILIO */ 54*0Sstevel@tonic-gate #include <sys/ioctl.h> 55*0Sstevel@tonic-gate #endif /* NEED_FILIO */ 56*0Sstevel@tonic-gate #endif /* notyet */ 57*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #ifdef MACOS 60*0Sstevel@tonic-gate #define tcp_close(s) tcpclose(s) 61*0Sstevel@tonic-gate #else /* MACOS */ 62*0Sstevel@tonic-gate #ifdef DOS 63*0Sstevel@tonic-gate #ifdef PCNFS 64*0Sstevel@tonic-gate #define tcp_close(s) close(s) 65*0Sstevel@tonic-gate #endif /* PCNFS */ 66*0Sstevel@tonic-gate #ifdef NCSA 67*0Sstevel@tonic-gate #define tcp_close(s) netclose(s); netshut() 68*0Sstevel@tonic-gate #endif /* NCSA */ 69*0Sstevel@tonic-gate #ifdef WINSOCK 70*0Sstevel@tonic-gate #define tcp_close(s) closesocket(s); WSACleanup(); 71*0Sstevel@tonic-gate #endif /* WINSOCK */ 72*0Sstevel@tonic-gate #else /* DOS */ 73*0Sstevel@tonic-gate #define tcp_close(s) close(s) 74*0Sstevel@tonic-gate #endif /* DOS */ 75*0Sstevel@tonic-gate #endif /* MACOS */ 76*0Sstevel@tonic-gate #ifdef SUN 77*0Sstevel@tonic-gate #include <nss_dbdefs.h> 78*0Sstevel@tonic-gate #endif 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate #include <fcntl.h> 81*0Sstevel@tonic-gate #include <sys/poll.h> 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate /* 85*0Sstevel@tonic-gate * Do an async connect or blocking connect depending on the timeout 86*0Sstevel@tonic-gate * value. LDAP_X_IO_TIMEOUT_NO_TIMEOUT means do a blocking connect. 87*0Sstevel@tonic-gate * Otherwise wait for timeout milliseconds for the connection. 88*0Sstevel@tonic-gate * Returns 0 on success and -1 on failure. 89*0Sstevel@tonic-gate */ 90*0Sstevel@tonic-gate static int 91*0Sstevel@tonic-gate do_connect(int s, struct sockaddr *sin, int timeout) 92*0Sstevel@tonic-gate { 93*0Sstevel@tonic-gate int flags, connected = 0; 94*0Sstevel@tonic-gate int retval, error, n; 95*0Sstevel@tonic-gate fd_set wfds; 96*0Sstevel@tonic-gate struct timeval waittime, *sel_timeout; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate /* set the socket to do non-blocking i/o */ 99*0Sstevel@tonic-gate flags = fcntl(s, F_GETFL, 0); 100*0Sstevel@tonic-gate fcntl(s, F_SETFL, flags | O_NONBLOCK); 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate if (connect(s, sin, sizeof (struct sockaddr_in)) == 0) { 103*0Sstevel@tonic-gate connected = 1; 104*0Sstevel@tonic-gate } else if (errno == EINPROGRESS) { 105*0Sstevel@tonic-gate /* if NO_TIMEOUT is specified do a blocking connect */ 106*0Sstevel@tonic-gate if (timeout <= LDAP_X_IO_TIMEOUT_NO_TIMEOUT) { 107*0Sstevel@tonic-gate sel_timeout = NULL; 108*0Sstevel@tonic-gate } else { 109*0Sstevel@tonic-gate /* set the timeout to the specified value */ 110*0Sstevel@tonic-gate waittime.tv_sec = timeout / MILLISEC; 111*0Sstevel@tonic-gate waittime.tv_usec = (timeout % MILLISEC) * 1000; 112*0Sstevel@tonic-gate sel_timeout = &waittime; 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate FD_ZERO(&wfds); 116*0Sstevel@tonic-gate FD_SET(s, &wfds); 117*0Sstevel@tonic-gate n = sizeof (error); 118*0Sstevel@tonic-gate if (select(s+1, NULL, &wfds, NULL, sel_timeout) > 0 && 119*0Sstevel@tonic-gate FD_ISSET(s, &wfds) && 120*0Sstevel@tonic-gate getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &n) == 0 && 121*0Sstevel@tonic-gate error == 0) { 122*0Sstevel@tonic-gate connected = 1; 123*0Sstevel@tonic-gate } 124*0Sstevel@tonic-gate } 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate /* if we are connected restore the flags for the socket */ 127*0Sstevel@tonic-gate if (connected) { 128*0Sstevel@tonic-gate fcntl(s, F_SETFL, flags); 129*0Sstevel@tonic-gate } 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate return (connected ? 0 : -1); 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate int 136*0Sstevel@tonic-gate connect_to_host(Sockbuf *sb, char *host, in_addr_t address, 137*0Sstevel@tonic-gate int port, int async, int timeout) 138*0Sstevel@tonic-gate /* 139*0Sstevel@tonic-gate * if host == NULL, connect using address 140*0Sstevel@tonic-gate * "address" and "port" must be in network byte order 141*0Sstevel@tonic-gate * zero is returned upon success, -1 if fatal error, -2 EINPROGRESS 142*0Sstevel@tonic-gate * async is only used ifdef LDAP_REFERRALS (non-0 means don't wait for connect) 143*0Sstevel@tonic-gate * XXX async is not used yet! 144*0Sstevel@tonic-gate */ 145*0Sstevel@tonic-gate { 146*0Sstevel@tonic-gate int rc, i, s, connected, use_hp; 147*0Sstevel@tonic-gate struct sockaddr_in sin; 148*0Sstevel@tonic-gate struct hostent *hp; 149*0Sstevel@tonic-gate #ifdef notyet 150*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 151*0Sstevel@tonic-gate int status; /* for ioctl call */ 152*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 153*0Sstevel@tonic-gate #endif /* notyet */ 154*0Sstevel@tonic-gate #ifdef SUN 155*0Sstevel@tonic-gate struct hostent hpret; 156*0Sstevel@tonic-gate char hpbuf[NSS_BUFLEN_HOSTS]; 157*0Sstevel@tonic-gate int hperrno; 158*0Sstevel@tonic-gate #endif 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 201, "connect_to_host: " 161*0Sstevel@tonic-gate "%1$s:%2$d\n"), (host == NULL) ? catgets(slapdcat, 1, 202, 162*0Sstevel@tonic-gate "(by address)") : host, ntohs(port), 0); 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate connected = use_hp = 0; 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate if (host != NULL && (address = inet_addr(host)) == -1) { 167*0Sstevel@tonic-gate #ifdef SUN 168*0Sstevel@tonic-gate if ((hp = gethostbyname_r(host, &hpret, hpbuf, 169*0Sstevel@tonic-gate NSS_BUFLEN_HOSTS, &hperrno)) == NULL) { 170*0Sstevel@tonic-gate #else 171*0Sstevel@tonic-gate if ((hp = gethostbyname(host)) == NULL) { 172*0Sstevel@tonic-gate #endif 173*0Sstevel@tonic-gate errno = EHOSTUNREACH; /* not exactly right, but... */ 174*0Sstevel@tonic-gate return (-1); 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate use_hp = 1; 177*0Sstevel@tonic-gate } 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate rc = -1; 180*0Sstevel@tonic-gate for (i = 0; !use_hp || (hp->h_addr_list[i] != 0); i++) { 181*0Sstevel@tonic-gate if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 182*0Sstevel@tonic-gate return (-1); 183*0Sstevel@tonic-gate } 184*0Sstevel@tonic-gate #ifdef notyet 185*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 186*0Sstevel@tonic-gate status = 1; 187*0Sstevel@tonic-gate if (async && ioctl(s, FIONBIO, (caddr_t)&status) == -1) { 188*0Sstevel@tonic-gate Debug(LDAP_DEBUG_ANY, catgets(slapdcat, 1, 203, 189*0Sstevel@tonic-gate "FIONBIO ioctl failed on %d\n"), s, 0, 0); 190*0Sstevel@tonic-gate } 191*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 192*0Sstevel@tonic-gate #endif /* notyet */ 193*0Sstevel@tonic-gate (void) memset((char *)&sin, 0, sizeof (struct sockaddr_in)); 194*0Sstevel@tonic-gate sin.sin_family = AF_INET; 195*0Sstevel@tonic-gate sin.sin_port = port; 196*0Sstevel@tonic-gate SAFEMEMCPY((char *) &sin.sin_addr.s_addr, 197*0Sstevel@tonic-gate (use_hp ? (char *) hp->h_addr_list[i] : 198*0Sstevel@tonic-gate (char *)&address), sizeof (sin.sin_addr.s_addr)); 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate if (do_connect(s, (struct sockaddr *)&sin, timeout) == 0) { 201*0Sstevel@tonic-gate connected = 1; 202*0Sstevel@tonic-gate break; 203*0Sstevel@tonic-gate } 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate #ifdef notyet 206*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 207*0Sstevel@tonic-gate #ifdef EAGAIN 208*0Sstevel@tonic-gate if (errno == EINPROGRESS || errno == EAGAIN) { 209*0Sstevel@tonic-gate #else /* EAGAIN */ 210*0Sstevel@tonic-gate if (errno == EINPROGRESS) { 211*0Sstevel@tonic-gate #endif /* EAGAIN */ 212*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 204, 213*0Sstevel@tonic-gate "connect would block...\n"), 0, 0, 0); 214*0Sstevel@tonic-gate rc = -2; 215*0Sstevel@tonic-gate break; 216*0Sstevel@tonic-gate } 217*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 218*0Sstevel@tonic-gate #endif /* notyet */ 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate #ifdef LDAP_DEBUG 221*0Sstevel@tonic-gate if (ldap_debug & LDAP_DEBUG_TRACE) { 222*0Sstevel@tonic-gate perror((char *)inet_ntoa(sin.sin_addr)); 223*0Sstevel@tonic-gate } 224*0Sstevel@tonic-gate #endif 225*0Sstevel@tonic-gate close(s); 226*0Sstevel@tonic-gate if (!use_hp) { 227*0Sstevel@tonic-gate break; 228*0Sstevel@tonic-gate } 229*0Sstevel@tonic-gate } 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate if (connected) { 232*0Sstevel@tonic-gate rc = 0; 233*0Sstevel@tonic-gate sb->sb_sd = s; 234*0Sstevel@tonic-gate #ifdef notyet 235*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 236*0Sstevel@tonic-gate status = 0; 237*0Sstevel@tonic-gate if (!async && ioctl(s, FIONBIO, (caddr_t)&on) == -1) { 238*0Sstevel@tonic-gate Debug(LDAP_DEBUG_ANY, catgets(slapdcat, 1, 203, 239*0Sstevel@tonic-gate "FIONBIO ioctl failed on %d\n"), s, 0, 0); 240*0Sstevel@tonic-gate } 241*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 242*0Sstevel@tonic-gate #endif /* notyet */ 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 205, 245*0Sstevel@tonic-gate "sd %1$d connected to: %2$s\n"), s, 246*0Sstevel@tonic-gate inet_ntoa(sin.sin_addr), 0); 247*0Sstevel@tonic-gate } 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate return (rc); 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate void 254*0Sstevel@tonic-gate close_ldap_connection( Sockbuf *sb ) 255*0Sstevel@tonic-gate { 256*0Sstevel@tonic-gate #ifdef LDAP_SSL 257*0Sstevel@tonic-gate if (sb->sb_ssl){ 258*0Sstevel@tonic-gate SSL_close(sb->sb_ssl); 259*0Sstevel@tonic-gate SSL_delete(sb->sb_ssl); 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate sb->sb_ssl = NULL; 262*0Sstevel@tonic-gate sb->sb_ssl_tls = 0; 263*0Sstevel@tonic-gate #endif 264*0Sstevel@tonic-gate tcp_close( sb->sb_sd ); 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate #ifdef KERBEROS 269*0Sstevel@tonic-gate char * 270*0Sstevel@tonic-gate host_connected_to( Sockbuf *sb ) 271*0Sstevel@tonic-gate { 272*0Sstevel@tonic-gate struct hostent *hp; 273*0Sstevel@tonic-gate char *p; 274*0Sstevel@tonic-gate int len; 275*0Sstevel@tonic-gate struct sockaddr_in sin; 276*0Sstevel@tonic-gate #ifdef SUN 277*0Sstevel@tonic-gate struct hostent hpret; 278*0Sstevel@tonic-gate char hpbuf[NSS_BUFLEN_HOSTS]; 279*0Sstevel@tonic-gate int hperrno; 280*0Sstevel@tonic-gate #endif 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate (void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in )); 283*0Sstevel@tonic-gate len = sizeof( sin ); 284*0Sstevel@tonic-gate if ( getpeername( sb->sb_sd, (struct sockaddr *)&sin, &len ) == -1 ) { 285*0Sstevel@tonic-gate return( NULL ); 286*0Sstevel@tonic-gate } 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gate /* 289*0Sstevel@tonic-gate * do a reverse lookup on the addr to get the official hostname. 290*0Sstevel@tonic-gate * this is necessary for kerberos to work right, since the official 291*0Sstevel@tonic-gate * hostname is used as the kerberos instance. 292*0Sstevel@tonic-gate */ 293*0Sstevel@tonic-gate #ifdef SUN 294*0Sstevel@tonic-gate if (( hp = gethostbyaddr_r((char *) &sin.sin_addr, 295*0Sstevel@tonic-gate sizeof( sin.sin_addr ), AF_INET, 296*0Sstevel@tonic-gate &hpret, hpbuf, NSS_BUFLEN_HOSTS, &hperrno)) != NULL ) { 297*0Sstevel@tonic-gate #else 298*0Sstevel@tonic-gate if (( hp = gethostbyaddr( (char *) &sin.sin_addr, 299*0Sstevel@tonic-gate sizeof( sin.sin_addr ), AF_INET )) != NULL ) { 300*0Sstevel@tonic-gate #endif 301*0Sstevel@tonic-gate if ( hp->h_name != NULL ) { 302*0Sstevel@tonic-gate return( strdup( hp->h_name )); 303*0Sstevel@tonic-gate } 304*0Sstevel@tonic-gate } 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate return( NULL ); 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate #endif /* KERBEROS */ 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 312*0Sstevel@tonic-gate #ifdef SUN 313*0Sstevel@tonic-gate /* for UNIX */ 314*0Sstevel@tonic-gate #include <stropts.h> 315*0Sstevel@tonic-gate #include <poll.h> 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gate struct selectinfo { 318*0Sstevel@tonic-gate struct pollfd fds[LDAP_DEFAULT_REFHOPLIMIT]; 319*0Sstevel@tonic-gate int nbfds; 320*0Sstevel@tonic-gate }; 321*0Sstevel@tonic-gate 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate void 324*0Sstevel@tonic-gate mark_select_write( LDAP *ld, Sockbuf *sb ) 325*0Sstevel@tonic-gate { 326*0Sstevel@tonic-gate struct selectinfo *sip; 327*0Sstevel@tonic-gate int i; 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate /* find if sb is in fds */ 332*0Sstevel@tonic-gate for (i=0; i< sip->nbfds; i++) { 333*0Sstevel@tonic-gate if (sip->fds[i].fd == sb->sb_sd){ 334*0Sstevel@tonic-gate sip->fds[i].events |= POLLOUT; 335*0Sstevel@tonic-gate return; 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate if (sip->nbfds < LDAP_DEFAULT_REFHOPLIMIT) { 339*0Sstevel@tonic-gate sip->fds[sip->nbfds].fd = sb->sb_sd; 340*0Sstevel@tonic-gate sip->fds[sip->nbfds].events |= POLLOUT; 341*0Sstevel@tonic-gate sip->nbfds++; 342*0Sstevel@tonic-gate } 343*0Sstevel@tonic-gate else { 344*0Sstevel@tonic-gate /* Should not happen */ 345*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 206, "Mark for poll : Too many descriptors\n"), 0, 0, 0 ); 346*0Sstevel@tonic-gate } 347*0Sstevel@tonic-gate } 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate void 351*0Sstevel@tonic-gate mark_select_read( LDAP *ld, Sockbuf *sb ) 352*0Sstevel@tonic-gate { 353*0Sstevel@tonic-gate struct selectinfo *sip; 354*0Sstevel@tonic-gate int i; 355*0Sstevel@tonic-gate 356*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate /* find if sb is in fds */ 359*0Sstevel@tonic-gate for (i=0; i< sip->nbfds; i++) { 360*0Sstevel@tonic-gate if (sip->fds[i].fd == sb->sb_sd) { 361*0Sstevel@tonic-gate sip->fds[i].events |= POLLIN; 362*0Sstevel@tonic-gate return; 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate } 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate if (sip->nbfds < LDAP_DEFAULT_REFHOPLIMIT) { 367*0Sstevel@tonic-gate sip->fds[sip->nbfds].fd = sb->sb_sd; 368*0Sstevel@tonic-gate sip->fds[sip->nbfds].events |= POLLIN; 369*0Sstevel@tonic-gate sip->nbfds++; 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate else { 372*0Sstevel@tonic-gate /* Should not happen */ 373*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 206, "Mark for poll : Too many descriptors\n"), 0, 0, 0 ); 374*0Sstevel@tonic-gate } 375*0Sstevel@tonic-gate } 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate 378*0Sstevel@tonic-gate void 379*0Sstevel@tonic-gate mark_select_clear( LDAP *ld, Sockbuf *sb ) 380*0Sstevel@tonic-gate { 381*0Sstevel@tonic-gate struct selectinfo *sip; 382*0Sstevel@tonic-gate int i; 383*0Sstevel@tonic-gate 384*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 385*0Sstevel@tonic-gate 386*0Sstevel@tonic-gate for (i = 0; i< sip->nbfds; i++) { 387*0Sstevel@tonic-gate if (sip->fds[i].fd == sb->sb_sd){ 388*0Sstevel@tonic-gate i++; 389*0Sstevel@tonic-gate for (; i < sip->nbfds; i ++) { 390*0Sstevel@tonic-gate sip->fds[ i - 1] = sip->fds[i]; 391*0Sstevel@tonic-gate } 392*0Sstevel@tonic-gate sip->fds[i].fd = -1; 393*0Sstevel@tonic-gate sip->fds[i].events = -1; 394*0Sstevel@tonic-gate sip->nbfds--; 395*0Sstevel@tonic-gate return; 396*0Sstevel@tonic-gate } 397*0Sstevel@tonic-gate } 398*0Sstevel@tonic-gate /* If we reach here, there's a pb. */ 399*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 207, "Clear poll : descriptor not found\n"), 0, 0, 0 ); 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gate long 404*0Sstevel@tonic-gate is_write_ready( LDAP *ld, Sockbuf *sb ) 405*0Sstevel@tonic-gate { 406*0Sstevel@tonic-gate struct selectinfo *sip; 407*0Sstevel@tonic-gate int i; 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 410*0Sstevel@tonic-gate 411*0Sstevel@tonic-gate for (i=0; i< sip->nbfds; i++) { 412*0Sstevel@tonic-gate if (sip->fds[i].fd == sb->sb_sd) { 413*0Sstevel@tonic-gate if ( sip->fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) { 414*0Sstevel@tonic-gate return (-1); 415*0Sstevel@tonic-gate } 416*0Sstevel@tonic-gate return( sip->fds[i].revents & POLLOUT ); 417*0Sstevel@tonic-gate } 418*0Sstevel@tonic-gate } 419*0Sstevel@tonic-gate return(0); 420*0Sstevel@tonic-gate } 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate 423*0Sstevel@tonic-gate long 424*0Sstevel@tonic-gate is_read_ready( LDAP *ld, Sockbuf *sb ) 425*0Sstevel@tonic-gate { 426*0Sstevel@tonic-gate struct selectinfo *sip; 427*0Sstevel@tonic-gate int i; 428*0Sstevel@tonic-gate 429*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate for (i=0; i< sip->nbfds; i++) { 432*0Sstevel@tonic-gate if (sip->fds[i].fd == sb->sb_sd) { 433*0Sstevel@tonic-gate if (sip->fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) { 434*0Sstevel@tonic-gate return (-1); 435*0Sstevel@tonic-gate } 436*0Sstevel@tonic-gate return( sip->fds[i].revents & POLLIN ); 437*0Sstevel@tonic-gate } 438*0Sstevel@tonic-gate } 439*0Sstevel@tonic-gate return(0); 440*0Sstevel@tonic-gate } 441*0Sstevel@tonic-gate 442*0Sstevel@tonic-gate void * 443*0Sstevel@tonic-gate new_select_info() 444*0Sstevel@tonic-gate { 445*0Sstevel@tonic-gate struct selectinfo *sip; 446*0Sstevel@tonic-gate 447*0Sstevel@tonic-gate sip = (struct selectinfo *)calloc( 1, sizeof( struct selectinfo )); 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate return( (void *)sip ); 450*0Sstevel@tonic-gate } 451*0Sstevel@tonic-gate 452*0Sstevel@tonic-gate 453*0Sstevel@tonic-gate void 454*0Sstevel@tonic-gate free_select_info( void *sip ) 455*0Sstevel@tonic-gate { 456*0Sstevel@tonic-gate free( sip ); 457*0Sstevel@tonic-gate } 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate int 461*0Sstevel@tonic-gate do_ldap_select( LDAP *ld, struct timeval *timeout ) 462*0Sstevel@tonic-gate { 463*0Sstevel@tonic-gate struct selectinfo *sip; 464*0Sstevel@tonic-gate int tim; 465*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 466*0Sstevel@tonic-gate int rv; 467*0Sstevel@tonic-gate #endif 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 208, "do_ldap_select\n"), 0, 0, 0 ); 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 472*0Sstevel@tonic-gate 473*0Sstevel@tonic-gate /* sip->fds[0].revents = 0; */ 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate if ( timeout ) { 476*0Sstevel@tonic-gate tim = (timeout->tv_sec*1000)+(timeout->tv_usec/1000); 477*0Sstevel@tonic-gate } else { 478*0Sstevel@tonic-gate tim = INFTIM; 479*0Sstevel@tonic-gate } /* end if */ 480*0Sstevel@tonic-gate errno=0; 481*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 482*0Sstevel@tonic-gate /* UNLOCK_LDAP(ld); */ 483*0Sstevel@tonic-gate LOCK_POLL(ld); 484*0Sstevel@tonic-gate rv = poll(sip->fds,sip->nbfds,tim); 485*0Sstevel@tonic-gate /* LOCK_LDAP(ld); */ 486*0Sstevel@tonic-gate UNLOCK_POLL(ld); 487*0Sstevel@tonic-gate return(rv); 488*0Sstevel@tonic-gate #else 489*0Sstevel@tonic-gate return( poll(sip->fds,sip->nbfds,tim) ); 490*0Sstevel@tonic-gate #endif 491*0Sstevel@tonic-gate } 492*0Sstevel@tonic-gate #else 493*0Sstevel@tonic-gate /* for UNIX */ 494*0Sstevel@tonic-gate struct selectinfo { 495*0Sstevel@tonic-gate fd_set si_readfds; 496*0Sstevel@tonic-gate fd_set si_writefds; 497*0Sstevel@tonic-gate fd_set si_use_readfds; 498*0Sstevel@tonic-gate fd_set si_use_writefds; 499*0Sstevel@tonic-gate }; 500*0Sstevel@tonic-gate 501*0Sstevel@tonic-gate 502*0Sstevel@tonic-gate void 503*0Sstevel@tonic-gate mark_select_write( LDAP *ld, Sockbuf *sb ) 504*0Sstevel@tonic-gate { 505*0Sstevel@tonic-gate struct selectinfo *sip; 506*0Sstevel@tonic-gate 507*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gate if ( !FD_ISSET( sb->sb_sd, &sip->si_writefds )) { 510*0Sstevel@tonic-gate FD_SET( sb->sb_sd, &sip->si_writefds ); 511*0Sstevel@tonic-gate } 512*0Sstevel@tonic-gate } 513*0Sstevel@tonic-gate 514*0Sstevel@tonic-gate 515*0Sstevel@tonic-gate void 516*0Sstevel@tonic-gate mark_select_read( LDAP *ld, Sockbuf *sb ) 517*0Sstevel@tonic-gate { 518*0Sstevel@tonic-gate struct selectinfo *sip; 519*0Sstevel@tonic-gate 520*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 521*0Sstevel@tonic-gate 522*0Sstevel@tonic-gate if ( !FD_ISSET( sb->sb_sd, &sip->si_readfds )) { 523*0Sstevel@tonic-gate FD_SET( sb->sb_sd, &sip->si_readfds ); 524*0Sstevel@tonic-gate } 525*0Sstevel@tonic-gate } 526*0Sstevel@tonic-gate 527*0Sstevel@tonic-gate 528*0Sstevel@tonic-gate void 529*0Sstevel@tonic-gate mark_select_clear( LDAP *ld, Sockbuf *sb ) 530*0Sstevel@tonic-gate { 531*0Sstevel@tonic-gate struct selectinfo *sip; 532*0Sstevel@tonic-gate 533*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 534*0Sstevel@tonic-gate 535*0Sstevel@tonic-gate FD_CLR( sb->sb_sd, &sip->si_writefds ); 536*0Sstevel@tonic-gate FD_CLR( sb->sb_sd, &sip->si_readfds ); 537*0Sstevel@tonic-gate } 538*0Sstevel@tonic-gate 539*0Sstevel@tonic-gate 540*0Sstevel@tonic-gate long 541*0Sstevel@tonic-gate is_write_ready( LDAP *ld, Sockbuf *sb ) 542*0Sstevel@tonic-gate { 543*0Sstevel@tonic-gate struct selectinfo *sip; 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 546*0Sstevel@tonic-gate 547*0Sstevel@tonic-gate return( FD_ISSET( sb->sb_sd, &sip->si_use_writefds )); 548*0Sstevel@tonic-gate } 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate 551*0Sstevel@tonic-gate long 552*0Sstevel@tonic-gate is_read_ready( LDAP *ld, Sockbuf *sb ) 553*0Sstevel@tonic-gate { 554*0Sstevel@tonic-gate struct selectinfo *sip; 555*0Sstevel@tonic-gate 556*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 557*0Sstevel@tonic-gate 558*0Sstevel@tonic-gate return( FD_ISSET( sb->sb_sd, &sip->si_use_readfds )); 559*0Sstevel@tonic-gate } 560*0Sstevel@tonic-gate 561*0Sstevel@tonic-gate 562*0Sstevel@tonic-gate void * 563*0Sstevel@tonic-gate new_select_info() 564*0Sstevel@tonic-gate { 565*0Sstevel@tonic-gate struct selectinfo *sip; 566*0Sstevel@tonic-gate 567*0Sstevel@tonic-gate if (( sip = (struct selectinfo *)calloc( 1, 568*0Sstevel@tonic-gate sizeof( struct selectinfo ))) != NULL ) { 569*0Sstevel@tonic-gate FD_ZERO( &sip->si_readfds ); 570*0Sstevel@tonic-gate FD_ZERO( &sip->si_writefds ); 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate return( (void *)sip ); 574*0Sstevel@tonic-gate } 575*0Sstevel@tonic-gate 576*0Sstevel@tonic-gate 577*0Sstevel@tonic-gate void 578*0Sstevel@tonic-gate free_select_info( void *sip ) 579*0Sstevel@tonic-gate { 580*0Sstevel@tonic-gate free( sip ); 581*0Sstevel@tonic-gate } 582*0Sstevel@tonic-gate 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate int 585*0Sstevel@tonic-gate do_ldap_select( LDAP *ld, struct timeval *timeout ) 586*0Sstevel@tonic-gate { 587*0Sstevel@tonic-gate struct selectinfo *sip; 588*0Sstevel@tonic-gate static int tblsize; 589*0Sstevel@tonic-gate 590*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 208, "do_ldap_select\n"), 0, 0, 0 ); 591*0Sstevel@tonic-gate 592*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 593*0Sstevel@tonic-gate LOCK_LDAP(ld); 594*0Sstevel@tonic-gate #endif 595*0Sstevel@tonic-gate if ( tblsize == 0 ) { 596*0Sstevel@tonic-gate #ifdef USE_SYSCONF 597*0Sstevel@tonic-gate tblsize = (int)sysconf( _SC_OPEN_MAX ); 598*0Sstevel@tonic-gate #else /* USE_SYSCONF */ 599*0Sstevel@tonic-gate tblsize = getdtablesize(); 600*0Sstevel@tonic-gate #endif /* USE_SYSCONF */ 601*0Sstevel@tonic-gate } 602*0Sstevel@tonic-gate 603*0Sstevel@tonic-gate sip = (struct selectinfo *)ld->ld_selectinfo; 604*0Sstevel@tonic-gate sip->si_use_readfds = sip->si_readfds; 605*0Sstevel@tonic-gate sip->si_use_writefds = sip->si_writefds; 606*0Sstevel@tonic-gate 607*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 608*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 609*0Sstevel@tonic-gate #endif 610*0Sstevel@tonic-gate return( select( tblsize, &sip->si_use_readfds, &sip->si_use_writefds, 611*0Sstevel@tonic-gate NULL, timeout )); 612*0Sstevel@tonic-gate } 613*0Sstevel@tonic-gate #endif /* SUN */ 614*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 615