Browse Source

Implement some of GETINFO control message

svn:r3694
Nick Mathewson 20 years ago
parent
commit
8396105d84
1 changed files with 71 additions and 1 deletions
  1. 71 1
      src/or/control.c

+ 71 - 1
src/or/control.c

@@ -59,6 +59,7 @@ const char control_c_id[] = "$Id$";
 #define ERR_UNAUTHORIZED            0x0007
 #define ERR_REJECTED_AUTHENTICATION 0x0008
 #define ERR_RESOURCE_EXHAUSETED     0x0009
+#define ERR_TOO_LONG                0x000A
 
 /* Recognized asynchronous event types. */
 #define _EVENT_MIN            0x0001
@@ -447,10 +448,79 @@ handle_control_mapaddress(connection_t *conn, uint16_t len, const char *body)
   send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented");
   return 0;
 }
+
+static char *
+handle_getinfo_helper(const char *question)
+{
+  if (!strcmp(question, "version")) {
+    return tor_strdup(VERSION);
+  } else if (!strcmpstart(question, "desc/id/")) {
+    return NULL; /* XXXX */
+  } else if (!strcmp(question, "desc/all-ids")) {
+    routerlist_t *rl;
+    char *answer, *cp;
+    router_get_routerlist(&rl);
+    if (!rl)
+      return tor_strdup("");
+    answer = tor_malloc(smartlist_len(rl->routers)*(HEX_DIGEST_LEN+1)+1);
+    cp = answer;
+    SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
+    {
+      base16_encode(cp, HEX_DIGEST_LEN+1, r->identity_digest, DIGEST_LEN);
+      cp += HEX_DIGEST_LEN;
+      *cp++ = ',';
+    });
+    return answer;
+  } else if (!strcmp(question, "addr-mappings")) {
+    return NULL; /* XXXX */
+  } else {
+    /* unrecognized key */
+    return NULL;
+  }
+}
+
 static int
 handle_control_getinfo(connection_t *conn, uint16_t len, const char *body)
 {
-  send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented");
+  smartlist_t *questions = NULL;
+  smartlist_t *answers = NULL;
+  char *msg = NULL, *ans;
+  size_t msg_len;
+
+  questions = smartlist_create();
+  smartlist_split_string(questions, body, "\n",
+                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+  answers = smartlist_create();
+  SMARTLIST_FOREACH(questions, const char *, q,
+  {
+    ans = handle_getinfo_helper(q);
+    if (!ans) {
+      send_control_error(conn, ERR_UNRECOGNIZED_CONFIG_KEY, body);
+      goto done;
+    } else {
+      smartlist_add(answers, tor_strdup(q));
+      smartlist_add(answers, ans);
+      msg_len += 2 + strlen(ans) + strlen(q);
+    }
+  });
+
+  if (msg_len > 65535) {
+    /* XXXX What if it *is* this long? */
+    send_control_error(conn, ERR_TOO_LONG, body);
+    goto done;
+  }
+
+  msg = smartlist_join_strings2(answers, "\0", 1, 1, &msg_len);
+  send_control_message(conn, CONTROL_CMD_INFOVALUE,
+                       (uint16_t)msg_len, msg_len?msg:NULL);
+
+ done:
+  if (answers) SMARTLIST_FOREACH(answers, char *, cp, tor_free(cp));
+  if (questions) SMARTLIST_FOREACH(questions, char *, cp, tor_free(cp));
+  smartlist_free(answers);
+  smartlist_free(questions);
+  tor_free(msg);
+
   return 0;
 }
 static int