浏览代码

Add a 'quit' command for the controller.
Add a 'getinfo unregistered-servers' for arma's internal use.


svn:r4774

Roger Dingledine 20 年之前
父节点
当前提交
66b21a19db
共有 3 个文件被更改,包括 47 次插入2 次删除
  1. 11 2
      src/or/control.c
  2. 35 0
      src/or/dirserv.c
  3. 1 0
      src/or/or.h

+ 11 - 2
src/or/control.c

@@ -75,7 +75,8 @@ const char control_c_id[] = "$Id$";
 #define _EVENT_MAX            0x000C
 
 /** Array mapping from message type codes to human-readable message
- * type names.  */
+ * type names. Used for compatibility with version 0 of the control
+ * protocol. */
 static const char * CONTROL0_COMMANDS[_CONTROL0_CMD_MAX_RECOGNIZED+1] = {
   "error",
   "done",
@@ -1172,6 +1173,8 @@ handle_getinfo_helper(const char *question, char **answer)
     routerinfo_t *ri = router_get_by_nickname(question+strlen("desc/name/"));
     if (ri && ri->signed_descriptor)
       *answer = tor_strdup(ri->signed_descriptor);
+  } else if (!strcmp(question, "unregistered-servers")) {
+    *answer = dirserver_getinfo_unregistered();
   } else if (!strcmp(question, "network-status")) {
     routerlist_t *routerlist;
     router_get_routerlist(&routerlist);
@@ -1309,7 +1312,7 @@ handle_control_getinfo(connection_t *conn, uint32_t len, const char *body)
   smartlist_t *questions = NULL;
   smartlist_t *answers = NULL;
   smartlist_t *unrecognized = NULL;
-  char *msg = NULL, *ans;
+  char *msg = NULL, *ans = NULL;
   size_t msg_len;
   int v0 = STATE_IS_V0(conn->state);
 
@@ -1964,6 +1967,12 @@ connection_control_process_inbuf_v1(connection_t *conn)
   log_fn(LOG_NOTICE, "ARGS ARE: <%s>", args);
   */
 
+  if (!strcasecmp(conn->incoming_cmd, "QUIT")) {
+    connection_write_str_to_buf("250 closing connection\r\n", conn);
+    connection_mark_for_close(conn);
+    return 0;
+  }
+
   if (conn->state == CONTROL_CONN_STATE_NEEDAUTH_V1 &&
       strcasecmp(conn->incoming_cmd, "AUTHENTICATE")) {
     connection_write_str_to_buf("514 Authentication required.\r\n", conn);

+ 35 - 0
src/or/dirserv.c

@@ -442,6 +442,41 @@ directory_remove_invalid(void)
   }
 }
 
+/** Write a list of unregistered descriptors into a newly allocated
+ * string and return it. Used by dirserv operators to keep track of
+ * fast nodes that haven't registered.
+ */
+char *
+dirserver_getinfo_unregistered(void)
+{
+  int i, r;
+  smartlist_t *answerlist;
+  char buf[1024];
+  char *answer;
+  routerinfo_t *ent;
+
+  if (!descriptor_list)
+    return tor_strdup("");
+
+  answerlist = smartlist_create();
+  for (i = 0; i < smartlist_len(descriptor_list); ++i) {
+    ent = smartlist_get(descriptor_list, i);
+    r = dirserv_router_fingerprint_is_known(ent);
+    if (ent->bandwidthcapacity > 100000 && r == 0) {
+      /* then log this one */
+      tor_snprintf(buf, sizeof(buf),
+                   "%s: BW %d on '%s'.",
+                   ent->nickname, ent->bandwidthcapacity,
+                   ent->platform ? ent->platform : "");
+      smartlist_add(answerlist, tor_strdup(buf));
+    }
+  }
+  answer = smartlist_join_strings(answerlist, "\r\n", 0, NULL);
+  SMARTLIST_FOREACH(answerlist, char *, cp, tor_free(cp));
+  smartlist_free(answerlist);
+  return answer;
+}
+
 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
  * directory, we will rebuild it instead of reusing the most recently
  * generated one.

+ 1 - 0
src/or/or.h

@@ -1621,6 +1621,7 @@ int dirserv_router_fingerprint_is_known(const routerinfo_t *router);
 void dirserv_free_fingerprint_list(void);
 const char *dirserv_get_nickname_by_digest(const char *digest);
 int dirserv_add_descriptor(const char **desc, const char **msg);
+char *dirserver_getinfo_unregistered(void);
 int dirserv_load_from_directory_string(const char *dir);
 void dirserv_free_descriptors(void);
 int list_server_status(smartlist_t *routers, char **router_status_out);