| 
					
				 | 
			
			
				@@ -14,6 +14,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "bridges.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "circuitlist.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "config.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "confparse.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "entrynodes.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "nodelist.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "networkstatus.h" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1247,6 +1248,239 @@ test_entry_guard_parse_from_state_partial_failure(void *arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(mem_op_hex_tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+mock_entry_guard_is_listed(guard_selection_t *gs, const entry_guard_t *guard) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (void)gs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (void)guard; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+test_entry_guard_parse_from_state_full(void *arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (void)arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Here's a state I made while testing.  The identities and locations for 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * the bridges are redacted. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const char STATE[] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=214F44BD5B638E8C817D47FF7C97397790BF0345 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=TotallyNinja sampled_on=2016-11-12T19:32:49 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=052900AB0EA3ED54BAB84AE8A99E74E8693CE2B2 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=5OfNovember sampled_on=2016-11-20T04:32:05 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1 confirmed_on=2016-11-22T08:13:28 confirmed_idx=0 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_circ_attempts=4.000000 pb_circ_successes=2.000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_successful_circuits_closed=2.000000\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=7B700C0C207EBD0002E00F499BE265519AC3C25A " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=dc6jgk11 sampled_on=2016-11-28T11:50:13 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1 confirmed_on=2016-11-24T08:45:30 confirmed_idx=4 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_circ_attempts=5.000000 pb_circ_successes=5.000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_successful_circuits_closed=5.000000\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=wobblesome rsa_id=7B700C0C207EBD0002E00F499BE265519AC3C25A " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=dc6jgk11 sampled_on=2016-11-28T11:50:13 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=E9025AD60D86875D5F11548D536CC6AF60F0EF5E " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=maibrunn sampled_on=2016-11-25T22:36:38 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev listed=1\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=DCD30B90BA3A792DA75DC54A327EF353FB84C38E " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=Unnamed sampled_on=2016-11-25T14:34:00 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev listed=1\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=bridges rsa_id=8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "bridge_addr=24.1.1.1:443 sampled_on=2016-11-25T06:44:14 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev listed=1 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "confirmed_on=2016-11-29T10:36:06 confirmed_idx=0 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_circ_attempts=8.000000 pb_circ_successes=8.000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_successful_circuits_closed=13.000000\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=bridges rsa_id=5800000000000000000000000000000000000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "bridge_addr=37.218.246.143:28366 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_on=2016-11-18T15:07:34 sampled_by=0.3.0.0-alpha-dev listed=1\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  config_line_t *lines = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  or_state_t *state = tor_malloc_zero(sizeof(or_state_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int r = config_get_lines(STATE, &lines, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  char *msg = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  smartlist_t *text = smartlist_new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  char *joined = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MOCK(entry_guard_is_listed, mock_entry_guard_is_listed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  dummy_state = state; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MOCK(get_or_state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       get_or_state_replacement); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(r == 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(lines); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  state->Guard = lines; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Try it first without setting the result. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  r = entry_guards_parse_state(state, 0, &msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(r == 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  guard_selection_t *gs_br = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get_guard_selection_by_name("bridges", GS_TYPE_BRIDGE, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(!gs_br); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  r = entry_guards_parse_state(state, 1, &msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(r == 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gs_br = get_guard_selection_by_name("bridges", GS_TYPE_BRIDGE, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  guard_selection_t *gs_df = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get_guard_selection_by_name("default", GS_TYPE_NORMAL, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  guard_selection_t *gs_wb = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get_guard_selection_by_name("wobblesome", GS_TYPE_NORMAL, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(gs_br); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(gs_df); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(gs_wb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_int_op(smartlist_len(gs_df->sampled_entry_guards), OP_EQ, 5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_int_op(smartlist_len(gs_br->sampled_entry_guards), OP_EQ, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_int_op(smartlist_len(gs_wb->sampled_entry_guards), OP_EQ, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Try again; make sure it doesn't double-add the guards. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  r = entry_guards_parse_state(state, 1, &msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(r == 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gs_br = get_guard_selection_by_name("bridges", GS_TYPE_BRIDGE, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gs_df = get_guard_selection_by_name("default", GS_TYPE_NORMAL, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(gs_br); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(gs_df); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_int_op(smartlist_len(gs_df->sampled_entry_guards), OP_EQ, 5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_int_op(smartlist_len(gs_br->sampled_entry_guards), OP_EQ, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Re-encode; it should be the same... almost. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* (Make a guard nonpersistent first) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    entry_guard_t *g = smartlist_get(gs_df->sampled_entry_guards, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    g->is_persistent = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  config_free_lines(lines); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lines = state->Guard = NULL; // to prevent double-free. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  entry_guards_update_state(state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(state->Guard); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lines = state->Guard; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  config_line_t *ln; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (ln = lines; ln; ln = ln->next) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    smartlist_add_asprintf(text, "%s %s\n",ln->key, ln->value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  joined = smartlist_join_strings(text, "", 0, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_str_op(joined, OP_EQ, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=052900AB0EA3ED54BAB84AE8A99E74E8693CE2B2 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=5OfNovember sampled_on=2016-11-20T04:32:05 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1 confirmed_on=2016-11-22T08:13:28 confirmed_idx=0 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_circ_attempts=4.000000 pb_circ_successes=2.000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_successful_circuits_closed=2.000000\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=7B700C0C207EBD0002E00F499BE265519AC3C25A " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=dc6jgk11 sampled_on=2016-11-28T11:50:13 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1 confirmed_on=2016-11-24T08:45:30 confirmed_idx=1 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_circ_attempts=5.000000 pb_circ_successes=5.000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_successful_circuits_closed=5.000000\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=E9025AD60D86875D5F11548D536CC6AF60F0EF5E " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=maibrunn sampled_on=2016-11-25T22:36:38 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev listed=1\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=DCD30B90BA3A792DA75DC54A327EF353FB84C38E " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=Unnamed sampled_on=2016-11-25T14:34:00 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev listed=1\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=wobblesome rsa_id=7B700C0C207EBD0002E00F499BE265519AC3C25A " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=dc6jgk11 sampled_on=2016-11-28T11:50:13 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=bridges rsa_id=8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "bridge_addr=24.1.1.1:443 sampled_on=2016-11-25T06:44:14 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev listed=1 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "confirmed_on=2016-11-29T10:36:06 confirmed_idx=0 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_circ_attempts=8.000000 pb_circ_successes=8.000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_successful_circuits_closed=13.000000\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=bridges rsa_id=5800000000000000000000000000000000000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "bridge_addr=37.218.246.143:28366 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_on=2016-11-18T15:07:34 sampled_by=0.3.0.0-alpha-dev listed=1\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  config_free_lines(lines); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UNMOCK(get_or_state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UNMOCK(entry_guard_is_listed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SMARTLIST_FOREACH(text, char *, cp, tor_free(cp)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  smartlist_free(text); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(joined); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+test_entry_guard_parse_from_state_broken(void *arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (void)arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Here's a variation on the previous state. Every line but the first is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * busted somehow. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const char STATE[] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Okay. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=default rsa_id=214F44BD5B638E8C817D47FF7C97397790BF0345 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=TotallyNinja sampled_on=2016-11-12T19:32:49 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* No selection listed. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard rsa_id=052900AB0EA3ED54BAB84AE8A99E74E8693CE2B2 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=5OfNovember sampled_on=2016-11-20T04:32:05 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1 confirmed_on=2016-11-22T08:13:28 confirmed_idx=0 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_circ_attempts=4.000000 pb_circ_successes=2.000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_successful_circuits_closed=2.000000\n" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Selection is "legacy"!! */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Guard in=legacy rsa_id=7B700C0C207EBD0002E00F499BE265519AC3C25A " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "nickname=dc6jgk11 sampled_on=2016-11-28T11:50:13 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "sampled_by=0.3.0.0-alpha-dev " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "listed=1 confirmed_on=2016-11-24T08:45:30 confirmed_idx=4 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_circ_attempts=5.000000 pb_circ_successes=5.000000 " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "pb_successful_circuits_closed=5.000000\n"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  config_line_t *lines = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  or_state_t *state = tor_malloc_zero(sizeof(or_state_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int r = config_get_lines(STATE, &lines, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  char *msg = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  dummy_state = state; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  MOCK(get_or_state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       get_or_state_replacement); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(r == 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(lines); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  state->Guard = lines; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* First, no-set case. we should get an error. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  r = entry_guards_parse_state(state, 0, &msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_int_op(r, OP_LT, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_ptr_op(msg, OP_NE, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* And we shouldn't have made anything. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  guard_selection_t *gs_df = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get_guard_selection_by_name("default", GS_TYPE_NORMAL, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(gs_df == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Now see about the set case (which shouldn't happen IRL) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  r = entry_guards_parse_state(state, 1, &msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_int_op(r, OP_LT, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_ptr_op(msg, OP_NE, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gs_df = get_guard_selection_by_name("default", GS_TYPE_NORMAL, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(gs_df != NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_int_op(smartlist_len(gs_df->sampled_entry_guards), OP_EQ, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  guard_selection_t *gs_legacy = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get_guard_selection_by_name("legacy", GS_TYPE_LEGACY, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_assert(gs_legacy != NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tt_int_op(smartlist_len(gs_legacy->chosen_entry_guards), OP_EQ, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  config_free_lines(lines); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  UNMOCK(get_or_state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 test_entry_guard_get_guard_selection_by_name(void *arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -3019,6 +3253,10 @@ struct testcase_t entrynodes_tests[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     test_entry_guard_parse_from_state_failure, 0, NULL, NULL }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { "parse_from_state_partial_failure", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     test_entry_guard_parse_from_state_partial_failure, 0, NULL, NULL }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { "parse_from_state_full", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    test_entry_guard_parse_from_state_full, TT_FORK, NULL, NULL }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { "parse_from_state_broken", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    test_entry_guard_parse_from_state_broken, TT_FORK, NULL, NULL }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { "get_guard_selection_by_name", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     test_entry_guard_get_guard_selection_by_name, TT_FORK, NULL, NULL }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   BFN_TEST(add_single_guard), 
			 |