|
@@ -26,16 +26,7 @@
|
|
|
|
|
|
#include "feature/nodelist/networkstatus_st.h"
|
|
|
|
|
|
-#define SUBPROCESS_PRIVATE
|
|
|
-#include "lib/process/env.h"
|
|
|
-#include "lib/process/subprocess.h"
|
|
|
-#include "lib/evloop/compat_libevent.h"
|
|
|
-
|
|
|
-#include <event2/event.h>
|
|
|
-
|
|
|
-#ifdef HAVE_UNISTD_H
|
|
|
-#include <unistd.h>
|
|
|
-#endif
|
|
|
+#include "feature/hs/hs_pirprocess.h"
|
|
|
|
|
|
static int cached_client_descriptor_has_expired(time_t now,
|
|
|
const hs_cache_client_descriptor_t *cached_desc);
|
|
@@ -978,19 +969,6 @@ hs_cache_get_max_descriptor_size(void)
|
|
|
HS_DESC_MAX_LEN, 1, INT32_MAX);
|
|
|
}
|
|
|
|
|
|
-static process_handle_t *pirserver;
|
|
|
-static buf_t *pirserver_stdin_buf;
|
|
|
-static struct event *pirserver_stdin_ev;
|
|
|
-static struct event *pirserver_stdout_ev;
|
|
|
-static struct event *pirserver_stderr_ev;
|
|
|
-
|
|
|
-typedef enum {
|
|
|
- PIRSERVER_READSTATE_HEADER,
|
|
|
- PIRSERVER_READSTATE_BODY
|
|
|
-} PIRServerReadState;
|
|
|
-
|
|
|
-#define PIRSERVER_HDR_SIZE 13
|
|
|
-
|
|
|
#define PIRSERVER_REQUEST_PARAMS 0x01
|
|
|
#define PIRSERVER_REQUEST_STORE 0x02
|
|
|
#define PIRSERVER_REQUEST_LOOKUP 0x03
|
|
@@ -1013,199 +991,15 @@ hs_cache_pirserver_received(const unsigned char *hdrbuf,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static void
|
|
|
-hs_cache_pirserver_stdoutcb(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_HDR_SIZE;
|
|
|
- static unsigned char hdrbuf[PIRSERVER_HDR_SIZE];
|
|
|
- static char *bodybuf = NULL;
|
|
|
-
|
|
|
- if (!(what & EV_READ)) {
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (readstate == PIRSERVER_READSTATE_HEADER) {
|
|
|
- int res = read(fd, hdrbuf + readoff, readleft);
|
|
|
- if (res <= 0) return;
|
|
|
- readoff += res;
|
|
|
- readleft -= res;
|
|
|
- if (readleft == 0) {
|
|
|
- readleft = ntohl(*(uint32_t*)(hdrbuf+PIRSERVER_HDR_SIZE-4));
|
|
|
- tor_free(bodybuf);
|
|
|
- if (readleft > 0) {
|
|
|
- bodybuf = tor_malloc(readleft);
|
|
|
- readoff = 0;
|
|
|
- readstate = PIRSERVER_READSTATE_BODY;
|
|
|
- } else {
|
|
|
- hs_cache_pirserver_received(hdrbuf, NULL, 0);
|
|
|
- readoff = 0;
|
|
|
- readleft = PIRSERVER_HDR_SIZE;
|
|
|
- readstate = PIRSERVER_READSTATE_HEADER;
|
|
|
- }
|
|
|
- }
|
|
|
- } else if (readstate == PIRSERVER_READSTATE_BODY) {
|
|
|
- int res = read(fd, bodybuf + readoff, readleft);
|
|
|
- if (res <= 0) return;
|
|
|
- readoff += res;
|
|
|
- readleft -= res;
|
|
|
- if (readleft == 0) {
|
|
|
-
|
|
|
- hs_cache_pirserver_received(hdrbuf, bodybuf, readoff);
|
|
|
-
|
|
|
-
|
|
|
- tor_free(bodybuf);
|
|
|
- readoff = 0;
|
|
|
- readleft = PIRSERVER_HDR_SIZE;
|
|
|
- readstate = PIRSERVER_READSTATE_HEADER;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void
|
|
|
-hs_cache_pirserver_stdincb(evutil_socket_t fd, short what,
|
|
|
- ATTR_UNUSED void *arg) {
|
|
|
- int res;
|
|
|
- size_t bufsize = buf_datalen(pirserver_stdin_buf);
|
|
|
- char *netbuf = NULL;
|
|
|
-
|
|
|
- if (!(what & EV_WRITE)) {
|
|
|
-
|
|
|
- log_info(LD_DIRSERV,"PIRSERVER bailing");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (bufsize == 0) {
|
|
|
- log_err(LD_DIRSERV,"PIRSERVER trying to write 0-length buffer");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- netbuf = tor_malloc(bufsize);
|
|
|
- if (netbuf == NULL) {
|
|
|
- log_err(LD_DIRSERV,"PIRSERVER failed to allocate buffer");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- * the thing to do, but that function ends up calling sendto()
|
|
|
- * instead of write(), which doesn't work on pipes. So we do it
|
|
|
- * more manually. Using a bufferevent may be another option. */
|
|
|
- buf_peek(pirserver_stdin_buf, netbuf, bufsize);
|
|
|
- res = write(fd, netbuf, bufsize);
|
|
|
- tor_free(netbuf);
|
|
|
- if (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
|
|
|
-
|
|
|
- event_add(pirserver_stdin_ev, NULL);
|
|
|
- return;
|
|
|
- }
|
|
|
- if (res <= 0) {
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
- buf_drain(pirserver_stdin_buf, res);
|
|
|
- bufsize -= res;
|
|
|
-
|
|
|
- if (bufsize > 0) {
|
|
|
-
|
|
|
- event_add(pirserver_stdin_ev, NULL);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void
|
|
|
-hs_cache_pirserver_stderrcb(evutil_socket_t fd, short what,
|
|
|
- ATTR_UNUSED void *arg) {
|
|
|
- if (!(what & EV_READ)) {
|
|
|
-
|
|
|
- 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));
|
|
|
-}
|
|
|
+static pir_process_t pirserver;
|
|
|
|
|
|
|
|
|
server if needed. */
|
|
|
static void
|
|
|
hs_cache_pir_poke(void)
|
|
|
{
|
|
|
- int res;
|
|
|
- const char *pirserverpath = getenv("PIR_SERVER_PATH");
|
|
|
- smartlist_t *env_vars = get_current_process_environment_variables();
|
|
|
- const char *argv[2];
|
|
|
- process_environment_t *env;
|
|
|
-
|
|
|
- if (pirserver && pirserver->status == PROCESS_STATUS_RUNNING) {
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (pirserver) {
|
|
|
- if (pirserver_stdin_buf) {
|
|
|
- buf_free(pirserver_stdin_buf);
|
|
|
- pirserver_stdin_buf = NULL;
|
|
|
- }
|
|
|
- if (pirserver_stdin_ev) {
|
|
|
- event_free(pirserver_stdin_ev);
|
|
|
- pirserver_stdin_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;
|
|
|
- }
|
|
|
-
|
|
|
- if (!pirserverpath) {
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- argv[0] = pirserverpath;
|
|
|
- argv[1] = NULL;
|
|
|
-
|
|
|
- env = process_environment_make(env_vars);
|
|
|
-
|
|
|
- res = tor_spawn_background(pirserverpath, argv, env, &pirserver);
|
|
|
-
|
|
|
- SMARTLIST_FOREACH(env_vars, void *, x, tor_free(x));
|
|
|
- smartlist_free(env_vars);
|
|
|
-
|
|
|
- if (res != PROCESS_STATUS_RUNNING) {
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- pirserver_stdout_ev = event_new(tor_libevent_get_base(),
|
|
|
- pirserver->stdout_pipe, EV_READ|EV_PERSIST,
|
|
|
- hs_cache_pirserver_stdoutcb, NULL);
|
|
|
- event_add(pirserver_stdout_ev, NULL);
|
|
|
-
|
|
|
-
|
|
|
- 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);
|
|
|
-
|
|
|
-
|
|
|
- * it just yet. Also create the buffer it will use. */
|
|
|
- pirserver_stdin_buf = buf_new();
|
|
|
- pirserver_stdin_ev = event_new(tor_libevent_get_base(),
|
|
|
- pirserver->stdin_pipe, EV_WRITE, hs_cache_pirserver_stdincb,
|
|
|
- NULL);
|
|
|
+ hs_pirprocess_poke(getenv("PIR_SERVER_PATH"), "PIRSERVER",
|
|
|
+ hs_cache_pirserver_received, &pirserver);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1213,27 +1007,13 @@ static void
|
|
|
hs_cache_pir_init(void)
|
|
|
{
|
|
|
pirserver = NULL;
|
|
|
- pirserver_stdin_buf = NULL;
|
|
|
- pirserver_stdin_ev = NULL;
|
|
|
- pirserver_stdout_ev = NULL;
|
|
|
- pirserver_stderr_ev = NULL;
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
hs_cache_pirserver_send(const unsigned char *buf, size_t len)
|
|
|
{
|
|
|
hs_cache_pir_poke();
|
|
|
- if (pirserver == NULL || pirserver->status != PROCESS_STATUS_RUNNING) {
|
|
|
-
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if (len > 0) {
|
|
|
- buf_add(pirserver_stdin_buf, (const char *)buf, len);
|
|
|
- event_add(pirserver_stdin_ev, NULL);
|
|
|
- }
|
|
|
- return len;
|
|
|
+ return hs_pirprocess_send(pirserver, buf, len);
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -1255,7 +1035,7 @@ hs_cache_pirserver_insert_desc(hs_cache_dir_descriptor_t *desc)
|
|
|
len = DIGEST256_LEN + encoded_desc_len;
|
|
|
*(uint32_t*)(hdr+9) = htonl(len);
|
|
|
|
|
|
- res = hs_cache_pirserver_send(hdr, PIRSERVER_HDR_SIZE);
|
|
|
+ res = hs_cache_pirserver_send(hdr, PIRPROCESS_HDR_SIZE);
|
|
|
if (res <= 0) return -1;
|
|
|
written += res;
|
|
|
|
|
@@ -1280,7 +1060,7 @@ hs_cache_pirserver_get_params(dir_connection_t *conn)
|
|
|
|
|
|
|
|
|
int res;
|
|
|
- unsigned char hdr[PIRSERVER_HDR_SIZE];
|
|
|
+ unsigned char hdr[PIRPROCESS_HDR_SIZE];
|
|
|
|
|
|
|
|
|
* dir_connection_t pointer itself, so that when we get the
|
|
@@ -1290,8 +1070,8 @@ hs_cache_pirserver_get_params(dir_connection_t *conn)
|
|
|
memmove(hdr, (const char *)(&conn), sizeof(conn));
|
|
|
hdr[8] = PIRSERVER_REQUEST_PARAMS;
|
|
|
memmove(hdr+9, "\0\0\0\0", 4);
|
|
|
- res = hs_cache_pirserver_send(hdr, PIRSERVER_HDR_SIZE);
|
|
|
- if (res < PIRSERVER_HDR_SIZE) {
|
|
|
+ res = hs_cache_pirserver_send(hdr, PIRPROCESS_HDR_SIZE);
|
|
|
+ if (res < PIRPROCESS_HDR_SIZE) {
|
|
|
return -1;
|
|
|
}
|
|
|
return 0;
|