]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/conn.c
075b6abba09bfe0d46d2d58607bca5cc4177f4a9
[openldap] / servers / slapd / back-monitor / conn.c
1 /* conn.c - deal with connection subsystem */
2 /*
3  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
8  * 
9  * This work has beed deveolped for the OpenLDAP Foundation 
10  * in the hope that it may be useful to the Open Source community, 
11  * but WITHOUT ANY WARRANTY.
12  * 
13  * Permission is granted to anyone to use this software for any purpose
14  * on any computer system, and to alter it and redistribute it, subject
15  * to the following restrictions:
16  * 
17  * 1. The author and SysNet s.n.c. are not responsible for the consequences
18  *    of use of this software, no matter how awful, even if they arise from
19  *    flaws in it.
20  * 
21  * 2. The origin of this software must not be misrepresented, either by
22  *    explicit claim or by omission.  Since few users ever read sources,
23  *    credits should appear in the documentation.
24  * 
25  * 3. Altered versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.  Since few users
27  *    ever read sources, credits should appear in the documentation.
28  *    SysNet s.n.c. cannot be responsible for the consequences of the
29  *    alterations.
30  * 
31  * 4. This notice may not be removed or altered.
32  */
33
34 #include "portable.h"
35
36 #include <stdio.h>
37 #include <ac/string.h>
38
39 #include "slap.h"
40 #include "lutil.h"
41 #include "back-monitor.h"
42
43 #define CONN_CN_PREFIX  "Connection"
44
45 int
46 monitor_subsys_conn_init(
47         BackendDB               *be
48 )
49 {
50         struct monitorinfo      *mi;
51         
52         Entry                   *e, *e_tmp, *e_conn;
53         struct monitorentrypriv *mp;
54         char                    buf[ BACKMONITOR_BUFSIZE ];
55         struct berval           bv;
56
57         assert( be != NULL );
58
59         mi = ( struct monitorinfo * )be->be_private;
60
61         if ( monitor_cache_get( mi,
62                         &monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn, &e_conn ) ) {
63 #ifdef NEW_LOGGING
64                 LDAP_LOG( OPERATION, CRIT,
65                         "monitor_subsys_conn_init: "
66                         "unable to get entry '%s'\n",
67                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
68 #else
69                 Debug( LDAP_DEBUG_ANY,
70                         "monitor_subsys_conn_init: "
71                         "unable to get entry '%s'\n%s%s",
72                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 
73                         "", "" );
74 #endif
75                 return( -1 );
76         }
77
78         e_tmp = NULL;
79
80         /*
81          * Total conns
82          */
83         snprintf( buf, sizeof( buf ),
84                 "dn: cn=Total,%s\n"
85                 "objectClass: %s\n"
86                 "structuralObjectClass: %s\n"
87                 "cn: Total\n"
88                 "createTimestamp: %s\n"
89                 "modifyTimestamp: %s\n",
90                 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val,
91                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
92                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
93                 mi->mi_startTime.bv_val,
94                 mi->mi_startTime.bv_val );
95         
96         e = str2entry( buf );
97         if ( e == NULL ) {
98 #ifdef NEW_LOGGING
99                 LDAP_LOG( OPERATION, CRIT,
100                         "monitor_subsys_conn_init: "
101                         "unable to create entry 'cn=Total,%s'\n",
102                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
103 #else
104                 Debug( LDAP_DEBUG_ANY,
105                         "monitor_subsys_conn_init: "
106                         "unable to create entry 'cn=Total,%s'\n%s%s",
107                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
108                         "", "" );
109 #endif
110                 return( -1 );
111         }
112         
113         bv.bv_val = "0";
114         bv.bv_len = 1;
115         attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
116         
117         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
118         e->e_private = ( void * )mp;
119         mp->mp_next = e_tmp;
120         mp->mp_children = NULL;
121         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
122         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
123                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
124         mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
125
126         if ( monitor_cache_add( mi, e ) ) {
127 #ifdef NEW_LOGGING
128                 LDAP_LOG( OPERATION, CRIT,
129                         "monitor_subsys_conn_init: "
130                         "unable to add entry 'cn=Total,%s'\n",
131                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
132 #else
133                 Debug( LDAP_DEBUG_ANY,
134                         "monitor_subsys_conn_init: "
135                         "unable to add entry 'cn=Total,%s'\n%s%s",
136                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
137                         "", "" );
138 #endif
139                 return( -1 );
140         }
141         
142         e_tmp = e;
143
144         /*
145          * Current conns
146          */
147         snprintf( buf, sizeof( buf ),
148                 "dn: cn=Current,%s\n"
149                 "objectClass: %s\n"
150                 "structuralObjectClass: %s\n"
151                 "cn: Current\n"
152                 "createTimestamp: %s\n"
153                 "modifyTimestamp: %s\n",
154                 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val,
155                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
156                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
157                 mi->mi_startTime.bv_val,
158                 mi->mi_startTime.bv_val );
159         
160         e = str2entry( buf );
161         if ( e == NULL ) {
162 #ifdef NEW_LOGGING
163                 LDAP_LOG( OPERATION, CRIT,
164                         "monitor_subsys_conn_init: "
165                         "unable to create entry 'cn=Current,%s'\n",
166                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
167 #else
168                 Debug( LDAP_DEBUG_ANY,
169                         "monitor_subsys_conn_init: "
170                         "unable to create entry 'cn=Current,%s'\n%s%s",
171                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
172                         "", "" );
173 #endif
174                 return( -1 );
175         }
176         
177         bv.bv_val = "0";
178         bv.bv_len = 1;
179         attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
180         
181         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
182         e->e_private = ( void * )mp;
183         mp->mp_next = e_tmp;
184         mp->mp_children = NULL;
185         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
186         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
187                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
188         mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
189
190         if ( monitor_cache_add( mi, e ) ) {
191 #ifdef NEW_LOGGING
192                 LDAP_LOG( OPERATION, CRIT,
193                         "monitor_subsys_conn_init: "
194                         "unable to add entry 'cn=Current,%s'\n",
195                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
196 #else
197                 Debug( LDAP_DEBUG_ANY,
198                         "monitor_subsys_conn_init: "
199                         "unable to add entry 'cn=Current,%s'\n%s%s",
200                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
201                         "", "" );
202 #endif
203                 return( -1 );
204         }
205         
206         e_tmp = e;
207
208         mp = ( struct monitorentrypriv * )e_conn->e_private;
209         mp->mp_children = e_tmp;
210
211         monitor_cache_release( mi, e_conn );
212
213         return( 0 );
214 }
215
216 int
217 monitor_subsys_conn_update(
218         Operation               *op,
219         Entry                   *e
220 )
221 {
222         struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
223         long            n = -1;
224
225         assert( mi );
226         assert( e );
227         
228         if ( strncasecmp( e->e_ndn, "cn=total", 
229                                 sizeof("cn=total")-1 ) == 0 ) {
230                 n = connections_nextid();
231
232         } else if ( strncasecmp( e->e_ndn, "cn=current", 
233                                 sizeof("cn=current")-1 ) == 0 ) {
234                 Connection      *c;
235                 int             connindex;
236
237                 for ( n = 0, c = connection_first( &connindex );
238                                 c != NULL;
239                                 n++, c = connection_next( c, &connindex ) ) {
240                         /* No Op */ ;
241                 }
242                 connection_done(c);
243         }
244
245         if ( n != -1 ) {
246                 Attribute       *a;
247                 char            buf[] = "+9223372036854775807L";
248
249                 a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
250                 if ( a == NULL ) {
251                         return( -1 );
252                 }
253
254                 snprintf( buf, sizeof( buf ), "%ld", n );
255                 free( a->a_vals[ 0 ].bv_val );
256                 ber_str2bv( buf, 0, 1, a->a_vals );
257         }
258
259         return( 0 );
260 }
261
262 static int
263 conn_create(
264         struct monitorinfo      *mi,
265         Connection              *c,
266         Entry                   **ep
267 )
268 {
269         struct monitorentrypriv *mp;
270         struct tm               *ltm;
271         char                    buf[ BACKMONITOR_BUFSIZE ];
272         char                    buf2[ LDAP_LUTIL_GENTIME_BUFSIZE ];
273         char                    buf3[ LDAP_LUTIL_GENTIME_BUFSIZE ];
274
275         struct berval           bv;
276
277         Entry                   *e;
278
279         struct tm       *ctm;
280         char            ctmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
281         struct tm       *mtm;
282         char            mtmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
283
284         assert( c != NULL );
285         assert( ep != NULL );
286
287         ldap_pvt_thread_mutex_lock( &gmtime_mutex );
288 #ifdef HACK_LOCAL_TIME
289         ctm = localtime( &c->c_starttime );
290         lutil_localtime( ctmbuf, sizeof( ctmbuf ), ctm, -timezone );
291         mtm = localtime( &c->c_activitytime );
292         lutil_localtime( mtmbuf, sizeof( mtmbuf ), mtm, -timezone );
293 #else /* !HACK_LOCAL_TIME */
294         ctm = gmtime( &c->c_starttime );
295         lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
296         mtm = gmtime( &c->c_activitytime );
297         lutil_gentime( mtmbuf, sizeof( mtmbuf ), mtm );
298 #endif /* !HACK_LOCAL_TIME */
299         ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
300
301         snprintf( buf, sizeof( buf ),
302                 "dn: cn=" CONN_CN_PREFIX " %ld,%s\n"
303                 "objectClass: %s\n"
304                 "structuralObjectClass: %s\n"
305                 "cn: " CONN_CN_PREFIX " %ld\n"
306                 "createTimestamp: %s\n"
307                 "modifyTimestamp: %s\n",
308                 c->c_connid, monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val,
309                 mi->mi_oc_monitorConnection->soc_cname.bv_val,
310                 mi->mi_oc_monitorConnection->soc_cname.bv_val,
311                 c->c_connid,
312                 ctmbuf, mtmbuf );
313                 
314         e = str2entry( buf );
315
316         if ( e == NULL) {
317 #ifdef NEW_LOGGING
318                 LDAP_LOG( OPERATION, CRIT,
319                         "monitor_subsys_conn_create: "
320                         "unable to create entry "
321                         "'cn=" CONN_CN_PREFIX " %ld,%s' entry\n",
322                         c->c_connid, monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val, 0 );
323 #else
324                 Debug( LDAP_DEBUG_ANY,
325                         "monitor_subsys_conn_create: "
326                         "unable to create entry "
327                         "'cn=" CONN_CN_PREFIX " %ld,%s' entry\n",
328                         c->c_connid, 
329                         monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val, 0 );
330 #endif
331                 return( -1 );
332         }
333
334         ldap_pvt_thread_mutex_lock( &gmtime_mutex );
335         
336         ltm = gmtime( &c->c_starttime );
337         lutil_gentime( buf2, sizeof( buf2 ), ltm );
338                         
339         ltm = gmtime( &c->c_activitytime );
340         lutil_gentime( buf3, sizeof( buf3 ), ltm );
341                         
342         ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
343
344         /* monitored info */
345         sprintf( buf,
346                 "%ld : %ld "
347                 ": %ld/%ld/%ld/%ld "
348                 ": %ld/%ld/%ld "
349                 ": %s%s%s%s%s%s "
350                 ": %s : %s : %s "
351                 ": %s : %s : %s : %s",
352                 c->c_connid,
353                 (long) c->c_protocol,
354                 c->c_n_ops_received, c->c_n_ops_executing,
355                 c->c_n_ops_pending, c->c_n_ops_completed,
356                 
357                 /* add low-level counters here */
358                 c->c_n_get, c->c_n_read, c->c_n_write,
359                 
360                 c->c_currentber ? "r" : "",
361                 c->c_writewaiter ? "w" : "",
362                 LDAP_STAILQ_EMPTY( &c->c_ops ) ? "" : "x",
363                 LDAP_STAILQ_EMPTY( &c->c_pending_ops ) ? "" : "p",
364                 connection_state2str( c->c_conn_state ),
365                 c->c_sasl_bind_in_progress ? "S" : "",
366                 
367                 c->c_dn.bv_len ? c->c_dn.bv_val : SLAPD_ANONYMOUS,
368                 
369                 c->c_listener_url.bv_val,
370                 c->c_peer_domain.bv_val,
371                 c->c_peer_name.bv_val,
372                 c->c_sock_name.bv_val,
373                 
374                 buf2,
375                 buf3
376                 );
377
378         bv.bv_val = buf;
379         bv.bv_len = strlen( buf );
380         attr_merge_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
381
382         /* connection number */
383         snprintf( buf, sizeof( buf ), "%ld", c->c_connid );
384         bv.bv_val = buf;
385         bv.bv_len = strlen( buf );
386         attr_merge_one( e, mi->mi_ad_monitorConnectionNumber, &bv, NULL );
387
388         /* authz DN */
389         attr_merge_one( e, mi->mi_ad_monitorConnectionAuthzDN,
390                         &c->c_dn, &c->c_ndn );
391
392         /* local address */
393         attr_merge_one( e, mi->mi_ad_monitorConnectionLocalAddress,
394                         &c->c_sock_name, NULL );
395
396         /* peer address */
397         attr_merge_one( e, mi->mi_ad_monitorConnectionPeerAddress,
398                         &c->c_peer_name, NULL );
399
400         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
401         e->e_private = ( void * )mp;
402         mp->mp_info = &monitor_subsys[ SLAPD_MONITOR_CONN ];
403         mp->mp_children = NULL;
404         mp->mp_flags = MONITOR_F_SUB | MONITOR_F_VOLATILE;
405
406         *ep = e;
407
408         return( 0 );
409 }
410
411 int 
412 monitor_subsys_conn_create( 
413         Operation               *op,
414         struct berval           *ndn,
415         Entry                   *e_parent,
416         Entry                   **ep
417 )
418 {
419         struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
420         Connection              *c;
421         int                     connindex;
422         struct monitorentrypriv *mp;
423
424         assert( mi != NULL );
425         assert( e_parent != NULL );
426         assert( ep != NULL );
427
428         *ep = NULL;
429
430         if ( ndn == NULL ) {
431                 Entry *e, *e_tmp = NULL;
432
433                 /* create all the children of e_parent */
434                 for ( c = connection_first( &connindex );
435                                 c != NULL;
436                                 c = connection_next( c, &connindex )) {
437                         if ( conn_create( mi, c, &e ) || e == NULL ) {
438                                 connection_done(c);
439                                 for ( ; e_tmp != NULL; ) {
440                                         mp = ( struct monitorentrypriv * )e_tmp->e_private;
441                                         e = mp->mp_next;
442
443                                         ch_free( mp );
444                                         e_tmp->e_private = NULL;
445                                         entry_free( e_tmp );
446
447                                         e_tmp = e;
448                                 }
449                                 return( -1 );
450                         }
451                         mp = ( struct monitorentrypriv * )e->e_private;
452                         mp->mp_next = e_tmp;
453                         e_tmp = e;
454                 }
455                 connection_done(c);
456
457                 *ep = e;
458
459         } else {
460                 LDAPRDN         values = NULL;
461                 const char      *text = NULL;
462                 unsigned long   connid;
463                
464                 /* create exactly the required entry */
465
466                 if ( ldap_bv2rdn( ndn, &values, (char **)&text,
467                         LDAP_DN_FORMAT_LDAP ) )
468                 {
469                         return( -1 );
470                 }
471                 
472                 assert( values );
473                 assert( values[ 0 ] );
474
475                 connid = atol( values[ 0 ]->la_value.bv_val
476                                 + sizeof( CONN_CN_PREFIX ) );
477
478                 ldap_rdnfree( values );
479
480                 for ( c = connection_first( &connindex );
481                                 c != NULL;
482                                 c = connection_next( c, &connindex )) {
483                         if ( c->c_connid == connid ) {
484                                 if ( conn_create( mi, c, ep ) || *ep == NULL ) {
485                                         connection_done( c );
486                                         return( -1 );
487                                 }
488
489                                 break;
490                         }
491                 }
492                 
493                 connection_done(c);
494         
495         }
496
497         return( 0 );
498 }
499