be more clear about a possible integer underflow problem. this
[tor.git] / src / or / rendcommon.c
blob26454d24bd5dbd3a3c8e56327ac5a66969a28301
1 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2 * Copyright (c) 2007-2008, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
4 /* $Id$ */
5 const char rendcommon_c_id[] =
6 "$Id$";
8 /**
9 * \file rendcommon.c
10 * \brief Rendezvous implementation: shared code between
11 * introducers, services, clients, and rendezvous points.
12 **/
14 #include "or.h"
16 /** Return 0 if one and two are the same service ids, else -1 or 1 */
17 int
18 rend_cmp_service_ids(const char *one, const char *two)
20 return strcasecmp(one,two);
23 /** Free the storage held by the service descriptor <b>desc</b>.
25 void
26 rend_service_descriptor_free(rend_service_descriptor_t *desc)
28 if (desc->pk)
29 crypto_free_pk_env(desc->pk);
30 if (desc->intro_nodes) {
31 SMARTLIST_FOREACH(desc->intro_nodes, rend_intro_point_t *, intro,
32 rend_intro_point_free(intro););
33 smartlist_free(desc->intro_nodes);
35 tor_free(desc);
38 /** Length of the descriptor cookie that is used for versioned hidden
39 * service descriptors. */
40 #define REND_DESC_COOKIE_LEN 16
42 /** Length of the replica number that is used to determine the secret ID
43 * part of versioned hidden service descriptors. */
44 #define REND_REPLICA_LEN 1
46 /** Compute the descriptor ID for <b>service_id</b> of length
47 * <b>REND_SERVICE_ID_LEN</b> and <b>secret_id_part</b> of length
48 * <b>DIGEST_LEN</b>, and write it to <b>descriptor_id_out</b> of length
49 * <b>DIGEST_LEN</b>. */
50 void
51 rend_get_descriptor_id_bytes(char *descriptor_id_out,
52 const char *service_id,
53 const char *secret_id_part)
55 crypto_digest_env_t *digest = crypto_new_digest_env();
56 crypto_digest_add_bytes(digest, service_id, REND_SERVICE_ID_LEN);
57 crypto_digest_add_bytes(digest, secret_id_part, DIGEST_LEN);
58 crypto_digest_get_digest(digest, descriptor_id_out, DIGEST_LEN);
59 crypto_free_digest_env(digest);
62 /** Compute the secret ID part for time_period,
63 * a <b>descriptor_cookie</b> of length
64 * <b>REND_DESC_COOKIE_LEN</b> which may also be <b>NULL</b> if no
65 * descriptor_cookie shall be used, and <b>replica</b>, and write it to
66 * <b>secret_id_part</b> of length DIGEST_LEN. */
67 static void
68 get_secret_id_part_bytes(char *secret_id_part, uint32_t time_period,
69 const char *descriptor_cookie, uint8_t replica)
71 crypto_digest_env_t *digest = crypto_new_digest_env();
72 time_period = htonl(time_period);
73 crypto_digest_add_bytes(digest, (char*)&time_period, sizeof(uint32_t));
74 if (descriptor_cookie) {
75 crypto_digest_add_bytes(digest, descriptor_cookie,
76 REND_DESC_COOKIE_LEN);
78 crypto_digest_add_bytes(digest, (const char *)&replica, REND_REPLICA_LEN);
79 crypto_digest_get_digest(digest, secret_id_part, DIGEST_LEN);
80 crypto_free_digest_env(digest);
83 /** Return the time period for time <b>now</b> plus a potentially
84 * intended <b>deviation</b> of one or more periods, based on the first byte
85 * of <b>service_id</b>. */
86 static uint32_t
87 get_time_period(time_t now, uint8_t deviation, const char *service_id)
89 /* The time period is the number of REND_TIME_PERIOD_V2_DESC_VALIDITY
90 * intervals that have passed since the epoch, offset slightly so that
91 * each service's time periods start and end at a fraction of that
92 * period based on their first byte. */
93 return (uint32_t)
94 (now + ((uint8_t) *service_id) * REND_TIME_PERIOD_V2_DESC_VALIDITY / 256)
95 / REND_TIME_PERIOD_V2_DESC_VALIDITY + deviation;
98 /** Compute the time in seconds that a descriptor that is generated
99 * <b>now</b> for <b>service_id</b> will be valid. */
100 static uint32_t
101 get_seconds_valid(time_t now, const char *service_id)
103 uint32_t result = REND_TIME_PERIOD_V2_DESC_VALIDITY -
104 ((uint32_t)
105 (now + ((uint8_t) *service_id) * REND_TIME_PERIOD_V2_DESC_VALIDITY / 256)
106 % REND_TIME_PERIOD_V2_DESC_VALIDITY);
107 return result;
110 /** Compute the binary <b>desc_id_out</b> (DIGEST_LEN bytes long) for a given
111 * base32-encoded <b>service_id</b> and optional unencoded
112 * <b>descriptor_cookie</b> of length REND_DESC_COOKIE_LEN,
113 * at time <b>now</b> for replica number
114 * <b>replica</b>. <b>desc_id</b> needs to have <b>DIGEST_LEN</b> bytes
115 * free. Return 0 for success, -1 otherwise. */
117 rend_compute_v2_desc_id(char *desc_id_out, const char *service_id,
118 const char *descriptor_cookie, time_t now,
119 uint8_t replica)
121 char service_id_binary[REND_SERVICE_ID_LEN];
122 char secret_id_part[DIGEST_LEN];
123 uint32_t time_period;
124 if (!service_id ||
125 strlen(service_id) != REND_SERVICE_ID_LEN_BASE32) {
126 log_warn(LD_REND, "Could not compute v2 descriptor ID: "
127 "Illegal service ID: %s", safe_str(service_id));
128 return -1;
130 if (replica >= REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS) {
131 log_warn(LD_REND, "Could not compute v2 descriptor ID: "
132 "Replica number out of range: %d", replica);
133 return -1;
135 /* Convert service ID to binary. */
136 if (base32_decode(service_id_binary, REND_SERVICE_ID_LEN,
137 service_id, REND_SERVICE_ID_LEN_BASE32) < 0) {
138 log_warn(LD_REND, "Could not compute v2 descriptor ID: "
139 "Illegal characters in service ID: %s",
140 safe_str(service_id));
141 return -1;
143 /* Calculate current time-period. */
144 time_period = get_time_period(now, 0, service_id_binary);
145 /* Calculate secret-id-part = h(time-period + replica). */
146 get_secret_id_part_bytes(secret_id_part, time_period, descriptor_cookie,
147 replica);
148 /* Calculate descriptor ID. */
149 rend_get_descriptor_id_bytes(desc_id_out, service_id_binary, secret_id_part);
150 return 0;
153 /* Encode the introduction points in <b>desc</b>, optionally encrypt them with
154 * an optional <b>descriptor_cookie</b> of length REND_DESC_COOKIE_LEN,
155 * encode it in base64, and write it to a newly allocated string, and write a
156 * pointer to it to *<b>ipos_base64</b>. Return 0 for success, -1
157 * otherwise. */
158 static int
159 rend_encode_v2_intro_points(char **ipos_base64,
160 rend_service_descriptor_t *desc,
161 const char *descriptor_cookie)
163 size_t unenc_len;
164 char *unenc = NULL;
165 size_t unenc_written = 0;
166 int i;
167 int r = -1;
168 /* Assemble unencrypted list of introduction points. */
169 *ipos_base64 = NULL;
170 unenc_len = smartlist_len(desc->intro_nodes) * 1000; /* too long, but ok. */
171 unenc = tor_malloc_zero(unenc_len);
172 for (i = 0; i < smartlist_len(desc->intro_nodes); i++) {
173 char id_base32[REND_INTRO_POINT_ID_LEN_BASE32 + 1];
174 char *onion_key = NULL;
175 size_t onion_key_len;
176 crypto_pk_env_t *intro_key;
177 char *service_key = NULL;
178 char *address = NULL;
179 size_t service_key_len;
180 int res;
181 rend_intro_point_t *intro = smartlist_get(desc->intro_nodes, i);
182 /* Obtain extend info with introduction point details. */
183 extend_info_t *info = intro->extend_info;
184 /* Encode introduction point ID. */
185 base32_encode(id_base32, sizeof(id_base32),
186 info->identity_digest, DIGEST_LEN);
187 /* Encode onion key. */
188 if (crypto_pk_write_public_key_to_string(info->onion_key, &onion_key,
189 &onion_key_len) < 0) {
190 log_warn(LD_REND, "Could not write onion key.");
191 goto done;
193 /* Encode intro key. */
194 intro_key = intro->intro_key;
195 if (!intro_key ||
196 crypto_pk_write_public_key_to_string(intro_key, &service_key,
197 &service_key_len) < 0) {
198 log_warn(LD_REND, "Could not write intro key.");
199 tor_free(onion_key);
200 goto done;
202 /* Assemble everything for this introduction point. */
203 address = tor_dup_addr(info->addr);
204 res = tor_snprintf(unenc + unenc_written, unenc_len - unenc_written,
205 "introduction-point %s\n"
206 "ip-address %s\n"
207 "onion-port %d\n"
208 "onion-key\n%s"
209 "service-key\n%s",
210 id_base32,
211 address,
212 info->port,
213 onion_key,
214 service_key);
215 tor_free(address);
216 tor_free(onion_key);
217 tor_free(service_key);
218 if (res < 0) {
219 log_warn(LD_REND, "Not enough space for writing introduction point "
220 "string.");
221 goto done;
223 /* Update total number of written bytes for unencrypted intro points. */
224 unenc_written += res;
226 /* Finalize unencrypted introduction points. */
227 if (unenc_len < unenc_written + 2) {
228 log_warn(LD_REND, "Not enough space for finalizing introduction point "
229 "string.");
230 goto done;
232 unenc[unenc_written++] = '\n';
233 unenc[unenc_written++] = 0;
234 /* If a descriptor cookie is passed, encrypt introduction points. */
235 if (descriptor_cookie) {
236 char *enc = tor_malloc_zero(unenc_written + CIPHER_IV_LEN);
237 crypto_cipher_env_t *cipher =
238 crypto_create_init_cipher(descriptor_cookie, 1);
239 int enclen = crypto_cipher_encrypt_with_iv(cipher, enc,
240 unenc_written + CIPHER_IV_LEN,
241 unenc, unenc_written);
242 crypto_free_cipher_env(cipher);
243 if (enclen < 0) {
244 log_warn(LD_REND, "Could not encrypt introduction point string.");
245 tor_free(enc);
246 goto done;
248 /* Replace original string with the encrypted one. */
249 tor_free(unenc);
250 unenc = enc;
251 unenc_written = enclen;
253 /* Base64-encode introduction points. */
254 *ipos_base64 = tor_malloc_zero(unenc_written * 2);
255 if (base64_encode(*ipos_base64, unenc_written * 2, unenc, unenc_written)<0) {
256 log_warn(LD_REND, "Could not encode introduction point string to "
257 "base64.");
258 goto done;
260 r = 0;
261 done:
262 if (r<0)
263 tor_free(*ipos_base64);
264 tor_free(unenc);
265 return r;
268 /** Attempt to parse the given <b>desc_str</b> and return true if this
269 * succeeds, false otherwise. */
270 static int
271 rend_desc_v2_is_parsable(rend_encoded_v2_service_descriptor_t *desc)
273 rend_service_descriptor_t *test_parsed = NULL;
274 char test_desc_id[DIGEST_LEN];
275 char *test_intro_content = NULL;
276 size_t test_intro_size;
277 size_t test_encoded_size;
278 const char *test_next;
279 int res = rend_parse_v2_service_descriptor(&test_parsed, test_desc_id,
280 &test_intro_content,
281 &test_intro_size,
282 &test_encoded_size,
283 &test_next, desc->desc_str);
284 if (test_parsed)
285 rend_service_descriptor_free(test_parsed);
286 tor_free(test_intro_content);
287 return (res >= 0);
290 /** Free the storage held by an encoded v2 service descriptor. */
291 void
292 rend_encoded_v2_service_descriptor_free(
293 rend_encoded_v2_service_descriptor_t *desc)
295 tor_free(desc->desc_str);
296 tor_free(desc);
299 /** Free the storage held by an introduction point info. */
300 void
301 rend_intro_point_free(rend_intro_point_t *intro)
303 if (intro->extend_info)
304 extend_info_free(intro->extend_info);
305 if (intro->intro_key)
306 crypto_free_pk_env(intro->intro_key);
307 tor_free(intro);
310 /** Encode a set of rend_encoded_v2_service_descriptor_t's for <b>desc</b>
311 * at time <b>now</b> using <b>descriptor_cookie</b> (may be <b>NULL</b> if
312 * introduction points shall not be encrypted) and <b>period</b> (e.g. 0
313 * for the current period, 1 for the next period, etc.) and add them to
314 * the existing list <b>descs_out</b>; return the number of seconds that
315 * the descriptors will be found by clients, or -1 if the encoding was not
316 * successful. */
318 rend_encode_v2_descriptors(smartlist_t *descs_out,
319 rend_service_descriptor_t *desc, time_t now,
320 const char *descriptor_cookie, uint8_t period)
322 char service_id[DIGEST_LEN];
323 uint32_t time_period;
324 char *ipos_base64 = NULL;
325 int k;
326 uint32_t seconds_valid;
327 if (!desc) {
328 log_warn(LD_REND, "Could not encode v2 descriptor: No desc given.");
329 return -1;
331 /* Obtain service_id from public key. */
332 crypto_pk_get_digest(desc->pk, service_id);
333 /* Calculate current time-period. */
334 time_period = get_time_period(now, period, service_id);
335 /* Determine how many seconds the descriptor will be valid. */
336 seconds_valid = period * REND_TIME_PERIOD_V2_DESC_VALIDITY +
337 get_seconds_valid(now, service_id);
338 /* Assemble, possibly encrypt, and encode introduction points. */
339 if (smartlist_len(desc->intro_nodes) > 0 &&
340 rend_encode_v2_intro_points(&ipos_base64, desc, descriptor_cookie) < 0) {
341 log_warn(LD_REND, "Encoding of introduction points did not succeed.");
342 return -1;
344 /* Encode REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS descriptors. */
345 for (k = 0; k < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; k++) {
346 char secret_id_part[DIGEST_LEN];
347 char secret_id_part_base32[REND_SECRET_ID_PART_LEN_BASE32 + 1];
348 char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
349 char *permanent_key = NULL;
350 size_t permanent_key_len;
351 char published[ISO_TIME_LEN+1];
352 int i;
353 char protocol_versions_string[16]; /* max len: "0,1,2,3,4,5,6,7\0" */
354 size_t protocol_versions_written;
355 size_t desc_len;
356 char *desc_str = NULL;
357 int result = 0;
358 size_t written = 0;
359 char desc_digest[DIGEST_LEN];
360 rend_encoded_v2_service_descriptor_t *enc =
361 tor_malloc_zero(sizeof(rend_encoded_v2_service_descriptor_t));
362 /* Calculate secret-id-part = h(time-period + cookie + replica). */
363 get_secret_id_part_bytes(secret_id_part, time_period, descriptor_cookie,
365 base32_encode(secret_id_part_base32, sizeof(secret_id_part_base32),
366 secret_id_part, DIGEST_LEN);
367 /* Calculate descriptor ID. */
368 rend_get_descriptor_id_bytes(enc->desc_id, service_id, secret_id_part);
369 base32_encode(desc_id_base32, sizeof(desc_id_base32),
370 enc->desc_id, DIGEST_LEN);
371 /* PEM-encode the public key */
372 if (crypto_pk_write_public_key_to_string(desc->pk, &permanent_key,
373 &permanent_key_len) < 0) {
374 log_warn(LD_BUG, "Could not write public key to string.");
375 rend_encoded_v2_service_descriptor_free(enc);
376 goto err;
378 /* Encode timestamp. */
379 format_iso_time(published, desc->timestamp);
380 /* Write protocol-versions bitmask to comma-separated value string. */
381 protocol_versions_written = 0;
382 for (i = 0; i < 8; i++) {
383 if (desc->protocols & 1 << i) {
384 tor_snprintf(protocol_versions_string + protocol_versions_written,
385 16 - protocol_versions_written, "%d,", i);
386 protocol_versions_written += 2;
389 if (protocol_versions_written)
390 protocol_versions_string[protocol_versions_written - 1] = '\0';
391 else
392 protocol_versions_string[0]= '\0';
393 /* Assemble complete descriptor. */
394 desc_len = 2000 + smartlist_len(desc->intro_nodes) * 1000; /* far too long,
395 but okay.*/
396 enc->desc_str = desc_str = tor_malloc_zero(desc_len);
397 result = tor_snprintf(desc_str, desc_len,
398 "rendezvous-service-descriptor %s\n"
399 "version 2\n"
400 "permanent-key\n%s"
401 "secret-id-part %s\n"
402 "publication-time %s\n"
403 "protocol-versions %s\n",
404 desc_id_base32,
405 permanent_key,
406 secret_id_part_base32,
407 published,
408 protocol_versions_string);
409 tor_free(permanent_key);
410 if (result < 0) {
411 log_warn(LD_BUG, "Descriptor ran out of room.");
412 rend_encoded_v2_service_descriptor_free(enc);
413 goto err;
415 written = result;
416 /* Add introduction points. */
417 if (ipos_base64) {
418 result = tor_snprintf(desc_str + written, desc_len - written,
419 "introduction-points\n"
420 "-----BEGIN MESSAGE-----\n%s"
421 "-----END MESSAGE-----\n",
422 ipos_base64);
423 if (result < 0) {
424 log_warn(LD_BUG, "could not write introduction points.");
425 rend_encoded_v2_service_descriptor_free(enc);
426 goto err;
428 written += result;
430 /* Add signature. */
431 strlcpy(desc_str + written, "signature\n", desc_len - written);
432 written += strlen(desc_str + written);
433 if (crypto_digest(desc_digest, desc_str, written) < 0) {
434 log_warn(LD_BUG, "could not create digest.");
435 rend_encoded_v2_service_descriptor_free(enc);
436 goto err;
438 if (router_append_dirobj_signature(desc_str + written,
439 desc_len - written,
440 desc_digest, desc->pk) < 0) {
441 log_warn(LD_BUG, "Couldn't sign desc.");
442 rend_encoded_v2_service_descriptor_free(enc);
443 goto err;
445 written += strlen(desc_str+written);
446 if (written+2 > desc_len) {
447 log_warn(LD_BUG, "Could not finish desc.");
448 rend_encoded_v2_service_descriptor_free(enc);
449 goto err;
451 desc_str[written++] = '\n';
452 desc_str[written++] = 0;
453 /* Check if we can parse our own descriptor. */
454 if (!rend_desc_v2_is_parsable(enc)) {
455 log_warn(LD_BUG, "Could not parse my own descriptor: %s", desc_str);
456 rend_encoded_v2_service_descriptor_free(enc);
457 goto err;
459 smartlist_add(descs_out, enc);
462 log_info(LD_REND, "Successfully encoded a v2 descriptor and "
463 "confirmed that it is parsable.");
464 goto done;
466 err:
467 SMARTLIST_FOREACH(descs_out, rend_encoded_v2_service_descriptor_t *, d,
468 rend_encoded_v2_service_descriptor_free(d););
469 smartlist_clear(descs_out);
470 seconds_valid = -1;
472 done:
473 tor_free(ipos_base64);
474 return seconds_valid;
477 /** Encode a service descriptor for <b>desc</b>, and sign it with
478 * <b>key</b>. Store the descriptor in *<b>str_out</b>, and set
479 * *<b>len_out</b> to its length.
482 rend_encode_service_descriptor(rend_service_descriptor_t *desc,
483 crypto_pk_env_t *key,
484 char **str_out, size_t *len_out)
486 char *cp;
487 char *end;
488 int i, r;
489 size_t asn1len;
490 size_t buflen =
491 PK_BYTES*2*(smartlist_len(desc->intro_nodes)+2);/*Too long, but ok*/
492 cp = *str_out = tor_malloc(buflen);
493 end = cp + PK_BYTES*2*(smartlist_len(desc->intro_nodes)+1);
494 r = crypto_pk_asn1_encode(desc->pk, cp+2, end-(cp+2));
495 if (r < 0) {
496 tor_free(*str_out);
497 return -1;
499 asn1len = r;
500 set_uint16(cp, htons((uint16_t)asn1len));
501 cp += 2+asn1len;
502 set_uint32(cp, htonl((uint32_t)desc->timestamp));
503 cp += 4;
504 set_uint16(cp, htons((uint16_t)smartlist_len(desc->intro_nodes)));
505 cp += 2;
506 for (i=0; i < smartlist_len(desc->intro_nodes); ++i) {
507 rend_intro_point_t *intro = smartlist_get(desc->intro_nodes, i);
508 char ipoint[HEX_DIGEST_LEN+2];
509 ipoint[0] = '$';
510 base16_encode(ipoint+1, HEX_DIGEST_LEN+1,
511 intro->extend_info->identity_digest,
512 DIGEST_LEN);
513 tor_assert(buflen >= cp-*str_out); /* XXX021 This assert is a kludge. */
514 strlcpy(cp, ipoint, buflen-(cp-*str_out));
515 cp += strlen(ipoint)+1;
517 note_crypto_pk_op(REND_SERVER);
518 r = crypto_pk_private_sign_digest(key, cp, *str_out, cp-*str_out);
519 if (r<0) {
520 tor_free(*str_out);
521 return -1;
523 cp += r;
524 *len_out = (size_t)(cp-*str_out);
525 return 0;
528 /** Parse a service descriptor at <b>str</b> (<b>len</b> bytes). On
529 * success, return a newly alloced service_descriptor_t. On failure,
530 * return NULL.
532 rend_service_descriptor_t *
533 rend_parse_service_descriptor(const char *str, size_t len)
535 rend_service_descriptor_t *result = NULL;
536 int i, n_intro_points;
537 size_t keylen, asn1len;
538 const char *end, *cp, *eos;
539 rend_intro_point_t *intro;
541 result = tor_malloc_zero(sizeof(rend_service_descriptor_t));
542 cp = str;
543 end = str+len;
544 if (end-cp<2) goto truncated;
545 result->version = 0;
546 if (end-cp < 2) goto truncated;
547 asn1len = ntohs(get_uint16(cp));
548 cp += 2;
549 if ((size_t)(end-cp) < asn1len) goto truncated;
550 result->pk = crypto_pk_asn1_decode(cp, asn1len);
551 if (!result->pk) goto truncated;
552 cp += asn1len;
553 if (end-cp < 4) goto truncated;
554 result->timestamp = (time_t) ntohl(get_uint32(cp));
555 cp += 4;
556 result->protocols = 1<<2; /* always use intro format 2 */
557 if (end-cp < 2) goto truncated;
558 n_intro_points = ntohs(get_uint16(cp));
559 cp += 2;
561 result->intro_nodes = smartlist_create();
562 for (i=0;i<n_intro_points;++i) {
563 if (end-cp < 2) goto truncated;
564 eos = (const char *)memchr(cp,'\0',end-cp);
565 if (!eos) goto truncated;
566 /* Write nickname to extend info, but postpone the lookup whether
567 * we know that router. It's not part of the parsing process. */
568 intro = tor_malloc_zero(sizeof(rend_intro_point_t));
569 intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
570 strlcpy(intro->extend_info->nickname, cp,
571 sizeof(intro->extend_info->nickname));
572 smartlist_add(result->intro_nodes, intro);
573 cp = eos+1;
575 keylen = crypto_pk_keysize(result->pk);
576 tor_assert(end-cp >= 0);
577 if ((size_t)(end-cp) < keylen) goto truncated;
578 if ((size_t)(end-cp) > keylen) {
579 log_warn(LD_PROTOCOL,
580 "Signature is %d bytes too long on service descriptor.",
581 (int)((size_t)(end-cp) - keylen));
582 goto error;
584 note_crypto_pk_op(REND_CLIENT);
585 if (crypto_pk_public_checksig_digest(result->pk,
586 (char*)str,cp-str, /* data */
587 (char*)cp,end-cp /* signature*/
588 )<0) {
589 log_warn(LD_PROTOCOL, "Bad signature on service descriptor.");
590 goto error;
593 return result;
594 truncated:
595 log_warn(LD_PROTOCOL, "Truncated service descriptor.");
596 error:
597 rend_service_descriptor_free(result);
598 return NULL;
601 /** Sets <b>out</b> to the first 10 bytes of the digest of <b>pk</b>,
602 * base32 encoded. NUL-terminates out. (We use this string to
603 * identify services in directory requests and .onion URLs.)
606 rend_get_service_id(crypto_pk_env_t *pk, char *out)
608 char buf[DIGEST_LEN];
609 tor_assert(pk);
610 if (crypto_pk_get_digest(pk, buf) < 0)
611 return -1;
612 base32_encode(out, REND_SERVICE_ID_LEN_BASE32+1, buf, REND_SERVICE_ID_LEN);
613 return 0;
616 /* ==== Rendezvous service descriptor cache. */
618 /** How old do we let hidden service descriptors get before discarding
619 * them as too old? */
620 #define REND_CACHE_MAX_AGE (2*24*60*60)
621 /** How wrong do we assume our clock may be when checking whether hidden
622 * services are too old or too new? */
623 #define REND_CACHE_MAX_SKEW (24*60*60)
625 /** Map from service id (as generated by rend_get_service_id) to
626 * rend_cache_entry_t. */
627 static strmap_t *rend_cache = NULL;
629 /** Map from descriptor id to rend_cache_entry_t; only for hidden service
630 * directories. */
631 static digestmap_t *rend_cache_v2_dir = NULL;
633 /** Initializes the service descriptor cache.
635 void
636 rend_cache_init(void)
638 rend_cache = strmap_new();
639 rend_cache_v2_dir = digestmap_new();
642 /** Helper: free storage held by a single service descriptor cache entry. */
643 static void
644 _rend_cache_entry_free(void *p)
646 rend_cache_entry_t *e = p;
647 rend_service_descriptor_free(e->parsed);
648 tor_free(e->desc);
649 tor_free(e);
652 /** Free all storage held by the service descriptor cache. */
653 void
654 rend_cache_free_all(void)
656 strmap_free(rend_cache, _rend_cache_entry_free);
657 digestmap_free(rend_cache_v2_dir, _rend_cache_entry_free);
658 rend_cache = NULL;
659 rend_cache_v2_dir = NULL;
662 /** Removes all old entries from the service descriptor cache.
664 void
665 rend_cache_clean(void)
667 strmap_iter_t *iter;
668 const char *key;
669 void *val;
670 rend_cache_entry_t *ent;
671 time_t cutoff;
672 cutoff = time(NULL) - REND_CACHE_MAX_AGE - REND_CACHE_MAX_SKEW;
673 for (iter = strmap_iter_init(rend_cache); !strmap_iter_done(iter); ) {
674 strmap_iter_get(iter, &key, &val);
675 ent = (rend_cache_entry_t*)val;
676 if (ent->parsed->timestamp < cutoff) {
677 iter = strmap_iter_next_rmv(rend_cache, iter);
678 _rend_cache_entry_free(ent);
679 } else {
680 iter = strmap_iter_next(rend_cache, iter);
685 /** Remove all old v2 descriptors and those for which this hidden service
686 * directory is not responsible for any more. */
687 void
688 rend_cache_clean_v2_descs_as_dir(void)
690 digestmap_iter_t *iter;
691 time_t cutoff = time(NULL) - REND_CACHE_MAX_AGE - REND_CACHE_MAX_SKEW;
692 for (iter = digestmap_iter_init(rend_cache_v2_dir);
693 !digestmap_iter_done(iter); ) {
694 const char *key;
695 void *val;
696 rend_cache_entry_t *ent;
697 digestmap_iter_get(iter, &key, &val);
698 ent = val;
699 if (ent->parsed->timestamp < cutoff ||
700 !hid_serv_responsible_for_desc_id(key)) {
701 char key_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
702 base32_encode(key_base32, sizeof(key_base32), key, DIGEST_LEN);
703 log_info(LD_REND, "Removing descriptor with ID '%s' from cache",
704 safe_str(key_base32));
705 iter = digestmap_iter_next_rmv(rend_cache_v2_dir, iter);
706 _rend_cache_entry_free(ent);
707 } else {
708 iter = digestmap_iter_next(rend_cache_v2_dir, iter);
713 /** Determines whether <b>a</b> is in the interval of <b>b</b> (excluded) and
714 * <b>c</b> (included) in a circular digest ring; returns 1 if this is the
715 * case, and 0 otherwise.
718 rend_id_is_in_interval(const char *a, const char *b, const char *c)
720 int a_b, b_c, c_a;
721 tor_assert(a);
722 tor_assert(b);
723 tor_assert(c);
725 /* There are five cases in which a is outside the interval ]b,c]: */
726 a_b = memcmp(a,b,DIGEST_LEN);
727 if (a_b == 0)
728 return 0; /* 1. a == b (b is excluded) */
729 b_c = memcmp(b,c,DIGEST_LEN);
730 if (b_c == 0)
731 return 0; /* 2. b == c (interval is empty) */
732 else if (a_b <= 0 && b_c < 0)
733 return 0; /* 3. a b c */
734 c_a = memcmp(c,a,DIGEST_LEN);
735 if (c_a < 0 && a_b <= 0)
736 return 0; /* 4. c a b */
737 else if (b_c < 0 && c_a < 0)
738 return 0; /* 5. b c a */
740 /* In the other cases (a c b; b a c; c b a), a is inside the interval. */
741 return 1;
744 /** Return true iff <b>query</b> is a syntactically valid service ID (as
745 * generated by rend_get_service_id). */
747 rend_valid_service_id(const char *query)
749 if (strlen(query) != REND_SERVICE_ID_LEN_BASE32)
750 return 0;
752 if (strspn(query, BASE32_CHARS) != REND_SERVICE_ID_LEN_BASE32)
753 return 0;
755 return 1;
758 /** If we have a cached rend_cache_entry_t for the service ID <b>query</b>
759 * with <b>version</b>, set *<b>e</b> to that entry and return 1.
760 * Else return 0. If <b>version</b> is nonnegative, only return an entry
761 * in that descriptor format version. Otherwise (if <b>version</b> is
762 * negative), return the most recent format we have.
765 rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e)
767 char key[REND_SERVICE_ID_LEN_BASE32+2]; /* <version><query>\0 */
768 tor_assert(rend_cache);
769 if (!rend_valid_service_id(query))
770 return -1;
771 *e = NULL;
772 if (version != 0) {
773 tor_snprintf(key, sizeof(key), "2%s", query);
774 *e = strmap_get_lc(rend_cache, key);
776 if (!*e && version != 2) {
777 tor_snprintf(key, sizeof(key), "0%s", query);
778 *e = strmap_get_lc(rend_cache, key);
780 if (!*e)
781 return 0;
782 return 1;
785 /** <b>query</b> is a base-32'ed service id. If it's malformed, return -1.
786 * Else look it up.
787 * - If it is found, point *desc to it, and write its length into
788 * *desc_len, and return 1.
789 * - If it is not found, return 0.
790 * Note: calls to rend_cache_clean or rend_cache_store may invalidate
791 * *desc.
794 rend_cache_lookup_desc(const char *query, int version, const char **desc,
795 size_t *desc_len)
797 rend_cache_entry_t *e;
798 int r;
799 r = rend_cache_lookup_entry(query,version,&e);
800 if (r <= 0) return r;
801 *desc = e->desc;
802 *desc_len = e->len;
803 return 1;
806 /** Lookup the v2 service descriptor with base32-encoded <b>desc_id</b> and
807 * copy the pointer to it to *<b>desc</b>. Return 1 on success, 0 on
808 * well-formed-but-not-found, and -1 on failure.
811 rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc)
813 rend_cache_entry_t *e;
814 char desc_id_digest[DIGEST_LEN];
815 tor_assert(rend_cache_v2_dir);
816 if (base32_decode(desc_id_digest, DIGEST_LEN,
817 desc_id, REND_DESC_ID_V2_LEN_BASE32) < 0) {
818 log_warn(LD_REND, "Descriptor ID contains illegal characters: %s",
819 safe_str(desc_id));
820 return -1;
822 /* Determine if we are responsible. */
823 if (hid_serv_responsible_for_desc_id(desc_id_digest) < 0) {
824 log_info(LD_REND, "Could not answer fetch request for v2 descriptor; "
825 "either we are no hidden service directory, or we are "
826 "not responsible for the requested ID.");
827 return -1;
829 /* Lookup descriptor and return. */
830 e = digestmap_get(rend_cache_v2_dir, desc_id_digest);
831 if (e) {
832 *desc = e->desc;
833 return 1;
835 return 0;
838 /** Parse *desc, calculate its service id, and store it in the cache.
839 * If we have a newer v0 descriptor with the same ID, ignore this one.
840 * If we have an older descriptor with the same ID, replace it.
841 * If we are acting as client due to the published flag and have any v2
842 * descriptor with the same ID, reject this one in order to not get
843 * confused with having both versions for the same service.
844 * Return -1 if it's malformed or otherwise rejected; return 0 if
845 * it's the same or older than one we've already got; return 1 if
846 * it's novel. The published flag tells us if we store the descriptor
847 * in our role as directory (1) or if we cache it as client (0).
850 rend_cache_store(const char *desc, size_t desc_len, int published)
852 rend_cache_entry_t *e;
853 rend_service_descriptor_t *parsed;
854 char query[REND_SERVICE_ID_LEN_BASE32+1];
855 char key[REND_SERVICE_ID_LEN_BASE32+2]; /* 0<query>\0 */
856 time_t now;
857 or_options_t *options = get_options();
858 tor_assert(rend_cache);
859 parsed = rend_parse_service_descriptor(desc,desc_len);
860 if (!parsed) {
861 log_warn(LD_PROTOCOL,"Couldn't parse service descriptor.");
862 return -1;
864 if (rend_get_service_id(parsed->pk, query)<0) {
865 log_warn(LD_BUG,"Couldn't compute service ID.");
866 rend_service_descriptor_free(parsed);
867 return -1;
869 now = time(NULL);
870 if (parsed->timestamp < now-REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
871 log_fn(LOG_PROTOCOL_WARN, LD_REND,
872 "Service descriptor %s is too old.", safe_str(query));
873 rend_service_descriptor_free(parsed);
874 return -1;
876 if (parsed->timestamp > now+REND_CACHE_MAX_SKEW) {
877 log_fn(LOG_PROTOCOL_WARN, LD_REND,
878 "Service descriptor %s is too far in the future.", safe_str(query));
879 rend_service_descriptor_free(parsed);
880 return -1;
882 /* Do we have a v2 descriptor and fetched this descriptor as a client? */
883 tor_snprintf(key, sizeof(key), "2%s", query);
884 if (!published && strmap_get_lc(rend_cache, key)) {
885 log_info(LD_REND, "We already have a v2 descriptor for service %s.",
886 safe_str(query));
887 return -1;
889 /* report novel publication to statistics */
890 if (published && options->HSAuthorityRecordStats) {
891 hs_usage_note_publish_total(query, now);
893 tor_snprintf(key, sizeof(key), "0%s", query);
894 e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key);
895 if (e && e->parsed->timestamp > parsed->timestamp) {
896 log_info(LD_REND,"We already have a newer service descriptor %s with the "
897 "same ID and version.", safe_str(query));
898 rend_service_descriptor_free(parsed);
899 return 0;
901 if (e && e->len == desc_len && !memcmp(desc,e->desc,desc_len)) {
902 log_info(LD_REND,"We already have this service descriptor %s.",
903 safe_str(query));
904 e->received = time(NULL);
905 rend_service_descriptor_free(parsed);
906 return 0;
908 if (!e) {
909 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
910 strmap_set_lc(rend_cache, key, e);
911 /* report novel publication to statistics */
912 if (published && options->HSAuthorityRecordStats) {
913 hs_usage_note_publish_novel(query, now);
915 } else {
916 rend_service_descriptor_free(e->parsed);
917 tor_free(e->desc);
919 e->received = time(NULL);
920 e->parsed = parsed;
921 e->len = desc_len;
922 e->desc = tor_malloc(desc_len);
923 memcpy(e->desc, desc, desc_len);
925 log_debug(LD_REND,"Successfully stored rend desc '%s', len %d.",
926 safe_str(query), (int)desc_len);
927 return 1;
930 /** Parse the v2 service descriptor(s) in <b>desc</b> and store it/them to the
931 * local rend cache. Don't attempt to decrypt the included list of introduction
932 * points (as we don't have a descriptor cookie for it).
934 * If we have a newer descriptor with the same ID, ignore this one.
935 * If we have an older descriptor with the same ID, replace it.
936 * Return -2 if we are not acting as hidden service directory;
937 * return -1 if the descriptor(s) were not parsable; return 0 if all
938 * descriptors are the same or older than those we've already got;
939 * return a positive number for the number of novel stored descriptors.
942 rend_cache_store_v2_desc_as_dir(const char *desc)
944 rend_service_descriptor_t *parsed;
945 char desc_id[DIGEST_LEN];
946 char *intro_content;
947 size_t intro_size;
948 size_t encoded_size;
949 char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
950 int number_parsed = 0, number_stored = 0;
951 const char *current_desc = desc;
952 const char *next_desc;
953 rend_cache_entry_t *e;
954 time_t now = time(NULL);
955 tor_assert(rend_cache_v2_dir);
956 tor_assert(desc);
957 if (!hid_serv_acting_as_directory()) {
958 /* Cannot store descs, because we are (currently) not acting as
959 * hidden service directory. */
960 log_info(LD_REND, "Cannot store descs: Not acting as hs dir");
961 return -2;
963 while (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content,
964 &intro_size, &encoded_size,
965 &next_desc, current_desc) >= 0) {
966 number_parsed++;
967 /* We don't care about the introduction points. */
968 tor_free(intro_content);
969 /* For pretty log statements. */
970 base32_encode(desc_id_base32, sizeof(desc_id_base32),
971 desc_id, DIGEST_LEN);
972 /* Is desc ID in the range that we are (directly or indirectly) responsible
973 * for? */
974 if (!hid_serv_responsible_for_desc_id(desc_id)) {
975 log_info(LD_REND, "Service descriptor with desc ID %s is not in "
976 "interval that we are responsible for.",
977 safe_str(desc_id_base32));
978 goto skip;
980 /* Is descriptor too old? */
981 if (parsed->timestamp < now - REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
982 log_info(LD_REND, "Service descriptor with desc ID %s is too old.",
983 safe_str(desc_id_base32));
984 goto skip;
986 /* Is descriptor too far in the future? */
987 if (parsed->timestamp > now + REND_CACHE_MAX_SKEW) {
988 log_info(LD_REND, "Service descriptor with desc ID %s is too far in the "
989 "future.",
990 safe_str(desc_id_base32));
991 goto skip;
993 /* Do we already have a newer descriptor? */
994 e = digestmap_get(rend_cache_v2_dir, desc_id);
995 if (e && e->parsed->timestamp > parsed->timestamp) {
996 log_info(LD_REND, "We already have a newer service descriptor with the "
997 "same desc ID %s and version.",
998 safe_str(desc_id_base32));
999 goto skip;
1001 /* Do we already have this descriptor? */
1002 if (e && !strcmp(desc, e->desc)) {
1003 log_info(LD_REND, "We already have this service descriptor with desc "
1004 "ID %s.", safe_str(desc_id_base32));
1005 e->received = time(NULL);
1006 goto skip;
1008 /* Store received descriptor. */
1009 if (!e) {
1010 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1011 digestmap_set(rend_cache_v2_dir, desc_id, e);
1012 } else {
1013 rend_service_descriptor_free(e->parsed);
1014 tor_free(e->desc);
1016 e->received = time(NULL);
1017 e->parsed = parsed;
1018 e->desc = tor_strndup(current_desc, encoded_size);
1019 e->len = encoded_size;
1020 log_info(LD_REND, "Successfully stored service descriptor with desc ID "
1021 "'%s' and len %d.",
1022 safe_str(desc_id_base32), (int)encoded_size);
1023 number_stored++;
1024 goto advance;
1025 skip:
1026 rend_service_descriptor_free(parsed);
1027 advance:
1028 /* advance to next descriptor, if available. */
1029 current_desc = next_desc;
1030 /* check if there is a next descriptor. */
1031 if (!current_desc ||
1032 strcmpstart(current_desc, "rendezvous-service-descriptor "))
1033 break;
1035 if (!number_parsed) {
1036 log_info(LD_REND, "Could not parse any descriptor.");
1037 return -1;
1039 log_info(LD_REND, "Parsed %d and added %d descriptor%s.",
1040 number_parsed, number_stored, number_stored != 1 ? "s" : "");
1041 return number_stored;
1044 /** Parse the v2 service descriptor in <b>desc</b>, decrypt the included list
1045 * of introduction points with <b>descriptor_cookie</b> (which may also be
1046 * <b>NULL</b> if decryption is not necessary), and store the descriptor to
1047 * the local cache under its version and service id.
1049 * If we have a newer v2 descriptor with the same ID, ignore this one.
1050 * If we have an older descriptor with the same ID, replace it.
1051 * If we have any v0 descriptor with the same ID, reject this one in order
1052 * to not get confused with having both versions for the same service.
1053 * Return -2 if it's malformed or otherwise rejected; return -1 if we
1054 * already have a v0 descriptor here; return 0 if it's the same or older
1055 * than one we've already got; return 1 if it's novel.
1058 rend_cache_store_v2_desc_as_client(const char *desc,
1059 const char *descriptor_cookie)
1061 /*XXXX this seems to have a bit of duplicate code with
1062 * rend_cache_store_v2_desc_as_dir(). Fix that. */
1063 /* Though having similar elements, both functions were separated on
1064 * purpose:
1065 * - dirs don't care about encoded/encrypted introduction points, clients
1066 * do.
1067 * - dirs store descriptors in a separate cache by descriptor ID, whereas
1068 * clients store them by service ID; both caches are different data
1069 * structures and have different access methods.
1070 * - dirs store a descriptor only if they are responsible for its ID,
1071 * clients do so in every way (because they have requested it before).
1072 * - dirs can process multiple concatenated descriptors which is required
1073 * for replication, whereas clients only accept a single descriptor.
1074 * Thus, combining both methods would result in a lot of if statements
1075 * which probably would not improve, but worsen code readability. -KL */
1076 rend_service_descriptor_t *parsed = NULL;
1077 char desc_id[DIGEST_LEN];
1078 char *intro_content = NULL;
1079 size_t intro_size;
1080 size_t encoded_size;
1081 const char *next_desc;
1082 time_t now = time(NULL);
1083 char key[REND_SERVICE_ID_LEN_BASE32+2];
1084 char service_id[REND_SERVICE_ID_LEN_BASE32+1];
1085 rend_cache_entry_t *e;
1086 tor_assert(rend_cache);
1087 tor_assert(desc);
1088 /* Parse the descriptor. */
1089 if (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content,
1090 &intro_size, &encoded_size,
1091 &next_desc, desc) < 0) {
1092 if (parsed) rend_service_descriptor_free(parsed);
1093 tor_free(intro_content);
1094 log_warn(LD_REND, "Could not parse descriptor.");
1095 return -2;
1097 /* Compute service ID from public key. */
1098 if (rend_get_service_id(parsed->pk, service_id)<0) {
1099 log_warn(LD_REND, "Couldn't compute service ID.");
1100 rend_service_descriptor_free(parsed);
1101 tor_free(intro_content);
1102 return -2;
1104 /* Decode/decrypt introduction points. */
1105 if (intro_content) {
1106 if (rend_decrypt_introduction_points(parsed, descriptor_cookie,
1107 intro_content, intro_size) < 0) {
1108 log_warn(LD_PROTOCOL,"Couldn't decode/decrypt introduction points.");
1109 rend_service_descriptor_free(parsed);
1110 tor_free(intro_content);
1111 return -2;
1113 } else {
1114 parsed->intro_nodes = smartlist_create();
1116 /* We don't need the encoded/encrypted introduction points any longer. */
1117 tor_free(intro_content);
1118 /* Is descriptor too old? */
1119 if (parsed->timestamp < now - REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
1120 log_warn(LD_REND, "Service descriptor with service ID %s is too old.",
1121 safe_str(service_id));
1122 rend_service_descriptor_free(parsed);
1123 return -2;
1125 /* Is descriptor too far in the future? */
1126 if (parsed->timestamp > now + REND_CACHE_MAX_SKEW) {
1127 log_warn(LD_REND, "Service descriptor with service ID %s is too far in "
1128 "the future.", safe_str(service_id));
1129 rend_service_descriptor_free(parsed);
1130 return -2;
1132 /* Do we have a v0 descriptor? */
1133 tor_snprintf(key, sizeof(key), "0%s", service_id);
1134 if (strmap_get_lc(rend_cache, key)) {
1135 log_info(LD_REND, "We already have a v0 descriptor for service ID %s.",
1136 safe_str(service_id));
1137 return -1;
1139 /* Do we already have a newer descriptor? */
1140 tor_snprintf(key, sizeof(key), "2%s", service_id);
1141 e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key);
1142 if (e && e->parsed->timestamp > parsed->timestamp) {
1143 log_info(LD_REND, "We already have a newer service descriptor for "
1144 "service ID %s with the same desc ID and version.",
1145 safe_str(service_id));
1146 rend_service_descriptor_free(parsed);
1147 return 0;
1149 /* Do we already have this descriptor? */
1150 if (e && !strcmp(desc, e->desc)) {
1151 log_info(LD_REND,"We already have this service descriptor %s.",
1152 safe_str(service_id));
1153 e->received = time(NULL);
1154 rend_service_descriptor_free(parsed);
1155 return 0;
1157 if (!e) {
1158 e = tor_malloc_zero(sizeof(rend_cache_entry_t));
1159 strmap_set_lc(rend_cache, key, e);
1160 } else {
1161 rend_service_descriptor_free(e->parsed);
1162 tor_free(e->desc);
1164 e->received = time(NULL);
1165 e->parsed = parsed;
1166 e->desc = tor_malloc_zero(encoded_size + 1);
1167 strlcpy(e->desc, desc, encoded_size + 1);
1168 e->len = encoded_size;
1169 log_debug(LD_REND,"Successfully stored rend desc '%s', len %d.",
1170 safe_str(service_id), (int)encoded_size);
1171 return 1;
1174 /** Called when we get a rendezvous-related relay cell on circuit
1175 * <b>circ</b>. Dispatch on rendezvous relay command. */
1176 void
1177 rend_process_relay_cell(circuit_t *circ, int command, size_t length,
1178 const char *payload)
1180 or_circuit_t *or_circ = NULL;
1181 origin_circuit_t *origin_circ = NULL;
1182 int r = -2;
1183 if (CIRCUIT_IS_ORIGIN(circ))
1184 origin_circ = TO_ORIGIN_CIRCUIT(circ);
1185 else
1186 or_circ = TO_OR_CIRCUIT(circ);
1188 switch (command) {
1189 case RELAY_COMMAND_ESTABLISH_INTRO:
1190 if (or_circ)
1191 r = rend_mid_establish_intro(or_circ,payload,length);
1192 break;
1193 case RELAY_COMMAND_ESTABLISH_RENDEZVOUS:
1194 if (or_circ)
1195 r = rend_mid_establish_rendezvous(or_circ,payload,length);
1196 break;
1197 case RELAY_COMMAND_INTRODUCE1:
1198 if (or_circ)
1199 r = rend_mid_introduce(or_circ,payload,length);
1200 break;
1201 case RELAY_COMMAND_INTRODUCE2:
1202 if (origin_circ)
1203 r = rend_service_introduce(origin_circ,payload,length);
1204 break;
1205 case RELAY_COMMAND_INTRODUCE_ACK:
1206 if (origin_circ)
1207 r = rend_client_introduction_acked(origin_circ,payload,length);
1208 break;
1209 case RELAY_COMMAND_RENDEZVOUS1:
1210 if (or_circ)
1211 r = rend_mid_rendezvous(or_circ,payload,length);
1212 break;
1213 case RELAY_COMMAND_RENDEZVOUS2:
1214 if (origin_circ)
1215 r = rend_client_receive_rendezvous(origin_circ,payload,length);
1216 break;
1217 case RELAY_COMMAND_INTRO_ESTABLISHED:
1218 if (origin_circ)
1219 r = rend_service_intro_established(origin_circ,payload,length);
1220 break;
1221 case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED:
1222 if (origin_circ)
1223 r = rend_client_rendezvous_acked(origin_circ,payload,length);
1224 break;
1225 default:
1226 tor_fragile_assert();
1229 if (r == -2)
1230 log_info(LD_PROTOCOL, "Dropping cell (type %d) for wrong circuit type.",
1231 command);
1234 /** Return the number of entries in our rendezvous descriptor cache. */
1236 rend_cache_size(void)
1238 return strmap_size(rend_cache);