From d1e874c605233de3ecb4dfb44e12dfb9f7acb267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Tue, 9 Oct 2018 12:24:04 +0200 Subject: [PATCH] ITS#8768 Introduce delcsn into our syncrepl cookies --- servers/slapd/ldapsync.c | 63 ++++++++++++++++++++++++++++++- servers/slapd/overlays/syncprov.c | 13 ++++--- servers/slapd/proto-slap.h | 2 +- servers/slapd/slap.h | 1 + servers/slapd/syncrepl.c | 8 ++-- 5 files changed, 76 insertions(+), 11 deletions(-) diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c index c120bdf30c..9f30dce5d3 100644 --- a/servers/slapd/ldapsync.c +++ b/servers/slapd/ldapsync.c @@ -36,7 +36,8 @@ slap_compose_sync_cookie( struct berval *cookie, BerVarray csn, int rid, - int sid ) + int sid, + struct berval *delcsn ) { int len, numcsn = 0; @@ -65,6 +66,8 @@ slap_compose_sync_cookie( len = 0; for ( i=0; ibv_len; len += STRLENOF("rid=123,csn="); if ( sid >= 0 ) @@ -83,6 +86,10 @@ slap_compose_sync_cookie( *ptr++ = ';'; } ptr--; + if ( delcsn && !BER_BVISEMPTY(delcsn) ) { + ptr = lutil_strcopy( ptr, ",delcsn=" ); + ptr = lutil_strncopy( ptr, delcsn->bv_val, delcsn->bv_len ); + } *ptr = '\0'; cookie->bv_len = ptr - cookie->bv_val; } @@ -112,6 +119,11 @@ slap_sync_cookie_free( BER_BVZERO( &cookie->octet_str ); } + if ( !BER_BVISNULL( &cookie->delcsn )) { + ch_free( cookie->delcsn.bv_val ); + BER_BVZERO( &cookie->delcsn ); + } + if ( free_cookie ) { ch_free( cookie ); } @@ -273,6 +285,7 @@ slap_parse_sync_cookie( cookie->ctxcsn = NULL; cookie->sids = NULL; cookie->numcsns = 0; + BER_BVZERO( &cookie->delcsn ); end = cookie->octet_str.bv_val + cookie->octet_str.bv_len; @@ -359,6 +372,49 @@ slap_parse_sync_cookie( } continue; } + if ( !strncmp( next, "delcsn=", STRLENOF("delcsn=") )) { + struct berval stamp; + + next += STRLENOF("delcsn="); + while ( next < end ) { + csn_str = next; + csn_ptr = strchr( csn_str, '#' ); + if ( !csn_ptr || csn_ptr > end ) + break; + /* ad will be NULL when called from main. we just + * want to parse the rid then. But we still iterate + * through the string to find the end. + */ + cval = strchr( csn_ptr, ';' ); + if ( !cval ) + cval = strchr(csn_ptr, ',' ); + if ( cval ) + stamp.bv_len = cval - csn_str; + else + stamp.bv_len = end - csn_str; + if ( ad ) { + struct berval bv; + stamp.bv_val = csn_str; + if ( ad->ad_type->sat_syntax->ssyn_validate( + ad->ad_type->sat_syntax, &stamp ) != LDAP_SUCCESS ) + break; + if ( ad->ad_type->sat_equality->smr_normalize( + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + ad->ad_type->sat_syntax, + ad->ad_type->sat_equality, + &stamp, &bv, memctx ) != LDAP_SUCCESS ) + break; + cookie->delcsn = bv; + } + if ( cval ) { + next = cval + 1; + } else { + next = end; + } + break; + } + continue; + } next++; } if ( cookie->numcsns ) { @@ -411,6 +467,7 @@ slap_init_sync_cookie_ctxcsn( value_add_one( &cookie->ctxcsn, &ctxcsn ); cookie->numcsns = 1; cookie->sid = -1; + BER_BVZERO( &cookie->delcsn ); return 0; } @@ -455,6 +512,10 @@ slap_dup_sync_cookie( new->sids[i] = src->sids[i]; } + if ( !BER_BVISNULL( &src->delcsn )) { + ber_dupbv( &new->delcsn, &src->delcsn ); + } + if ( !BER_BVISNULL( &src->octet_str )) { ber_dupbv( &new->octet_str, &src->octet_str ); } diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 8dfcc3a465..5ea9e81c9c 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -887,7 +887,8 @@ syncprov_sendresp( Operation *op, resinfo *ri, syncops *so, int mode ) rs.sr_flags = REP_CTRLS_MUSTBEFREED; csns[0] = ri->ri_csn; BER_BVZERO( &csns[1] ); - slap_compose_sync_cookie( op, &cookie, csns, so->s_rid, slap_serverID ? slap_serverID : -1 ); + slap_compose_sync_cookie( op, &cookie, csns, so->s_rid, + slap_serverID ? slap_serverID : -1, NULL ); #ifdef LDAP_DEBUG if ( so->s_sid > 0 ) { @@ -1139,7 +1140,7 @@ syncprov_qresp( opcookie *opc, syncops *so, int mode ) syncprov_info_t *si = opc->son->on_bi.bi_private; slap_compose_sync_cookie( NULL, &ri->ri_cookie, si->si_ctxcsn, - so->s_rid, slap_serverID ? slap_serverID : -1); + so->s_rid, slap_serverID ? slap_serverID : -1, NULL ); } Debug( LDAP_DEBUG_SYNC, "%s syncprov_qresp: " "set up a new syncres mode=%d csn=%s\n", @@ -1899,7 +1900,7 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl, if ( delcsn[0].bv_len ) { slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid, - slap_serverID ? slap_serverID : -1 ); + slap_serverID ? slap_serverID : -1, delcsn ); Debug( LDAP_DEBUG_SYNC, "%s syncprov_playlog: cookie=%s\n", op->o_log_prefix, cookie.bv_val ); @@ -2537,7 +2538,8 @@ syncprov_search_response( Operation *op, SlapReply *rs ) /* If we're in delta-sync mode, always send a cookie */ if ( si->si_nopres && si->si_usehint && a ) { struct berval cookie; - slap_compose_sync_cookie( op, &cookie, a->a_nvals, srs->sr_state.rid, slap_serverID ? slap_serverID : -1 ); + slap_compose_sync_cookie( op, &cookie, a->a_nvals, srs->sr_state.rid, + slap_serverID ? slap_serverID : -1, NULL ); rs->sr_err = syncprov_state_ctrl( op, rs, rs->sr_entry, LDAP_SYNC_ADD, rs->sr_ctrls, 0, 1, &cookie ); op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx ); @@ -2551,7 +2553,8 @@ syncprov_search_response( Operation *op, SlapReply *rs ) if ( ( ss->ss_flags & SS_CHANGED ) && ss->ss_ctxcsn && !BER_BVISNULL( &ss->ss_ctxcsn[0] )) { slap_compose_sync_cookie( op, &cookie, ss->ss_ctxcsn, - srs->sr_state.rid, slap_serverID ? slap_serverID : -1 ); + srs->sr_state.rid, + slap_serverID ? slap_serverID : -1, NULL ); Debug( LDAP_DEBUG_SYNC, "%s syncprov_search_response: cookie=%s\n", op->o_log_prefix, cookie.bv_val ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 0790a80040..628f165fed 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -1188,7 +1188,7 @@ LDAP_SLAPD_V (char *) slap_known_controls[]; * ldapsync.c */ LDAP_SLAPD_F (void) slap_compose_sync_cookie LDAP_P(( - Operation *, struct berval *, BerVarray, int, int )); + Operation *, struct berval *, BerVarray, int, int, struct berval * )); LDAP_SLAPD_F (void) slap_sync_cookie_free LDAP_P(( struct sync_cookie *, int free_cookie )); LDAP_SLAPD_F (int) slap_parse_csn_sid LDAP_P(( diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 38c6bf1c48..400f9bbc4c 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1769,6 +1769,7 @@ struct sync_cookie { int numcsns; int rid; struct berval octet_str; + struct berval delcsn; int sid; LDAP_STAILQ_ENTRY(sync_cookie) sc_next; }; diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index afebf74b39..af5c3cef7a 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -764,7 +764,7 @@ check_syncprov( ch_free( si->si_syncCookie.octet_str.bv_val ); slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, - si->si_syncCookie.sid ); + si->si_syncCookie.sid, NULL ); ch_free( si->si_syncCookie.sids ); slap_reparse_sync_cookie( &si->si_syncCookie, op->o_tmpmemctx ); } @@ -927,7 +927,7 @@ do_syncrep1( ch_free( si->si_syncCookie.octet_str.bv_val ); slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, - si->si_syncCookie.sid ); + si->si_syncCookie.sid, NULL ); } else { /* ITS#6367: recreate the cookie so it has our SID, not our peer's */ ch_free( si->si_syncCookie.octet_str.bv_val ); @@ -937,7 +937,7 @@ do_syncrep1( if ( BER_BVISNULL( &si->si_syncCookie.octet_str )) slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, - si->si_syncCookie.sid ); + si->si_syncCookie.sid, NULL ); } } @@ -1852,7 +1852,7 @@ reload: if ( BER_BVISNULL( &si->si_syncCookie.octet_str )) slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, - si->si_syncCookie.sid ); + si->si_syncCookie.sid, NULL ); rc = ldap_sync_search( si, op->o_tmpmemctx ); goto reload; }