diff options
author | Roger Dingledine <arma@torproject.org> | 2004-04-01 21:32:01 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2004-04-01 21:32:01 +0000 |
commit | 64cb3a027f0ed4823945c4daa086295120a2c18f (patch) | |
tree | 3fbe0d75651dcec989b2bca7fe2a036489ea50f8 /src | |
parent | 05b99bcf7dad3be0c205d813269e21080a1d5373 (diff) | |
download | tor-64cb3a027f0ed4823945c4daa086295120a2c18f.tar tor-64cb3a027f0ed4823945c4daa086295120a2c18f.tar.gz |
teach directory servers to handle renddesc responses
svn:r1434
Diffstat (limited to 'src')
-rw-r--r-- | src/or/directory.c | 84 | ||||
-rw-r--r-- | src/or/main.c | 2 | ||||
-rw-r--r-- | src/or/or.h | 22 |
3 files changed, 72 insertions, 36 deletions
diff --git a/src/or/directory.c b/src/or/directory.c index 06f49b692..c953c6f06 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -24,11 +24,11 @@ void directory_initiate_command(routerinfo_t *router, int purpose, if(purpose == DIR_PURPOSE_FETCH_DIR) 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"); if(purpose == DIR_PURPOSE_UPLOAD_DIR) 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"); 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); connection_write_to_buf(tmp, strlen(tmp), conn); break; - case DIR_PURPOSE_FETCH_HIDSERV: + case DIR_PURPOSE_FETCH_RENDDESC: 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); connection_write_to_buf(tmp, strlen(tmp), conn); break; - case DIR_PURPOSE_UPLOAD_HIDSERV: + case DIR_PURPOSE_UPLOAD_RENDDESC: assert(payload); snprintf(tmp, sizeof(tmp), "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) { - char *directory; + char *body; char *headers; - int dir_len=0; + int body_len=0; int status_code; 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, &headers, MAX_HEADERS_SIZE, - &directory, &dir_len, MAX_DIR_SIZE)) { + &body, &body_len, MAX_DIR_SIZE)) { case -1: /* overflow */ log_fn(LOG_WARN,"'fetch' response too large. Failing."); 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) { log_fn(LOG_WARN,"Unparseable headers. Closing."); - free(directory); free(headers); + free(body); free(headers); connection_mark_for_close(conn,0); return -1; } if(conn->purpose == DIR_PURPOSE_FETCH_DIR) { /* fetch/process the directory to learn about new routers. */ - log_fn(LOG_INFO,"Received directory (size %d):\n%s", dir_len, directory); - if(status_code == 503 || dir_len == 0) { + log_fn(LOG_INFO,"Received directory (size %d):\n%s", body_len, body); + if(status_code == 503 || body_len == 0) { log_fn(LOG_INFO,"Empty directory. Ignoring."); - free(directory); free(headers); + free(body); free(headers); connection_mark_for_close(conn,0); return 0; } if(status_code != 200) { log_fn(LOG_WARN,"Received http status code %d from dirserver. Failing.", status_code); - free(directory); free(headers); + free(body); free(headers); connection_mark_for_close(conn,0); 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."); } else { 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 */ router_retry_connections(); } - free(directory); free(headers); - connection_mark_for_close(conn,0); - return 0; } if(conn->purpose == DIR_PURPOSE_UPLOAD_DIR) { switch(status_code) { 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; 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; 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?"); @@ -260,21 +263,46 @@ int connection_dir_process_inbuf(connection_t *conn) { log_fn(LOG_WARN,"http status %d response unrecognized.", status_code); break; } - free(directory); free(headers); - connection_mark_for_close(conn,0); - return 0; } - if(conn->purpose == DIR_PURPOSE_FETCH_HIDSERV) { - - + 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_HIDSERV) { - - + 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; + } } - assert(0); /* never reached */ + free(body); free(headers); + connection_mark_for_close(conn,0); + return 0; } if(conn->state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) { diff --git a/src/or/main.c b/src/or/main.c index 76d9bc743..38cf93a96 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -283,7 +283,7 @@ void directory_has_arrived(void) { /* just for testing */ 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 */ diff --git a/src/or/or.h b/src/or/or.h index f93b96edb..ceea9e1eb 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -170,6 +170,11 @@ #define AP_CONN_STATE_OPEN 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_CONNECTING 1 #define DIR_CONN_STATE_CLIENT_SENDING 2 @@ -180,9 +185,9 @@ #define _DIR_PURPOSE_MIN 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_HIDSERV 4 +#define DIR_PURPOSE_UPLOAD_RENDDESC 4 #define DIR_PURPOSE_SERVER 5 #define _DIR_PURPOSE_MAX 5 @@ -235,6 +240,9 @@ #define END_STREAM_REASON_TIMEOUT 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 */ #define CLOSE_REASON_UNUSED_OR_CONN 100 @@ -343,7 +351,7 @@ struct connection_t { uint8_t type; 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 * the bandwidth throttler allows it? */ @@ -391,6 +399,9 @@ struct connection_t { * 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: */ uint16_t stream_id; 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]; /* 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]; @@ -999,9 +1010,6 @@ void rep_hist_dump_stats(time_t now, int severity); /********************************* rendcommon.c ***************************/ -/* length of 'y' portion of 'y.onion' URL. */ -#define REND_SERVICE_ID_LEN 16 - typedef struct rend_service_descriptor_t { crypto_pk_env_t *pk; time_t timestamp; |