1 /* conn.c - deal with connection subsystem */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2005 The OpenLDAP Foundation.
6 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software.
25 #include <ac/string.h>
29 #include "back-monitor.h"
32 #define MONITOR_LEGACY_CONN
36 monitor_subsys_conn_update(
42 monitor_subsys_conn_create(
50 monitor_subsys_conn_init(
52 monitor_subsys_t *ms )
55 Entry *e, **ep, *e_conn;
57 char buf[ BACKMONITOR_BUFSIZE ];
62 ms->mss_update = monitor_subsys_conn_update;
63 ms->mss_create = monitor_subsys_conn_create;
65 mi = ( monitor_info_t * )be->be_private;
67 if ( monitor_cache_get( mi, &ms->mss_ndn, &e_conn ) ) {
68 Debug( LDAP_DEBUG_ANY,
69 "monitor_subsys_conn_init: "
70 "unable to get entry \"%s\"\n",
71 ms->mss_ndn.bv_val, 0, 0 );
75 mp = ( monitor_entry_t * )e_conn->e_private;
76 mp->mp_children = NULL;
77 ep = &mp->mp_children;
82 snprintf( buf, sizeof( buf ),
85 "structuralObjectClass: %s\n"
89 "createTimestamp: %s\n"
90 "modifyTimestamp: %s\n",
92 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
93 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
94 mi->mi_creatorsName.bv_val,
95 mi->mi_creatorsName.bv_val,
96 mi->mi_startTime.bv_val,
97 mi->mi_startTime.bv_val );
101 Debug( LDAP_DEBUG_ANY,
102 "monitor_subsys_conn_init: "
103 "unable to create entry \"cn=Total,%s\"\n",
104 ms->mss_ndn.bv_val, 0, 0 );
108 BER_BVSTR( &bv, "0" );
109 attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, &bv );
111 mp = monitor_entrypriv_create();
115 e->e_private = ( void * )mp;
117 mp->mp_flags = ms->mss_flags \
118 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
119 mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
121 if ( monitor_cache_add( mi, e ) ) {
122 Debug( LDAP_DEBUG_ANY,
123 "monitor_subsys_conn_init: "
124 "unable to add entry \"cn=Total,%s\"\n",
125 ms->mss_ndn.bv_val, 0, 0 );
135 snprintf( buf, sizeof( buf ),
136 "dn: cn=Current,%s\n"
138 "structuralObjectClass: %s\n"
141 "modifiersName: %s\n"
142 "createTimestamp: %s\n"
143 "modifyTimestamp: %s\n",
145 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
146 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
147 mi->mi_creatorsName.bv_val,
148 mi->mi_creatorsName.bv_val,
149 mi->mi_startTime.bv_val,
150 mi->mi_startTime.bv_val );
152 e = str2entry( buf );
154 Debug( LDAP_DEBUG_ANY,
155 "monitor_subsys_conn_init: "
156 "unable to create entry \"cn=Current,%s\"\n",
157 ms->mss_ndn.bv_val, 0, 0 );
161 BER_BVSTR( &bv, "0" );
162 attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, &bv );
164 mp = monitor_entrypriv_create();
168 e->e_private = ( void * )mp;
170 mp->mp_flags = ms->mss_flags \
171 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
172 mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
174 if ( monitor_cache_add( mi, e ) ) {
175 Debug( LDAP_DEBUG_ANY,
176 "monitor_subsys_conn_init: "
177 "unable to add entry \"cn=Current,%s\"\n",
178 ms->mss_ndn.bv_val, 0, 0 );
185 monitor_cache_release( mi, e_conn );
191 monitor_subsys_conn_update(
196 monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private;
199 static struct berval total_bv = BER_BVC( "cn=total" ),
200 current_bv = BER_BVC( "cn=current" );
203 assert( mi != NULL );
206 dnRdn( &e->e_nname, &rdn );
208 if ( dn_match( &rdn, &total_bv ) ) {
209 n = connections_nextid();
211 } else if ( dn_match( &rdn, ¤t_bv ) ) {
215 for ( n = 0, c = connection_first( &connindex );
217 n++, c = connection_next( c, &connindex ) ) {
220 connection_done( c );
225 char buf[] = "+9223372036854775807L";
228 a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
233 snprintf( buf, sizeof( buf ), "%ld", n );
235 if ( len > a->a_vals[ 0 ].bv_len ) {
236 a->a_vals[ 0 ].bv_val = ber_memrealloc( a->a_vals[ 0 ].bv_val, len + 1 );
238 a->a_vals[ 0 ].bv_len = len;
239 AC_MEMCPY( a->a_vals[ 0 ].bv_val, buf, len + 1 );
241 /* FIXME: touch modifyTimestamp? */
244 return SLAP_CB_CONTINUE;
252 monitor_subsys_t *ms )
256 char buf[ BACKMONITOR_BUFSIZE ];
257 char buf2[ LDAP_LUTIL_GENTIME_BUFSIZE ];
258 char buf3[ LDAP_LUTIL_GENTIME_BUFSIZE ];
263 char ctmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
265 char mtmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
268 #endif /* HAVE_GMTIME_R */
271 assert( ep != NULL );
273 #ifndef HAVE_GMTIME_R
274 ldap_pvt_thread_mutex_lock( &gmtime_mutex );
276 #ifdef HACK_LOCAL_TIME
277 # ifdef HAVE_LOCALTIME_R
278 ctm = localtime_r( &c->c_starttime, &tm_buf );
279 lutil_localtime( ctmbuf, sizeof( ctmbuf ), ctm, -timezone );
280 mtm = localtime_r( &c->c_activitytime, &tm_buf );
281 lutil_localtime( mtmbuf, sizeof( mtmbuf ), mtm, -timezone );
283 ctm = localtime( &c->c_starttime );
284 lutil_localtime( ctmbuf, sizeof( ctmbuf ), ctm, -timezone );
285 mtm = localtime( &c->c_activitytime );
286 lutil_localtime( mtmbuf, sizeof( mtmbuf ), mtm, -timezone );
287 # endif /* HAVE_LOCALTIME_R */
288 #else /* !HACK_LOCAL_TIME */
289 # ifdef HAVE_GMTIME_R
290 ctm = gmtime_r( &c->c_starttime, &tm_buf );
291 lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
292 mtm = gmtime_r( &c->c_activitytime, &tm_buf );
293 lutil_gentime( mtmbuf, sizeof( mtmbuf ), mtm );
295 ctm = gmtime( &c->c_starttime );
296 lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
297 mtm = gmtime( &c->c_activitytime );
298 lutil_gentime( mtmbuf, sizeof( mtmbuf ), mtm );
299 # endif /* HAVE_GMTIME_R */
300 #endif /* !HACK_LOCAL_TIME */
301 #ifndef HAVE_GMTIME_R
302 ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
305 #ifndef HAVE_GMTIME_R
306 ldap_pvt_thread_mutex_lock( &gmtime_mutex );
310 ltm = gmtime_r( &c->c_starttime, &tm_buf );
312 ltm = gmtime( &c->c_starttime );
314 lutil_gentime( buf2, sizeof( buf2 ), ltm );
317 ltm = gmtime_r( &c->c_activitytime, &tm_buf );
319 ltm = gmtime( &c->c_activitytime );
321 lutil_gentime( buf3, sizeof( buf3 ), ltm );
323 #ifndef HAVE_GMTIME_R
324 ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
325 #endif /* HAVE_GMTIME_R */
327 snprintf( buf, sizeof( buf ),
328 "dn: cn=Connection %ld,%s\n"
330 "structuralObjectClass: %s\n"
331 "cn: Connection %ld\n"
333 #ifdef MONITOR_LEGACY_CONN
334 /* NOTE: this will disappear, as the exploded data
335 * has been moved to dedicated attributes */
349 #endif /* MONITOR_LEGACY_CONN */
376 "modifiersName: %s\n"
377 "createTimestamp: %s\n"
378 "modifyTimestamp: %s\n",
379 c->c_connid, ms->mss_dn.bv_val,
380 mi->mi_oc_monitorConnection->soc_cname.bv_val,
381 mi->mi_oc_monitorConnection->soc_cname.bv_val,
384 #ifdef MONITOR_LEGACY_CONN
385 mi->mi_ad_monitoredInfo->ad_cname.bv_val,
387 (long) c->c_protocol,
388 c->c_n_ops_received, c->c_n_ops_executing,
389 c->c_n_ops_pending, c->c_n_ops_completed,
391 /* add low-level counters here */
392 c->c_n_get, c->c_n_read, c->c_n_write,
394 c->c_currentber ? "r" : "",
395 c->c_writewaiter ? "w" : "",
396 LDAP_STAILQ_EMPTY( &c->c_ops ) ? "" : "x",
397 LDAP_STAILQ_EMPTY( &c->c_pending_ops ) ? "" : "p",
398 connection_state2str( c->c_conn_state ),
399 c->c_sasl_bind_in_progress ? "S" : "",
401 c->c_dn.bv_len ? c->c_dn.bv_val : SLAPD_ANONYMOUS,
403 c->c_listener_url.bv_val,
404 c->c_peer_domain.bv_val,
405 c->c_peer_name.bv_val,
406 c->c_sock_name.bv_val,
410 #endif /* MONITOR_LEGACY_CONN */
412 mi->mi_ad_monitorConnectionNumber->ad_cname.bv_val,
414 mi->mi_ad_monitorConnectionProtocol->ad_cname.bv_val,
417 mi->mi_ad_monitorConnectionOpsReceived->ad_cname.bv_val,
419 mi->mi_ad_monitorConnectionOpsExecuting->ad_cname.bv_val,
420 c->c_n_ops_executing,
421 mi->mi_ad_monitorConnectionOpsPending->ad_cname.bv_val,
423 mi->mi_ad_monitorConnectionOpsCompleted->ad_cname.bv_val,
424 c->c_n_ops_completed,
426 mi->mi_ad_monitorConnectionGet->ad_cname.bv_val,
428 mi->mi_ad_monitorConnectionRead->ad_cname.bv_val,
430 mi->mi_ad_monitorConnectionWrite->ad_cname.bv_val,
433 mi->mi_ad_monitorConnectionMask->ad_cname.bv_val,
434 c->c_currentber ? "r" : "",
435 c->c_writewaiter ? "w" : "",
436 LDAP_STAILQ_EMPTY( &c->c_ops ) ? "" : "x",
437 LDAP_STAILQ_EMPTY( &c->c_pending_ops ) ? "" : "p",
438 connection_state2str( c->c_conn_state ),
439 c->c_sasl_bind_in_progress ? "S" : "",
441 mi->mi_ad_monitorConnectionAuthzDN->ad_cname.bv_val,
442 c->c_dn.bv_len ? c->c_dn.bv_val : SLAPD_ANONYMOUS,
444 /* NOTE: client connections leave the c_peer_* fields NULL */
445 mi->mi_ad_monitorConnectionListener->ad_cname.bv_val,
446 c->c_listener_url.bv_val,
447 mi->mi_ad_monitorConnectionPeerDomain->ad_cname.bv_val,
448 BER_BVISNULL( &c->c_peer_domain ) ? "unknown" : c->c_peer_domain.bv_val,
449 mi->mi_ad_monitorConnectionLocalAddress->ad_cname.bv_val,
450 BER_BVISNULL( &c->c_peer_name ) ? "unknown" : c->c_peer_name.bv_val,
451 mi->mi_ad_monitorConnectionPeerAddress->ad_cname.bv_val,
452 c->c_sock_name.bv_val,
454 mi->mi_ad_monitorConnectionStartTime->ad_cname.bv_val,
456 mi->mi_ad_monitorConnectionActivityTime->ad_cname.bv_val,
459 mi->mi_creatorsName.bv_val,
460 mi->mi_creatorsName.bv_val,
464 e = str2entry( buf );
467 Debug( LDAP_DEBUG_ANY,
468 "monitor_subsys_conn_create: "
469 "unable to create entry "
470 "\"cn=Connection %ld,%s\" entry\n",
472 ms->mss_dn.bv_val, 0 );
476 mp = monitor_entrypriv_create();
480 e->e_private = ( void * )mp;
482 mp->mp_flags = MONITOR_F_SUB | MONITOR_F_VOLATILE;
486 return SLAP_CB_CONTINUE;
490 monitor_subsys_conn_create(
497 monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private;
502 int rc = SLAP_CB_CONTINUE;
503 monitor_subsys_t *ms;
505 assert( mi != NULL );
506 assert( e_parent != NULL );
507 assert( ep != NULL );
509 ms = (( monitor_entry_t *)e_parent->e_private)->mp_info;
517 /* create all the children of e_parent */
518 for ( c = connection_first( &connindex );
520 c = connection_next( c, &connindex ) )
522 if ( conn_create( mi, c, &e, ms ) != SLAP_CB_CONTINUE
525 for ( ; e_tmp != NULL; ) {
526 mp = ( monitor_entry_t * )e_tmp->e_private;
530 e_tmp->e_private = NULL;
535 rc = rs->sr_err = LDAP_OTHER;
538 mp = ( monitor_entry_t * )e->e_private;
542 connection_done( c );
546 unsigned long connid;
548 static struct berval nconn_bv = BER_BVC( "cn=connection " );
551 /* create exactly the required entry;
552 * the normalized DN must start with "cn=connection ",
553 * followed by the connection id, followed by
554 * the RDN separator "," */
555 if ( ndn->bv_len <= nconn_bv.bv_len
556 || strncmp( ndn->bv_val, nconn_bv.bv_val, nconn_bv.bv_len ) != 0 )
561 connid = strtol( &ndn->bv_val[ nconn_bv.bv_len ], &next, 10 );
562 if ( next[ 0 ] != ',' ) {
563 return ( rs->sr_err = LDAP_OTHER );
566 for ( c = connection_first( &connindex );
568 c = connection_next( c, &connindex ) )
570 if ( c->c_connid == connid ) {
571 rc = conn_create( mi, c, ep, ms );
572 if ( rc != SLAP_CB_CONTINUE ) {
575 } else if ( *ep == NULL ) {
576 rc = rs->sr_err = LDAP_OTHER;
583 connection_done( c );