Loading src/or/directory.c +76 −40 Original line number Diff line number Diff line Loading @@ -29,7 +29,8 @@ static void directory_initiate_command(routerinfo_t *router, uint8_t purpose, const char *payload, int payload_len); static void directory_send_command(connection_t *conn, int purpose, static void directory_send_command(connection_t *conn, routerinfo_t *router, int purpose, const char *payload, int payload_len); static int directory_handle_command(connection_t *conn); Loading Loading @@ -128,8 +129,7 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, tor_assert(router); tor_assert(router->dir_port); switch (purpose) { switch (purpose) { case DIR_PURPOSE_FETCH_DIR: log_fn(LOG_DEBUG,"initiating directory fetch"); break; Loading @@ -150,8 +150,13 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, conn = connection_new(CONN_TYPE_DIR); /* set up conn so it's got all the data we need to remember */ if(options.HttpProxy) { conn->addr = options.HttpProxyAddr; conn->port = options.HttpProxyPort; } else { conn->addr = router->addr; conn->port = router->dir_port; } conn->address = tor_strdup(router->address); conn->nickname = tor_strdup(router->nickname); tor_assert(router->identity_pkey); Loading Loading @@ -180,7 +185,7 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, /* fall through */ case 0: /* queue the command on the outbuf */ directory_send_command(conn, purpose, payload, payload_len); directory_send_command(conn, router, purpose, payload, payload_len); connection_watch_events(conn, POLLIN | POLLOUT | POLLERR); /* writable indicates finish, readable indicates broken link, Loading @@ -201,7 +206,7 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, conn->state = DIR_CONN_STATE_CLIENT_SENDING; connection_add(conn); /* queue the command on the outbuf */ directory_send_command(conn, purpose, payload, payload_len); directory_send_command(conn, router, purpose, payload, payload_len); connection_watch_events(conn, POLLIN | POLLOUT | POLLERR); } } Loading @@ -210,44 +215,49 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, * <b>purpose</b>, <b>payload</b>, and <b>payload_len</b> are as in * directory_initiate_command. */ static void directory_send_command(connection_t *conn, int purpose, static void directory_send_command(connection_t *conn, routerinfo_t *router, int purpose, const char *payload, int payload_len) { char fetchwholedir[] = "GET / HTTP/1.0\r\n\r\n"; /* deprecated */ char fetchwholedir_z[] = "GET /tor/dir.z HTTP/1.0\r\n\r\n"; char fetchrunninglist[] = "GET /tor/running-routers HTTP/1.0\r\n\r\n"; char tmp[8192]; routerinfo_t *router; char proxystring[128]; char hoststring[128]; char url[128]; int use_newer = 0; char *httpcommand = NULL; tor_assert(conn && conn->type == CONN_TYPE_DIR); router = router_get_by_digest(conn->identity_digest); tor_assert(router); /* the func that calls us found it, so we should too */ tor_assert(router); use_newer = tor_version_as_new_as(router->platform, "0.0.9pre1"); if(router->dir_port == 80) { strlcpy(hoststring, router->address, sizeof(hoststring)); } else { sprintf(hoststring, "%s:%d", router->address, router->dir_port); } if(options.HttpProxy) { sprintf(proxystring, "http://%s", hoststring); } else { proxystring[0] = 0; } switch(purpose) { case DIR_PURPOSE_FETCH_DIR: tor_assert(payload == NULL); if(use_newer) { log_fn(LOG_DEBUG, "Asking for compressed directory from server running %s", router->platform); connection_write_to_buf(fetchwholedir_z, strlen(fetchwholedir_z), conn); } else { log_fn(LOG_DEBUG, "Asking for uncompressed directory from server running %s", router->platform); connection_write_to_buf(fetchwholedir, strlen(fetchwholedir), conn); } log_fn(LOG_DEBUG, "Asking for %scompressed directory from server running %s", use_newer?"":"un", router->platform); httpcommand = "GET"; strlcpy(url, use_newer ? "/tor/dir.z" : "/", sizeof(url)); break; case DIR_PURPOSE_FETCH_RUNNING_LIST: tor_assert(payload == NULL); connection_write_to_buf(fetchrunninglist, strlen(fetchrunninglist), conn); httpcommand = "GET"; strlcpy(url, use_newer ? "/tor/running-routers" : "/running-routers", sizeof(url)); break; case DIR_PURPOSE_UPLOAD_DIR: tor_assert(payload); snprintf(tmp, sizeof(tmp), "POST %s/ HTTP/1.0\r\nContent-Length: %d\r\n\r\n", use_newer ? "/tor" : "", payload_len); connection_write_to_buf(tmp, strlen(tmp), conn); connection_write_to_buf(payload, payload_len, conn); httpcommand = "POST"; strlcpy(url, use_newer ? "/tor/" : "/", sizeof(url)); break; case DIR_PURPOSE_FETCH_RENDDESC: tor_assert(payload); Loading @@ -258,21 +268,32 @@ static void directory_send_command(connection_t *conn, int purpose, memcpy(conn->rend_query, payload, payload_len); conn->rend_query[payload_len] = 0; snprintf(tmp, sizeof(tmp), "GET %s%s HTTP/1.0\r\n\r\n", "/rendezvous/", payload); connection_write_to_buf(tmp, strlen(tmp), conn); httpcommand = "GET"; sprintf(url, "%s/rendezvous/%s", use_newer ? "/tor" : "", payload); break; case DIR_PURPOSE_UPLOAD_RENDDESC: tor_assert(payload); snprintf(tmp, sizeof(tmp), "POST %s HTTP/1.0\r\nContent-Length: %d\r\n\r\n", "/rendezvous/publish", payload_len); httpcommand = "POST"; sprintf(url, "%s/rendezvous/publish", use_newer ? "/tor" : ""); break; } snprintf(tmp, sizeof(tmp), "%s %s%s HTTP/1.0\r\nContent-Length: %d\r\nHost: %s\r\n\r\n", httpcommand, proxystring, url, payload_len, hoststring); connection_write_to_buf(tmp, strlen(tmp), conn); /* could include nuls, need to write it separately */ if(purpose == DIR_PURPOSE_UPLOAD_DIR || purpose == DIR_PURPOSE_UPLOAD_RENDDESC) { /* then send the payload afterwards too */ connection_write_to_buf(payload, payload_len, conn); break; } } /** Parse an HTTP request string <b>headers</b> of the form "\%s \%s HTTP/1..." /** Parse an HTTP request string <b>headers</b> of the form * "\%s [http[s]://]\%s HTTP/1..." * If it's well-formed, strdup the second \%s into *<b>url</b>, and * null-terminate it. If the url doesn't start with "/tor/", rewrite it * so it does. Return 0. Loading @@ -281,7 +302,7 @@ static void directory_send_command(connection_t *conn, int purpose, static int parse_http_url(char *headers, char **url) { char *s, *start; char *s, *start, *tmp; s = (char *)eat_whitespace_no_nl(headers); if (!*s) return -1; Loading @@ -292,6 +313,21 @@ parse_http_url(char *headers, char **url) start = s; /* this is it, assuming it's valid */ s = (char *)find_whitespace(start); if (!*s) return -1; /* tolerate the http[s] proxy style of putting the hostname in the url */ if(s-start >= 4 && !strcmpstart(start,"http")) { tmp = start + 4; if(*tmp == 's') tmp++; if(s-tmp >= 3 && !strcmpstart(tmp,"://")) { tmp = strchr(tmp+3, '/'); if(tmp && tmp < s) { log_fn(LOG_DEBUG,"Skipping over 'http[s]://hostname' string"); start = tmp; } } } if(s-start < 5 || strcmpstart(start,"/tor/")) { /* need to rewrite it */ *url = tor_malloc(s - start + 5); strcpy(*url,"/tor"); Loading src/or/or.h +6 −1 Original line number Diff line number Diff line Loading @@ -894,7 +894,12 @@ typedef struct { allowed to sign directories. */ struct config_line_t *RendConfigLines; /**< List of configuration lines * for rendezvous services. */ char *ContactInfo; /** Contact info to be published in the directory */ char *ContactInfo; /**< Contact info to be published in the directory */ char *HttpProxy; /**< hostname[:port] to use as http proxy, if any */ uint32_t HttpProxyAddr; /**< Parsed IPv4 addr for http proxy, if any */ uint16_t HttpProxyPort; /**< Parsed port for http proxy, if any */ } or_options_t; /* XXX are these good enough defaults? */ Loading Loading
src/or/directory.c +76 −40 Original line number Diff line number Diff line Loading @@ -29,7 +29,8 @@ static void directory_initiate_command(routerinfo_t *router, uint8_t purpose, const char *payload, int payload_len); static void directory_send_command(connection_t *conn, int purpose, static void directory_send_command(connection_t *conn, routerinfo_t *router, int purpose, const char *payload, int payload_len); static int directory_handle_command(connection_t *conn); Loading Loading @@ -128,8 +129,7 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, tor_assert(router); tor_assert(router->dir_port); switch (purpose) { switch (purpose) { case DIR_PURPOSE_FETCH_DIR: log_fn(LOG_DEBUG,"initiating directory fetch"); break; Loading @@ -150,8 +150,13 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, conn = connection_new(CONN_TYPE_DIR); /* set up conn so it's got all the data we need to remember */ if(options.HttpProxy) { conn->addr = options.HttpProxyAddr; conn->port = options.HttpProxyPort; } else { conn->addr = router->addr; conn->port = router->dir_port; } conn->address = tor_strdup(router->address); conn->nickname = tor_strdup(router->nickname); tor_assert(router->identity_pkey); Loading Loading @@ -180,7 +185,7 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, /* fall through */ case 0: /* queue the command on the outbuf */ directory_send_command(conn, purpose, payload, payload_len); directory_send_command(conn, router, purpose, payload, payload_len); connection_watch_events(conn, POLLIN | POLLOUT | POLLERR); /* writable indicates finish, readable indicates broken link, Loading @@ -201,7 +206,7 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, conn->state = DIR_CONN_STATE_CLIENT_SENDING; connection_add(conn); /* queue the command on the outbuf */ directory_send_command(conn, purpose, payload, payload_len); directory_send_command(conn, router, purpose, payload, payload_len); connection_watch_events(conn, POLLIN | POLLOUT | POLLERR); } } Loading @@ -210,44 +215,49 @@ directory_initiate_command(routerinfo_t *router, uint8_t purpose, * <b>purpose</b>, <b>payload</b>, and <b>payload_len</b> are as in * directory_initiate_command. */ static void directory_send_command(connection_t *conn, int purpose, static void directory_send_command(connection_t *conn, routerinfo_t *router, int purpose, const char *payload, int payload_len) { char fetchwholedir[] = "GET / HTTP/1.0\r\n\r\n"; /* deprecated */ char fetchwholedir_z[] = "GET /tor/dir.z HTTP/1.0\r\n\r\n"; char fetchrunninglist[] = "GET /tor/running-routers HTTP/1.0\r\n\r\n"; char tmp[8192]; routerinfo_t *router; char proxystring[128]; char hoststring[128]; char url[128]; int use_newer = 0; char *httpcommand = NULL; tor_assert(conn && conn->type == CONN_TYPE_DIR); router = router_get_by_digest(conn->identity_digest); tor_assert(router); /* the func that calls us found it, so we should too */ tor_assert(router); use_newer = tor_version_as_new_as(router->platform, "0.0.9pre1"); if(router->dir_port == 80) { strlcpy(hoststring, router->address, sizeof(hoststring)); } else { sprintf(hoststring, "%s:%d", router->address, router->dir_port); } if(options.HttpProxy) { sprintf(proxystring, "http://%s", hoststring); } else { proxystring[0] = 0; } switch(purpose) { case DIR_PURPOSE_FETCH_DIR: tor_assert(payload == NULL); if(use_newer) { log_fn(LOG_DEBUG, "Asking for compressed directory from server running %s", router->platform); connection_write_to_buf(fetchwholedir_z, strlen(fetchwholedir_z), conn); } else { log_fn(LOG_DEBUG, "Asking for uncompressed directory from server running %s", router->platform); connection_write_to_buf(fetchwholedir, strlen(fetchwholedir), conn); } log_fn(LOG_DEBUG, "Asking for %scompressed directory from server running %s", use_newer?"":"un", router->platform); httpcommand = "GET"; strlcpy(url, use_newer ? "/tor/dir.z" : "/", sizeof(url)); break; case DIR_PURPOSE_FETCH_RUNNING_LIST: tor_assert(payload == NULL); connection_write_to_buf(fetchrunninglist, strlen(fetchrunninglist), conn); httpcommand = "GET"; strlcpy(url, use_newer ? "/tor/running-routers" : "/running-routers", sizeof(url)); break; case DIR_PURPOSE_UPLOAD_DIR: tor_assert(payload); snprintf(tmp, sizeof(tmp), "POST %s/ HTTP/1.0\r\nContent-Length: %d\r\n\r\n", use_newer ? "/tor" : "", payload_len); connection_write_to_buf(tmp, strlen(tmp), conn); connection_write_to_buf(payload, payload_len, conn); httpcommand = "POST"; strlcpy(url, use_newer ? "/tor/" : "/", sizeof(url)); break; case DIR_PURPOSE_FETCH_RENDDESC: tor_assert(payload); Loading @@ -258,21 +268,32 @@ static void directory_send_command(connection_t *conn, int purpose, memcpy(conn->rend_query, payload, payload_len); conn->rend_query[payload_len] = 0; snprintf(tmp, sizeof(tmp), "GET %s%s HTTP/1.0\r\n\r\n", "/rendezvous/", payload); connection_write_to_buf(tmp, strlen(tmp), conn); httpcommand = "GET"; sprintf(url, "%s/rendezvous/%s", use_newer ? "/tor" : "", payload); break; case DIR_PURPOSE_UPLOAD_RENDDESC: tor_assert(payload); snprintf(tmp, sizeof(tmp), "POST %s HTTP/1.0\r\nContent-Length: %d\r\n\r\n", "/rendezvous/publish", payload_len); httpcommand = "POST"; sprintf(url, "%s/rendezvous/publish", use_newer ? "/tor" : ""); break; } snprintf(tmp, sizeof(tmp), "%s %s%s HTTP/1.0\r\nContent-Length: %d\r\nHost: %s\r\n\r\n", httpcommand, proxystring, url, payload_len, hoststring); connection_write_to_buf(tmp, strlen(tmp), conn); /* could include nuls, need to write it separately */ if(purpose == DIR_PURPOSE_UPLOAD_DIR || purpose == DIR_PURPOSE_UPLOAD_RENDDESC) { /* then send the payload afterwards too */ connection_write_to_buf(payload, payload_len, conn); break; } } /** Parse an HTTP request string <b>headers</b> of the form "\%s \%s HTTP/1..." /** Parse an HTTP request string <b>headers</b> of the form * "\%s [http[s]://]\%s HTTP/1..." * If it's well-formed, strdup the second \%s into *<b>url</b>, and * null-terminate it. If the url doesn't start with "/tor/", rewrite it * so it does. Return 0. Loading @@ -281,7 +302,7 @@ static void directory_send_command(connection_t *conn, int purpose, static int parse_http_url(char *headers, char **url) { char *s, *start; char *s, *start, *tmp; s = (char *)eat_whitespace_no_nl(headers); if (!*s) return -1; Loading @@ -292,6 +313,21 @@ parse_http_url(char *headers, char **url) start = s; /* this is it, assuming it's valid */ s = (char *)find_whitespace(start); if (!*s) return -1; /* tolerate the http[s] proxy style of putting the hostname in the url */ if(s-start >= 4 && !strcmpstart(start,"http")) { tmp = start + 4; if(*tmp == 's') tmp++; if(s-tmp >= 3 && !strcmpstart(tmp,"://")) { tmp = strchr(tmp+3, '/'); if(tmp && tmp < s) { log_fn(LOG_DEBUG,"Skipping over 'http[s]://hostname' string"); start = tmp; } } } if(s-start < 5 || strcmpstart(start,"/tor/")) { /* need to rewrite it */ *url = tor_malloc(s - start + 5); strcpy(*url,"/tor"); Loading
src/or/or.h +6 −1 Original line number Diff line number Diff line Loading @@ -894,7 +894,12 @@ typedef struct { allowed to sign directories. */ struct config_line_t *RendConfigLines; /**< List of configuration lines * for rendezvous services. */ char *ContactInfo; /** Contact info to be published in the directory */ char *ContactInfo; /**< Contact info to be published in the directory */ char *HttpProxy; /**< hostname[:port] to use as http proxy, if any */ uint32_t HttpProxyAddr; /**< Parsed IPv4 addr for http proxy, if any */ uint16_t HttpProxyPort; /**< Parsed port for http proxy, if any */ } or_options_t; /* XXX are these good enough defaults? */ Loading