コード例 #1
0
ファイル: request.c プロジェクト: ajinkya93/netbsd-src
/* protected by conn_mutex */
int
ldap_int_flush_request(
	LDAP *ld,
	LDAPRequest *lr )
{
	LDAPConn *lc = lr->lr_conn;

	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_conn_mutex );
	if ( ber_flush2( lc->lconn_sb, lr->lr_ber, LBER_FLUSH_FREE_NEVER ) != 0 ) {
		if ( sock_errno() == EAGAIN ) {
			/* need to continue write later */
			lr->lr_status = LDAP_REQST_WRITING;
			ldap_mark_select_write( ld, lc->lconn_sb );
			ld->ld_errno = LDAP_BUSY;
			return -2;
		} else {
			ld->ld_errno = LDAP_SERVER_DOWN;
			ldap_free_request( ld, lr );
			ldap_free_connection( ld, lc, 0, 0 );
			return( -1 );
		}
	} else {
		if ( lr->lr_parent == NULL ) {
			lr->lr_ber->ber_end = lr->lr_ber->ber_ptr;
			lr->lr_ber->ber_ptr = lr->lr_ber->ber_buf;
		}
		lr->lr_status = LDAP_REQST_INPROGRESS;

		/* sent -- waiting for a response */
		ldap_mark_select_read( ld, lc->lconn_sb );
		ldap_clear_select_write( ld, lc->lconn_sb );
	}
	return 0;
}
コード例 #2
0
ファイル: io.c プロジェクト: bagel/openldap-ga
int
ber_flush( Sockbuf *sb, BerElement *ber, int freeit )
{
	return ber_flush2( sb, ber,
		freeit ? LBER_FLUSH_FREE_ON_SUCCESS
			: LBER_FLUSH_FREE_NEVER );
}
コード例 #3
0
ファイル: unbind.c プロジェクト: 1ack/Impala
/* FIXME: this function is called only by ldap_free_connection(),
 * which, most of the times, is called with ld_req_mutex locked */
int
ldap_send_unbind(
	LDAP *ld,
	Sockbuf *sb,
	LDAPControl **sctrls,
	LDAPControl **cctrls )
{
	BerElement	*ber;
	ber_int_t	id;

	Debug( LDAP_DEBUG_TRACE, "ldap_send_unbind\n", 0, 0, 0 );

#ifdef LDAP_CONNECTIONLESS
	if (LDAP_IS_UDP(ld))
		return LDAP_SUCCESS;
#endif
	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		return( ld->ld_errno );
	}

	LDAP_NEXT_MSGID(ld, id);

	/* fill it in */
	if ( ber_printf( ber, "{itn" /*}*/, id,
	    LDAP_REQ_UNBIND ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}", LDAP_REQ_UNBIND ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	ld->ld_errno = LDAP_SUCCESS;
	/* send the message */
	if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) == -1 ) {
		ld->ld_errno = LDAP_SERVER_DOWN;
	}

	return( ld->ld_errno );
}
コード例 #4
0
ファイル: result.c プロジェクト: DhanashreeA/lightwave
static
int
WriteBerOnSocket(
   VDIR_CONNECTION * conn,
   BerElement * ber )
{
   long         retVal = 0;
   uint64_t     iWriteStartTimeInMSec = 0;

   iWriteStartTimeInMSec = VmDirGetTimeInMilliSec();
   while( VmDirGetTimeInMilliSec() - iWriteStartTimeInMSec <
          (MAX_NUM_SECONDS_OF_SOCK_WRITE_RETRIES * MSECS_IN_SECOND) )
   {
      if ( (retVal = ber_flush2( conn->sb, ber, LBER_FLUSH_FREE_NEVER )) == 0 )
      {
         break;
      }

#ifdef _WIN32
      // in ber_flush2 (liblber) call, sock_errset() call WSASetLastError()
      errno = WSAGetLastError();
#endif

      if ( errno == EWOULDBLOCK || errno == EAGAIN )
      {
         continue;
      }
   }

   if (retVal != 0)
   {
      VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "WriteBerOnSocket:  ber_flush2() call failed with errno = %d.", errno );
   }

   return retVal;
}
コード例 #5
0
ファイル: abandon.c プロジェクト: gosudream/netbsd-src
static int
do_abandon(
	LDAP *ld,
	ber_int_t origid,
	ber_int_t msgid,
	LDAPControl **sctrls,
	int sendabandon )
{
	BerElement	*ber;
	int		i, err;
	Sockbuf		*sb;
	LDAPRequest	*lr;

	Debug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n",
		origid, msgid, 0 );

	/* find the request that we are abandoning */
start_again:;
	lr = ld->ld_requests;
	while ( lr != NULL ) {
		/* this message */
		if ( lr->lr_msgid == msgid ) {
			break;
		}

		/* child: abandon it */
		if ( lr->lr_origid == msgid && !lr->lr_abandoned ) {
			(void)do_abandon( ld, lr->lr_origid, lr->lr_msgid,
				sctrls, sendabandon );

			/* restart, as lr may now be dangling... */
			goto start_again;
		}

		lr = lr->lr_next;
	}

	if ( lr != NULL ) {
		if ( origid == msgid && lr->lr_parent != NULL ) {
			/* don't let caller abandon child requests! */
			ld->ld_errno = LDAP_PARAM_ERROR;
			return( LDAP_PARAM_ERROR );
		}
		if ( lr->lr_status != LDAP_REQST_INPROGRESS ) {
			/* no need to send abandon message */
			sendabandon = 0;
		}
	}

	/* ldap_msgdelete locks the res_mutex. Give up the req_mutex
	 * while we're in there.
	 */
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
	err = ldap_msgdelete( ld, msgid );
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
	if ( err == 0 ) {
		ld->ld_errno = LDAP_SUCCESS;
		return LDAP_SUCCESS;
	}

	/* fetch again the request that we are abandoning */
	if ( lr != NULL ) {
		for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
			/* this message */
			if ( lr->lr_msgid == msgid ) {
				break;
			}
		}
	}

	err = 0;
	if ( sendabandon ) {
		if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
			/* not connected */
			err = -1;
			ld->ld_errno = LDAP_SERVER_DOWN;

		} else if ( ( ber = ldap_alloc_ber_with_options( ld ) ) == NULL ) {
			/* BER element allocation failed */
			err = -1;
			ld->ld_errno = LDAP_NO_MEMORY;

		} else {
			/*
			 * We already have the mutex in LDAP_R_COMPILE, so
			 * don't try to get it again.
			 *		LDAP_NEXT_MSGID(ld, i);
			 */

			i = ++(ld)->ld_msgid;
#ifdef LDAP_CONNECTIONLESS
			if ( LDAP_IS_UDP(ld) ) {
				struct sockaddr sa = {0};
				/* dummy, filled with ldo_peer in request.c */
				err = ber_write( ber, &sa, sizeof(sa), 0 );
			}
			if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version ==
				LDAP_VERSION2 )
			{
				char *dn = ld->ld_options.ldo_cldapdn;
				if (!dn) dn = "";
				err = ber_printf( ber, "{isti",  /* '}' */
					i, dn,
					LDAP_REQ_ABANDON, msgid );
			} else
#endif
			{
				/* create a message to send */
				err = ber_printf( ber, "{iti",  /* '}' */
					i,
					LDAP_REQ_ABANDON, msgid );
			}

			if ( err == -1 ) {
				/* encoding error */
				ld->ld_errno = LDAP_ENCODING_ERROR;

			} else {
				/* Put Server Controls */
				if ( ldap_int_put_controls( ld, sctrls, ber )
					!= LDAP_SUCCESS )
				{
					err = -1;

				} else {
					/* close '{' */
					err = ber_printf( ber, /*{*/ "N}" );

					if ( err == -1 ) {
						/* encoding error */
						ld->ld_errno = LDAP_ENCODING_ERROR;
					}
				}
			}

			if ( err == -1 ) {
				ber_free( ber, 1 );

			} else {
				/* send the message */
				if ( lr != NULL ) {
					assert( lr->lr_conn != NULL );
					sb = lr->lr_conn->lconn_sb;
				} else {
					sb = ld->ld_sb;
				}

				if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) != 0 ) {
					ld->ld_errno = LDAP_SERVER_DOWN;
					err = -1;
				} else {
					err = 0;
				}
			}
		}
	}

	if ( lr != NULL ) {
		if ( sendabandon || lr->lr_status == LDAP_REQST_WRITING ) {
			ldap_free_connection( ld, lr->lr_conn, 0, 1 );
		}

		if ( origid == msgid ) {
			ldap_free_request( ld, lr );

		} else {
			lr->lr_abandoned = 1;
		}
	}

#ifdef LDAP_R_COMPILE
	/* ld_abandoned is actually protected by the ld_res_mutex;
	 * give up the ld_req_mutex and get the other */
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
	ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
#endif

	/* use bisection */
	i = 0;
	if ( ld->ld_nabandoned == 0 ||
		ldap_int_bisect_find( ld->ld_abandoned, ld->ld_nabandoned, msgid, &i ) == 0 )
	{
		ldap_int_bisect_insert( &ld->ld_abandoned, &ld->ld_nabandoned, msgid, i );
	}

	if ( err != -1 ) {
		ld->ld_errno = LDAP_SUCCESS;
	}

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
	return( ld->ld_errno );
}
コード例 #6
0
ファイル: result.c プロジェクト: Smilefant/ReOpenLDAP
static long send_ldap_ber(
	Operation *op,
	BerElement *ber )
{
	Connection *conn = op->o_conn;
	ber_len_t bytes;
	long ret = 0;

	ber_get_option( ber, LBER_OPT_BER_BYTES_TO_WRITE, &bytes );

	/* write only one pdu at a time - wait til it's our turn */
	ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex );
	if (( op->o_abandon && !op->o_cancel ) || !connection_valid( conn ) ||
		conn->c_writers < 0 ) {
		ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );
		return 0;
	}

	conn->c_writers++;

	while ( conn->c_writers > 0 && conn->c_writing ) {
		ldap_pvt_thread_cond_wait( &conn->c_write1_cv, &conn->c_write1_mutex );
	}

	/* connection was closed under us */
	if ( conn->c_writers < 0 ) {
		/* we're the last waiter, let the closer continue */
		if ( conn->c_writers == -1 )
			ldap_pvt_thread_cond_signal( &conn->c_write1_cv );
		conn->c_writers++;
		ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );
		return 0;
	}

	/* Our turn */
	conn->c_writing = 1;

	/* write the pdu */
	while( 1 ) {
		int err;

		if ( ber_flush2( conn->c_sb, ber, LBER_FLUSH_FREE_NEVER ) == 0 ) {
			ret = bytes;
			break;
		}

		err = sock_errno();

		/*
		 * we got an error.  if it's ewouldblock, we need to
		 * wait on the socket being writable.  otherwise, figure
		 * it's a hard error and return.
		 */

		Debug( LDAP_DEBUG_CONNS, "ber_flush2 failed errno=%d reason=\"%s\"\n",
		    err, sock_errstr(err) );

		if ( err != EWOULDBLOCK && err != EAGAIN ) {
			conn->c_writers--;
			conn->c_writing = 0;
			ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );
			ldap_pvt_thread_mutex_lock( &conn->c_mutex );
			connection_closing( conn, "connection lost on write" );

			ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
			return -1;
		}

		/* wait for socket to be write-ready */
		slap_writewait_play( op );
		ldap_pvt_thread_mutex_lock( &conn->c_write2_mutex );
		conn->c_writewaiter = 1;
		slapd_set_write( conn->c_sd, 2 );

		ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );
		ldap_pvt_thread_pool_idle( &connection_pool );
		ldap_pvt_thread_cond_wait( &conn->c_write2_cv, &conn->c_write2_mutex );
		conn->c_writewaiter = 0;
		ldap_pvt_thread_mutex_unlock( &conn->c_write2_mutex );
		ldap_pvt_thread_pool_unidle( &connection_pool );
		ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex );
		if ( conn->c_writers < 0 ) {
			ret = 0;
			break;
		}
	}

	conn->c_writing = 0;
	if ( conn->c_writers < 0 ) {
		conn->c_writers++;
		if ( !conn->c_writers )
			ldap_pvt_thread_cond_signal( &conn->c_write1_cv );
	} else {
		conn->c_writers--;
		ldap_pvt_thread_cond_signal( &conn->c_write1_cv );
	}
	ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );

	return ret;
}
コード例 #7
0
ファイル: etest.c プロジェクト: ajinkya93/netbsd-src
int
main( int argc, char **argv )
{
	char	*s;
	int tag;

	int			fd, rc;
	BerElement	*ber;
	Sockbuf		*sb;

	/* enable debugging */
	int ival = -1;
	ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &ival );

	if ( argc < 2 ) {
		usage( argv[0] );
		return( EXIT_FAILURE );
	}

#ifdef HAVE_CONSOLE_H
	ccommand( &argv );
	cshow( stdout );

	if (( fd = open( "lber-test", O_WRONLY|O_CREAT|O_TRUNC|O_BINARY ))
		< 0 ) {
	    perror( "open" );
	    return( EXIT_FAILURE );
	}

#else
	fd = fileno(stdout);
#endif

	sb = ber_sockbuf_alloc();
	ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd, LBER_SBIOD_LEVEL_PROVIDER,
		(void *)&fd );

	if( sb == NULL ) {
		perror( "ber_sockbuf_alloc_fd" );
		return( EXIT_FAILURE );
	}

	if ( (ber = ber_alloc_t( LBER_USE_DER )) == NULL ) {
		perror( "ber_alloc" );
		return( EXIT_FAILURE );
	}

	fprintf(stderr, "encode: start\n" );
	if( ber_printf( ber, "{" /*}*/ ) ) {
		perror( "ber_printf {" /*}*/ );
		return( EXIT_FAILURE );
	}

	for ( s = argv[1]; *s; s++ ) {
		char *buf;
		char fmt[2];

		fmt[0] = *s;
		fmt[1] = '\0';

		fprintf(stderr, "encode: %s\n", fmt );
		switch ( *s ) {
		case 'i':	/* int */
		case 'b':	/* boolean */
		case 'e':	/* enumeration */
			buf = getbuf();
			rc = ber_printf( ber, fmt, atoi(buf) );
			break;

		case 'n':	/* null */
		case '{':	/* begin sequence */
		case '}':	/* end sequence */
		case '[':	/* begin set */
		case ']':	/* end set */
			rc = ber_printf( ber, fmt );
			break;

		case 'o':	/* octet string (non-null terminated) */
		case 'B':	/* bit string */
			buf = getbuf();
			rc = ber_printf( ber, fmt, buf, strlen(buf) );
			break;

		case 's':	/* string */
			buf = getbuf();
			rc = ber_printf( ber, fmt, buf );
			break;
		case 't':	/* tag for the next element */
			buf = getbuf();
			tag = atoi(buf);
			rc = ber_printf( ber, fmt, tag );
			break;

		default:
			fprintf( stderr, "encode: unknown fmt %c\n", *fmt );
			rc = -1;
			break;
		}

		if( rc == -1 ) {
			perror( "ber_printf" );
			return( EXIT_FAILURE );
		}
	}

	fprintf(stderr, "encode: end\n" );
	if( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		perror( /*{*/ "ber_printf }" );
		return( EXIT_FAILURE );
	}

	if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) == -1 ) {
		perror( "ber_flush2" );
		return( EXIT_FAILURE );
	}

	ber_sockbuf_free( sb );
	return( EXIT_SUCCESS );
}