|  | @@ -1047,9 +1047,14 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc)
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * The published flag tells us if we store the descriptor
 | 
	
		
			
				|  |  |   * in our role as directory (1) or if we cache it as client (0).
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * If <b>service_id</b> is non-NULL and the descriptor is not for that
 | 
	
		
			
				|  |  | + * service ID, reject it.  <b>service_id</b> must be specified if and
 | 
	
		
			
				|  |  | + * only if <b>published</b> is 0 (we fetched this descriptor).
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  int
 | 
	
		
			
				|  |  | -rend_cache_store(const char *desc, size_t desc_len, int published)
 | 
	
		
			
				|  |  | +rend_cache_store(const char *desc, size_t desc_len, int published,
 | 
	
		
			
				|  |  | +                 const char *service_id)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    rend_cache_entry_t *e;
 | 
	
		
			
				|  |  |    rend_service_descriptor_t *parsed;
 | 
	
	
		
			
				|  | @@ -1068,6 +1073,12 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
 | 
	
		
			
				|  |  |      rend_service_descriptor_free(parsed);
 | 
	
		
			
				|  |  |      return -2;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  if ((service_id != NULL) && strcmp(query, service_id)) {
 | 
	
		
			
				|  |  | +    log_warn(LD_REND, "Received service descriptor for service ID %s; "
 | 
	
		
			
				|  |  | +             "expected descriptor for service ID %s.",
 | 
	
		
			
				|  |  | +             query, safe_str(service_id));
 | 
	
		
			
				|  |  | +    return -2;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |    now = time(NULL);
 | 
	
		
			
				|  |  |    if (parsed->timestamp < now-REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
 | 
	
		
			
				|  |  |      log_fn(LOG_PROTOCOL_WARN, LD_REND,
 | 
	
	
		
			
				|  | @@ -1253,6 +1264,8 @@ rend_cache_store_v2_desc_as_dir(const char *desc)
 | 
	
		
			
				|  |  |   * If we have an older descriptor with the same ID, replace it.
 | 
	
		
			
				|  |  |   * If we have any v0 descriptor with the same ID, reject this one in order
 | 
	
		
			
				|  |  |   * to not get confused with having both versions for the same service.
 | 
	
		
			
				|  |  | + * If the descriptor's service ID does not match
 | 
	
		
			
				|  |  | + * <b>rend_query</b>-\>onion_address, reject it.
 | 
	
		
			
				|  |  |   * Return -2 if it's malformed or otherwise rejected; return -1 if we
 | 
	
		
			
				|  |  |   * already have a v0 descriptor here; return 0 if it's the same or older
 | 
	
		
			
				|  |  |   * than one we've already got; return 1 if it's novel.
 | 
	
	
		
			
				|  | @@ -1303,6 +1316,13 @@ rend_cache_store_v2_desc_as_client(const char *desc,
 | 
	
		
			
				|  |  |      retval = -2;
 | 
	
		
			
				|  |  |      goto err;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  if (strcmp(rend_query->onion_address, service_id)) {
 | 
	
		
			
				|  |  | +    log_warn(LD_REND, "Received service descriptor for service ID %s; "
 | 
	
		
			
				|  |  | +             "expected descriptor for service ID %s.",
 | 
	
		
			
				|  |  | +             service_id, safe_str(rend_query->onion_address));
 | 
	
		
			
				|  |  | +    retval = -2;
 | 
	
		
			
				|  |  | +    goto err;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |    /* Decode/decrypt introduction points. */
 | 
	
		
			
				|  |  |    if (intro_content) {
 | 
	
		
			
				|  |  |      if (rend_query->auth_type != REND_NO_AUTH &&
 |