return;
} else if ( error ) {
goto done;
- } else if ( upstream_init( s, conn->backend ) == NULL ) {
+ } else if ( upstream_init( s, &conn->localbv, &conn->peerbv,
+ conn->backend ) == NULL ) {
goto done;
}
rc = LDAP_SUCCESS;
{
LloadBackend *b = arg;
ber_socket_t s = AC_SOCKET_INVALID;
+ char localname[LDAP_IPADDRLEN], peername[LDAP_IPADDRLEN];
+ struct berval localbv = BER_BVC(localname), peerbv = BER_BVC(peername);
+ Sockaddr local_addr;
+ socklen_t addrlen = sizeof(local_addr);
epoch_t epoch;
int rc;
struct sockaddr_in *ai = (struct sockaddr_in *)res->ai_addr;
ai->sin_port = htons( b->b_port );
rc = connect( s, (struct sockaddr *)ai, res->ai_addrlen );
+ ldap_pvt_sockaddrstr( (Sockaddr *)ai, &peerbv );
} else {
struct sockaddr_in6 *ai = (struct sockaddr_in6 *)res->ai_addr;
ai->sin6_port = htons( b->b_port );
rc = connect( s, (struct sockaddr *)ai, res->ai_addrlen );
+ ldap_pvt_sockaddrstr( (Sockaddr *)ai, &peerbv );
}
+
+ if ( !getsockname( s, (struct sockaddr *)&local_addr, &addrlen ) ) {
+ ldap_pvt_sockaddrstr( (Sockaddr *)&local_addr, &localbv );
+ } else {
+ ber_str2bv( "unknown", 0, 0, &localbv );
+ }
+
/* Asynchronous connect */
if ( rc ) {
LloadPendingConnection *conn;
goto fail;
}
- conn = ch_calloc( 1, sizeof(LloadPendingConnection) );
+ conn = ch_calloc( 1, sizeof(LloadPendingConnection) +
+ peerbv.bv_len + localbv.bv_len );
LDAP_LIST_ENTRY_INIT( conn, next );
conn->backend = b;
conn->fd = s;
+ conn->localbv.bv_val = (char *)(conn + 1);
+ memcpy( conn->localbv.bv_val, localbv.bv_val, localbv.bv_len );
+ conn->localbv.bv_len = localbv.bv_len;
+
+ conn->peerbv.bv_val = conn->localbv.bv_val + localbv.bv_len;
+ memcpy( conn->peerbv.bv_val, peerbv.bv_val, peerbv.bv_len );
+ conn->peerbv.bv_len = peerbv.bv_len;
+
conn->event = event_new( lload_get_base( s ), s, EV_WRITE|EV_PERSIST,
upstream_connect_cb, conn );
if ( !conn->event ) {
Debug( LDAP_DEBUG_CONNS, "upstream_name_cb: "
"connection to backend uri=%s in progress\n",
b->b_uri.bv_val );
- } else if ( upstream_init( s, b ) == NULL ) {
+ } else if ( upstream_init( s, &localbv, &peerbv, b ) == NULL ) {
goto fail;
}
if ( b->b_proto == LDAP_PROTO_IPC ) {
struct sockaddr_un addr;
ber_socket_t s = socket( PF_LOCAL, SOCK_STREAM, 0 );
+ char peerbuf[sizeof("PATH=")+sizeof(addr.sun_path)];
+ struct berval peerbv = BER_BVC(peerbuf);
int rc;
if ( s == AC_SOCKET_INVALID ) {
memset( &addr, '\0', sizeof(addr) );
addr.sun_family = AF_LOCAL;
strcpy( addr.sun_path, b->b_host );
+ peerbv.bv_len = snprintf( peerbuf, sizeof(peerbuf), "PATH=%s",
+ b->b_host );
rc = connect(
s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un) );
Debug( LDAP_DEBUG_CONNS, "backend_connect: "
"connection to backend uri=%s in progress\n",
b->b_uri.bv_val );
- } else if ( upstream_init( s, b ) == NULL ) {
+ } else if ( upstream_init( s, &peerbv, &peerbv, b ) == NULL ) {
goto fail;
}
LloadConnection *
client_init(
ber_socket_t s,
- const char *peername,
+ struct berval *localname,
+ struct berval *peername,
struct event_base *base,
int flags )
{
event_callback_fn read_cb = connection_read_cb,
write_cb = connection_write_cb;
- if ( (c = lload_connection_init( s, peername, flags) ) == NULL ) {
+ if ( (c = lload_connection_init(
+ s, localname, peername, flags )) == NULL ) {
return NULL;
}
ber_memfree( c->c_sasl_bind_mech.bv_val );
BER_BVZERO( &c->c_sasl_bind_mech );
}
+ if ( !BER_BVISNULL( &c->c_local_name ) ) {
+ ber_memfree( c->c_local_name.bv_val );
+ BER_BVZERO( &c->c_local_name );
+ }
+ if ( !BER_BVISNULL( &c->c_peer_name ) ) {
+ ber_memfree( c->c_peer_name.bv_val );
+ BER_BVZERO( &c->c_peer_name );
+ }
#ifdef HAVE_CYRUS_SASL
if ( c->c_sasl_defaults ) {
lutil_sasl_freedefs( c->c_sasl_defaults );
}
LloadConnection *
-lload_connection_init( ber_socket_t s, const char *peername, int flags )
+lload_connection_init(
+ ber_socket_t s,
+ struct berval *localname,
+ struct berval *peername,
+ int flags )
{
LloadConnection *c;
- assert( peername != NULL );
+ assert( localname && !BER_BVISNULL( localname ) );
+ assert( peername && !BER_BVISNULL( peername ) );
if ( s == AC_SOCKET_INVALID ) {
Debug( LDAP_DEBUG_ANY, "lload_connection_init: "
c->c_fd = s;
c->c_sb = ber_sockbuf_alloc();
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &s );
+ ber_dupbv( &c->c_local_name, localname );
+ ber_dupbv( &c->c_peer_name, peername );
#ifdef LDAP_PF_LOCAL
if ( flags & CONN_IS_IPC ) {
Debug( LDAP_DEBUG_CONNS, "lload_connection_init: "
"connection connid=%lu allocated for socket fd=%d peername=%s\n",
- c->c_connid, s, peername );
+ c->c_connid, s, peername->bv_val );
c->c_state = LLOAD_C_ACTIVE;
struct sockaddr **sal = NULL, **psal;
int socktype = SOCK_STREAM; /* default to COTS */
ber_socket_t s;
- char ebuf[128];
+ char ebuf[LDAP_IPADDRLEN];
+ struct berval namebv = BER_BVC(ebuf);
#if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
/*
switch ( (*sal)->sa_family ) {
#ifdef LDAP_PF_LOCAL
- case AF_LOCAL: {
+ case AF_LOCAL: /* {
char *path = ((struct sockaddr_un *)*sal)->sun_path;
l.sl_name.bv_len = strlen( path ) + STRLENOF("PATH=");
l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len + 1 );
snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1, "PATH=%s",
path );
- } break;
+ } break; */
#endif /* LDAP_PF_LOCAL */
- case AF_INET: {
- char addr[INET_ADDRSTRLEN];
- const char *s;
-#if defined(HAVE_GETADDRINFO) && defined(HAVE_INET_NTOP)
- s = inet_ntop( AF_INET,
- &((struct sockaddr_in *)*sal)->sin_addr, addr,
- sizeof(addr) );
-#else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
- s = inet_ntoa( ((struct sockaddr_in *)*sal)->sin_addr );
-#endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
- if ( !s ) s = SLAP_STRING_UNKNOWN;
- port = ntohs( ((struct sockaddr_in *)*sal)->sin_port );
- l.sl_name.bv_val =
- ch_malloc( sizeof("IP=255.255.255.255:65535") );
- snprintf( l.sl_name.bv_val,
- sizeof("IP=255.255.255.255:65535"), "IP=%s:%d", s,
- port );
- l.sl_name.bv_len = strlen( l.sl_name.bv_val );
- } break;
-
+ case AF_INET:
#ifdef LDAP_PF_INET6
- case AF_INET6: {
- char addr[INET6_ADDRSTRLEN];
- const char *s;
- s = inet_ntop( AF_INET6,
- &((struct sockaddr_in6 *)*sal)->sin6_addr, addr,
- sizeof(addr) );
- if ( !s ) s = SLAP_STRING_UNKNOWN;
- port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
- l.sl_name.bv_len = strlen( s ) + sizeof("IP=[]:65535");
- l.sl_name.bv_val = ch_malloc( l.sl_name.bv_len );
- snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=[%s]:%d", s,
- port );
- l.sl_name.bv_len = strlen( l.sl_name.bv_val );
- } break;
+ case AF_INET6:
#endif /* LDAP_PF_INET6 */
+ ldap_pvt_sockaddrstr( (Sockaddr *)*sal, &namebv );
+ ber_dupbv( &l.sl_name, &namebv );
+ break;
default:
Debug( LDAP_DEBUG_ANY, "lload_open_listener: "
cflag |= CONN_IS_IPC;
/* FIXME: apparently accept doesn't fill the sun_path member */
- sprintf( peername, "PATH=%s", sl->sl_sa.sa_un_addr.sun_path );
+ peerbv.bv_len = sprintf(
+ peername, "PATH=%s", sl->sl_sa.sa_un_addr.sun_path );
break;
#endif /* LDAP_PF_LOCAL */
#ifdef HAVE_TLS
if ( sl->sl_is_tls ) cflag |= CONN_IS_TLS;
#endif
- c = client_init( s, peername, lload_daemon[tid].base, cflag );
+ c = client_init( s, &sl->sl_name, &peerbv, lload_daemon[tid].base, cflag );
if ( !c ) {
Debug( LDAP_DEBUG_ANY, "lload_listener: "
struct event *event;
ber_socket_t fd;
+ struct berval localbv, peerbv;
+
LDAP_LIST_ENTRY(LloadPendingConnection) next;
};
/* set by connection_init */
unsigned long c_connid; /* unique id of this connection */
struct berval c_peer_name; /* peer name (trans=addr:port) */
+ struct berval c_local_name; /* local name (trans=addr:port) */
time_t c_starttime; /* when the connection was opened */
time_t c_activitytime; /* when the connection was last used */
LDAP_SLAPD_F (int) request_process( LloadConnection *c, LloadOperation *op );
LDAP_SLAPD_F (int) handle_one_request( LloadConnection *c );
LDAP_SLAPD_F (void) client_tls_handshake_cb( evutil_socket_t s, short what, void *arg );
-LDAP_SLAPD_F (LloadConnection *) client_init( ber_socket_t s, const char *peername, struct event_base *base, int use_tls );
+LDAP_SLAPD_F (LloadConnection *) client_init( ber_socket_t s,
+ struct berval *localname,
+ struct berval *peername,
+ struct event_base *base,
+ int use_tls );
LDAP_SLAPD_F (void) client_reset( LloadConnection *c );
LDAP_SLAPD_F (void) client_destroy( LloadConnection *c );
LDAP_SLAPD_F (void) clients_destroy( int gentle );
LDAP_SLAPD_F (void) connection_write_cb( evutil_socket_t s, short what, void *arg );
LDAP_SLAPD_F (void) connection_read_cb( evutil_socket_t s, short what, void *arg );
LDAP_SLAPD_F (int) lload_connection_close( LloadConnection *c, void *arg );
-LDAP_SLAPD_F (LloadConnection *) lload_connection_init( ber_socket_t s, const char *peername, int use_tls );
+LDAP_SLAPD_F (LloadConnection *) lload_connection_init( ber_socket_t s,
+ struct berval *localname,
+ struct berval *peername,
+ int use_tls );
LDAP_SLAPD_F (void) connection_destroy( LloadConnection *c );
LDAP_SLAPD_F (void) connections_walk_last( ldap_pvt_thread_mutex_t *cq_mutex,
lload_c_head *cq,
LDAP_SLAPD_F (int) forward_final_response( LloadConnection *client, LloadOperation *op, BerElement *ber );
LDAP_SLAPD_F (int) forward_response( LloadConnection *client, LloadOperation *op, BerElement *ber );
LDAP_SLAPD_F (void *) upstream_bind( void *ctx, void *arg );
-LDAP_SLAPD_F (LloadConnection *) upstream_init( ber_socket_t s, LloadBackend *b );
+LDAP_SLAPD_F (LloadConnection *) upstream_init( ber_socket_t s,
+ struct berval *localbv,
+ struct berval *peerbv,
+ LloadBackend *b );
LDAP_SLAPD_F (void) upstream_destroy( LloadConnection *c );
LDAP_SLAPD_V (ber_len_t) sockbuf_max_incoming_client;
* We must already hold b->b_mutex when called.
*/
LloadConnection *
-upstream_init( ber_socket_t s, LloadBackend *b )
+upstream_init(
+ ber_socket_t s,
+ struct berval *localbv,
+ struct berval *peerbv,
+ LloadBackend *b )
{
LloadConnection *c;
struct event_base *base = lload_get_base( s );
assert( b != NULL );
flags = (b->b_proto == LDAP_PROTO_IPC) ? CONN_IS_IPC : 0;
- if ( (c = lload_connection_init( s, b->b_host, flags )) == NULL ) {
+ if ( (c = lload_connection_init( s, localbv, peerbv, flags )) == NULL ) {
return NULL;
}