2010-07-22 10:43:02 +02:00
|
|
|
/* Copyright (c) 2001 Matej Pfajfar.
|
|
|
|
* Copyright (c) 2001-2004, Roger Dingledine.
|
|
|
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
2012-06-05 02:58:17 +02:00
|
|
|
* Copyright (c) 2007-2012, The Tor Project, Inc. */
|
2010-07-22 10:43:02 +02:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \file connection_edge.h
|
|
|
|
* \brief Header file for connection_edge.c.
|
|
|
|
**/
|
|
|
|
|
2012-10-12 18:13:10 +02:00
|
|
|
#ifndef TOR_CONNECTION_EDGE_H
|
|
|
|
#define TOR_CONNECTION_EDGE_H
|
2010-07-22 10:43:02 +02:00
|
|
|
|
|
|
|
#define connection_mark_unattached_ap(conn, endreason) \
|
2012-10-12 18:22:13 +02:00
|
|
|
connection_mark_unattached_ap_((conn), (endreason), __LINE__, SHORT_FILE__)
|
2010-07-22 10:43:02 +02:00
|
|
|
|
2012-10-12 18:22:13 +02:00
|
|
|
void connection_mark_unattached_ap_(entry_connection_t *conn, int endreason,
|
2010-07-22 10:43:02 +02:00
|
|
|
int line, const char *file);
|
|
|
|
int connection_edge_reached_eof(edge_connection_t *conn);
|
|
|
|
int connection_edge_process_inbuf(edge_connection_t *conn,
|
|
|
|
int package_partial);
|
|
|
|
int connection_edge_destroy(circid_t circ_id, edge_connection_t *conn);
|
|
|
|
int connection_edge_end(edge_connection_t *conn, uint8_t reason);
|
|
|
|
int connection_edge_end_errno(edge_connection_t *conn);
|
2011-03-14 22:48:45 +01:00
|
|
|
int connection_edge_flushed_some(edge_connection_t *conn);
|
2010-07-22 10:43:02 +02:00
|
|
|
int connection_edge_finished_flushing(edge_connection_t *conn);
|
|
|
|
int connection_edge_finished_connecting(edge_connection_t *conn);
|
|
|
|
|
2011-07-20 18:55:42 +02:00
|
|
|
void connection_ap_about_to_close(entry_connection_t *edge_conn);
|
2011-06-22 19:57:19 +02:00
|
|
|
void connection_exit_about_to_close(edge_connection_t *edge_conn);
|
|
|
|
|
2011-07-20 18:55:42 +02:00
|
|
|
int connection_ap_handshake_send_begin(entry_connection_t *ap_conn);
|
|
|
|
int connection_ap_handshake_send_resolve(entry_connection_t *ap_conn);
|
2010-07-22 10:43:02 +02:00
|
|
|
|
2011-07-20 18:55:42 +02:00
|
|
|
entry_connection_t *connection_ap_make_link(connection_t *partner,
|
2009-08-11 21:16:16 +02:00
|
|
|
char *address, uint16_t port,
|
2010-07-22 10:43:02 +02:00
|
|
|
const char *digest,
|
2011-07-08 21:54:30 +02:00
|
|
|
int session_group,
|
|
|
|
int isolation_flags,
|
2010-07-22 10:43:02 +02:00
|
|
|
int use_begindir, int want_onehop);
|
2011-07-20 18:55:42 +02:00
|
|
|
void connection_ap_handshake_socks_reply(entry_connection_t *conn, char *reply,
|
2010-07-22 10:43:02 +02:00
|
|
|
size_t replylen,
|
|
|
|
int endreason);
|
2011-07-20 18:55:42 +02:00
|
|
|
void connection_ap_handshake_socks_resolved(entry_connection_t *conn,
|
2010-07-22 10:43:02 +02:00
|
|
|
int answer_type,
|
|
|
|
size_t answer_len,
|
2010-12-16 04:47:28 +01:00
|
|
|
const uint8_t *answer,
|
2010-07-22 10:43:02 +02:00
|
|
|
int ttl,
|
|
|
|
time_t expires);
|
|
|
|
|
|
|
|
int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
|
|
|
|
int connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ);
|
|
|
|
void connection_exit_connect(edge_connection_t *conn);
|
|
|
|
int connection_edge_is_rendezvous_stream(edge_connection_t *conn);
|
2011-07-20 18:55:42 +02:00
|
|
|
int connection_ap_can_use_exit(const entry_connection_t *conn,
|
2011-04-27 20:36:30 +02:00
|
|
|
const node_t *exit);
|
2010-07-22 10:43:02 +02:00
|
|
|
void connection_ap_expire_beginning(void);
|
|
|
|
void connection_ap_attach_pending(void);
|
|
|
|
void connection_ap_fail_onehop(const char *failed_digest,
|
|
|
|
cpath_build_state_t *build_state);
|
|
|
|
void circuit_discard_optional_exit_enclaves(extend_info_t *info);
|
2011-07-20 18:55:42 +02:00
|
|
|
int connection_ap_detach_retriable(entry_connection_t *conn,
|
2010-07-22 10:43:02 +02:00
|
|
|
origin_circuit_t *circ,
|
|
|
|
int reason);
|
2011-07-20 18:55:42 +02:00
|
|
|
int connection_ap_process_transparent(entry_connection_t *conn);
|
2010-07-22 10:43:02 +02:00
|
|
|
|
|
|
|
int address_is_invalid_destination(const char *address, int client);
|
|
|
|
|
2011-07-20 18:55:42 +02:00
|
|
|
int connection_ap_rewrite_and_attach_if_allowed(entry_connection_t *conn,
|
2010-08-06 21:29:15 +02:00
|
|
|
origin_circuit_t *circ,
|
|
|
|
crypt_path_t *cpath);
|
2011-07-20 18:55:42 +02:00
|
|
|
int connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
|
2010-07-22 10:43:02 +02:00
|
|
|
origin_circuit_t *circ,
|
|
|
|
crypt_path_t *cpath);
|
|
|
|
|
|
|
|
/** Possible return values for parse_extended_hostname. */
|
|
|
|
typedef enum hostname_type_t {
|
|
|
|
NORMAL_HOSTNAME, ONION_HOSTNAME, EXIT_HOSTNAME, BAD_HOSTNAME
|
|
|
|
} hostname_type_t;
|
2012-05-11 23:00:41 +02:00
|
|
|
hostname_type_t parse_extended_hostname(char *address);
|
2010-07-22 10:43:02 +02:00
|
|
|
|
|
|
|
#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
|
|
|
|
int get_pf_socket(void);
|
|
|
|
#endif
|
|
|
|
|
2011-07-20 18:55:42 +02:00
|
|
|
int connection_edge_compatible_with_circuit(const entry_connection_t *conn,
|
2011-07-06 22:03:47 +02:00
|
|
|
const origin_circuit_t *circ);
|
2011-07-20 18:55:42 +02:00
|
|
|
int connection_edge_update_circuit_isolation(const entry_connection_t *conn,
|
2011-07-06 22:03:47 +02:00
|
|
|
origin_circuit_t *circ,
|
|
|
|
int dry_run);
|
Launch sufficient circuits to satisfy pending isolated streams
Our old "do we need to launch a circuit for stream S" logic was,
more or less, that if we had a pending circuit that could handle S,
we didn't need to launch a new one.
But now that we have streams isolated from one another, we need
something stronger here: It's possible that some pending C can
handle either S1 or S2, but not both.
This patch reuses the existing isolation logic for a simple
solution: when we decide during circuit launching that some pending
C would satisfy stream S1, we "hypothetically" mark C as though S1
had been connected to it. Now if S2 is incompatible with S1, it
won't be something that can attach to C, and so we'll launch a new
stream.
When the circuit becomes OPEN for the first time (with no streams
attached to it), we reset the circuit's isolation status. I'm not
too sure about this part: I wanted some way to be sure that, if all
streams that would have used a circuit die before the circuit is
done, the circuit can still get used. But I worry that this
approach could also lead to us launching too many circuits. Careful
thought needed here.
2011-07-07 16:40:23 +02:00
|
|
|
void circuit_clear_isolation(origin_circuit_t *circ);
|
2011-07-06 22:03:47 +02:00
|
|
|
|
Revise the DNS subsystem to handle IPv6 exits.
Now, every cached_resolve_t can remember an IPv4 result *and* an IPv6
result. As a light protection against timing-based distinguishers for
IPv6 users (and against complexity!), every forward request generates
an IPv4 *and* an IPv6 request, assuming that we're an IPv6 exit. Once
we have answers or errors for both, we act accordingly.
This patch additionally makes some useful refactorings in the dns.c
code, though there is quite a bit more of useful refactoring that could
be done.
Additionally, have a new interface for the argument passed to the
evdns_callback function. Previously, it was just the original address
we were resolving. But it turns out that, on error, evdns doesn't
tell you the type of the query, so on a failure we didn't know whether
IPv4 or IPv6 queries were failing.
The new convention is to have the first byte of that argument include
the query type. I've refactored the code a bit to make that simpler.
2012-11-05 19:26:29 +01:00
|
|
|
/* DOCDOC*/
|
2012-10-25 06:20:41 +02:00
|
|
|
#define BEGIN_FLAG_IPV6_OK (1u<<0)
|
|
|
|
#define BEGIN_FLAG_IPV4_NOT_OK (1u<<1)
|
|
|
|
#define BEGIN_FLAG_IPV6_PREFERRED (1u<<2)
|
|
|
|
|
Revise the DNS subsystem to handle IPv6 exits.
Now, every cached_resolve_t can remember an IPv4 result *and* an IPv6
result. As a light protection against timing-based distinguishers for
IPv6 users (and against complexity!), every forward request generates
an IPv4 *and* an IPv6 request, assuming that we're an IPv6 exit. Once
we have answers or errors for both, we act accordingly.
This patch additionally makes some useful refactorings in the dns.c
code, though there is quite a bit more of useful refactoring that could
be done.
Additionally, have a new interface for the argument passed to the
evdns_callback function. Previously, it was just the original address
we were resolving. But it turns out that, on error, evdns doesn't
tell you the type of the query, so on a failure we didn't know whether
IPv4 or IPv6 queries were failing.
The new convention is to have the first byte of that argument include
the query type. I've refactored the code a bit to make that simpler.
2012-11-05 19:26:29 +01:00
|
|
|
#ifdef CONNECTION_EDGE_PRIVATE
|
|
|
|
|
2012-10-22 17:28:37 +02:00
|
|
|
/*DOCDOC*/
|
|
|
|
typedef struct begin_cell_t {
|
|
|
|
char *address;
|
|
|
|
uint32_t flags;
|
|
|
|
uint16_t port;
|
|
|
|
uint16_t stream_id;
|
|
|
|
unsigned is_begindir : 1;
|
|
|
|
} begin_cell_t;
|
|
|
|
|
|
|
|
int begin_cell_parse(const cell_t *cell, begin_cell_t *bcell,
|
|
|
|
uint8_t *end_reason_out);
|
2012-10-31 23:27:48 +01:00
|
|
|
|
2012-10-22 17:28:37 +02:00
|
|
|
#endif
|
|
|
|
|
2010-07-22 10:43:02 +02:00
|
|
|
#endif
|
|
|
|
|