mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 20:33:31 +01:00
teach directory servers to handle renddesc responses
svn:r1434
This commit is contained in:
parent
05b99bcf7d
commit
64cb3a027f
@ -24,11 +24,11 @@ void directory_initiate_command(routerinfo_t *router, int purpose,
|
|||||||
|
|
||||||
if(purpose == DIR_PURPOSE_FETCH_DIR)
|
if(purpose == DIR_PURPOSE_FETCH_DIR)
|
||||||
log_fn(LOG_DEBUG,"initiating directory fetch");
|
log_fn(LOG_DEBUG,"initiating directory fetch");
|
||||||
if(purpose == DIR_PURPOSE_FETCH_HIDSERV)
|
if(purpose == DIR_PURPOSE_FETCH_RENDDESC)
|
||||||
log_fn(LOG_DEBUG,"initiating hidden-service descriptor fetch");
|
log_fn(LOG_DEBUG,"initiating hidden-service descriptor fetch");
|
||||||
if(purpose == DIR_PURPOSE_UPLOAD_DIR)
|
if(purpose == DIR_PURPOSE_UPLOAD_DIR)
|
||||||
log_fn(LOG_DEBUG,"initiating server descriptor upload");
|
log_fn(LOG_DEBUG,"initiating server descriptor upload");
|
||||||
if(purpose == DIR_PURPOSE_UPLOAD_HIDSERV)
|
if(purpose == DIR_PURPOSE_UPLOAD_RENDDESC)
|
||||||
log_fn(LOG_DEBUG,"initiating hidden-service descriptor upload");
|
log_fn(LOG_DEBUG,"initiating hidden-service descriptor upload");
|
||||||
|
|
||||||
if (!router) { /* i guess they didn't have one in mind for me to use */
|
if (!router) { /* i guess they didn't have one in mind for me to use */
|
||||||
@ -111,12 +111,18 @@ static void directory_send_command(connection_t *conn, int purpose,
|
|||||||
payload_len, payload);
|
payload_len, payload);
|
||||||
connection_write_to_buf(tmp, strlen(tmp), conn);
|
connection_write_to_buf(tmp, strlen(tmp), conn);
|
||||||
break;
|
break;
|
||||||
case DIR_PURPOSE_FETCH_HIDSERV:
|
case DIR_PURPOSE_FETCH_RENDDESC:
|
||||||
assert(payload);
|
assert(payload);
|
||||||
|
|
||||||
|
/* this must be true or we wouldn't be doing the lookup */
|
||||||
|
assert(payload_len <= REND_SERVICE_ID_LEN);
|
||||||
|
memcpy(conn->rend_query, payload, payload_len);
|
||||||
|
conn->rend_query[payload_len] = 0;
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp), "GET /hidserv/%s HTTP/1.0\r\n\r\n", payload);
|
snprintf(tmp, sizeof(tmp), "GET /hidserv/%s HTTP/1.0\r\n\r\n", payload);
|
||||||
connection_write_to_buf(tmp, strlen(tmp), conn);
|
connection_write_to_buf(tmp, strlen(tmp), conn);
|
||||||
break;
|
break;
|
||||||
case DIR_PURPOSE_UPLOAD_HIDSERV:
|
case DIR_PURPOSE_UPLOAD_RENDDESC:
|
||||||
assert(payload);
|
assert(payload);
|
||||||
snprintf(tmp, sizeof(tmp),
|
snprintf(tmp, sizeof(tmp),
|
||||||
"POST /hidserv/ HTTP/1.0\r\nContent-Length: %d\r\n\r\n", payload_len);
|
"POST /hidserv/ HTTP/1.0\r\nContent-Length: %d\r\n\r\n", payload_len);
|
||||||
@ -175,9 +181,9 @@ int parse_http_response(char *headers, int *code, char **message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int connection_dir_process_inbuf(connection_t *conn) {
|
int connection_dir_process_inbuf(connection_t *conn) {
|
||||||
char *directory;
|
char *body;
|
||||||
char *headers;
|
char *headers;
|
||||||
int dir_len=0;
|
int body_len=0;
|
||||||
int status_code;
|
int status_code;
|
||||||
|
|
||||||
assert(conn && conn->type == CONN_TYPE_DIR);
|
assert(conn && conn->type == CONN_TYPE_DIR);
|
||||||
@ -192,7 +198,7 @@ int connection_dir_process_inbuf(connection_t *conn) {
|
|||||||
|
|
||||||
switch(fetch_from_buf_http(conn->inbuf,
|
switch(fetch_from_buf_http(conn->inbuf,
|
||||||
&headers, MAX_HEADERS_SIZE,
|
&headers, MAX_HEADERS_SIZE,
|
||||||
&directory, &dir_len, MAX_DIR_SIZE)) {
|
&body, &body_len, MAX_DIR_SIZE)) {
|
||||||
case -1: /* overflow */
|
case -1: /* overflow */
|
||||||
log_fn(LOG_WARN,"'fetch' response too large. Failing.");
|
log_fn(LOG_WARN,"'fetch' response too large. Failing.");
|
||||||
connection_mark_for_close(conn,0);
|
connection_mark_for_close(conn,0);
|
||||||
@ -206,28 +212,28 @@ int connection_dir_process_inbuf(connection_t *conn) {
|
|||||||
|
|
||||||
if(parse_http_response(headers, &status_code, NULL) < 0) {
|
if(parse_http_response(headers, &status_code, NULL) < 0) {
|
||||||
log_fn(LOG_WARN,"Unparseable headers. Closing.");
|
log_fn(LOG_WARN,"Unparseable headers. Closing.");
|
||||||
free(directory); free(headers);
|
free(body); free(headers);
|
||||||
connection_mark_for_close(conn,0);
|
connection_mark_for_close(conn,0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->purpose == DIR_PURPOSE_FETCH_DIR) {
|
if(conn->purpose == DIR_PURPOSE_FETCH_DIR) {
|
||||||
/* fetch/process the directory to learn about new routers. */
|
/* fetch/process the directory to learn about new routers. */
|
||||||
log_fn(LOG_INFO,"Received directory (size %d):\n%s", dir_len, directory);
|
log_fn(LOG_INFO,"Received directory (size %d):\n%s", body_len, body);
|
||||||
if(status_code == 503 || dir_len == 0) {
|
if(status_code == 503 || body_len == 0) {
|
||||||
log_fn(LOG_INFO,"Empty directory. Ignoring.");
|
log_fn(LOG_INFO,"Empty directory. Ignoring.");
|
||||||
free(directory); free(headers);
|
free(body); free(headers);
|
||||||
connection_mark_for_close(conn,0);
|
connection_mark_for_close(conn,0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(status_code != 200) {
|
if(status_code != 200) {
|
||||||
log_fn(LOG_WARN,"Received http status code %d from dirserver. Failing.",
|
log_fn(LOG_WARN,"Received http status code %d from dirserver. Failing.",
|
||||||
status_code);
|
status_code);
|
||||||
free(directory); free(headers);
|
free(body); free(headers);
|
||||||
connection_mark_for_close(conn,0);
|
connection_mark_for_close(conn,0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(router_set_routerlist_from_directory(directory, conn->identity_pkey) < 0){
|
if(router_set_routerlist_from_directory(body, conn->identity_pkey) < 0){
|
||||||
log_fn(LOG_INFO,"...but parsing failed. Ignoring.");
|
log_fn(LOG_INFO,"...but parsing failed. Ignoring.");
|
||||||
} else {
|
} else {
|
||||||
log_fn(LOG_INFO,"updated routers.");
|
log_fn(LOG_INFO,"updated routers.");
|
||||||
@ -239,18 +245,15 @@ int connection_dir_process_inbuf(connection_t *conn) {
|
|||||||
if(options.ORPort) { /* connect to them all */
|
if(options.ORPort) { /* connect to them all */
|
||||||
router_retry_connections();
|
router_retry_connections();
|
||||||
}
|
}
|
||||||
free(directory); free(headers);
|
|
||||||
connection_mark_for_close(conn,0);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->purpose == DIR_PURPOSE_UPLOAD_DIR) {
|
if(conn->purpose == DIR_PURPOSE_UPLOAD_DIR) {
|
||||||
switch(status_code) {
|
switch(status_code) {
|
||||||
case 200:
|
case 200:
|
||||||
log_fn(LOG_INFO,"eof (status 200) while reading upload response: finished.");
|
log_fn(LOG_INFO,"eof (status 200) after uploading server descriptor: finished.");
|
||||||
break;
|
break;
|
||||||
case 400:
|
case 400:
|
||||||
log_fn(LOG_WARN,"http status 400 (bad request) response from dirserver.");
|
log_fn(LOG_WARN,"http status 400 (bad request) response from dirserver. Malformed server descriptor?");
|
||||||
break;
|
break;
|
||||||
case 403:
|
case 403:
|
||||||
log_fn(LOG_WARN,"http status 403 (unapproved server) response from dirserver. Is your clock skewed? Have you mailed arma your identity fingerprint? Are you using the right key?");
|
log_fn(LOG_WARN,"http status 403 (unapproved server) response from dirserver. Is your clock skewed? Have you mailed arma your identity fingerprint? Are you using the right key?");
|
||||||
@ -260,23 +263,48 @@ int connection_dir_process_inbuf(connection_t *conn) {
|
|||||||
log_fn(LOG_WARN,"http status %d response unrecognized.", status_code);
|
log_fn(LOG_WARN,"http status %d response unrecognized.", status_code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(directory); free(headers);
|
}
|
||||||
|
|
||||||
|
if(conn->purpose == DIR_PURPOSE_FETCH_RENDDESC) {
|
||||||
|
log_fn(LOG_INFO,"Received rendezvous descriptor (size %d, status code %d)",
|
||||||
|
body_len, status_code);
|
||||||
|
switch(status_code) {
|
||||||
|
case 200:
|
||||||
|
if(rend_cache_store(body, body_len) < 0) {
|
||||||
|
log_fn(LOG_WARN,"Failed to store rendezvous descriptor. Abandoning stream.");
|
||||||
|
/* alice's ap_stream is just going to have to time out. */
|
||||||
|
} else {
|
||||||
|
/* success. notify pending connections about this. */
|
||||||
|
//alice_notify_desc_fetched(conn->rend_query);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 404:
|
||||||
|
//alice_notify_desc_not_fetched(conn->rend_query);
|
||||||
|
break;
|
||||||
|
case 400:
|
||||||
|
log_fn(LOG_WARN,"http status 400 (bad request). Dirserver didn't like our rendezvous query?");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(conn->purpose == DIR_PURPOSE_UPLOAD_RENDDESC) {
|
||||||
|
switch(status_code) {
|
||||||
|
case 200:
|
||||||
|
log_fn(LOG_INFO,"eof (status 200) after uploading rendezvous descriptor: finished.");
|
||||||
|
break;
|
||||||
|
case 400:
|
||||||
|
log_fn(LOG_WARN,"http status 400 (bad request) response from dirserver. Malformed rendezvous descriptor?");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log_fn(LOG_WARN,"http status %d response unrecognized.", status_code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(body); free(headers);
|
||||||
connection_mark_for_close(conn,0);
|
connection_mark_for_close(conn,0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->purpose == DIR_PURPOSE_FETCH_HIDSERV) {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(conn->purpose == DIR_PURPOSE_UPLOAD_HIDSERV) {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
assert(0); /* never reached */
|
|
||||||
}
|
|
||||||
|
|
||||||
if(conn->state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
|
if(conn->state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
|
||||||
if (directory_handle_command(conn) < 0) {
|
if (directory_handle_command(conn) < 0) {
|
||||||
connection_mark_for_close(conn,0);
|
connection_mark_for_close(conn,0);
|
||||||
|
@ -283,7 +283,7 @@ void directory_has_arrived(void) {
|
|||||||
|
|
||||||
/* just for testing */
|
/* just for testing */
|
||||||
directory_initiate_command(router_pick_directory_server(),
|
directory_initiate_command(router_pick_directory_server(),
|
||||||
DIR_PURPOSE_FETCH_HIDSERV, "foo", 3);
|
DIR_PURPOSE_FETCH_RENDDESC, "foo", 3);
|
||||||
|
|
||||||
rend_services_init(); /* get bob to initialize all his hidden services */
|
rend_services_init(); /* get bob to initialize all his hidden services */
|
||||||
|
|
||||||
|
22
src/or/or.h
22
src/or/or.h
@ -170,6 +170,11 @@
|
|||||||
#define AP_CONN_STATE_OPEN 8
|
#define AP_CONN_STATE_OPEN 8
|
||||||
#define _AP_CONN_STATE_MAX 8
|
#define _AP_CONN_STATE_MAX 8
|
||||||
|
|
||||||
|
#define _AP_PURPOSE_MIN 1
|
||||||
|
#define AP_PURPOSE_GENERAL 1
|
||||||
|
#define AP_PURPOSE_
|
||||||
|
#define _AP_PURPOSE_MAX 1
|
||||||
|
|
||||||
#define _DIR_CONN_STATE_MIN 1
|
#define _DIR_CONN_STATE_MIN 1
|
||||||
#define DIR_CONN_STATE_CONNECTING 1
|
#define DIR_CONN_STATE_CONNECTING 1
|
||||||
#define DIR_CONN_STATE_CLIENT_SENDING 2
|
#define DIR_CONN_STATE_CLIENT_SENDING 2
|
||||||
@ -180,9 +185,9 @@
|
|||||||
|
|
||||||
#define _DIR_PURPOSE_MIN 1
|
#define _DIR_PURPOSE_MIN 1
|
||||||
#define DIR_PURPOSE_FETCH_DIR 1
|
#define DIR_PURPOSE_FETCH_DIR 1
|
||||||
#define DIR_PURPOSE_FETCH_HIDSERV 2
|
#define DIR_PURPOSE_FETCH_RENDDESC 2
|
||||||
#define DIR_PURPOSE_UPLOAD_DIR 3
|
#define DIR_PURPOSE_UPLOAD_DIR 3
|
||||||
#define DIR_PURPOSE_UPLOAD_HIDSERV 4
|
#define DIR_PURPOSE_UPLOAD_RENDDESC 4
|
||||||
#define DIR_PURPOSE_SERVER 5
|
#define DIR_PURPOSE_SERVER 5
|
||||||
#define _DIR_PURPOSE_MAX 5
|
#define _DIR_PURPOSE_MAX 5
|
||||||
|
|
||||||
@ -235,6 +240,9 @@
|
|||||||
#define END_STREAM_REASON_TIMEOUT 7
|
#define END_STREAM_REASON_TIMEOUT 7
|
||||||
#define _MAX_END_STREAM_REASON 7
|
#define _MAX_END_STREAM_REASON 7
|
||||||
|
|
||||||
|
/* length of 'y' portion of 'y.onion' URL. */
|
||||||
|
#define REND_SERVICE_ID_LEN 16
|
||||||
|
|
||||||
/* Reasons used by connection_mark_for_close */
|
/* Reasons used by connection_mark_for_close */
|
||||||
#define CLOSE_REASON_UNUSED_OR_CONN 100
|
#define CLOSE_REASON_UNUSED_OR_CONN 100
|
||||||
|
|
||||||
@ -343,7 +351,7 @@ struct connection_t {
|
|||||||
|
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
uint8_t purpose; /* only used for DIR types currently */
|
uint8_t purpose; /* only used for DIR and AP types currently */
|
||||||
uint8_t wants_to_read; /* should we start reading again once
|
uint8_t wants_to_read; /* should we start reading again once
|
||||||
* the bandwidth throttler allows it?
|
* the bandwidth throttler allows it?
|
||||||
*/
|
*/
|
||||||
@ -391,6 +399,9 @@ struct connection_t {
|
|||||||
* add 'bandwidth' to this, capping it at 10*bandwidth.
|
* add 'bandwidth' to this, capping it at 10*bandwidth.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Used only by dir connections: */
|
||||||
|
char rend_query[REND_SERVICE_ID_LEN+1];
|
||||||
|
|
||||||
/* Used only by edge connections: */
|
/* Used only by edge connections: */
|
||||||
uint16_t stream_id;
|
uint16_t stream_id;
|
||||||
struct connection_t *next_stream; /* points to the next stream at this edge, if any */
|
struct connection_t *next_stream; /* points to the next stream at this edge, if any */
|
||||||
@ -543,7 +554,7 @@ struct circuit_t {
|
|||||||
char rend_service[CRYPTO_SHA1_DIGEST_LEN];
|
char rend_service[CRYPTO_SHA1_DIGEST_LEN];
|
||||||
|
|
||||||
/* Holds rendezvous cookie if purpose is REND_POINT_WAITING or
|
/* Holds rendezvous cookie if purpose is REND_POINT_WAITING or
|
||||||
* S_RENDEZVOUSING. Filled with zeroes otherwise.
|
* S_RENDEZVOUSING or C_ESTABLISH_REND. Filled with zeroes otherwise.
|
||||||
*/
|
*/
|
||||||
char rend_cookie[REND_COOKIE_LEN];
|
char rend_cookie[REND_COOKIE_LEN];
|
||||||
|
|
||||||
@ -999,9 +1010,6 @@ void rep_hist_dump_stats(time_t now, int severity);
|
|||||||
|
|
||||||
/********************************* rendcommon.c ***************************/
|
/********************************* rendcommon.c ***************************/
|
||||||
|
|
||||||
/* length of 'y' portion of 'y.onion' URL. */
|
|
||||||
#define REND_SERVICE_ID_LEN 16
|
|
||||||
|
|
||||||
typedef struct rend_service_descriptor_t {
|
typedef struct rend_service_descriptor_t {
|
||||||
crypto_pk_env_t *pk;
|
crypto_pk_env_t *pk;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
|
Loading…
Reference in New Issue
Block a user