|
@@ -142,6 +142,7 @@ static void repl5_debug_timeout_callback(time_t when, void *arg);
|
|
|
|
|
|
|
|
/* Forward declarations */
|
|
/* Forward declarations */
|
|
|
static void close_connection_internal(Repl_Connection *conn);
|
|
static void close_connection_internal(Repl_Connection *conn);
|
|
|
|
|
+static void conn_delete_internal(Repl_Connection *conn);
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
* Create a new connection object. Returns a pointer to the object, or
|
|
* Create a new connection object. Returns a pointer to the object, or
|
|
@@ -186,11 +187,22 @@ conn_new(Repl_Agmt *agmt)
|
|
|
rpc->plain = NULL;
|
|
rpc->plain = NULL;
|
|
|
return rpc;
|
|
return rpc;
|
|
|
loser:
|
|
loser:
|
|
|
- conn_delete(rpc);
|
|
|
|
|
|
|
+ conn_delete_internal(rpc);
|
|
|
slapi_ch_free((void**)&rpc);
|
|
slapi_ch_free((void**)&rpc);
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static PRBool
|
|
|
|
|
+conn_connected_locked(Repl_Connection *conn, int locked)
|
|
|
|
|
+{
|
|
|
|
|
+ PRBool return_value;
|
|
|
|
|
+
|
|
|
|
|
+ if(!locked) PR_Lock(conn->lock);
|
|
|
|
|
+ return_value = STATE_CONNECTED == conn->state;
|
|
|
|
|
+ if(!locked) PR_Unlock(conn->lock);
|
|
|
|
|
+
|
|
|
|
|
+ return return_value;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
* Return PR_TRUE if the connection is in the connected state
|
|
* Return PR_TRUE if the connection is in the connected state
|
|
@@ -198,14 +210,9 @@ loser:
|
|
|
static PRBool
|
|
static PRBool
|
|
|
conn_connected(Repl_Connection *conn)
|
|
conn_connected(Repl_Connection *conn)
|
|
|
{
|
|
{
|
|
|
- PRBool return_value;
|
|
|
|
|
- PR_Lock(conn->lock);
|
|
|
|
|
- return_value = STATE_CONNECTED == conn->state;
|
|
|
|
|
- PR_Unlock(conn->lock);
|
|
|
|
|
- return return_value;
|
|
|
|
|
|
|
+ return conn_connected_locked(conn, 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Destroy a connection object.
|
|
* Destroy a connection object.
|
|
|
*/
|
|
*/
|
|
@@ -247,7 +254,6 @@ conn_delete(Repl_Connection *conn)
|
|
|
if (slapi_eq_cancel(conn->linger_event) == 1)
|
|
if (slapi_eq_cancel(conn->linger_event) == 1)
|
|
|
{
|
|
{
|
|
|
/* Event was found and cancelled. Destroy the connection object. */
|
|
/* Event was found and cancelled. Destroy the connection object. */
|
|
|
- PR_Unlock(conn->lock);
|
|
|
|
|
destroy_it = PR_TRUE;
|
|
destroy_it = PR_TRUE;
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
@@ -258,16 +264,15 @@ conn_delete(Repl_Connection *conn)
|
|
|
* off, so arrange for the event to destroy the object .
|
|
* off, so arrange for the event to destroy the object .
|
|
|
*/
|
|
*/
|
|
|
conn->delete_after_linger = PR_TRUE;
|
|
conn->delete_after_linger = PR_TRUE;
|
|
|
- PR_Unlock(conn->lock);
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if (destroy_it)
|
|
if (destroy_it)
|
|
|
{
|
|
{
|
|
|
conn_delete_internal(conn);
|
|
conn_delete_internal(conn);
|
|
|
}
|
|
}
|
|
|
|
|
+ PR_Unlock(conn->lock);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Return the last operation type processed by the connection
|
|
* Return the last operation type processed by the connection
|
|
|
* object, and the LDAP error encountered.
|
|
* object, and the LDAP error encountered.
|
|
@@ -331,17 +336,18 @@ conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retda
|
|
|
while (!slapi_is_shutting_down())
|
|
while (!slapi_is_shutting_down())
|
|
|
{
|
|
{
|
|
|
/* we have to make sure the update sending thread does not
|
|
/* we have to make sure the update sending thread does not
|
|
|
- attempt to call conn_disconnect while we are reading
|
|
|
|
|
|
|
+ attempt to close connection while we are reading
|
|
|
results - so lock the conn while we get the results */
|
|
results - so lock the conn while we get the results */
|
|
|
PR_Lock(conn->lock);
|
|
PR_Lock(conn->lock);
|
|
|
|
|
+
|
|
|
if ((STATE_CONNECTED != conn->state) || !conn->ld) {
|
|
if ((STATE_CONNECTED != conn->state) || !conn->ld) {
|
|
|
rc = -1;
|
|
rc = -1;
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
PR_Unlock(conn->lock);
|
|
PR_Unlock(conn->lock);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
rc = ldap_result(conn->ld, send_msgid, 1, &local_timeout, &res);
|
|
rc = ldap_result(conn->ld, send_msgid, 1, &local_timeout, &res);
|
|
|
|
|
+
|
|
|
PR_Unlock(conn->lock);
|
|
PR_Unlock(conn->lock);
|
|
|
|
|
|
|
|
if (0 != rc)
|
|
if (0 != rc)
|
|
@@ -665,8 +671,10 @@ perform_operation(Repl_Connection *conn, int optype, const char *dn,
|
|
|
server_controls[1] = update_control;
|
|
server_controls[1] = update_control;
|
|
|
server_controls[2] = NULL;
|
|
server_controls[2] = NULL;
|
|
|
|
|
|
|
|
- /* lock the conn to prevent the result reader thread
|
|
|
|
|
- from closing the connection out from under us */
|
|
|
|
|
|
|
+ /*
|
|
|
|
|
+ * Lock the conn to prevent the result reader thread
|
|
|
|
|
+ * from closing the connection out from under us.
|
|
|
|
|
+ */
|
|
|
PR_Lock(conn->lock);
|
|
PR_Lock(conn->lock);
|
|
|
if (STATE_CONNECTED == conn->state)
|
|
if (STATE_CONNECTED == conn->state)
|
|
|
{
|
|
{
|
|
@@ -808,7 +816,6 @@ conn_send_rename(Repl_Connection *conn, const char *dn,
|
|
|
NULL /* extop OID */, NULL /* extop payload */, message_id);
|
|
NULL /* extop OID */, NULL /* extop payload */, message_id);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Send an LDAP extended operation.
|
|
* Send an LDAP extended operation.
|
|
|
*/
|
|
*/
|
|
@@ -822,7 +829,6 @@ conn_send_extended_operation(Repl_Connection *conn, const char *extop_oid,
|
|
|
update_control, extop_oid, payload, message_id);
|
|
update_control, extop_oid, payload, message_id);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Synchronously read an entry and return a specific attribute's values.
|
|
* Synchronously read an entry and return a specific attribute's values.
|
|
|
* Returns CONN_OPERATION_SUCCESS if successful. Returns
|
|
* Returns CONN_OPERATION_SUCCESS if successful. Returns
|
|
@@ -842,6 +848,8 @@ conn_read_entry_attribute(Repl_Connection *conn, const char *dn,
|
|
|
LDAPMessage *res = NULL;
|
|
LDAPMessage *res = NULL;
|
|
|
char *attrs[2];
|
|
char *attrs[2];
|
|
|
|
|
|
|
|
|
|
+ PR_Lock(conn->lock);
|
|
|
|
|
+
|
|
|
PR_ASSERT(NULL != type);
|
|
PR_ASSERT(NULL != type);
|
|
|
if (conn_connected(conn))
|
|
if (conn_connected(conn))
|
|
|
{
|
|
{
|
|
@@ -864,7 +872,7 @@ conn_read_entry_attribute(Repl_Connection *conn, const char *dn,
|
|
|
}
|
|
}
|
|
|
else if (IS_DISCONNECT_ERROR(ldap_rc))
|
|
else if (IS_DISCONNECT_ERROR(ldap_rc))
|
|
|
{
|
|
{
|
|
|
- conn_disconnect(conn);
|
|
|
|
|
|
|
+ close_connection_internal(conn);
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
@@ -882,10 +890,11 @@ conn_read_entry_attribute(Repl_Connection *conn, const char *dn,
|
|
|
{
|
|
{
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
}
|
|
}
|
|
|
|
|
+ PR_Unlock(conn->lock);
|
|
|
|
|
+
|
|
|
return return_value;
|
|
return return_value;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Return an pointer to a string describing the connection's status.
|
|
* Return an pointer to a string describing the connection's status.
|
|
|
*/
|
|
*/
|
|
@@ -896,8 +905,6 @@ conn_get_status(Repl_Connection *conn)
|
|
|
return conn->status;
|
|
return conn->status;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Cancel any outstanding linger timer. Should be called when
|
|
* Cancel any outstanding linger timer. Should be called when
|
|
|
* a replication session is beginning.
|
|
* a replication session is beginning.
|
|
@@ -929,7 +936,6 @@ conn_cancel_linger(Repl_Connection *conn)
|
|
|
PR_Unlock(conn->lock);
|
|
PR_Unlock(conn->lock);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Called when our linger timeout timer expires. This means
|
|
* Called when our linger timeout timer expires. This means
|
|
|
* we should check to see if perhaps the connection's become
|
|
* we should check to see if perhaps the connection's become
|
|
@@ -961,7 +967,6 @@ linger_timeout(time_t event_time, void *arg)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Indicate that a session is ending. The linger timer starts when
|
|
* Indicate that a session is ending. The linger timer starts when
|
|
|
* this function is called.
|
|
* this function is called.
|
|
@@ -999,8 +1004,6 @@ conn_start_linger(Repl_Connection *conn)
|
|
|
PR_Unlock(conn->lock);
|
|
PR_Unlock(conn->lock);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* If no connection is currently active, opens a connection and binds to
|
|
* If no connection is currently active, opens a connection and binds to
|
|
|
* the remote server. If a connection is open (e.g. lingering) then
|
|
* the remote server. If a connection is open (e.g. lingering) then
|
|
@@ -1019,10 +1022,14 @@ conn_connect(Repl_Connection *conn)
|
|
|
ConnResult return_value = CONN_OPERATION_SUCCESS;
|
|
ConnResult return_value = CONN_OPERATION_SUCCESS;
|
|
|
int pw_ret = 1;
|
|
int pw_ret = 1;
|
|
|
|
|
|
|
|
- /** Connection already open just return SUCCESS **/
|
|
|
|
|
- if(conn->state == STATE_CONNECTED) goto done;
|
|
|
|
|
-
|
|
|
|
|
PR_Lock(conn->lock);
|
|
PR_Lock(conn->lock);
|
|
|
|
|
+
|
|
|
|
|
+ /* Connection already open, just return SUCCESS */
|
|
|
|
|
+ if(conn->state == STATE_CONNECTED){
|
|
|
|
|
+ PR_Unlock(conn->lock);
|
|
|
|
|
+ return return_value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (conn->flag_agmt_changed) {
|
|
if (conn->flag_agmt_changed) {
|
|
|
/* So far we cannot change Hostname and Port */
|
|
/* So far we cannot change Hostname and Port */
|
|
|
/* slapi_ch_free((void **)&conn->hostname); */
|
|
/* slapi_ch_free((void **)&conn->hostname); */
|
|
@@ -1037,7 +1044,6 @@ conn_connect(Repl_Connection *conn)
|
|
|
conn->port = agmt_get_port(conn->agmt); /* port could be updated */
|
|
conn->port = agmt_get_port(conn->agmt); /* port could be updated */
|
|
|
slapi_ch_free((void **)&conn->plain);
|
|
slapi_ch_free((void **)&conn->plain);
|
|
|
}
|
|
}
|
|
|
- PR_Unlock(conn->lock);
|
|
|
|
|
|
|
|
|
|
creds = agmt_get_credentials(conn->agmt);
|
|
creds = agmt_get_credentials(conn->agmt);
|
|
|
|
|
|
|
@@ -1178,6 +1184,7 @@ done:
|
|
|
{
|
|
{
|
|
|
close_connection_internal(conn);
|
|
close_connection_internal(conn);
|
|
|
}
|
|
}
|
|
|
|
|
+ PR_Unlock(conn->lock);
|
|
|
|
|
|
|
|
return return_value;
|
|
return return_value;
|
|
|
}
|
|
}
|
|
@@ -1213,7 +1220,6 @@ conn_disconnect(Repl_Connection *conn)
|
|
|
PR_Unlock(conn->lock);
|
|
PR_Unlock(conn->lock);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Determine if the remote replica supports DS 5.0 replication.
|
|
* Determine if the remote replica supports DS 5.0 replication.
|
|
|
* Return codes:
|
|
* Return codes:
|
|
@@ -1230,6 +1236,7 @@ conn_replica_supports_ds5_repl(Repl_Connection *conn)
|
|
|
ConnResult return_value;
|
|
ConnResult return_value;
|
|
|
int ldap_rc;
|
|
int ldap_rc;
|
|
|
|
|
|
|
|
|
|
+ PR_Lock(conn->lock);
|
|
|
if (conn_connected(conn))
|
|
if (conn_connected(conn))
|
|
|
{
|
|
{
|
|
|
if (conn->supports_ds50_repl == -1) {
|
|
if (conn->supports_ds50_repl == -1) {
|
|
@@ -1277,7 +1284,7 @@ conn_replica_supports_ds5_repl(Repl_Connection *conn)
|
|
|
if (IS_DISCONNECT_ERROR(ldap_rc))
|
|
if (IS_DISCONNECT_ERROR(ldap_rc))
|
|
|
{
|
|
{
|
|
|
conn->last_ldap_error = ldap_rc; /* specific reason */
|
|
conn->last_ldap_error = ldap_rc; /* specific reason */
|
|
|
- conn_disconnect(conn);
|
|
|
|
|
|
|
+ close_connection_internal(conn);
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
@@ -1297,10 +1304,11 @@ conn_replica_supports_ds5_repl(Repl_Connection *conn)
|
|
|
/* Not connected */
|
|
/* Not connected */
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
}
|
|
}
|
|
|
|
|
+ PR_Unlock(conn->lock);
|
|
|
|
|
+
|
|
|
return return_value;
|
|
return return_value;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Determine if the remote replica supports DS 7.1 replication.
|
|
* Determine if the remote replica supports DS 7.1 replication.
|
|
|
* Return codes:
|
|
* Return codes:
|
|
@@ -1317,6 +1325,7 @@ conn_replica_supports_ds71_repl(Repl_Connection *conn)
|
|
|
ConnResult return_value;
|
|
ConnResult return_value;
|
|
|
int ldap_rc;
|
|
int ldap_rc;
|
|
|
|
|
|
|
|
|
|
+ PR_Lock(conn->lock);
|
|
|
if (conn_connected(conn))
|
|
if (conn_connected(conn))
|
|
|
{
|
|
{
|
|
|
if (conn->supports_ds71_repl == -1) {
|
|
if (conn->supports_ds71_repl == -1) {
|
|
@@ -1348,7 +1357,7 @@ conn_replica_supports_ds71_repl(Repl_Connection *conn)
|
|
|
if (IS_DISCONNECT_ERROR(ldap_rc))
|
|
if (IS_DISCONNECT_ERROR(ldap_rc))
|
|
|
{
|
|
{
|
|
|
conn->last_ldap_error = ldap_rc; /* specific reason */
|
|
conn->last_ldap_error = ldap_rc; /* specific reason */
|
|
|
- conn_disconnect(conn);
|
|
|
|
|
|
|
+ close_connection_internal(conn);
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
@@ -1368,6 +1377,8 @@ conn_replica_supports_ds71_repl(Repl_Connection *conn)
|
|
|
/* Not connected */
|
|
/* Not connected */
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
}
|
|
}
|
|
|
|
|
+ PR_Unlock(conn->lock);
|
|
|
|
|
+
|
|
|
return return_value;
|
|
return return_value;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1387,6 +1398,7 @@ conn_replica_supports_ds90_repl(Repl_Connection *conn)
|
|
|
ConnResult return_value;
|
|
ConnResult return_value;
|
|
|
int ldap_rc;
|
|
int ldap_rc;
|
|
|
|
|
|
|
|
|
|
+ PR_Lock(conn->lock);
|
|
|
if (conn_connected(conn))
|
|
if (conn_connected(conn))
|
|
|
{
|
|
{
|
|
|
if (conn->supports_ds90_repl == -1) {
|
|
if (conn->supports_ds90_repl == -1) {
|
|
@@ -1418,7 +1430,7 @@ conn_replica_supports_ds90_repl(Repl_Connection *conn)
|
|
|
if (IS_DISCONNECT_ERROR(ldap_rc))
|
|
if (IS_DISCONNECT_ERROR(ldap_rc))
|
|
|
{
|
|
{
|
|
|
conn->last_ldap_error = ldap_rc; /* specific reason */
|
|
conn->last_ldap_error = ldap_rc; /* specific reason */
|
|
|
- conn_disconnect(conn);
|
|
|
|
|
|
|
+ close_connection_internal(conn);
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
@@ -1427,7 +1439,7 @@ conn_replica_supports_ds90_repl(Repl_Connection *conn)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if (NULL != res)
|
|
if (NULL != res)
|
|
|
- ldap_msgfree(res);
|
|
|
|
|
|
|
+ ldap_msgfree(res);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
@@ -1439,6 +1451,8 @@ conn_replica_supports_ds90_repl(Repl_Connection *conn)
|
|
|
/* Not connected */
|
|
/* Not connected */
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
}
|
|
}
|
|
|
|
|
+ PR_Unlock(conn->lock);
|
|
|
|
|
+
|
|
|
return return_value;
|
|
return return_value;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1456,7 +1470,6 @@ conn_replica_is_readonly(Repl_Connection *conn)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Return 1 if "value" is a value of attribute type "type" in entry "entry".
|
|
* Return 1 if "value" is a value of attribute type "type" in entry "entry".
|
|
|
* Otherwise, return 0.
|
|
* Otherwise, return 0.
|
|
@@ -1505,9 +1518,6 @@ attribute_string_value_present(LDAP *ld, LDAPMessage *entry, const char *type,
|
|
|
return return_value;
|
|
return return_value;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* Read the remote server's schema entry, then read the local schema entry,
|
|
* Read the remote server's schema entry, then read the local schema entry,
|
|
|
* and compare the nsschemacsn attribute. If the local csn is newer, or
|
|
* and compare the nsschemacsn attribute. If the local csn is newer, or
|
|
@@ -1537,7 +1547,7 @@ conn_push_schema(Repl_Connection *conn, CSN **remotecsn)
|
|
|
return_value = CONN_OPERATION_FAILED;
|
|
return_value = CONN_OPERATION_FAILED;
|
|
|
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "NULL remote CSN\n");
|
|
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "NULL remote CSN\n");
|
|
|
}
|
|
}
|
|
|
- else if (!conn_connected(conn))
|
|
|
|
|
|
|
+ else if (!conn_connected_locked(conn, 0 /* not locked */))
|
|
|
{
|
|
{
|
|
|
return_value = CONN_NOT_CONNECTED;
|
|
return_value = CONN_NOT_CONNECTED;
|
|
|
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
|
|
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
|
|
@@ -1754,6 +1764,7 @@ conn_push_schema(Repl_Connection *conn, CSN **remotecsn)
|
|
|
{
|
|
{
|
|
|
csn_free(&localcsn);
|
|
csn_free(&localcsn);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
return return_value;
|
|
return return_value;
|
|
|
}
|
|
}
|
|
|
|
|
|