Selaa lähdekoodia

r9312@Kushana: nickm | 2006-10-20 14:45:22 -0400
Add an event type to tell the controller when our opinion of a router status has changed. I might have missed some cases here.


svn:r8781

Nick Mathewson 19 vuotta sitten
vanhempi
commit
01bc03eff4
6 muutettua tiedostoa jossa 80 lisäystä ja 9 poistoa
  1. 2 0
      ChangeLog
  2. 5 3
      doc/TODO
  3. 9 1
      doc/control-spec.txt
  4. 48 1
      src/or/control.c
  5. 3 0
      src/or/or.h
  6. 13 4
      src/or/routerlist.c

+ 2 - 0
ChangeLog

@@ -24,6 +24,8 @@ Changes in version 0.1.2.3-alpha - 2006-10-??
       about the current state of a router.
     - Stream events also have REASON and REMOTE_REASON fields, working much
       like those for circuit events.
+    - NS events to inform a controller when our opinion of a router's status
+      has changed.
 
   o Security bugfixes:
     - When the user sends a NEWNYM signal, clear the client-side DNS

+ 5 - 3
doc/TODO

@@ -79,9 +79,11 @@ d     - Tolerate clock skew on bridge relays.
       o A way to examine router flags from controller.
         o Specify: GETINFO ns/id/x, ns/name/x, ns/all.
         o Implement
-N     - A way to alert controller when router flags change.
-        - Specify: SETEVENTS NS
-        - Implement
+      o A way to alert controller when router flags change.
+        o Specify: SETEVENTS NS
+        o Implement
+N       - Hunt for places that change networkstatus info that I might have
+          missed.
 d     - A way to adjust router flags from the controller
 d     - a way to pick entries based wholly on extend_info equivalent;
         a way to export extend_info equivalent.

+ 9 - 1
doc/control-spec.txt

@@ -194,7 +194,8 @@ $Id$
      EventCode = "CIRC" / "STREAM" / "ORCONN" / "BW" / "DEBUG" /
          "INFO" / "NOTICE" / "WARN" / "ERR" / "NEWDESC" / "ADDRMAP" /
          "AUTHDIR_NEWDESCS" / "DESCCHANGED" / "STATUS_GENERAL" /
-         "STATUS_CLIENT" / "STATUS_SERVER" / "GUARDS"
+         "STATUS_CLIENT" / "STATUS_SERVER" / "GUARDS" / "NS" /
+         "NS_FULL"
 
   Any events *not* listed in the SETEVENTS line are turned off; thus, sending
   SETEVENTS with an empty body turns off all event reporting.
@@ -1085,6 +1086,13 @@ $Id$
      ...
   [needs to be fleshed out; not implemented yet]
 
+4.1.12. Network status has changed
+
+  Syntax:
+     "650" "+" "NS" CRLF  1*NetworkStatus "." CRLF
+
+  [First added in 0.1.2.3-alpha]
+
 5. Implementation notes
 
 5.1. Authentication

+ 48 - 1
src/or/control.c

@@ -82,7 +82,9 @@ const char control_c_id[] =
 #define EVENT_ADDRMAP          0x000C
 #define EVENT_AUTHDIR_NEWDESCS 0x000D
 #define EVENT_DESCCHANGED      0x000E
-#define _EVENT_MAX             0x000E
+#define EVENT_NS               0x000F
+#define _EVENT_MAX             0x000F
+/* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */
 
 /** Array mapping from message type codes to human-readable message
  * type names. Used for compatibility with version 0 of the control
@@ -1050,6 +1052,8 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
           event_code = EVENT_AUTHDIR_NEWDESCS;
         else if (!strcasecmp(ev, "DESCCHANGED"))
           event_code = EVENT_DESCCHANGED;
+        else if (!strcasecmp(ev, "NS"))
+          event_code = EVENT_NS;
         else {
           connection_printf_to_buf(conn, "552 Unrecognized event \"%s\"\r\n",
                                    ev);
@@ -3347,6 +3351,49 @@ control_event_or_authdir_new_descriptor(const char *action,
   return 0;
 }
 
+/* DOCDOC takes a list of local_routerstatus_t */
+int
+control_event_networkstatus_changed(smartlist_t *statuses)
+{
+  smartlist_t *strs;
+  char *s;
+  if (!EVENT_IS_INTERESTING(EVENT_NS) || !smartlist_len(statuses))
+    return 0;
+
+  strs = smartlist_create();
+  smartlist_add(strs, tor_strdup("650+NS\r\n"));
+  SMARTLIST_FOREACH(statuses, local_routerstatus_t *, rs,
+    {
+      s = networkstatus_getinfo_helper_single(&rs->status);
+      if (!s) continue;
+      smartlist_add(strs, s);
+    });
+  smartlist_add(strs, tor_strdup("\r\n.\r\n"));
+
+  s = smartlist_join_strings(strs, "", 0, NULL);
+  SMARTLIST_FOREACH(strs, char *, cp, tor_free(cp));
+  smartlist_free(strs);
+  send_control1_event_string(EVENT_NS, ALL_NAMES|ALL_FORMATS, s);
+  tor_free(s);
+  return 0;
+}
+
+int
+control_event_networkstatus_changed_single(local_routerstatus_t *rs)
+{
+  smartlist_t *statuses;
+  int r;
+
+  if (!EVENT_IS_INTERESTING(EVENT_NS))
+    return 0;
+
+  statuses = smartlist_create();
+  smartlist_add(statuses, rs);
+  r = control_event_networkstatus_changed(statuses);
+  smartlist_free(statuses);
+  return r;
+}
+
 /** Our own router descriptor has changed; tell any controllers that care.
  */
 int

+ 3 - 0
src/or/or.h

@@ -2115,6 +2115,8 @@ int control_event_or_authdir_new_descriptor(const char *action,
                                             const char *descriptor,
                                             const char *msg);
 int control_event_my_descriptor_changed(void);
+int control_event_networkstatus_changed(smartlist_t *statuses);
+int control_event_networkstatus_changed_single(local_routerstatus_t *rs);
 
 int init_cookie_authentication(int enabled);
 int decode_hashed_password(char *buf, const char *hashed);
@@ -2682,6 +2684,7 @@ void router_reset_status_download_failures(void);
 int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2);
 const char *esc_router_info(routerinfo_t *router);
 
+char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
 int networkstatus_getinfo_helper(const char *question, char **answer);
 
 /********************************* routerparse.c ************************/

+ 13 - 4
src/or/routerlist.c

@@ -606,8 +606,10 @@ mark_all_trusteddirservers_up(void)
       dir->is_running = 1;
       dir->n_networkstatus_failures = 0;
       rs = router_get_combined_status_by_digest(dir->digest);
-      if (rs)
+      if (rs && !rs->status.is_running) {
         rs->status.is_running = 1;
+        control_event_networkstatus_changed_single(rs);
+      }
     });
   }
   last_networkstatus_download_attempted = 0;
@@ -1670,8 +1672,9 @@ router_set_status(const char *digest, int up)
     router->is_running = up;
   }
   status = router_get_combined_status_by_digest(digest);
-  if (status) {
+  if (status && status->status.is_running != up) {
     status->status.is_running = up;
+    control_event_networkstatus_changed_single(status);
   }
   router_dir_info_changed();
 }
@@ -3187,7 +3190,7 @@ routerstatus_list_update_from_networkstatus(time_t now)
   int i, j, warned;
   int *index, *size;
   networkstatus_t **networkstatus;
-  smartlist_t *result;
+  smartlist_t *result, *changed_list;
   strmap_t *name_map;
   char conflict[DIGEST_LEN]; /* Sentinel value */
   desc_digest_count_t *digest_counts = NULL;
@@ -3287,6 +3290,7 @@ routerstatus_list_update_from_networkstatus(time_t now)
   }
 
   result = smartlist_create();
+  changed_list = smartlist_create();
   digest_counts = tor_malloc_zero(sizeof(desc_digest_count_t)*n_statuses);
 
   /* Iterate through all of the sorted routerstatus lists in lockstep.
@@ -3439,6 +3443,8 @@ routerstatus_list_update_from_networkstatus(time_t now)
     rs_out->status.is_stable = n_stable > n_statuses/2;
     rs_out->status.is_v2_dir = n_v2_dir > n_statuses/2;
     rs_out->status.is_bad_exit = n_bad_exit > n_listing_bad_exits/2;
+    if (!rs_old || memcmp(rs_old, rs_out, sizeof(local_routerstatus_t)))
+      smartlist_add(changed_list, rs_out);
   }
   SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, rs,
                     local_routerstatus_free(rs));
@@ -3454,6 +3460,9 @@ routerstatus_list_update_from_networkstatus(time_t now)
 
   networkstatus_list_has_changed = 0;
   routerstatus_list_has_changed = 1;
+
+  control_event_networkstatus_changed(changed_list);
+  smartlist_free(changed_list);
 }
 
 /** Given a list <b>routers</b> of routerinfo_t *, update each routers's
@@ -4113,7 +4122,7 @@ router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2)
  * return the result in a newly allocated string.  Used only by controller
  * interface (for now.) */
 /* XXXX This should eventually merge into generate_v2_networkstatus() */
-static char *
+char *
 networkstatus_getinfo_helper_single(routerstatus_t *rs)
 {
   char buf[192];