23 #include "core/or/or_circuit_st.h"
114 const char *resource)
121 && resource && !strcmp(resource,
"authority.z")) {
150 log_warn(
LD_BUG,
"Called with dir_purpose=%d, router_purpose=%d",
151 dir_purpose, router_purpose);
168 if (smartlist_len(lst)) {
171 result = tor_strdup(
"[Not an authority]");
225 if (linked_conn == NULL || linked_conn->
magic != EDGE_CONNECTION_MAGIC ||
227 log_debug(
LD_DIR,
"Directory connection is not anonymous: "
228 "not linked to edge");
237 log_debug(
LD_DIR,
"Directory connection is not anonymous: "
238 "not on OR circuit");
247 log_debug(
LD_DIR,
"Directory connection is not anonymous: "
248 "circuit marked for close");
255 if (BUG(CONST_TO_OR_CIRCUIT(circ)->p_chan == NULL)) {
256 log_debug(
LD_DIR,
"Directory connection is not anonymous: "
257 "no p_chan on circuit");
273 const char *
command, *end_of_command;
274 char *s, *start, *tmp;
294 tmp = strchr(tmp+3,
'/');
295 if (tmp && tmp < s) {
296 log_debug(
LD_DIR,
"Skipping over 'http[s]://hostname/' string");
308 if (2 !=
tor_sscanf(e,
"HTTP/1.%u%c", &minor_ver, &ch)) {
315 *url_out = tor_memdup_nulterm(start, s-start);
316 *command_out = tor_memdup_nulterm(
command, end_of_command -
command);
327 const char *cp = headers;
332 if ((eos = strchr(cp,
'\r')))
333 return tor_strndup(cp, eos-cp);
335 return tor_strdup(cp);
337 cp = strchr(cp,
'\n');
364 char datestr[RFC1123_TIME_LEN+1];
369 while (TOR_ISSPACE(*headers)) headers++;
371 if (
tor_sscanf(headers,
"HTTP/1.%u %u", &n1, &n2) < 2 ||
372 (n1 != 0 && n1 != 1) ||
373 (n2 < 100 || n2 >= 600)) {
381 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
386 smartlist_get(parsed_headers, 0),
387 " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
388 tor_assert(smartlist_len(status_line_elements) <= 3);
389 if (smartlist_len(status_line_elements) == 3) {
390 *reason = smartlist_get(status_line_elements, 2);
391 smartlist_set(status_line_elements, 2, NULL);
394 smartlist_free(status_line_elements);
400 strlcpy(datestr, s+6,
sizeof(datestr));
409 const char *enc = NULL;
416 *compression = NO_METHOD;
420 if (*compression == UNKNOWN_METHOD)
421 log_info(
LD_HTTP,
"Unrecognized content encoding: %s. Trying to deal.",
426 smartlist_free(parsed_headers);
435 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
437 #define MAX_VOTE_DL_SIZE (MAX_DIRECTORY_OBJECT_SIZE * 5)
458 connection_mark_for_close(
TO_CONN(conn));
468 if (connection_get_inbuf_len(
TO_CONN(conn)) > max_size) {
470 "Too much data received from %s: "
471 "denial of service attempt, or you need to upgrade?",
473 connection_mark_for_close(
TO_CONN(conn));
478 log_debug(
LD_HTTP,
"Got data, not eof. Leaving on inbuf.");
521 switch (conn->base_.
state) {
524 log_debug(
LD_DIR,
"client finished sending command.");
529 log_warn(
LD_BUG,
"Emptied a dirserv buffer, but it's still spooling!");
530 connection_mark_for_close(
TO_CONN(conn));
532 log_debug(
LD_DIRSERV,
"Finished writing server response. Closing.");
533 connection_mark_for_close(
TO_CONN(conn));
537 log_warn(
LD_BUG,
"called in unexpected state %d.",
555 log_debug(
LD_HTTP,
"Dir connection to %s established.",
588 if (smartlist_len(pairs_tmp)) {
589 char *last = smartlist_get(pairs_tmp,smartlist_len(pairs_tmp)-1);
590 size_t last_len = strlen(last);
591 if (last_len > 2 && !strcmp(last+last_len-2,
".z")) {
592 last[last_len-2] =
'\0';
598 "Skipping digest pair %s with non-standard length.",
escaped(cp));
601 "Skipping digest pair %s with missing dash.",
escaped(cp));
608 log_info(
LD_DIR,
"Skipping non-decodable digest pair %s",
escaped(cp));
610 smartlist_add(pairs_result, tor_memdup(&pair,
sizeof(pair)));
614 } SMARTLIST_FOREACH_END(cp);
615 smartlist_free(pairs_tmp);
622 smartlist_free(pairs_result);
644 const int decode_hex = flags & DSR_HEX;
645 const int decode_base64 = flags & DSR_BASE64;
646 const int digests_are_256 = flags & DSR_DIGEST256;
647 const int sort_uniq = flags & DSR_SORT_UNIQ;
650 const int hex_digest_len = digests_are_256 ?
652 const int base64_digest_len = digests_are_256 ?
662 if (smartlist_len(fp_tmp)) {
663 char *last = smartlist_get(fp_tmp,smartlist_len(fp_tmp)-1);
664 size_t last_len = strlen(last);
665 if (last_len > 2 && !strcmp(last+last_len-2,
".z")) {
666 last[last_len-2] =
'\0';
671 if (decode_hex || decode_base64) {
672 const size_t encoded_len = decode_hex ? hex_digest_len : base64_digest_len;
675 for (i = 0; i < smartlist_len(fp_tmp); ++i) {
676 cp = smartlist_get(fp_tmp, i);
677 if (strlen(cp) != encoded_len) {
679 "Skipping digest %s with non-standard length.",
escaped(cp));
683 d = tor_malloc_zero(digest_len);
685 (
base16_decode(d, digest_len, cp, hex_digest_len) != digest_len) :
688 log_info(
LD_DIR,
"Skipping non-decodable digest %s",
escaped(cp));
692 smartlist_set(fp_tmp, i, d);
700 if (decode_hex || decode_base64) {
701 if (digests_are_256) {
714 smartlist_free(fp_tmp);
int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
int channel_is_client(const channel_t *chan)
Header file for channeltls.c.
Header file for circuitlist.c.
#define CIRCUIT_IS_ORIGIN(c)
compress_method_t compression_method_get_by_name(const char *name)
const or_options_t * get_options(void)
tor_cmdline_mode_t command
Header file for config.c.
const char * connection_describe(const connection_t *conn)
const char * connection_describe_peer(const connection_t *conn)
Header file for connection.c.
const edge_connection_t * CONST_TO_EDGE_CONN(const connection_t *c)
Header file for connection_edge.c.
Header file for connection_or.c.
#define BASE64_DIGEST256_LEN
#define HEX_DIGEST256_LEN
#define BASE64_DIGEST_LEN
#define fast_memcmp(a, b, c)
Client/server directory connection structure.
int directory_handle_command(dir_connection_t *conn)
Header file for dircache.c.
void connection_dir_client_request_failed(dir_connection_t *conn)
void connection_dir_client_refetch_hsdesc_if_needed(dir_connection_t *dir_conn)
Header file for dirclient.c.
int connection_dir_finished_flushing(dir_connection_t *conn)
int connection_dir_finished_connecting(dir_connection_t *conn)
int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose, const char *resource)
dir_connection_t * TO_DIR_CONN(connection_t *c)
char * authdir_type_to_string(dirinfo_type_t auth)
int dir_split_resource_into_fingerprint_pairs(const char *res, smartlist_t *pairs_out)
const dir_connection_t * CONST_TO_DIR_CONN(const connection_t *c)
int parse_http_response(const char *headers, int *code, time_t *date, compress_method_t *compression, char **reason)
static int compare_pairs_(const void **a, const void **b)
int connection_dir_is_encrypted(const dir_connection_t *conn)
char * http_get_header(const char *headers, const char *which)
int dir_split_resource_into_fingerprints(const char *resource, smartlist_t *fp_out, int *compressed_out, int flags)
bool connection_dir_is_anonymous(const dir_connection_t *dir_conn)
int parse_http_command(const char *headers, char **command_out, char **url_out)
void connection_dir_about_to_close(dir_connection_t *dir_conn)
#define MAX_DIRECTORY_OBJECT_SIZE
int connection_dir_process_inbuf(dir_connection_t *conn)
Header file for directory.c.
#define DIR_PURPOSE_FETCH_EXTRAINFO
#define DIR_PURPOSE_FETCH_CERTIFICATE
#define DIR_PURPOSE_UPLOAD_HSDESC
#define DIR_PURPOSE_FETCH_MICRODESC
#define DIR_CONN_STATE_CONNECTING
#define DIR_CONN_STATE_CLIENT_FINISHED
#define DIR_CONN_STATE_CLIENT_READING
#define DIR_CONN_STATE_SERVER_WRITING
#define DIR_PURPOSE_UPLOAD_VOTE
#define DIR_CONN_STATE_SERVER_COMMAND_WAIT
#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
#define DIR_PURPOSE_FETCH_CONSENSUS
#define DIR_PURPOSE_SERVER
#define DIR_PURPOSE_FETCH_SERVERDESC
#define DIR_PURPOSE_UPLOAD_SIGNATURES
#define DIR_CONN_STATE_CLIENT_SENDING
#define DIR_PURPOSE_FETCH_STATUS_VOTE
#define DIR_PURPOSE_HAS_FETCHED_HSDESC
#define DIR_PURPOSE_UPLOAD_DIR
#define DIR_PURPOSE_FETCH_HSDESC
Header file for dirserv.c.
Edge-connection structure.
const char * escaped(const char *s)
Header file for fp_pair.c.
Header file for geoip_stats.c.
@ DIRREQ_FLUSHING_DIR_CONN_FINISHED
void geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type, dirreq_state_t new_state)
void tor_free_(void *mem)
Master header file for Tor-specific functionality.
#define DOWNCAST(to, ptr)
Router descriptor structure.
#define ROUTER_PURPOSE_BRIDGE
int tor_sscanf(const char *buf, const char *pattern,...)
void smartlist_sort_digests(smartlist_t *sl)
void smartlist_sort_digests256(smartlist_t *sl)
void smartlist_uniq_digests(smartlist_t *sl)
void smartlist_uniq_digests256(smartlist_t *sl)
void smartlist_uniq_strings(smartlist_t *sl)
void smartlist_sort_strings(smartlist_t *sl)
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
void smartlist_uniq(smartlist_t *sl, int(*compare)(const void **a, const void **b), void(*free_fn)(void *a))
void smartlist_add_all(smartlist_t *s1, const smartlist_t *s2)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
void smartlist_del_keeporder(smartlist_t *sl, int idx)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)
uint16_t marked_for_close
unsigned int inbuf_reached_eof
struct connection_t * linked_conn
uint16_t marked_for_close
unsigned int linked_conn_is_closed
struct circuit_t * on_circuit
int parse_rfc1123_time(const char *buf, time_t *t)
#define tor_assert_nonfatal_unreached()
#define tor_fragile_assert()
int strcasecmpstart(const char *s1, const char *s2)
int strcmpstart(const char *s1, const char *s2)
const char * find_whitespace(const char *s)
const char * eat_whitespace_no_nl(const char *s)