From ae74fa109def47dafbf899d4453f07d15f152e19 Mon Sep 17 00:00:00 2001 From: "Ted C. Cheng" <tedcheng@symas.com> Date: Wed, 23 Jan 2013 17:10:41 -0800 Subject: [PATCH] added tcp keepalive support to back-ldap --- doc/man/man5/slapd-ldap.5 | 19 +++++++++++++++++++ servers/slapd/back-ldap/bind.c | 3 +++ servers/slapd/back-ldap/config.c | 31 +++++++++++++++++++++++++++++++ servers/slapd/config.c | 30 +++++++++++++++++++++++++++++- 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5 index 7f80883069..d5700c0e84 100644 --- a/doc/man/man5/slapd-ldap.5 +++ b/doc/man/man5/slapd-ldap.5 @@ -413,6 +413,25 @@ for details on the syntax of this field. This directive causes a cached connection to be dropped an recreated after it has been idle for the specified time. +.TP +.B keepalive <idle>:<probes>:<interval> +The +.B keepalive +parameter sets the values of \fIidle\fP, \fIprobes\fP, and \fIinterval\fP +used to check whether a socket is alive; +.I idle +is the number of seconds a connection needs to remain idle before TCP +starts sending keepalive probes; +.I probes +is the maximum number of keepalive probes TCP should send before dropping +the connection; +.I interval +is interval in seconds between individual keepalive probes. +Only some systems support the customization of these values; +the +.B keepalive +parameter is ignored otherwise, and system-wide settings are used. + .TP .B network\-timeout <time> Sets the network timeout value after which diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 409b93c454..45f228a282 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -716,6 +716,9 @@ ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_ ldap_set_option( ld, LDAP_OPT_NETWORK_TIMEOUT, (const void *)&tv ); } + /* turn on network keepalive, if configured so */ + slap_client_keepalive(ld, &li->li_tls.sb_keepalive); + #ifdef HAVE_TLS if ( LDAP_BACK_CONN_ISPRIV( lc ) ) { /* See "rationale" comment in ldap_back_getconn() */ diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index d6af1ffec5..abb6ec1fec 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -74,6 +74,7 @@ enum { LDAP_BACK_CFG_ONERR, LDAP_BACK_CFG_REWRITE, + LDAP_BACK_CFG_KEEPALIVE, LDAP_BACK_CFG_LAST }; @@ -353,6 +354,14 @@ static ConfigTable ldapcfg[] = { { "rewrite", "<arglist>", 2, 4, STRLENOF( "rewrite" ), ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE, ldap_back_cf_gen, NULL, NULL, NULL }, + { "keepalive", "keepalive", 2, 2, 0, + ARG_MAGIC|LDAP_BACK_CFG_KEEPALIVE, + ldap_back_cf_gen, "( OLcfgDbAt:3.29 " + "NAME 'olcDbKeepalive' " + "DESC 'TCP keepalive' " + "SYNTAX OMsDirectoryString " + "SINGLE-VALUE )", + NULL, NULL }, { NULL, NULL, 0, 0, 0, ARG_IGNORED, NULL, NULL, NULL, NULL } }; @@ -393,6 +402,7 @@ static ConfigOCs ldapocs[] = { "$ olcDbNoRefs " "$ olcDbNoUndefFilter " "$ olcDbOnErr " + "$ olcDbKeepalive " ") )", Cft_Database, ldapcfg}, { NULL, 0, NULL } @@ -1367,6 +1377,16 @@ ldap_back_cf_gen( ConfigArgs *c ) } break; + case LDAP_BACK_CFG_KEEPALIVE: { + struct berval bv; + char buf[AC_LINE_MAX]; + bv.bv_len = AC_LINE_MAX; + bv.bv_val = &buf[0]; + slap_keepalive_parse(&bv, &li->li_tls.sb_keepalive, 0, 0, 1); + value_add_one( &c->rvalue_vals, &bv ); + break; + } + default: /* FIXME: we need to handle all... */ assert( 0 ); @@ -1534,6 +1554,12 @@ ldap_back_cf_gen( ConfigArgs *c ) li->li_flags &= ~LDAP_BACK_F_ONERR_STOP; break; + case LDAP_BACK_CFG_KEEPALIVE: + li->li_tls.sb_keepalive.sk_idle = 0; + li->li_tls.sb_keepalive.sk_probes = 0; + li->li_tls.sb_keepalive.sk_interval = 0; + break; + default: /* FIXME: we need to handle all... */ assert( 0 ); @@ -2222,6 +2248,11 @@ done_url:; "and prefix all directives with \"rwm-\")" ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; + + case LDAP_BACK_CFG_KEEPALIVE: + slap_keepalive_parse( ber_bvstrdup(c->argv[1]), + &li->li_tls.sb_keepalive, 0, 0, 0); + break; default: /* FIXME: try to catch inconsistencies */ diff --git a/servers/slapd/config.c b/servers/slapd/config.c index abc379f198..374dced4c3 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -1283,7 +1283,7 @@ static slap_verbmasks versionkey[] = { { BER_BVNULL, 0 } }; -static int +int slap_keepalive_parse( struct berval *val, void *bc, @@ -1925,6 +1925,29 @@ int bindconf_tls_set( slap_bindconf *bc, LDAP *ld ) } #endif +/* + * set connection keepalive options + */ +void +slap_client_keepalive(LDAP *ld, slap_keepalive *sk) +{ + if (!sk) return; + + if ( sk->sk_idle ) { + ldap_set_option( ld, LDAP_OPT_X_KEEPALIVE_IDLE, &sk->sk_idle ); + } + + if ( sk->sk_probes ) { + ldap_set_option( ld, LDAP_OPT_X_KEEPALIVE_PROBES, &sk->sk_probes ); + } + + if ( sk->sk_interval ) { + ldap_set_option( ld, LDAP_OPT_X_KEEPALIVE_INTERVAL, &sk->sk_interval ); + } + + return; +} + /* * connect to a client using the bindconf data * note: should move "version" into bindconf... @@ -1963,6 +1986,10 @@ slap_client_connect( LDAP **ldp, slap_bindconf *sb ) ldap_set_option( ld, LDAP_OPT_NETWORK_TIMEOUT, &tv ); } + /* setting network keepalive options */ + slap_client_keepalive(ld, &sb->sb_keepalive); + +#if 0 if ( sb->sb_keepalive.sk_idle ) { ldap_set_option( ld, LDAP_OPT_X_KEEPALIVE_IDLE, &sb->sb_keepalive.sk_idle ); } @@ -1974,6 +2001,7 @@ slap_client_connect( LDAP **ldp, slap_bindconf *sb ) if ( sb->sb_keepalive.sk_interval ) { ldap_set_option( ld, LDAP_OPT_X_KEEPALIVE_INTERVAL, &sb->sb_keepalive.sk_interval ); } +#endif /* 0 */ #ifdef HAVE_TLS if ( sb->sb_tls_do_init ) { -- GitLab