aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection_edge.h
blob: 3c0e30a9735d2ae62d9c85b5f2b52f8542628df6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* Copyright (c) 2001 Matej Pfajfar.
 * Copyright (c) 2001-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
 * Copyright (c) 2007-2013, The Tor Project, Inc. */
/* See LICENSE for licensing information */

/**
 * \file connection_edge.h
 * \brief Header file for connection_edge.c.
 **/

#ifndef TOR_CONNECTION_EDGE_H
#define TOR_CONNECTION_EDGE_H

#include "testsupport.h"

#define connection_mark_unattached_ap(conn, endreason) \
  connection_mark_unattached_ap_((conn), (endreason), __LINE__, SHORT_FILE__)

MOCK_DECL(void,connection_mark_unattached_ap_,
          (entry_connection_t *conn, int endreason,
           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);
int connection_edge_flushed_some(edge_connection_t *conn);
int connection_edge_finished_flushing(edge_connection_t *conn);
int connection_edge_finished_connecting(edge_connection_t *conn);

void connection_ap_about_to_close(entry_connection_t *edge_conn);
void connection_exit_about_to_close(edge_connection_t *edge_conn);

int connection_ap_handshake_send_begin(entry_connection_t *ap_conn);
int connection_ap_handshake_send_resolve(entry_connection_t *ap_conn);

entry_connection_t  *connection_ap_make_link(connection_t *partner,
                                            char *address, uint16_t port,
                                            const char *digest,
                                            int session_group,
                                            int isolation_flags,
                                            int use_begindir, int want_onehop);
void connection_ap_handshake_socks_reply(entry_connection_t *conn, char *reply,
                                         size_t replylen,
                                         int endreason);
MOCK_DECL(void,connection_ap_handshake_socks_resolved,
          (entry_connection_t *conn,
           int answer_type,
           size_t answer_len,
           const uint8_t *answer,
           int ttl,
           time_t expires));
void connection_ap_handshake_socks_resolved_addr(entry_connection_t *conn,
                                                 const tor_addr_t *answer,
                                                 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);
int connection_ap_can_use_exit(const entry_connection_t *conn,
                               const node_t *exit);
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);
int connection_ap_detach_retriable(entry_connection_t *conn,
                                   origin_circuit_t *circ,
                                   int reason);
int connection_ap_process_transparent(entry_connection_t *conn);

int address_is_invalid_destination(const char *address, int client);

int connection_ap_rewrite_and_attach_if_allowed(entry_connection_t *conn,
                                                origin_circuit_t *circ,
                                                crypt_path_t *cpath);
int connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
                                               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;
hostname_type_t parse_extended_hostname(char *address);

#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
int get_pf_socket(void);
#endif

int connection_edge_compatible_with_circuit(const entry_connection_t *conn,
                                            const origin_circuit_t *circ);
int connection_edge_update_circuit_isolation(const entry_connection_t *conn,
                                             origin_circuit_t *circ,
                                             int dry_run);
void circuit_clear_isolation(origin_circuit_t *circ);
streamid_t get_unique_stream_id_by_circ(origin_circuit_t *circ);

/** @name Begin-cell flags
 *
 * These flags are used in RELAY_BEGIN cells to change the default behavior
 * of the cell.
 *
 * @{
 **/
/** When this flag is set, the client is willing to get connected to IPv6
 * addresses */
#define BEGIN_FLAG_IPV6_OK        (1u<<0)
/** When this flag is set, the client DOES NOT support connecting to IPv4
 * addresses.  (The sense of this flag is inverted from IPV6_OK, so that the
 * old default behavior of Tor is equivalent to having all flags set to 0.)
 **/
#define BEGIN_FLAG_IPV4_NOT_OK    (1u<<1)
/** When this flag is set, if we find both an IPv4 and an IPv6 address,
 * we use the IPv6 address.  Otherwise we use the IPv4 address. */
#define BEGIN_FLAG_IPV6_PREFERRED (1u<<2)
/**@}*/

#ifdef CONNECTION_EDGE_PRIVATE

/** A parsed BEGIN or BEGIN_DIR cell */
typedef struct begin_cell_t {
  /** The address the client has asked us to connect to, or NULL if this is
   * a BEGIN_DIR cell*/
  char *address;
  /** The flags specified in the BEGIN cell's body.  One or more of
   * BEGIN_FLAG_*. */
  uint32_t flags;
  /** The client's requested port. */
  uint16_t port;
  /** The client's requested Stream ID */
  uint16_t stream_id;
  /** True iff this is a BEGIN_DIR cell. */
  unsigned is_begindir : 1;
} begin_cell_t;

STATIC int begin_cell_parse(const cell_t *cell, begin_cell_t *bcell,
                     uint8_t *end_reason_out);
STATIC int connected_cell_format_payload(uint8_t *payload_out,
                                  const tor_addr_t *addr,
                                  uint32_t ttl);
#endif

#endif