|
@@ -4471,6 +4471,9 @@ typedef struct {
|
|
|
tor_addr_t addr;
|
|
|
/** TLS port for the bridge. */
|
|
|
uint16_t port;
|
|
|
+ /** Boolean: We are re-parsing our bridge list, and we are going to remove
|
|
|
+ * this one if we don't find it in the list of configured bridges. */
|
|
|
+ unsigned marked_for_removal : 1;
|
|
|
/** Expected identity digest, or all zero bytes if we don't know what the
|
|
|
* digest should be. */
|
|
|
char identity[DIGEST_LEN];
|
|
@@ -4479,11 +4482,39 @@ typedef struct {
|
|
|
} bridge_info_t;
|
|
|
|
|
|
/** A list of configured bridges. Whenever we actually get a descriptor
|
|
|
- * for one, we add it as an entry guard. */
|
|
|
+ * for one, we add it as an entry guard. Note that the order of bridges
|
|
|
+ * in this list does not necessarily correspond to the order of bridges
|
|
|
+ * in the torrc. */
|
|
|
static smartlist_t *bridge_list = NULL;
|
|
|
|
|
|
-/** Initialize the bridge list to empty, creating it if needed. */
|
|
|
+/** Mark every entry of the bridge list to be removed on our next call to
|
|
|
+ * sweep_bridge_list unless it has first been un-marked. */
|
|
|
+void
|
|
|
+mark_bridge_list(void)
|
|
|
+{
|
|
|
+ if (!bridge_list)
|
|
|
+ bridge_list = smartlist_create();
|
|
|
+ SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b,
|
|
|
+ b->marked_for_removal = 1);
|
|
|
+}
|
|
|
+
|
|
|
+/** Remove every entry of the bridge list that was marked with
|
|
|
+ * mark_bridge_list if it has not subsequently been un-marked. */
|
|
|
void
|
|
|
+sweep_bridge_list(void)
|
|
|
+{
|
|
|
+ if (!bridge_list)
|
|
|
+ bridge_list = smartlist_create();
|
|
|
+ SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) {
|
|
|
+ if (b->marked_for_removal) {
|
|
|
+ SMARTLIST_DEL_CURRENT(bridge_list, b);
|
|
|
+ tor_free(b);
|
|
|
+ }
|
|
|
+ } SMARTLIST_FOREACH_END(b);
|
|
|
+}
|
|
|
+
|
|
|
+/** Initialize the bridge list to empty, creating it if needed. */
|
|
|
+static void
|
|
|
clear_bridge_list(void)
|
|
|
{
|
|
|
if (!bridge_list)
|
|
@@ -4496,7 +4527,8 @@ clear_bridge_list(void)
|
|
|
* (either by comparing keys if possible, else by comparing addr/port).
|
|
|
* Else return NULL. */
|
|
|
static bridge_info_t *
|
|
|
-get_configured_bridge_by_addr_port_digest(tor_addr_t *addr, uint16_t port,
|
|
|
+get_configured_bridge_by_addr_port_digest(const tor_addr_t *addr,
|
|
|
+ uint16_t port,
|
|
|
const char *digest)
|
|
|
{
|
|
|
if (!bridge_list)
|
|
@@ -4537,7 +4569,8 @@ routerinfo_is_a_configured_bridge(routerinfo_t *ri)
|
|
|
* If it was a bridge, and we still don't know its digest, record it.
|
|
|
*/
|
|
|
void
|
|
|
-learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest)
|
|
|
+learned_router_identity(const tor_addr_t *addr, uint16_t port,
|
|
|
+ const char *digest)
|
|
|
{
|
|
|
bridge_info_t *bridge =
|
|
|
get_configured_bridge_by_addr_port_digest(addr, port, digest);
|
|
@@ -4549,11 +4582,20 @@ learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest)
|
|
|
}
|
|
|
|
|
|
/** Remember a new bridge at <b>addr</b>:<b>port</b>. If <b>digest</b>
|
|
|
- * is set, it tells us the identity key too. */
|
|
|
+ * is set, it tells us the identity key too. If we already had the
|
|
|
+ * bridge in our list, unmark it, and don't actually add anything new. */
|
|
|
void
|
|
|
-bridge_add_from_config(const tor_addr_t *addr, uint16_t port, char *digest)
|
|
|
+bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
|
|
|
+ const char *digest)
|
|
|
{
|
|
|
- bridge_info_t *b = tor_malloc_zero(sizeof(bridge_info_t));
|
|
|
+ bridge_info_t *b;
|
|
|
+
|
|
|
+ if ((b = get_configured_bridge_by_addr_port_digest(addr, port, digest))) {
|
|
|
+ b->marked_for_removal = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ b = tor_malloc_zero(sizeof(bridge_info_t));
|
|
|
tor_addr_copy(&b->addr, addr);
|
|
|
b->port = port;
|
|
|
if (digest)
|
|
@@ -4561,6 +4603,7 @@ bridge_add_from_config(const tor_addr_t *addr, uint16_t port, char *digest)
|
|
|
b->fetch_status.schedule = DL_SCHED_BRIDGE;
|
|
|
if (!bridge_list)
|
|
|
bridge_list = smartlist_create();
|
|
|
+
|
|
|
smartlist_add(bridge_list, b);
|
|
|
}
|
|
|
|