dirvote.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340
  1. /* Copyright 2001-2004 Roger Dingledine.
  2. * Copyright 2004-2007 Roger Dingledine, Nick Mathewson. */
  3. /* See LICENSE for licensing information */
  4. /* $Id$ */
  5. const char dirvote_c_id[] =
  6. "$Id$";
  7. #define DIRVOTE_PRIVATE
  8. #include "or.h"
  9. /**
  10. * \file dirvote.c
  11. * \brief Functions to compute directory consensus, and schedule voting.
  12. **/
  13. /* =====
  14. * Voting and consensus generation
  15. * ===== */
  16. /** Clear all storage held in <b>ns</b>. */
  17. void
  18. networkstatus_vote_free(networkstatus_vote_t *ns)
  19. {
  20. if (!ns)
  21. return;
  22. tor_free(ns->client_versions);
  23. tor_free(ns->server_versions);
  24. if (ns->known_flags) {
  25. SMARTLIST_FOREACH(ns->known_flags, char *, c, tor_free(c));
  26. smartlist_free(ns->known_flags);
  27. }
  28. if (ns->voters) {
  29. SMARTLIST_FOREACH(ns->voters, networkstatus_voter_info_t *, voter,
  30. {
  31. tor_free(voter->nickname);
  32. tor_free(voter->address);
  33. tor_free(voter->contact);
  34. });
  35. smartlist_free(ns->voters);
  36. }
  37. if (ns->cert)
  38. authority_cert_free(ns->cert);
  39. if (ns->routerstatus_list) {
  40. if (ns->is_vote) {
  41. SMARTLIST_FOREACH(ns->routerstatus_list, vote_routerstatus_t *, rs,
  42. {
  43. tor_free(rs->version);
  44. tor_free(rs);
  45. });
  46. } else {
  47. SMARTLIST_FOREACH(ns->routerstatus_list, routerstatus_t *, rs,
  48. tor_free(rs));
  49. }
  50. smartlist_free(ns->routerstatus_list);
  51. }
  52. memset(ns, 11, sizeof(*ns));
  53. tor_free(ns);
  54. }
  55. /** Return the voter info from <b>vote</b> for the voter whose identity digest
  56. * is <b>identity</b>, or NULL if no such voter is associated with
  57. * <b>vote</b>. */
  58. networkstatus_voter_info_t *
  59. networkstatus_get_voter_by_id(networkstatus_vote_t *vote,
  60. const char *identity)
  61. {
  62. if (!vote || !vote->voters)
  63. return NULL;
  64. SMARTLIST_FOREACH(vote->voters, networkstatus_voter_info_t *, voter,
  65. if (!memcmp(voter->identity_digest, identity, DIGEST_LEN))
  66. return voter);
  67. return NULL;
  68. }
  69. /** Helper for sorting a list of time_t*. */
  70. static int
  71. _compare_times(const void **_a, const void **_b)
  72. {
  73. const time_t *a = *_a, *b = *_b;
  74. if (*a<*b)
  75. return -1;
  76. else if (*a>*b)
  77. return 1;
  78. else
  79. return 0;
  80. }
  81. /** Helper for sorting a list of int*. */
  82. static int
  83. _compare_ints(const void **_a, const void **_b)
  84. {
  85. const int *a = *_a, *b = *_b;
  86. if (*a<*b)
  87. return -1;
  88. else if (*a>*b)
  89. return 1;
  90. else
  91. return 0;
  92. }
  93. /** Given a list of one or more time_t*, return the (low) median. */
  94. static time_t
  95. median_time(smartlist_t *times)
  96. {
  97. int idx;
  98. tor_assert(smartlist_len(times));
  99. smartlist_sort(times, _compare_times);
  100. idx = (smartlist_len(times)-1)/2;
  101. return *(time_t*)smartlist_get(times, idx);
  102. }
  103. /** Given a list of one or more int*, return the (low) median. */
  104. static int
  105. median_int(smartlist_t *ints)
  106. {
  107. int idx;
  108. tor_assert(smartlist_len(ints));
  109. smartlist_sort(ints, _compare_ints);
  110. idx = (smartlist_len(ints)-1)/2;
  111. return *(time_t*)smartlist_get(ints, idx);
  112. }
  113. /** Given a vote <b>vote</b> (not a consensus!), return its associated
  114. * networkstatus_voter_info_t.*/
  115. static networkstatus_voter_info_t *
  116. get_voter(const networkstatus_vote_t *vote)
  117. {
  118. tor_assert(vote);
  119. tor_assert(vote->is_vote);
  120. tor_assert(vote->voters);
  121. tor_assert(smartlist_len(vote->voters) == 1);
  122. return smartlist_get(vote->voters, 0);
  123. }
  124. /** Helper for sorting networkstatus_vote_t votes (not consensuses) by the
  125. * hash of their voters' identity digests. */
  126. static int
  127. _compare_votes_by_authority_id(const void **_a, const void **_b)
  128. {
  129. const networkstatus_vote_t *a = *_a, *b = *_b;
  130. return memcmp(get_voter(a)->identity_digest,
  131. get_voter(b)->identity_digest, DIGEST_LEN);
  132. }
  133. /** Given a sorted list of strings <b>in</b>, add every member to <b>out</b>
  134. * that occurs more than <b>min</b> times. */
  135. static void
  136. get_frequent_members(smartlist_t *out, smartlist_t *in, int min)
  137. {
  138. char *cur = NULL;
  139. int count = 0;
  140. SMARTLIST_FOREACH(in, char *, cp,
  141. {
  142. if (cur && !strcmp(cp, cur)) {
  143. ++count;
  144. } else {
  145. if (count > min)
  146. smartlist_add(out, cur);
  147. cur = cp;
  148. count = 1;
  149. }
  150. });
  151. if (count > min)
  152. smartlist_add(out, cur);
  153. }
  154. /** Given a sorted list of strings <b>lst</b>, return the member that appears
  155. * most. Break ties in favor of later-occurring members. */
  156. static const char *
  157. get_most_frequent_member(smartlist_t *lst)
  158. {
  159. const char *most_frequent = NULL;
  160. int most_frequent_count = 0;
  161. const char *cur = NULL;
  162. int count = 0;
  163. SMARTLIST_FOREACH(lst, const char *, s,
  164. {
  165. if (cur && !strcmp(s, cur)) {
  166. ++count;
  167. } else {
  168. if (count >= most_frequent_count) {
  169. most_frequent = cur;
  170. most_frequent_count = count;
  171. }
  172. cur = s;
  173. count = 1;
  174. }
  175. });
  176. if (count >= most_frequent_count) {
  177. most_frequent = cur;
  178. most_frequent_count = count;
  179. }
  180. return most_frequent;
  181. }
  182. /** Return 0 if and only if <b>a</b> and <b>b</b> are routerstatuses
  183. * that come from the same routerinfo, with the same derived elements.
  184. */
  185. static int
  186. compare_vote_rs(const vote_routerstatus_t *a, const vote_routerstatus_t *b)
  187. {
  188. int r;
  189. if ((r = memcmp(a->status.identity_digest, b->status.identity_digest,
  190. DIGEST_LEN)))
  191. return r;
  192. if ((r = memcmp(a->status.descriptor_digest, b->status.descriptor_digest,
  193. DIGEST_LEN)))
  194. return r;
  195. if ((r = (b->status.published_on - a->status.published_on)))
  196. return r;
  197. if ((r = strcmp(b->status.nickname, a->status.nickname)))
  198. return r;
  199. if ((r = (((int)b->status.addr) - ((int)a->status.addr))))
  200. return r;
  201. if ((r = (((int)b->status.or_port) - ((int)a->status.or_port))))
  202. return r;
  203. if ((r = (((int)b->status.dir_port) - ((int)a->status.dir_port))))
  204. return r;
  205. return 0;
  206. }
  207. /** Helper for sorting routerlists based on compare_vote_rs. */
  208. static int
  209. _compare_vote_rs(const void **_a, const void **_b)
  210. {
  211. const vote_routerstatus_t *a = *_a, *b = *_b;
  212. return compare_vote_rs(a,b);
  213. }
  214. /** Given a list of vote_routerstatus_t, all for the same router identity,
  215. * return whichever is most frequent, breaking ties in favor of more
  216. * recently published vote_routerstatus_t.
  217. */
  218. static vote_routerstatus_t *
  219. compute_routerstatus_consensus(smartlist_t *votes)
  220. {
  221. vote_routerstatus_t *most = NULL, *cur = NULL;
  222. int most_n = 0, cur_n = 0;
  223. time_t most_published = 0;
  224. smartlist_sort(votes, _compare_vote_rs);
  225. SMARTLIST_FOREACH(votes, vote_routerstatus_t *, rs,
  226. {
  227. if (cur && !compare_vote_rs(cur, rs)) {
  228. ++cur_n;
  229. } else {
  230. if (cur_n > most_n ||
  231. (cur && cur_n == most_n &&
  232. cur->status.published_on > most_published)) {
  233. most = cur;
  234. most_n = cur_n;
  235. most_published = cur->status.published_on;
  236. }
  237. cur_n = 1;
  238. cur = rs;
  239. }
  240. });
  241. if (cur_n > most_n ||
  242. (cur && cur_n == most_n && cur->status.published_on > most_published)) {
  243. most = cur;
  244. most_n = cur_n;
  245. most_published = cur->status.published_on;
  246. }
  247. tor_assert(most);
  248. return most;
  249. }
  250. /** Given a list of strings in <b>lst</b>, set the DIGEST_LEN-byte digest at
  251. * <b>digest_out</b> to the hash of the concatenation of those strings. */
  252. static void
  253. hash_list_members(char *digest_out, smartlist_t *lst)
  254. {
  255. crypto_digest_env_t *d = crypto_new_digest_env();
  256. SMARTLIST_FOREACH(lst, const char *, cp,
  257. crypto_digest_add_bytes(d, cp, strlen(cp)));
  258. crypto_digest_get_digest(d, digest_out, DIGEST_LEN);
  259. crypto_free_digest_env(d);
  260. }
  261. /** Given a list of vote networkstatus_vote_t in <b>votes</b>, our public
  262. * authority <b>identity_key</b>, our private authority <b>signing_key</b>,
  263. * and the number of <b>total_authorities</b> that we believe exist in our
  264. * voting quorum, generate the text of a new v3 consensus vote, and return the
  265. * value in a newly allocated string. */
  266. char *
  267. networkstatus_compute_consensus(smartlist_t *votes,
  268. int total_authorities,
  269. crypto_pk_env_t *identity_key,
  270. crypto_pk_env_t *signing_key)
  271. {
  272. smartlist_t *chunks;
  273. char *result = NULL;
  274. time_t valid_after, fresh_until, valid_until;
  275. int vote_seconds, dist_seconds;
  276. char *client_versions = NULL, *server_versions = NULL;
  277. smartlist_t *flags;
  278. tor_assert(total_authorities >= smartlist_len(votes));
  279. if (!smartlist_len(votes)) {
  280. log_warn(LD_DIR, "Can't compute a consensus from no votes.");
  281. return NULL;
  282. }
  283. /* XXXX020 somebody needs to check vote authority. It could be this
  284. * function, it could be somebody else. */
  285. flags = smartlist_create();
  286. /* Compute medians of time-related things, and figure out how many
  287. * routers we might need to talk about. */
  288. {
  289. smartlist_t *va_times = smartlist_create();
  290. smartlist_t *fu_times = smartlist_create();
  291. smartlist_t *vu_times = smartlist_create();
  292. smartlist_t *votesec_list = smartlist_create();
  293. smartlist_t *distsec_list = smartlist_create();
  294. int n_versioning_clients = 0, n_versioning_servers = 0;
  295. smartlist_t *combined_client_versions = smartlist_create();
  296. smartlist_t *combined_server_versions = smartlist_create();
  297. int j;
  298. SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v,
  299. {
  300. tor_assert(v->is_vote);
  301. smartlist_add(va_times, &v->valid_after);
  302. smartlist_add(fu_times, &v->fresh_until);
  303. smartlist_add(vu_times, &v->valid_until);
  304. smartlist_add(votesec_list, &v->vote_seconds);
  305. smartlist_add(distsec_list, &v->dist_seconds);
  306. if (v->client_versions) {
  307. smartlist_t *cv = smartlist_create();
  308. ++n_versioning_clients;
  309. smartlist_split_string(cv, v->client_versions, ",",
  310. SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  311. sort_version_list(cv, 1);
  312. smartlist_add_all(combined_client_versions, cv);
  313. smartlist_free(cv); /* elements get freed later. */
  314. }
  315. if (v->server_versions) {
  316. smartlist_t *sv = smartlist_create();
  317. ++n_versioning_servers;
  318. smartlist_split_string(sv, v->server_versions, ",",
  319. SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  320. sort_version_list(sv, 1);
  321. smartlist_add_all(combined_server_versions, sv);
  322. smartlist_free(sv); /* elements get freed later. */
  323. }
  324. SMARTLIST_FOREACH(v->known_flags, const char *, cp,
  325. smartlist_add(flags, tor_strdup(cp)));
  326. });
  327. valid_after = median_time(va_times);
  328. fresh_until = median_time(fu_times);
  329. valid_until = median_time(vu_times);
  330. vote_seconds = median_int(votesec_list);
  331. dist_seconds = median_int(distsec_list);
  332. for (j = 0; j < 2; ++j) {
  333. smartlist_t *lst =
  334. j ? combined_server_versions : combined_client_versions;
  335. int min = (j ? n_versioning_servers : n_versioning_clients) / 2;
  336. smartlist_t *good = smartlist_create();
  337. char *res;
  338. sort_version_list(lst, 0);
  339. get_frequent_members(good, lst, min);
  340. res = smartlist_join_strings(good, ",", 0, NULL);
  341. if (j)
  342. server_versions = res;
  343. else
  344. client_versions = res;
  345. SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
  346. smartlist_free(good);
  347. smartlist_free(lst);
  348. }
  349. smartlist_sort_strings(flags);
  350. smartlist_uniq_strings(flags);
  351. smartlist_free(va_times);
  352. smartlist_free(fu_times);
  353. smartlist_free(vu_times);
  354. smartlist_free(votesec_list);
  355. smartlist_free(distsec_list);
  356. }
  357. chunks = smartlist_create();
  358. {
  359. char buf[1024];
  360. char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
  361. vu_buf[ISO_TIME_LEN+1];
  362. char *flaglist;
  363. format_iso_time(va_buf, valid_after);
  364. format_iso_time(fu_buf, fresh_until);
  365. format_iso_time(vu_buf, valid_until);
  366. flaglist = smartlist_join_strings(flags, " ", 0, NULL);
  367. tor_snprintf(buf, sizeof(buf),
  368. "network-status-version 3\n"
  369. "vote-status consensus\n"
  370. "valid-after %s\n"
  371. "fresh-until %s\n"
  372. "valid-until %s\n"
  373. "voting-delay %d %d\n"
  374. "client-versions %s\n"
  375. "server-versions %s\n"
  376. "known-flags %s\n",
  377. va_buf, fu_buf, vu_buf,
  378. vote_seconds, dist_seconds,
  379. client_versions, server_versions, flaglist);
  380. smartlist_add(chunks, tor_strdup(buf));
  381. tor_free(flaglist);
  382. }
  383. /* Sort the votes. */
  384. smartlist_sort(votes, _compare_votes_by_authority_id);
  385. /* Add the authority sections. */
  386. SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v,
  387. {
  388. char buf[1024];
  389. struct in_addr in;
  390. char ip[INET_NTOA_BUF_LEN];
  391. char fingerprint[HEX_DIGEST_LEN+1];
  392. char votedigest[HEX_DIGEST_LEN+1];
  393. networkstatus_voter_info_t *voter = get_voter(v);
  394. in.s_addr = htonl(voter->addr);
  395. tor_inet_ntoa(&in, ip, sizeof(ip));
  396. base16_encode(fingerprint, sizeof(fingerprint), voter->identity_digest,
  397. DIGEST_LEN);
  398. base16_encode(votedigest, sizeof(votedigest), voter->vote_digest,
  399. DIGEST_LEN);
  400. tor_snprintf(buf, sizeof(buf),
  401. "dir-source %s %s %s %s %d %d\n"
  402. "contact %s\n"
  403. "vote-digest %s\n",
  404. voter->nickname, fingerprint, voter->address, ip,
  405. voter->dir_port,
  406. voter->or_port,
  407. voter->contact,
  408. votedigest);
  409. smartlist_add(chunks, tor_strdup(buf));
  410. });
  411. /* Add the actual router entries. */
  412. {
  413. /* document these XXXX020 */
  414. int *index;
  415. int *size;
  416. int *flag_counts;
  417. int i;
  418. smartlist_t *matching_descs = smartlist_create();
  419. smartlist_t *chosen_flags = smartlist_create();
  420. smartlist_t *versions = smartlist_create();
  421. int *n_voter_flags; /* n_voter_flags[j] is the number of flags that
  422. * votes[j] knows about. */
  423. int *n_flag_voters; /* n_flag_voters[f] is the number of votes that care
  424. * about flags[f]. */
  425. int **flag_map; /* flag_map[j][b] is an index f such that flag_map[f]
  426. * is the same flag as votes[j]->known_flags[b]. */
  427. int *named_flag;
  428. index = tor_malloc_zero(sizeof(int)*smartlist_len(votes));
  429. size = tor_malloc_zero(sizeof(int)*smartlist_len(votes));
  430. n_voter_flags = tor_malloc_zero(sizeof(int) * smartlist_len(votes));
  431. n_flag_voters = tor_malloc_zero(sizeof(int) * smartlist_len(flags));
  432. flag_map = tor_malloc_zero(sizeof(int*) * smartlist_len(votes));
  433. named_flag = tor_malloc_zero(sizeof(int*) * smartlist_len(votes));
  434. for (i = 0; i < smartlist_len(votes); ++i)
  435. named_flag[i] = -1;
  436. SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v,
  437. {
  438. flag_map[v_sl_idx] = tor_malloc_zero(
  439. sizeof(int)*smartlist_len(v->known_flags));
  440. SMARTLIST_FOREACH(v->known_flags, const char *, fl,
  441. {
  442. int p = smartlist_string_pos(flags, fl);
  443. tor_assert(p >= 0);
  444. flag_map[v_sl_idx][fl_sl_idx] = p;
  445. ++n_flag_voters[p];
  446. if (!strcmp(fl, "Named"))
  447. named_flag[v_sl_idx] = fl_sl_idx;
  448. });
  449. n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags);
  450. size[v_sl_idx] = smartlist_len(v->routerstatus_list);
  451. });
  452. /* Now go through all the votes */
  453. flag_counts = tor_malloc(sizeof(int) * smartlist_len(flags));
  454. while (1) {
  455. vote_routerstatus_t *rs;
  456. routerstatus_t rs_out;
  457. const char *lowest_id = NULL;
  458. const char *chosen_version;
  459. const char *chosen_name = NULL;
  460. int naming_conflict = 0;
  461. int n_listing = 0;
  462. int i;
  463. char buf[256];
  464. SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v, {
  465. if (index[v_sl_idx] < size[v_sl_idx]) {
  466. rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
  467. if (!lowest_id ||
  468. memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN) < 0)
  469. lowest_id = rs->status.identity_digest;
  470. }
  471. });
  472. if (!lowest_id) /* we're out of routers. */
  473. break;
  474. memset(flag_counts, 0, sizeof(int)*smartlist_len(flags));
  475. smartlist_clear(matching_descs);
  476. smartlist_clear(chosen_flags);
  477. smartlist_clear(versions);
  478. /* Okay, go through all the entries for this digest. */
  479. SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v, {
  480. if (index[v_sl_idx] >= size[v_sl_idx])
  481. continue; /* out of entries. */
  482. rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
  483. if (memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN))
  484. continue; /* doesn't include this router. */
  485. /* At this point, we know that we're looking at a routersatus with
  486. * identity "lowest".
  487. */
  488. ++index[v_sl_idx];
  489. ++n_listing;
  490. smartlist_add(matching_descs, rs);
  491. if (rs->version && rs->version[0])
  492. smartlist_add(versions, rs->version);
  493. /* Tally up all the flags. */
  494. for (i = 0; i < n_voter_flags[v_sl_idx]; ++i) {
  495. if (rs->flags & (U64_LITERAL(1) << i))
  496. ++flag_counts[flag_map[v_sl_idx][i]];
  497. }
  498. if (rs->flags & (U64_LITERAL(1) << named_flag[v_sl_idx])) {
  499. if (chosen_name && strcmp(chosen_name, rs->status.nickname))
  500. naming_conflict = 1; /* XXXX020 warn? */
  501. chosen_name = rs->status.nickname;
  502. }
  503. });
  504. /* We don't include this router at all unless more than half of
  505. * the authorities we believe in list it. */
  506. if (n_listing <= total_authorities/2)
  507. continue;
  508. /* Figure out the most popular opinion of what the most recent
  509. * routerinfo and its contents are. */
  510. rs = compute_routerstatus_consensus(matching_descs);
  511. /* Copy bits of that into rs_out. */
  512. tor_assert(!memcmp(lowest_id, rs->status.identity_digest, DIGEST_LEN));
  513. memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN);
  514. memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest,
  515. DIGEST_LEN);
  516. rs_out.addr = rs->status.addr;
  517. rs_out.published_on = rs->status.published_on;
  518. rs_out.dir_port = rs->status.dir_port;
  519. rs_out.or_port = rs->status.or_port;
  520. if (chosen_name && !naming_conflict) {
  521. strlcpy(rs_out.nickname, chosen_name, sizeof(rs_out.nickname));
  522. } else {
  523. strlcpy(rs_out.nickname, rs->status.nickname, sizeof(rs_out.nickname));
  524. }
  525. /* Set the flags. */
  526. smartlist_add(chosen_flags, (char*)"s"); /* for the start of the line. */
  527. SMARTLIST_FOREACH(flags, const char *, fl,
  528. {
  529. if (strcmp(fl, "Named")) {
  530. if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2)
  531. smartlist_add(chosen_flags, (char*)fl);
  532. } else {
  533. if (!naming_conflict && flag_counts[fl_sl_idx])
  534. smartlist_add(chosen_flags, (char*)"Named");
  535. }
  536. });
  537. /* Pick the version. */
  538. if (smartlist_len(versions)) {
  539. sort_version_list(versions, 0);
  540. chosen_version = get_most_frequent_member(versions);
  541. } else {
  542. chosen_version = NULL;
  543. }
  544. /* Okay!! Now we can write the descriptor... */
  545. /* First line goes into "buf". */
  546. routerstatus_format_entry(buf, sizeof(buf), &rs_out, NULL, 1);
  547. smartlist_add(chunks, tor_strdup(buf));
  548. /* Second line is all flags. The "\n" is missing. */
  549. smartlist_add(chunks,
  550. smartlist_join_strings(chosen_flags, " ", 0, NULL));
  551. /* Now the version line. */
  552. if (chosen_version) {
  553. /* XXXX020 fails on very long version string */
  554. tor_snprintf(buf, sizeof(buf), "\nv %s\n", chosen_version);
  555. smartlist_add(chunks, tor_strdup(buf));
  556. } else {
  557. smartlist_add(chunks, tor_strdup("\n"));
  558. }
  559. /* And the loop is over and we move on to the next router */
  560. }
  561. tor_free(index);
  562. tor_free(size);
  563. tor_free(n_voter_flags);
  564. tor_free(n_flag_voters);
  565. for (i = 0; i < smartlist_len(votes); ++i)
  566. tor_free(flag_map[i]);
  567. tor_free(flag_map);
  568. tor_free(flag_counts);
  569. smartlist_free(matching_descs);
  570. smartlist_free(chosen_flags);
  571. smartlist_free(versions);
  572. }
  573. /* Add a signature. */
  574. {
  575. char digest[DIGEST_LEN];
  576. char fingerprint[HEX_DIGEST_LEN+1];
  577. char signing_key_fingerprint[HEX_DIGEST_LEN+1];
  578. char buf[4096];
  579. smartlist_add(chunks, tor_strdup("directory-signature "));
  580. /* Compute the hash of the chunks. */
  581. hash_list_members(digest, chunks);
  582. /* Get the fingerprints */
  583. crypto_pk_get_fingerprint(identity_key, fingerprint, 0);
  584. crypto_pk_get_fingerprint(signing_key, signing_key_fingerprint, 0);
  585. /* add the junk that will go at the end of the line. */
  586. tor_snprintf(buf, sizeof(buf), "%s %s\n", fingerprint,
  587. signing_key_fingerprint);
  588. /* And the signature. */
  589. /* XXXX020 check return */
  590. router_append_dirobj_signature(buf, sizeof(buf), digest, signing_key);
  591. smartlist_add(chunks, tor_strdup(buf));
  592. }
  593. result = smartlist_join_strings(chunks, "", 0, NULL);
  594. tor_free(client_versions);
  595. tor_free(server_versions);
  596. smartlist_free(flags);
  597. SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
  598. smartlist_free(chunks);
  599. {
  600. networkstatus_vote_t *c;
  601. if (!(c = networkstatus_parse_vote_from_string(result, 0))) {
  602. log_err(LD_BUG,"Generated a networkstatus consensus we couldn't "
  603. "parse.");
  604. tor_free(result);
  605. return NULL;
  606. }
  607. networkstatus_vote_free(c);
  608. }
  609. return result;
  610. }
  611. /** Check whether the pending_signature on <b>voter</b> is correctly signed by
  612. * the signing key of <b>cert</b>. Return -1 if <b>cert</b> doesn't match the
  613. * signing key; otherwise set the good_signature or bad_signature flag on
  614. * <b>voter</b>, and return 0. */
  615. /* (private; exposed for testing.) */
  616. int
  617. networkstatus_check_voter_signature(networkstatus_vote_t *consensus,
  618. networkstatus_voter_info_t *voter,
  619. authority_cert_t *cert)
  620. {
  621. char d[DIGEST_LEN];
  622. char *signed_digest;
  623. size_t signed_digest_len;
  624. /*XXXX020 check return*/
  625. crypto_pk_get_digest(cert->signing_key, d);
  626. if (memcmp(voter->signing_key_digest, d, DIGEST_LEN)) {
  627. return -1;
  628. }
  629. signed_digest_len = crypto_pk_keysize(cert->signing_key);
  630. signed_digest = tor_malloc(signed_digest_len);
  631. if (crypto_pk_public_checksig(cert->signing_key,
  632. signed_digest,
  633. voter->signature,
  634. voter->signature_len) != DIGEST_LEN ||
  635. memcmp(signed_digest, consensus->networkstatus_digest, DIGEST_LEN)) {
  636. log_warn(LD_DIR, "Got a bad signature."); /*XXXX020 say more*/
  637. voter->bad_signature = 1;
  638. } else {
  639. voter->good_signature = 1;
  640. }
  641. /* XXXX020 did anything rely on this?
  642. * also, rename so it's no longer called "pending". */
  643. // tor_free(voter->signature);
  644. return 0;
  645. }
  646. /** DOCDOC */
  647. int
  648. networkstatus_check_consensus_signature(networkstatus_vote_t *consensus)
  649. {
  650. int n_good = 0;
  651. int n_missing_key = 0;
  652. int n_bad = 0;
  653. int n_unknown = 0;
  654. int n_no_signature = 0;
  655. tor_assert(! consensus->is_vote);
  656. SMARTLIST_FOREACH(consensus->voters, networkstatus_voter_info_t *, voter,
  657. {
  658. if (!voter->good_signature && !voter->bad_signature && voter->signature) {
  659. /* we can try to check the signature. */
  660. authority_cert_t *cert =
  661. authority_cert_get_by_digests(voter->identity_digest,
  662. voter->signing_key_digest);
  663. if (! cert) {
  664. ++n_unknown;
  665. continue;
  666. }
  667. if (networkstatus_check_voter_signature(consensus, voter, cert) < 0) {
  668. ++n_missing_key; /* XXXX020 what, really? */
  669. continue;
  670. }
  671. }
  672. if (voter->good_signature)
  673. ++n_good;
  674. else if (voter->bad_signature)
  675. ++n_bad;
  676. else
  677. ++n_no_signature;
  678. });
  679. /* XXXX020 actually use the result. */
  680. return 0;
  681. }
  682. /** DOCDOC */
  683. static int
  684. networkstatus_add_signatures_impl(networkstatus_vote_t *target,
  685. smartlist_t *src_voter_list,
  686. char **new_signatures_out)
  687. {
  688. smartlist_t *added_signatures, *sigs;
  689. int r;
  690. tor_assert(target);
  691. tor_assert(!target->is_vote);
  692. tor_assert(new_signatures_out);
  693. added_signatures = smartlist_create();
  694. /* For each voter in src... */
  695. SMARTLIST_FOREACH(src_voter_list, networkstatus_voter_info_t *, src_voter,
  696. {
  697. networkstatus_voter_info_t *target_voter =
  698. networkstatus_get_voter_by_id(target, src_voter->identity_digest);
  699. authority_cert_t *cert;
  700. /* If the target a doesn't know about this voter, then forget it. */
  701. if (!target_voter)
  702. continue;
  703. /* If the target already has a good signature from this voter, then skip
  704. * this one. */
  705. if (target_voter->good_signature)
  706. continue;
  707. /* Try checking the signature if we haven't already. */
  708. if (!src_voter->good_signature && !src_voter->bad_signature) {
  709. cert = authority_cert_get_by_digests(src_voter->identity_digest,
  710. src_voter->signing_key_digest);
  711. if (cert) {
  712. networkstatus_check_voter_signature(target, src_voter, cert);
  713. }
  714. }
  715. /* If this signature is good, then replace and add. */
  716. if (src_voter->good_signature || !target_voter->signature) {
  717. tor_free(target_voter->signature);
  718. target_voter->signature =
  719. tor_memdup(src_voter->signature, src_voter->signature_len);
  720. memcpy(target_voter->signing_key_digest, src_voter->signing_key_digest,
  721. DIGEST_LEN);
  722. target_voter->signature_len = src_voter->signature_len;
  723. target_voter->good_signature = 1;
  724. target_voter->bad_signature = 0;
  725. smartlist_add(added_signatures, target_voter);
  726. }
  727. });
  728. sigs = smartlist_create();
  729. SMARTLIST_FOREACH(added_signatures, networkstatus_voter_info_t *, v,
  730. {
  731. char buf[4096];
  732. char sk[HEX_DIGEST_LEN+1];
  733. char ik[HEX_DIGEST_LEN+1];
  734. tor_assert(v->signature);
  735. base16_encode(sk, sizeof(sk), v->signing_key_digest, DIGEST_LEN);
  736. base16_encode(ik, sizeof(ik), v->identity_digest, DIGEST_LEN);
  737. tor_snprintf(buf, sizeof(buf), "directory-signature %s %s\n"
  738. "-----BEGIN SIGNATURE-----\n", ik, sk);
  739. smartlist_add(sigs, tor_strdup(buf));
  740. base64_encode(buf, sizeof(buf), v->signature, v->signature_len);
  741. strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf));
  742. smartlist_add(sigs, tor_strdup(buf));
  743. });
  744. *new_signatures_out = smartlist_join_strings(sigs, "", 0, NULL);
  745. SMARTLIST_FOREACH(sigs, char *, cp, tor_free(cp));
  746. smartlist_free(sigs);
  747. r = smartlist_len(added_signatures);
  748. smartlist_free(added_signatures);
  749. return r;
  750. }
  751. /** DOCDOC */
  752. int
  753. networkstatus_add_consensus_signatures(networkstatus_vote_t *target,
  754. networkstatus_vote_t *src,
  755. char **new_signatures_out)
  756. {
  757. tor_assert(src);
  758. tor_assert(! src->is_vote);
  759. *new_signatures_out = NULL;
  760. /* Are they the same consensus? */
  761. if (memcmp(target->networkstatus_digest, src->networkstatus_digest,
  762. DIGEST_LEN))
  763. return -1;
  764. if (target == src)
  765. return 0;
  766. return networkstatus_add_signatures_impl(target, src->voters,
  767. new_signatures_out);
  768. }
  769. /** DOCDOC */
  770. int
  771. networkstatus_add_detached_signatures(networkstatus_vote_t *target,
  772. ns_detached_signatures_t *sigs,
  773. char **new_signatures_out)
  774. {
  775. tor_assert(sigs);
  776. *new_signatures_out = NULL;
  777. /* Are they the same consensus? */
  778. if (memcmp(target->networkstatus_digest, sigs->networkstatus_digest,
  779. DIGEST_LEN))
  780. return -1;
  781. return networkstatus_add_signatures_impl(target, sigs->signatures,
  782. new_signatures_out);
  783. }
  784. /** DOCDOC */
  785. char *
  786. networkstatus_get_detached_signatures(networkstatus_vote_t *consensus)
  787. {
  788. smartlist_t *elements;
  789. char buf[4096];
  790. char *result = NULL;
  791. tor_assert(consensus);
  792. tor_assert(! consensus->is_vote);
  793. elements = smartlist_create();
  794. {
  795. char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
  796. vu_buf[ISO_TIME_LEN+1];
  797. char d[HEX_DIGEST_LEN+1];
  798. base16_encode(d, sizeof(d), consensus->networkstatus_digest, DIGEST_LEN);
  799. format_iso_time(va_buf, consensus->valid_after);
  800. format_iso_time(fu_buf, consensus->fresh_until);
  801. format_iso_time(vu_buf, consensus->valid_until);
  802. tor_snprintf(buf, sizeof(buf),
  803. "consensus-digest %s\n"
  804. "valid-after %s\n"
  805. "fresh-until %s\n"
  806. "valid-until %s\n", d, va_buf, fu_buf, vu_buf);
  807. smartlist_add(elements, tor_strdup(buf));
  808. }
  809. SMARTLIST_FOREACH(consensus->voters, networkstatus_voter_info_t *, v,
  810. {
  811. char sk[HEX_DIGEST_LEN+1];
  812. char id[HEX_DIGEST_LEN+1];
  813. if (!v->signature || !v->good_signature)
  814. continue;
  815. base16_encode(sk, sizeof(sk), v->signing_key_digest, DIGEST_LEN);
  816. base16_encode(id, sizeof(id), v->identity_digest, DIGEST_LEN);
  817. tor_snprintf(buf, sizeof(buf),
  818. "directory-signature %s %s\n-----BEGIN SIGNATURE-----\n",
  819. id, sk);
  820. smartlist_add(elements, tor_strdup(buf));
  821. base64_encode(buf, sizeof(buf), v->signature, v->signature_len);
  822. strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf));
  823. smartlist_add(elements, tor_strdup(buf));
  824. });
  825. result = smartlist_join_strings(elements, "", 0, NULL);
  826. SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
  827. smartlist_free(elements);
  828. return result;
  829. }
  830. /** DOCDOC */
  831. void
  832. ns_detached_signatures_free(ns_detached_signatures_t *s)
  833. {
  834. if (s->signatures) {
  835. SMARTLIST_FOREACH(s->signatures, networkstatus_voter_info_t *, v,
  836. {
  837. tor_free(v->signature);
  838. tor_free(v);
  839. });
  840. smartlist_free(s->signatures);
  841. }
  842. tor_free(s);
  843. }
  844. /* =====
  845. * Certificate functions
  846. * ===== */
  847. /** Free storage held in <b>cert</b>. */
  848. void
  849. authority_cert_free(authority_cert_t *cert)
  850. {
  851. if (!cert)
  852. return;
  853. tor_free(cert->cache_info.signed_descriptor_body);
  854. if (cert->signing_key)
  855. crypto_free_pk_env(cert->signing_key);
  856. if (cert->identity_key)
  857. crypto_free_pk_env(cert->identity_key);
  858. tor_free(cert);
  859. }
  860. /** Allocate and return a new authority_cert_t with the same contents as
  861. * <b>cert</b>. */
  862. authority_cert_t *
  863. authority_cert_dup(authority_cert_t *cert)
  864. {
  865. authority_cert_t *out = tor_malloc(sizeof(authority_cert_t));
  866. tor_assert(cert);
  867. memcpy(out, cert, sizeof(authority_cert_t));
  868. /* Now copy pointed-to things. */
  869. out->cache_info.signed_descriptor_body =
  870. tor_strndup(cert->cache_info.signed_descriptor_body,
  871. cert->cache_info.signed_descriptor_len);
  872. out->cache_info.saved_location = SAVED_NOWHERE;
  873. out->identity_key = crypto_pk_dup_key(cert->identity_key);
  874. out->signing_key = crypto_pk_dup_key(cert->signing_key);
  875. return out;
  876. }
  877. /* =====
  878. * Vote scheduling
  879. * ===== */
  880. /** DOCDOC */
  881. void
  882. dirvote_get_preferred_voting_intervals(vote_timing_t *timing_out)
  883. {
  884. tor_assert(timing_out);
  885. /* XXXX020 make these configurable. */
  886. timing_out->vote_interval = 3600;
  887. timing_out->n_intervals_valid = 3;
  888. timing_out->vote_delay = 300;
  889. timing_out->dist_delay = 300;
  890. }
  891. /** DOCDOC */
  892. time_t
  893. dirvote_get_start_of_next_interval(time_t now, int interval)
  894. {
  895. struct tm tm;
  896. time_t midnight_today;
  897. time_t midnight_tomorrow;
  898. time_t next;
  899. tor_gmtime_r(&now, &tm);
  900. tm.tm_hour = 0;
  901. tm.tm_min = 0;
  902. tm.tm_sec = 0;
  903. midnight_today = tor_timegm(&tm);
  904. midnight_tomorrow = midnight_today + (24*60*60);
  905. next = midnight_today + ((now-midnight_today)/interval + 1)*interval;
  906. if (next > midnight_tomorrow)
  907. next = midnight_tomorrow;
  908. return next;
  909. }
  910. /** DOCDOC */
  911. static struct {
  912. time_t voting_starts;
  913. time_t voting_ends;
  914. time_t interval_starts;
  915. } voting_schedule;
  916. /** DOCDOC */
  917. void
  918. dirvote_recalculate_timing(time_t now)
  919. {
  920. int interval, vote_delay, dist_delay;
  921. time_t start;
  922. networkstatus_vote_t *consensus = networkstatus_get_latest_consensus();
  923. if (consensus) {
  924. /* XXXX020 sanity-check these somewhere! */
  925. interval = consensus->fresh_until - consensus->valid_after;
  926. vote_delay = consensus->vote_seconds;
  927. dist_delay = consensus->dist_seconds;
  928. } else {
  929. /* XXXX020 is this correct according the the spec? */
  930. interval = 3600;
  931. vote_delay = dist_delay = 300;
  932. }
  933. start = voting_schedule.interval_starts =
  934. dirvote_get_start_of_next_interval(now,interval);
  935. voting_schedule.voting_ends = start - vote_delay;
  936. voting_schedule.voting_starts = start - vote_delay - dist_delay;
  937. }
  938. /** DOCDOC */
  939. typedef struct pending_vote_t {
  940. cached_dir_t *vote_body;
  941. networkstatus_vote_t *vote;
  942. } pending_vote_t;
  943. /** DOCDOC */
  944. static smartlist_t *pending_vote_list = NULL;
  945. /** DOCDOC */
  946. static char *pending_consensus_body = NULL;
  947. /** DOCDOC */
  948. static char *pending_consensus_signatures = NULL;
  949. /** DOCDOC */
  950. static networkstatus_vote_t *pending_consensus = NULL;
  951. /** DOCDOC */
  952. static smartlist_t *pending_consensus_signature_list = NULL;
  953. /** DOCDOC */
  954. void
  955. dirvote_perform_vote(void)
  956. {
  957. cached_dir_t *new_vote = generate_v3_networkstatus();
  958. pending_vote_t *pending_vote;
  959. const char *msg = "";
  960. if ((pending_vote = dirvote_add_vote(new_vote->dir, &msg))) {
  961. log_warn(LD_DIR, "Couldn't store my own vote! (I told myself, '%s'.)",
  962. msg);
  963. return;
  964. }
  965. directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_VOTE,
  966. ROUTER_PURPOSE_GENERAL,
  967. V3_AUTHORITY,
  968. pending_vote->vote_body->dir,
  969. pending_vote->vote_body->dir_len, 0);
  970. }
  971. /** DOCDOC */
  972. void
  973. dirvote_clear_pending_votes(void)
  974. {
  975. if (pending_vote_list) {
  976. SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
  977. cached_dir_decref(v->vote_body);
  978. v->vote_body = NULL;
  979. networkstatus_vote_free(v->vote);
  980. tor_free(v);
  981. });
  982. smartlist_clear(pending_vote_list);
  983. }
  984. if (pending_consensus_signature_list) {
  985. SMARTLIST_FOREACH(pending_consensus_signature_list, char *, cp,
  986. tor_free(cp));
  987. smartlist_clear(pending_consensus_signature_list);
  988. }
  989. }
  990. /** DOCDOC */
  991. pending_vote_t *
  992. dirvote_add_vote(const char *vote_body, const char **msg_out)
  993. {
  994. networkstatus_vote_t *vote;
  995. networkstatus_voter_info_t *vi;
  996. trusted_dir_server_t *ds;
  997. pending_vote_t *pending_vote = NULL;
  998. tor_assert(vote_body);
  999. tor_assert(msg_out);
  1000. if (!pending_vote_list)
  1001. pending_vote_list = smartlist_create();
  1002. *msg_out = NULL;
  1003. vote = networkstatus_parse_vote_from_string(vote_body, 1);
  1004. if (!vote) {
  1005. *msg_out = "Unable to parse vote";
  1006. goto err;
  1007. }
  1008. tor_assert(smartlist_len(vote->voters) == 1);
  1009. vi = smartlist_get(vote->voters, 0);
  1010. tor_assert(vi->good_signature == 1);
  1011. ds = trusteddirserver_get_by_v3_auth_digest(vi->identity_digest);
  1012. if (!ds || !(ds->type & V3_AUTHORITY)) {
  1013. *msg_out = "Vote not from a recognized v3 authority";
  1014. goto err;
  1015. }
  1016. /* XXXX020 check times; make sure epochs match. */
  1017. SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
  1018. if (! memcmp(v->vote->cert->cache_info.identity_digest,
  1019. vote->cert->cache_info.identity_digest,
  1020. DIGEST_LEN)) {
  1021. log_notice(LD_DIR, "We already have a pending vote from this dir");
  1022. if (v->vote->published < vote->published) {
  1023. cached_dir_decref(v->vote_body);
  1024. networkstatus_vote_free(v->vote);
  1025. v->vote_body = new_cached_dir(tor_strdup(vote_body),
  1026. vote->published);
  1027. v->vote = vote;
  1028. *msg_out = "ok";
  1029. return v;
  1030. } else {
  1031. *msg_out = "Already have a newer pending vote";
  1032. goto err;
  1033. }
  1034. }
  1035. });
  1036. pending_vote = tor_malloc_zero(sizeof(pending_vote_t));
  1037. pending_vote->vote_body = new_cached_dir(tor_strdup(vote_body),
  1038. vote->published);
  1039. pending_vote->vote = vote;
  1040. smartlist_add(pending_vote_list, pending_vote);
  1041. *msg_out = "ok";
  1042. return pending_vote;
  1043. err:
  1044. if (vote)
  1045. networkstatus_vote_free(vote);
  1046. if (!*msg_out)
  1047. *msg_out = "Error adding vote";
  1048. /*XXXX020 free other fields */
  1049. return NULL;
  1050. }
  1051. /** DOCDOC */
  1052. int
  1053. dirvote_compute_consensus(void)
  1054. {
  1055. /* Have we got enough votes to try? */
  1056. int n_votes, n_voters;
  1057. smartlist_t *votes = NULL;
  1058. char *consensus_body = NULL, *signatures = NULL;
  1059. networkstatus_vote_t *consensus = NULL;
  1060. authority_cert_t *my_cert;
  1061. if (!pending_vote_list)
  1062. pending_vote_list = smartlist_create();
  1063. n_voters = get_n_authorities(V3_AUTHORITY);
  1064. n_votes = smartlist_len(pending_vote_list);
  1065. /* XXXX020 see if there are enough to go ahead. */
  1066. if (!(my_cert = get_my_v3_authority_cert())) {
  1067. log_warn(LD_DIR, "Can't generate consensus without a certificate.");
  1068. goto err;
  1069. }
  1070. votes = smartlist_create();
  1071. SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v,
  1072. smartlist_add(votes, v->vote));
  1073. consensus_body = networkstatus_compute_consensus(
  1074. votes, n_voters,
  1075. my_cert->identity_key,
  1076. get_my_v3_authority_signing_key());
  1077. consensus = networkstatus_parse_vote_from_string(consensus_body, 0);
  1078. if (!consensus) {
  1079. log_warn(LD_DIR, "Couldn't parse consensus we generated!");
  1080. goto err;
  1081. }
  1082. signatures = networkstatus_get_detached_signatures(consensus);
  1083. if (!signatures) {
  1084. log_warn(LD_DIR, "Couldn't extract signatures.");
  1085. goto err;
  1086. }
  1087. tor_free(pending_consensus_body);
  1088. pending_consensus_body = consensus_body;
  1089. tor_free(pending_consensus_signatures);
  1090. pending_consensus_signatures = signatures;
  1091. if (pending_consensus)
  1092. networkstatus_vote_free(pending_consensus);
  1093. pending_consensus = consensus;
  1094. return 0;
  1095. err:
  1096. if (votes)
  1097. smartlist_free(votes);
  1098. tor_free(consensus_body);
  1099. tor_free(signatures);
  1100. networkstatus_vote_free(consensus);
  1101. return -1;
  1102. }
  1103. /** DOCDOC */
  1104. static int
  1105. dirvote_add_signatures_to_pending_consensus(
  1106. const char *detached_signatures_body,
  1107. const char **msg_out)
  1108. {
  1109. ns_detached_signatures_t *sigs = NULL;
  1110. int r = -1;
  1111. char *new_signatures = NULL;
  1112. size_t siglen;
  1113. tor_assert(detached_signatures_body);
  1114. tor_assert(msg_out);
  1115. /* Only call if we have a pending consensus right now. */
  1116. tor_assert(pending_consensus);
  1117. tor_assert(pending_consensus_body);
  1118. tor_assert(pending_consensus_signatures);
  1119. *msg_out = NULL;
  1120. if (!(sigs = networkstatus_parse_detached_signatures(
  1121. detached_signatures_body, NULL))) {
  1122. *msg_out = "Couldn't parse detached signatures.";
  1123. goto err;
  1124. }
  1125. r = networkstatus_add_detached_signatures(pending_consensus,
  1126. sigs,
  1127. &new_signatures);
  1128. if (new_signatures && (siglen = strlen(new_signatures)) && r >= 0) {
  1129. size_t siglen = strlen(new_signatures);
  1130. size_t len = strlen(pending_consensus_body);
  1131. pending_consensus_body = tor_realloc(pending_consensus_body,
  1132. len+siglen+1);
  1133. memcpy(pending_consensus_body+len, new_signatures, siglen+1);
  1134. len = strlen(pending_consensus_signatures);
  1135. pending_consensus_signatures = tor_realloc(pending_consensus_signatures,
  1136. len+siglen+1);
  1137. memcpy(pending_consensus_signatures+len, new_signatures, siglen+1);
  1138. log_info(LD_DIR, "Added %d new signatures to the pending consensus.", r);
  1139. }
  1140. *msg_out = "ok";
  1141. goto done;
  1142. err:
  1143. if (!msg_out)
  1144. *msg_out = "Unrecognized error while adding detached signatures.";
  1145. done:
  1146. tor_free(new_signatures);
  1147. if (sigs)
  1148. ns_detached_signatures_free(sigs);
  1149. return r;
  1150. }
  1151. /** DOCDOC */
  1152. int
  1153. dirvote_add_signatures(const char *detached_signatures_body)
  1154. {
  1155. if (pending_consensus) {
  1156. const char *msg=NULL;
  1157. return dirvote_add_signatures_to_pending_consensus(
  1158. detached_signatures_body, &msg);
  1159. } else {
  1160. if (!pending_consensus_signature_list)
  1161. pending_consensus_signature_list = smartlist_create();
  1162. smartlist_add(pending_consensus_signature_list,
  1163. tor_strdup(detached_signatures_body));
  1164. return 0;
  1165. }
  1166. }
  1167. /** Release all static storage held in dirvote.c */
  1168. void
  1169. dirvote_free_all(void)
  1170. {
  1171. dirvote_clear_pending_votes();
  1172. if (pending_vote_list) {
  1173. /* now empty as a result of clear_pending_votes. */
  1174. smartlist_free(pending_vote_list);
  1175. pending_vote_list = NULL;
  1176. }
  1177. tor_free(pending_consensus_body);
  1178. tor_free(pending_consensus_signatures);
  1179. if (pending_consensus) {
  1180. networkstatus_vote_free(pending_consensus);
  1181. pending_consensus = NULL;
  1182. }
  1183. if (pending_consensus_signature_list) {
  1184. /* now empty as a result of clear_pending_votes. */
  1185. smartlist_free(pending_consensus_signature_list);
  1186. pending_consensus_signature_list = NULL;
  1187. }
  1188. }