371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * Use is subject to license terms.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * The contents of this file are subject to the Netscape Public
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * License Version 1.1 (the "License"); you may not use this file
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * except in compliance with the License. You may obtain a copy of
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * the License at http://www.mozilla.org/NPL/
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * Software distributed under the License is distributed on an "AS
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * implied. See the License for the specific language governing
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * rights and limitations under the License.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * The Original Code is Mozilla Communicator client code, released
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * March 31, 1998.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov *
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * The Initial Developer of the Original Code is Netscape
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Communications Corporation. Portions created by Netscape are
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Copyright (C) 1998-1999 Netscape Communications Corporation. All
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Rights Reserved.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Contributor(s):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Extended I/O callback functions for libldap that use
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * NSPR (Netscape Portable Runtime) I/O.
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * High level strategy: we use the socket-specific arg to hold our own data
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * structure that includes the NSPR file handle (PRFileDesc *), among other
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * useful information. We use the default argument to hold an LDAP session
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * handle specific data structure.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov#include "ldappr-int.h"
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov#include <string.h>
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov#define PRLDAP_POLL_ARRAY_GROWTH 5 /* grow arrays 5 elements at a time */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov/*
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Local function prototypes:
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic PRIntervalTime prldap_timeout2it( int ms_timeout, int ms_maxtimeout );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic int LDAP_CALLBACK prldap_read( int s, void *buf, int bufsize,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov struct lextiof_socket_private *socketarg );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic int LDAP_CALLBACK prldap_write( int s, const void *buf, int len,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov struct lextiof_socket_private *socketarg );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic int LDAP_CALLBACK prldap_poll( LDAP_X_PollFD fds[], int nfds,
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov int timeout, struct lextiof_session_private *sessionarg );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic int LDAP_CALLBACK prldap_connect( const char *hostlist, int defport,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov int timeout, unsigned long options,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov struct lextiof_session_private *sessionarg,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov struct lextiof_socket_private **socketargp
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov#ifdef _SOLARIS_SDK
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov , void **dhost );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#else
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore#endif /* _SOLARIS_SDK */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int LDAP_CALLBACK prldap_close( int s,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct lextiof_socket_private *socketarg );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int LDAP_CALLBACK prldap_newhandle( LDAP *ld,
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore struct lextiof_session_private *sessionarg );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amorestatic void LDAP_CALLBACK prldap_disposehandle( LDAP *ld,
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore struct lextiof_session_private *sessionarg );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amorestatic int LDAP_CALLBACK prldap_shared_newhandle( LDAP *ld,
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore struct lextiof_session_private *sessionarg );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void LDAP_CALLBACK prldap_shared_disposehandle( LDAP *ld,
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore struct lextiof_session_private *sessionarg );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic PRLDAPIOSessionArg *prldap_session_arg_alloc( void );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amorestatic void prldap_session_arg_free( PRLDAPIOSessionArg **prsesspp );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amorestatic PRLDAPIOSocketArg *prldap_socket_arg_alloc( PRLDAPIOSessionArg *sessionarg );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amorestatic void prldap_socket_arg_free( PRLDAPIOSocketArg **prsockpp );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amorestatic void *prldap_safe_realloc( void *ptr, PRUint32 size );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore/*
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * Local macros:
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/* given a socket-specific arg, return the corresponding PRFileDesc * */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore#define PRLDAP_GET_PRFD( socketarg ) \
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore (((PRLDAPIOSocketArg *)(socketarg))->prsock_prfd)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore/*
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * Static variables.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int prldap_default_io_max_timeout = LDAP_X_IO_TIMEOUT_NO_TIMEOUT;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore/*
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * Install NSPR I/O functions into ld (if ld is NULL, they are installed
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * as the default functions for new LDAP * handles).
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Returns 0 if all goes well and -1 if not.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreint
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreprldap_install_io_functions( LDAP *ld, int shared )
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct ldap_x_ext_io_fns iofns;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore memset( &iofns, 0, sizeof(iofns));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore iofns.lextiof_read = prldap_read;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore iofns.lextiof_write = prldap_write;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore iofns.lextiof_poll = prldap_poll;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore iofns.lextiof_connect = prldap_connect;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore iofns.lextiof_close = prldap_close;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( shared ) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore iofns.lextiof_newhandle = prldap_shared_newhandle;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore iofns.lextiof_disposehandle = prldap_shared_disposehandle;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore } else {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore iofns.lextiof_newhandle = prldap_newhandle;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore iofns.lextiof_disposehandle = prldap_disposehandle;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( NULL != ld ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * If we are dealing with a real ld, we allocate the session specific
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * data structure now. If not allocated here, it will be allocated
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * inside prldap_newhandle() or prldap_shared_newhandle().
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( NULL ==
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ( iofns.lextiof_session_arg = prldap_session_arg_alloc())) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ldap_set_lderrno( ld, LDAP_NO_MEMORY, NULL, NULL );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return( -1 );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore } else {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore iofns.lextiof_session_arg = NULL;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, &iofns ) != 0 ) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore prldap_session_arg_free(
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore (PRLDAPIOSessionArg **) &iofns.lextiof_session_arg );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return( -1 );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return( 0 );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic PRIntervalTime
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreprldap_timeout2it( int ms_timeout, int ms_maxtimeout )
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore{
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore PRIntervalTime prit;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( LDAP_X_IO_TIMEOUT_NO_WAIT == ms_timeout ) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore prit = PR_INTERVAL_NO_WAIT;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore } else if ( LDAP_X_IO_TIMEOUT_NO_TIMEOUT == ms_timeout ) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore prit = PR_INTERVAL_NO_TIMEOUT;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore } else {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore prit = PR_MillisecondsToInterval( ms_timeout );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /* cap at maximum I/O timeout */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( LDAP_X_IO_TIMEOUT_NO_WAIT == ms_maxtimeout ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore prit = LDAP_X_IO_TIMEOUT_NO_WAIT;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore } else if ( LDAP_X_IO_TIMEOUT_NO_TIMEOUT != ms_maxtimeout ) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( LDAP_X_IO_TIMEOUT_NO_TIMEOUT == ms_timeout ||
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore ms_timeout > ms_maxtimeout ) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore prit = PR_MillisecondsToInterval( ms_maxtimeout );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore#ifdef PRLDAP_DEBUG
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( PR_INTERVAL_NO_WAIT == prit ) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore fprintf( stderr, "prldap_timeout2it: NO_WAIT\n" );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else if ( PR_INTERVAL_NO_TIMEOUT == prit ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore fprintf( stderr, "prldap_timeout2it: NO_TIMEOUT\n" );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore } else {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore fprintf( stderr, "prldap_timeout2it: %dms\n",
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore PR_IntervalToMilliseconds(prit));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore#endif /* PRLDAP_DEBUG */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return( prit );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int LDAP_CALLBACK
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovprldap_read( int s, void *buf, int bufsize,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct lextiof_socket_private *socketarg )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore PRIntervalTime prit;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore prit = prldap_timeout2it( LDAP_X_IO_TIMEOUT_NO_TIMEOUT,
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore socketarg->prsock_io_max_timeout );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return( PR_Recv( PRLDAP_GET_PRFD(socketarg), buf, bufsize, 0, prit ));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore}
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amorestatic int LDAP_CALLBACK
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovprldap_write( int s, const void *buf, int len,
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov struct lextiof_socket_private *socketarg )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore PRIntervalTime prit;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore prit = prldap_timeout2it( LDAP_X_IO_TIMEOUT_NO_TIMEOUT,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore socketarg->prsock_io_max_timeout );
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Note the 4th parameter (flags) to PR_Send() has been obsoleted and
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * must always be 0
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return( PR_Send( PRLDAP_GET_PRFD(socketarg), buf, len, 0, prit ));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestruct prldap_eventmap_entry {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore PRInt16 evm_nspr; /* corresponding NSPR PR_Poll() event */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int evm_ldap; /* LDAP poll event */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov};
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic struct prldap_eventmap_entry prldap_eventmap[] = {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov { PR_POLL_READ, LDAP_X_POLLIN },
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore { PR_POLL_EXCEPT, LDAP_X_POLLPRI },
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore { PR_POLL_WRITE, LDAP_X_POLLOUT },
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore { PR_POLL_ERR, LDAP_X_POLLERR },
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov { PR_POLL_HUP, LDAP_X_POLLHUP },
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov { PR_POLL_NVAL, LDAP_X_POLLNVAL },
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore};
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov#define PRLDAP_EVENTMAP_ENTRIES \
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov sizeof(prldap_eventmap)/sizeof(struct prldap_eventmap_entry )
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovstatic int LDAP_CALLBACK
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreprldap_poll( LDAP_X_PollFD fds[], int nfds, int timeout,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct lextiof_session_private *sessionarg )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov PRLDAPIOSessionArg *prsessp = sessionarg;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PRPollDesc *pds;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int i, j, rc;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL == prsessp ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov prldap_set_system_errno( EINVAL );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( -1 );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov /* allocate or resize NSPR poll descriptor array */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( prsessp->prsess_pollds_count < nfds ) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov pds = prldap_safe_realloc( prsessp->prsess_pollds,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ( nfds + PRLDAP_POLL_ARRAY_GROWTH )
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * sizeof( PRPollDesc ));
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( NULL == pds ) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov prldap_set_system_errno( prldap_prerr2errno());
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( -1 );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov prsessp->prsess_pollds = pds;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov prsessp->prsess_pollds_count = nfds + PRLDAP_POLL_ARRAY_GROWTH;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov } else {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov pds = prsessp->prsess_pollds;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /* populate NSPR poll info. based on LDAP info. */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov for ( i = 0; i < nfds; ++i ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( NULL == fds[i].lpoll_socketarg ) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov pds[i].fd = NULL;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore pds[i].fd = PRLDAP_GET_PRFD( fds[i].lpoll_socketarg );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov pds[i].in_flags = pds[i].out_flags = 0;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( fds[i].lpoll_fd >= 0 ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov for ( j = 0; j < PRLDAP_EVENTMAP_ENTRIES; ++j ) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if (( fds[i].lpoll_events & prldap_eventmap[j].evm_ldap )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore != 0 ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore pds[i].in_flags |= prldap_eventmap[j].evm_nspr;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore fds[i].lpoll_revents = 0; /* clear revents */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov /* call PR_Poll() to do the real work */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore rc = PR_Poll( pds, nfds,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov prldap_timeout2it( timeout, prsessp->prsess_io_max_timeout ));
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov /* populate LDAP info. based on NSPR results */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore for ( i = 0; i < nfds; ++i ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( pds[i].fd != NULL ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov for ( j = 0; j < PRLDAP_EVENTMAP_ENTRIES; ++j ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (( pds[i].out_flags & prldap_eventmap[j].evm_nspr )
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov != 0 ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov fds[i].lpoll_revents |= prldap_eventmap[j].evm_ldap;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( rc );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov}
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov/*
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * Utility function to try one TCP connect()
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * Returns 1 if successful and -1 if not. Sets the NSPR fd inside prsockp.
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic int
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovprldap_try_one_address( struct lextiof_socket_private *prsockp,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PRNetAddr *addrp, int port, int timeout, unsigned long options )
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov{
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov /*
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * Set up address and open a TCP socket:
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( PR_SUCCESS != PR_SetNetAddr( PR_IpAddrNull, /* don't touch IP addr. */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov PRLDAP_DEFAULT_ADDRESS_FAMILY, (PRUint16)port, addrp )) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( -1 );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (( prsockp->prsock_prfd = PR_OpenTCPSocket(
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PRLDAP_DEFAULT_ADDRESS_FAMILY )) == NULL ) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( -1 );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /*
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Set nonblocking option if requested:
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( 0 != ( options & LDAP_X_EXTIOF_OPT_NONBLOCKING )) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov PRSocketOptionData optdata;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore optdata.option = PR_SockOpt_Nonblocking;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore optdata.value.non_blocking = PR_TRUE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( PR_SetSocketOption( prsockp->prsock_prfd, &optdata )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore != PR_SUCCESS ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore prldap_set_system_errno( prldap_prerr2errno());
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PR_Close( prsockp->prsock_prfd );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( -1 );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov#ifdef PRLDAP_DEBUG
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov char buf[ 256 ], *p, *fmtstr;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( PR_SUCCESS != PR_NetAddrToString( addrp, buf, sizeof(buf ))) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov strcpy( buf, "conversion failed!" );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( strncmp( buf, "::ffff:", 7 ) == 0 ) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov /* IPv4 address mapped into IPv6 address space */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov p = buf + 7;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov fmtstr = "prldap_try_one_address(): Trying %s:%d...\n";
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov } else {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov p = buf;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov fmtstr = "prldap_try_one_address(): Trying [%s]:%d...\n";
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov fprintf( stderr, fmtstr, p, PR_ntohs( addrp->ipv6.port ));
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov#endif /* PRLDAP_DEBUG */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /*
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov * Try to open the TCP connection itself:
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( PR_SUCCESS != PR_Connect( prsockp->prsock_prfd, addrp,
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov prldap_timeout2it( timeout, prsockp->prsock_io_max_timeout ))) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PR_Close( prsockp->prsock_prfd );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov prsockp->prsock_prfd = NULL;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( -1 );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov#ifdef PRLDAP_DEBUG
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov fputs( "prldap_try_one_address(): Connected.\n", stderr );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#endif /* PRLDAP_DEBUG */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Success. Return a valid file descriptor (1 is always valid)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( 1 );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * XXXmcs: At present, this code ignores the timeout when doing DNS lookups.
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int LDAP_CALLBACK
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovprldap_connect( const char *hostlist, int defport, int timeout,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore unsigned long options, struct lextiof_session_private *sessionarg,
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov struct lextiof_socket_private **socketargp
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#ifdef _SOLARIS_SDK
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore , void **dhost )
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov#else
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov )
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov#endif /* _SOLARIS_SDK */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov{
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov int rc, parse_err, port;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov char *host, hbuf[ PR_NETDB_BUF_SIZE ];
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov struct ldap_x_hostlist_status *status;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov struct lextiof_socket_private *prsockp;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PRNetAddr addr;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PRHostEnt hent;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov#ifdef _SOLARIS_SDK
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov char *hostname = NULL;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov char *nsldapi_strdup(char *);
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov#endif /* _SOLARIS_SDK */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( 0 != ( options & LDAP_X_EXTIOF_OPT_SECURE )) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov prldap_set_system_errno( EINVAL );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( -1 );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( NULL == ( prsockp = prldap_socket_arg_alloc( sessionarg ))) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov prldap_set_system_errno( prldap_prerr2errno());
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( -1 );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov rc = -1; /* pessimistic */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov for ( parse_err = ldap_x_hostlist_first( hostlist, defport, &host, &port,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov &status );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov rc < 0 && LDAP_SUCCESS == parse_err && NULL != host;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov parse_err = ldap_x_hostlist_next( &host, &port, status )) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( PR_SUCCESS == PR_StringToNetAddr( host, &addr )) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( PRLDAP_DEFAULT_ADDRESS_FAMILY == PR_AF_INET6 &&
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PR_AF_INET == PR_NetAddrFamily( &addr )) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PRUint32 ipv4ip = addr.inet.ip;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov memset( &addr, 0, sizeof(addr));
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov PR_ConvertIPv4AddrToIPv6( ipv4ip, &addr.ipv6.ip );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore addr.ipv6.family = PR_AF_INET6;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore rc = prldap_try_one_address( prsockp, &addr, port,
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov timeout, options );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov } else {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( PR_SUCCESS == PR_GetIPNodeByName( host,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore PRLDAP_DEFAULT_ADDRESS_FAMILY, PR_AI_DEFAULT | PR_AI_ALL, hbuf,
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov sizeof( hbuf ), &hent )) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov PRIntn enumIndex = 0;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore while ( rc < 0 && ( enumIndex = PR_EnumerateHostEnt(
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore enumIndex, &hent, (PRUint16)port, &addr )) > 0 ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov rc = prldap_try_one_address( prsockp, &addr, port,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov timeout, options );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore#ifdef _SOLARIS_SDK
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( NULL != hostname ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ldap_memfree(hostname);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore hostname = NULL;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( rc >= 0 ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov hostname = nsldapi_strdup(host);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#endif /* _SOLARIS_SDK */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ldap_memfree( host );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov ldap_x_hostlist_statusfree( status );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( rc < 0 ) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore prldap_set_system_errno( prldap_prerr2errno());
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov prldap_socket_arg_free( &prsockp );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *socketargp = prsockp;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#ifdef _SOLARIS_SDK
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL != hostname && NULL != dhost ) *dhost = hostname;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov else if ( NULL != hostname ) ldap_memfree(hostname);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#endif /* _SOLARIS_SDK */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( rc );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic int LDAP_CALLBACK
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovprldap_close( int s, struct lextiof_socket_private *socketarg )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore int rc;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore rc = 0;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( PR_Close( PRLDAP_GET_PRFD(socketarg)) != PR_SUCCESS ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore rc = -1;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore prldap_set_system_errno( prldap_prerr2errno());
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore prldap_socket_arg_free( &socketarg );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return( rc );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov/*
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * LDAP session handle creation callback.
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Allocate a session argument if not already done, and then call the
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * thread's new handle function.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int LDAP_CALLBACK
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovprldap_newhandle( LDAP *ld, struct lextiof_session_private *sessionarg )
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov{
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL == sessionarg ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct ldap_x_ext_io_fns iofns;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov memset( &iofns, 0, sizeof(iofns));
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( ldap_get_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS,
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov (void *)&iofns ) < 0 ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( ldap_get_lderrno( ld, NULL, NULL ));
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( NULL ==
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov ( iofns.lextiof_session_arg = prldap_session_arg_alloc())) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( LDAP_NO_MEMORY );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS,
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov (void *)&iofns ) < 0 ) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( ldap_get_lderrno( ld, NULL, NULL ));
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( LDAP_SUCCESS );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov/* only called/installed if shared is non-zero. */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic int LDAP_CALLBACK
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovprldap_shared_newhandle( LDAP *ld, struct lextiof_session_private *sessionarg )
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov{
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov int rc;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if (( rc = prldap_newhandle( ld, sessionarg )) == LDAP_SUCCESS ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov rc = prldap_thread_new_handle( ld, sessionarg );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return( rc );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov}
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic void LDAP_CALLBACK
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovprldap_disposehandle( LDAP *ld, struct lextiof_session_private *sessionarg )
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov{
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov prldap_session_arg_free( &sessionarg );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/* only called/installed if shared is non-zero */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void LDAP_CALLBACK
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreprldap_shared_disposehandle( LDAP *ld,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct lextiof_session_private *sessionarg )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov prldap_thread_dispose_handle( ld, sessionarg );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore prldap_disposehandle( ld, sessionarg );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Allocate a session argument.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic PRLDAPIOSessionArg *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreprldap_session_arg_alloc( void )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore PRLDAPIOSessionArg *prsessp;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore prsessp = PR_Calloc( 1, sizeof( PRLDAPIOSessionArg ));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( NULL != prsessp ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* copy global defaults to the new session handle */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov prsessp->prsess_io_max_timeout = prldap_default_io_max_timeout;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( prsessp );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreprldap_session_arg_free( PRLDAPIOSessionArg **prsesspp )
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov{
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov if ( NULL != prsesspp && NULL != *prsesspp ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( NULL != (*prsesspp)->prsess_pollds ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore PR_Free( (*prsesspp)->prsess_pollds );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore (*prsesspp)->prsess_pollds = NULL;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore PR_Free( *prsesspp );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov *prsesspp = NULL;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov/*
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Given an LDAP session handle, retrieve a session argument.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Returns an LDAP error code.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreprldap_session_arg_from_ld( LDAP *ld, PRLDAPIOSessionArg **sessargpp )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct ldap_x_ext_io_fns iofns;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL == ld || NULL == sessargpp ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* XXXmcs: NULL ld's are not supported */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( LDAP_PARAM_ERROR );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore memset( &iofns, 0, sizeof(iofns));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( ldap_get_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, (void *)&iofns ) < 0 ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( ldap_get_lderrno( ld, NULL, NULL ));
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL == iofns.lextiof_session_arg ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ldap_set_lderrno( ld, LDAP_LOCAL_ERROR, NULL, NULL );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( LDAP_LOCAL_ERROR );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov *sessargpp = iofns.lextiof_session_arg;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( LDAP_SUCCESS );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov/*
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Given an LDAP session handle, retrieve a socket argument.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Returns an LDAP error code.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovint
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovprldap_socket_arg_from_ld( LDAP *ld, PRLDAPIOSocketArg **sockargpp )
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov{
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov Sockbuf *sbp;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov struct lber_x_ext_io_fns extiofns;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( NULL == ld || NULL == sockargpp ) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov /* XXXmcs: NULL ld's are not supported */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return( LDAP_PARAM_ERROR );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( ldap_get_option( ld, LDAP_X_OPT_SOCKBUF, (void *)&sbp ) < 0 ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( ldap_get_lderrno( ld, NULL, NULL ));
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov memset( &extiofns, 0, sizeof(extiofns));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore extiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( ber_sockbuf_get_option( sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore (void *)&extiofns ) < 0 ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( ldap_get_lderrno( ld, NULL, NULL ));
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL == extiofns.lbextiofn_socket_arg ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ldap_set_lderrno( ld, LDAP_LOCAL_ERROR, NULL, NULL );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( LDAP_LOCAL_ERROR );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov *sockargpp = extiofns.lbextiofn_socket_arg;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( LDAP_SUCCESS );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov/*
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Allocate a socket argument.
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovstatic PRLDAPIOSocketArg *
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovprldap_socket_arg_alloc( PRLDAPIOSessionArg *sessionarg )
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov{
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov PRLDAPIOSocketArg *prsockp;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov prsockp = PR_Calloc( 1, sizeof( PRLDAPIOSocketArg ));
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL != prsockp && NULL != sessionarg ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /* copy socket defaults from the session */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov prsockp->prsock_io_max_timeout = sessionarg->prsess_io_max_timeout;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( prsockp );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovstatic void
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovprldap_socket_arg_free( PRLDAPIOSocketArg **prsockpp )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov if ( NULL != prsockpp && NULL != *prsockpp ) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov PR_Free( *prsockpp );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov *prsockpp = NULL;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovstatic void *
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovprldap_safe_realloc( void *ptr, PRUint32 size )
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore void *p;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL == ptr ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p = PR_Malloc( size );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov } else {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov p = PR_Realloc( ptr, size );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov return( p );
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov/* returns an LDAP result code */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreprldap_set_io_max_timeout( PRLDAPIOSessionArg *prsessp, int io_max_timeout )
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int rc = LDAP_SUCCESS; /* optimistic */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL == prsessp ) {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov prldap_default_io_max_timeout = io_max_timeout;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov } else {
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov prsessp->prsess_io_max_timeout = io_max_timeout;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov return( rc );
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov}
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov/* returns an LDAP result code */
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovint
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankovprldap_get_io_max_timeout( PRLDAPIOSessionArg *prsessp, int *io_max_timeoutp )
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov{
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov int rc = LDAP_SUCCESS; /* optimistic */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( NULL == io_max_timeoutp ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore rc = LDAP_PARAM_ERROR;
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov } else if ( NULL == prsessp ) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *io_max_timeoutp = prldap_default_io_max_timeout;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov *io_max_timeoutp = prsessp->prsess_io_max_timeout;
371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return( rc );
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore