|  | @@ -1385,7 +1385,12 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
 | 
	
		
			
				|  |  |    memcpy(launched->rend_data->rend_cookie, r_cookie, REND_COOKIE_LEN);
 | 
	
		
			
				|  |  |    strlcpy(launched->rend_data->onion_address, service->service_id,
 | 
	
		
			
				|  |  |            sizeof(launched->rend_data->onion_address));
 | 
	
		
			
				|  |  | -  launched->build_state->pending_final_cpath = cpath =
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  launched->build_state->service_pending_final_cpath_ref =
 | 
	
		
			
				|  |  | +    tor_malloc_zero(sizeof(crypt_path_reference_t));
 | 
	
		
			
				|  |  | +  launched->build_state->service_pending_final_cpath_ref->refcount = 1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  launched->build_state->service_pending_final_cpath_ref->cpath = cpath =
 | 
	
		
			
				|  |  |      tor_malloc_zero(sizeof(crypt_path_t));
 | 
	
		
			
				|  |  |    cpath->magic = CRYPT_PATH_MAGIC;
 | 
	
		
			
				|  |  |    launched->build_state->expiry_time = now + MAX_REND_TIMEOUT;
 | 
	
	
		
			
				|  | @@ -1445,7 +1450,7 @@ rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc)
 | 
	
		
			
				|  |  |    oldstate = oldcirc->build_state;
 | 
	
		
			
				|  |  |    tor_assert(oldstate);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  if (oldstate->pending_final_cpath == NULL) {
 | 
	
		
			
				|  |  | +  if (oldstate->service_pending_final_cpath_ref == NULL) {
 | 
	
		
			
				|  |  |      log_info(LD_REND,"Skipping relaunch of circ that failed on its first hop. "
 | 
	
		
			
				|  |  |               "Initiator will retry.");
 | 
	
		
			
				|  |  |      return;
 | 
	
	
		
			
				|  | @@ -1467,8 +1472,9 @@ rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc)
 | 
	
		
			
				|  |  |    tor_assert(newstate);
 | 
	
		
			
				|  |  |    newstate->failure_count = oldstate->failure_count+1;
 | 
	
		
			
				|  |  |    newstate->expiry_time = oldstate->expiry_time;
 | 
	
		
			
				|  |  | -  newstate->pending_final_cpath = oldstate->pending_final_cpath;
 | 
	
		
			
				|  |  | -  oldstate->pending_final_cpath = NULL;
 | 
	
		
			
				|  |  | +  newstate->service_pending_final_cpath_ref =
 | 
	
		
			
				|  |  | +    oldstate->service_pending_final_cpath_ref;
 | 
	
		
			
				|  |  | +  ++(newstate->service_pending_final_cpath_ref->refcount);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    newcirc->rend_data = rend_data_dup(oldcirc->rend_data);
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -1726,8 +1732,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
 | 
	
		
			
				|  |  |    tor_assert(!(circuit->build_state->onehop_tunnel));
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |    tor_assert(circuit->rend_data);
 | 
	
		
			
				|  |  | -  hop = circuit->build_state->pending_final_cpath;
 | 
	
		
			
				|  |  | -  tor_assert(hop);
 | 
	
		
			
				|  |  | +  hop = circuit->build_state->service_pending_final_cpath_ref->cpath;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    base16_encode(hexcookie,9,circuit->rend_data->rend_cookie,4);
 | 
	
		
			
				|  |  |    base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
 | 
	
	
		
			
				|  | @@ -1743,6 +1748,22 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
 | 
	
		
			
				|  |  |     * no effect on Tor's behaviour. */
 | 
	
		
			
				|  |  |    circuit->hs_circ_has_timed_out = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  /* If hop is NULL, another rend circ has already connected to this
 | 
	
		
			
				|  |  | +   * rend point.  Close this circ. */
 | 
	
		
			
				|  |  | +  if (hop == NULL) {
 | 
	
		
			
				|  |  | +    log_info(LD_REND, "Another rend circ has already reached this rend point; "
 | 
	
		
			
				|  |  | +             "closing this rend circ.");
 | 
	
		
			
				|  |  | +    reason = END_CIRC_REASON_NONE;
 | 
	
		
			
				|  |  | +    goto err;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* Remove our final cpath element from the reference, so that no
 | 
	
		
			
				|  |  | +   * other circuit will try to use it.  Store it in
 | 
	
		
			
				|  |  | +   * pending_final_cpath for now to ensure that it will be freed if
 | 
	
		
			
				|  |  | +   * our rendezvous attempt fails. */
 | 
	
		
			
				|  |  | +  circuit->build_state->pending_final_cpath = hop;
 | 
	
		
			
				|  |  | +  circuit->build_state->service_pending_final_cpath_ref->cpath = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    service = rend_service_get_by_pk_digest(
 | 
	
		
			
				|  |  |                  circuit->rend_data->rend_pk_digest);
 | 
	
		
			
				|  |  |    if (!service) {
 |