Browse Source

Storage into the pirserver now appears to work end to end

Note that the client doesn't do anything special to store an onion
service descriptor, so we just hook the v3 upload function to _also_
store it with the pirserver.
Ian Goldberg 3 years ago
parent
commit
af7d33c1fe
1 changed files with 56 additions and 16 deletions
  1. 56 16
      src/feature/hs/hs_cache.c

+ 56 - 16
src/feature/hs/hs_cache.c

@@ -977,14 +977,23 @@ hs_cache_get_max_descriptor_size(void)
 }
 
 static process_handle_t *pirserver;
-static struct event *pirserver_read_ev;
+static struct event *pirserver_stdout_ev;
+static struct event *pirserver_stderr_ev;
 
 typedef enum {
     PIRSERVER_READSTATE_HEADER,
     PIRSERVER_READSTATE_BODY
 } PIRServerReadState;
 
-#define PIRSERVER_READHDR_SIZE 13
+#define PIRSERVER_HDR_SIZE 13
+
+#define PIRSERVER_REQUEST_PARAMS 0x01
+#define PIRSERVER_REQUEST_STORE 0x02
+#define PIRSERVER_REQUEST_LOOKUP 0x03
+
+#define PIRSERVER_RESPONSE_PARAMS 0xFF
+#define PIRSERVER_RESPONSE_LOOKUP_SUCCESS 0xFE
+#define PIRSERVER_RESPONSE_LOOKUP_FAILURE 0xFD
 
 static void
 hs_cache_pirserver_received(const unsigned char *hdrbuf,
@@ -994,13 +1003,14 @@ hs_cache_pirserver_received(const unsigned char *hdrbuf,
     log_info(LD_DIRSERV,"PIRSERVER response header %p flag %d body len %ld body %s", *(void**)hdrbuf, hdrbuf[8], bodylen, escaped(bodybuf));
 }
 
+/* This is called when the pirserver has output for us. */
 static void
 hs_cache_pirserver_recvcb(evutil_socket_t fd, short what,
         ATTR_UNUSED void *arg) {
     static PIRServerReadState readstate = PIRSERVER_READSTATE_HEADER;
     static size_t readoff = 0;
-    static size_t readleft = PIRSERVER_READHDR_SIZE;
-    static unsigned char hdrbuf[PIRSERVER_READHDR_SIZE];
+    static size_t readleft = PIRSERVER_HDR_SIZE;
+    static unsigned char hdrbuf[PIRSERVER_HDR_SIZE];
     static char *bodybuf = NULL;
 
     if (!(what & EV_READ)) {
@@ -1014,7 +1024,7 @@ hs_cache_pirserver_recvcb(evutil_socket_t fd, short what,
         readoff += res;
         readleft -= res;
         if (readleft == 0) {
-            readleft = ntohl(*(uint32_t*)(hdrbuf+PIRSERVER_READHDR_SIZE-4));
+            readleft = ntohl(*(uint32_t*)(hdrbuf+PIRSERVER_HDR_SIZE-4));
             free(bodybuf);
             bodybuf = NULL;
             if (readleft > 0) {
@@ -1024,7 +1034,7 @@ hs_cache_pirserver_recvcb(evutil_socket_t fd, short what,
             } else {
                 hs_cache_pirserver_received(hdrbuf, NULL, 0);
                 readoff = 0;
-                readleft = PIRSERVER_READHDR_SIZE;
+                readleft = PIRSERVER_HDR_SIZE;
                 readstate = PIRSERVER_READSTATE_HEADER;
             }
         }
@@ -1041,12 +1051,28 @@ hs_cache_pirserver_recvcb(evutil_socket_t fd, short what,
             free(bodybuf);
             bodybuf = NULL;
             readoff = 0;
-            readleft = PIRSERVER_READHDR_SIZE;
+            readleft = PIRSERVER_HDR_SIZE;
             readstate = PIRSERVER_READSTATE_HEADER;
         }
     }
 }
 
+/* This is called when the pirserver writes something to its stderr. */
+static void
+hs_cache_pirserver_stderrcb(evutil_socket_t fd, short what,
+        ATTR_UNUSED void *arg) {
+    if (!(what & EV_READ)) {
+        /* Not sure why we're here */
+        return;
+    }
+
+    char buf[1000];
+    int res = read(fd, buf, sizeof(buf)-1);
+    if (res <= 0) return;
+    buf[res] = '\0';
+    log_info(LD_DIRSERV,"PIRSERVER %s", escaped(buf));
+}
+
 /* Poke the hidden service cache PIR subsystem to launch the PIR
    server if needed. */
 static void
@@ -1064,9 +1090,13 @@ hs_cache_pir_poke(void)
     }
 
     if (pirserver) {
-        if (pirserver_read_ev) {
-            event_free(pirserver_read_ev);
-            pirserver_read_ev = NULL;
+        if (pirserver_stdout_ev) {
+            event_free(pirserver_stdout_ev);
+            pirserver_stdout_ev = NULL;
+        }
+        if (pirserver_stderr_ev) {
+            event_free(pirserver_stderr_ev);
+            pirserver_stderr_ev = NULL;
         }
         tor_process_handle_destroy(pirserver, 1);
         pirserver = NULL;
@@ -1093,10 +1123,16 @@ hs_cache_pir_poke(void)
     }
 
     /* Create a libevent event to listen to the PIR server's responses. */
-    pirserver_read_ev = event_new(tor_libevent_get_base(),
+    pirserver_stdout_ev = event_new(tor_libevent_get_base(),
         pirserver->stdout_pipe, EV_READ|EV_PERSIST,
         hs_cache_pirserver_recvcb, NULL);
-    event_add(pirserver_read_ev, NULL);
+    event_add(pirserver_stdout_ev, NULL);
+
+    /* And one to listen to the PIR server's stderr. */
+    pirserver_stderr_ev = event_new(tor_libevent_get_base(),
+        pirserver->stderr_pipe, EV_READ|EV_PERSIST,
+        hs_cache_pirserver_stderrcb, NULL);
+    event_add(pirserver_stderr_ev, NULL);
 }
 
 /* Initialize the hidden service cache PIR subsystem. */
@@ -1104,7 +1140,8 @@ static void
 hs_cache_pir_init(void)
 {
     pirserver = NULL;
-    pirserver_read_ev = NULL;
+    pirserver_stdout_ev = NULL;
+    pirserver_stderr_ev = NULL;
 }
 
 static int
@@ -1140,15 +1177,18 @@ hs_cache_pirserver_insert_desc(hs_cache_dir_descriptor_t *desc)
     size_t len;
     int res;
     int written = 0;
+    static uint32_t inscounter = 0;
 
-    /* PIRONION TODO: This isn't the real insertion protocol yet. */
+    memmove(hdr, "\0\0\0\0", 4);
+    ++inscounter;
+    *(uint32_t*)(hdr+4) = htonl(inscounter);
+    hdr[8] = PIRSERVER_REQUEST_STORE;
 
-    memmove(hdr, "12345678\x01", 9);
     encoded_desc_len = strlen(desc->encoded_desc);
     len = DIGEST256_LEN + encoded_desc_len;
     *(uint32_t*)(hdr+9) = htonl(len);
 
-    res = hs_cache_pirserver_send(hdr, 13);
+    res = hs_cache_pirserver_send(hdr, PIRSERVER_HDR_SIZE);
     if (res <= 0) return -1;
     written += res;