mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
r16409@catbus: nickm | 2007-11-05 10:38:25 -0500
Split handshake state into its own structure. Revise versions and netinfo code to use this structure. svn:r12380
This commit is contained in:
parent
a7993ea2b6
commit
e94fad36ac
8
doc/TODO
8
doc/TODO
@ -24,11 +24,15 @@ Things we'd like to do in 0.2.0.x:
|
|||||||
D 118 if feasible and obvious
|
D 118 if feasible and obvious
|
||||||
D Maintain a skew estimate and use ftime consistently.
|
D Maintain a skew estimate and use ftime consistently.
|
||||||
- 105+TLS, if possible.
|
- 105+TLS, if possible.
|
||||||
- Add a separate handshake structure that handles version negotiation,
|
o Add a separate handshake structure that handles version negotiation,
|
||||||
and stores netinfo data until authentication is done.
|
and stores netinfo data until authentication is done.
|
||||||
- Revise versions and netinfo to use separate structure; make
|
o Revise versions and netinfo to use separate structure; make
|
||||||
act-on-netinfo logic separate so it can get called _after_
|
act-on-netinfo logic separate so it can get called _after_
|
||||||
negotiation.
|
negotiation.
|
||||||
|
- Variable-length cells
|
||||||
|
- Add structure
|
||||||
|
- Add parse logic
|
||||||
|
- Make CERT and VERSIONS variable.
|
||||||
- CERT cells
|
- CERT cells
|
||||||
- functions to parse x509 certs
|
- functions to parse x509 certs
|
||||||
- functions to validate a single x509 cert against a TLS connection
|
- functions to validate a single x509 cert against a TLS connection
|
||||||
|
@ -396,12 +396,14 @@ command_process_versions_cell(cell_t *cell, or_connection_t *conn)
|
|||||||
int highest_supported_version = 0;
|
int highest_supported_version = 0;
|
||||||
const char *cp, *end;
|
const char *cp, *end;
|
||||||
if (conn->link_proto != 0 ||
|
if (conn->link_proto != 0 ||
|
||||||
conn->_base.state != OR_CONN_STATE_WAITING_FOR_VERSIONS) {
|
conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING ||
|
||||||
|
(conn->handshake_state && conn->handshake_state->received_versions)) {
|
||||||
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||||
"Received a VERSIONS cell on a connection with its version "
|
"Received a VERSIONS cell on a connection with its version "
|
||||||
"already set to %d; dropping", (int) conn->link_proto);
|
"already set to %d; dropping", (int) conn->link_proto);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
tor_assert(conn->handshake_state);
|
||||||
versionslen = ntohs(get_uint16(cell->payload));
|
versionslen = ntohs(get_uint16(cell->payload));
|
||||||
end = cell->payload + 2 + versionslen;
|
end = cell->payload + 2 + versionslen;
|
||||||
if (end > cell->payload + CELL_PAYLOAD_SIZE)
|
if (end > cell->payload + CELL_PAYLOAD_SIZE)
|
||||||
@ -416,12 +418,12 @@ command_process_versions_cell(cell_t *cell, or_connection_t *conn)
|
|||||||
if (!highest_supported_version) {
|
if (!highest_supported_version) {
|
||||||
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||||
"Couldn't find a version in common; defaulting to v1.");
|
"Couldn't find a version in common; defaulting to v1.");
|
||||||
/*XXXX020 or just break the connection?*/
|
/*XXXX020 just break the connection?*/
|
||||||
conn->link_proto = 1;
|
conn->link_proto = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
conn->link_proto = highest_supported_version;
|
conn->link_proto = highest_supported_version;
|
||||||
conn->_base.state = OR_CONN_STATE_OPEN;
|
conn->handshake_state->received_versions = 1;
|
||||||
|
|
||||||
if (highest_supported_version >= 2)
|
if (highest_supported_version >= 2)
|
||||||
connection_or_send_netinfo(conn);
|
connection_or_send_netinfo(conn);
|
||||||
@ -438,33 +440,81 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
|
|||||||
const char *cp, *end;
|
const char *cp, *end;
|
||||||
uint8_t n_other_addrs;
|
uint8_t n_other_addrs;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
if (conn->link_proto < 2) {
|
||||||
/*XXXX020 reject duplicate netinfos. */
|
|
||||||
|
|
||||||
if (conn->link_proto < 2 || conn->_base.state != OR_CONN_STATE_OPEN) {
|
|
||||||
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||||
"Received a NETINFO cell on %s connection; dropping.",
|
"Received a NETINFO cell on %s connection; dropping.",
|
||||||
conn->link_proto == 0 ? "non-versioned" : "a v1");
|
conn->link_proto == 0 ? "non-versioned" : "a v1");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING) {
|
||||||
|
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||||
|
"Received a NETINFO cell on a non-handshaking; dropping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tor_assert(conn->handshake_state &&
|
||||||
|
conn->handshake_state->received_versions);
|
||||||
|
if (conn->handshake_state->received_netinfo) {
|
||||||
|
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||||
|
"Received a duplicate NETINFO cell; dropping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Decode the cell. */
|
/* Decode the cell. */
|
||||||
timestamp = ntohl(get_uint32(cell->payload));
|
timestamp = ntohl(get_uint32(cell->payload));
|
||||||
|
if (abs(now - conn->handshake_state->sent_versions_at) < 180) {
|
||||||
|
conn->handshake_state->apparent_skew = now - timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
my_addr_type = (uint8_t) cell->payload[4];
|
my_addr_type = (uint8_t) cell->payload[4];
|
||||||
my_addr_len = (uint8_t) cell->payload[5];
|
my_addr_len = (uint8_t) cell->payload[5];
|
||||||
my_addr_ptr = cell->payload + 6;
|
my_addr_ptr = cell->payload + 6;
|
||||||
/* Possibly learn my address. XXXX020 */
|
|
||||||
end = cell->payload + CELL_PAYLOAD_SIZE;
|
end = cell->payload + CELL_PAYLOAD_SIZE;
|
||||||
cp = cell->payload + 6 + my_addr_len;
|
cp = cell->payload + 6 + my_addr_len;
|
||||||
if (cp >= end) {
|
if (cp >= end) {
|
||||||
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||||
"Address too long in netinfo cell; dropping.");
|
"Address too long in netinfo cell; dropping.");
|
||||||
|
/*XXXX020 reject and break OR conn! */
|
||||||
return;
|
return;
|
||||||
|
} else if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) {
|
||||||
|
conn->handshake_state->my_apparent_addr = ntohl(get_uint32(my_addr_ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n_other_addrs = (uint8_t) *cp++;
|
||||||
|
while (n_other_addrs && cp < end-2) {
|
||||||
|
/* Consider all the other addresses; if any matches, this connection is
|
||||||
|
* "canonical." */
|
||||||
|
uint8_t other_addr_type = (uint8_t) *cp++;
|
||||||
|
uint8_t other_addr_len = (uint8_t) *cp++;
|
||||||
|
if (cp + other_addr_len >= end)
|
||||||
|
break; /*XXXX020 protocol warn. */
|
||||||
|
if (other_addr_type == RESOLVED_TYPE_IPV4 && other_addr_len == 4) {
|
||||||
|
uint32_t addr = ntohl(get_uint32(cp));
|
||||||
|
if (addr == conn->real_addr) {
|
||||||
|
conn->handshake_state->apparently_canonical = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cp += other_addr_len;
|
||||||
|
--n_other_addrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn->handshake_state->received_netinfo = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** DOCDOC Called when we're done authenticating; act on stuff we
|
||||||
|
* learned in netinfo. */
|
||||||
|
void
|
||||||
|
connection_or_act_on_netinfo(or_connection_t *conn)
|
||||||
|
{
|
||||||
|
long delta;
|
||||||
|
if (!conn->handshake_state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tor_assert(conn->handshake_state->authenticated != 0);
|
||||||
|
|
||||||
|
delta = conn->handshake_state->apparent_skew;
|
||||||
/*XXXX020 magic number 3600 */
|
/*XXXX020 magic number 3600 */
|
||||||
if (abs(timestamp - now) > 3600 &&
|
if (abs(delta) > 3600 &&
|
||||||
router_get_by_digest(conn->identity_digest)) {
|
router_get_by_digest(conn->identity_digest)) {
|
||||||
long delta = now - timestamp;
|
|
||||||
char dbuf[64];
|
char dbuf[64];
|
||||||
/*XXXX020 not always warn!*/
|
/*XXXX020 not always warn!*/
|
||||||
format_time_interval(dbuf, sizeof(dbuf), delta);
|
format_time_interval(dbuf, sizeof(dbuf), delta);
|
||||||
@ -480,23 +530,9 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
|
|||||||
delta, conn->_base.address, conn->_base.port);
|
delta, conn->_base.address, conn->_base.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
n_other_addrs = (uint8_t) *cp++;
|
/* XXX020 possibly, learn my address from my_apparent_addr */
|
||||||
while (n_other_addrs && cp < end-2) {
|
|
||||||
/* Consider all the other addresses; if any matches, this connection is
|
|
||||||
* "canonical." */
|
|
||||||
uint8_t other_addr_type = (uint8_t) *cp++;
|
|
||||||
uint8_t other_addr_len = (uint8_t) *cp++;
|
|
||||||
if (cp + other_addr_len >= end)
|
|
||||||
break; /*XXXX020 protocol warn. */
|
|
||||||
if (other_addr_type == RESOLVED_TYPE_IPV4 && other_addr_len == 4) {
|
|
||||||
uint32_t addr = ntohl(get_uint32(cp));
|
|
||||||
if (addr == conn->real_addr) {
|
|
||||||
conn->is_canonical = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cp += other_addr_len;
|
|
||||||
--n_other_addrs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (conn->handshake_state->apparently_canonical) {
|
||||||
|
conn->is_canonical = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -88,7 +88,8 @@ conn_state_to_string(int type, int state)
|
|||||||
case OR_CONN_STATE_CONNECTING: return "connect()ing";
|
case OR_CONN_STATE_CONNECTING: return "connect()ing";
|
||||||
case OR_CONN_STATE_PROXY_FLUSHING: return "proxy flushing";
|
case OR_CONN_STATE_PROXY_FLUSHING: return "proxy flushing";
|
||||||
case OR_CONN_STATE_PROXY_READING: return "proxy reading";
|
case OR_CONN_STATE_PROXY_READING: return "proxy reading";
|
||||||
case OR_CONN_STATE_HANDSHAKING: return "handshaking";
|
case OR_CONN_STATE_TLS_HANDSHAKING: return "handshaking (TLS)";
|
||||||
|
case OR_CONN_STATE_OR_HANDSHAKING: return "handshaking (Tor)";
|
||||||
case OR_CONN_STATE_OPEN: return "open";
|
case OR_CONN_STATE_OPEN: return "open";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -314,7 +315,10 @@ _connection_free(connection_t *conn)
|
|||||||
tor_tls_free(or_conn->tls);
|
tor_tls_free(or_conn->tls);
|
||||||
or_conn->tls = NULL;
|
or_conn->tls = NULL;
|
||||||
}
|
}
|
||||||
|
if (or_conn->handshake_state) {
|
||||||
|
or_handshake_state_free(or_conn->handshake_state);
|
||||||
|
or_conn->handshake_state = NULL;
|
||||||
|
}
|
||||||
tor_free(or_conn->nickname);
|
tor_free(or_conn->nickname);
|
||||||
}
|
}
|
||||||
if (CONN_IS_EDGE(conn)) {
|
if (CONN_IS_EDGE(conn)) {
|
||||||
@ -1879,7 +1883,7 @@ connection_read_to_buf(connection_t *conn, int *max_to_read)
|
|||||||
conn->state > OR_CONN_STATE_PROXY_READING) {
|
conn->state > OR_CONN_STATE_PROXY_READING) {
|
||||||
int pending;
|
int pending;
|
||||||
or_connection_t *or_conn = TO_OR_CONN(conn);
|
or_connection_t *or_conn = TO_OR_CONN(conn);
|
||||||
if (conn->state == OR_CONN_STATE_HANDSHAKING) {
|
if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING) {
|
||||||
/* continue handshaking even if global token bucket is empty */
|
/* continue handshaking even if global token bucket is empty */
|
||||||
return connection_tls_continue_handshake(or_conn);
|
return connection_tls_continue_handshake(or_conn);
|
||||||
}
|
}
|
||||||
@ -2100,7 +2104,7 @@ connection_handle_write(connection_t *conn, int force)
|
|||||||
if (connection_speaks_cells(conn) &&
|
if (connection_speaks_cells(conn) &&
|
||||||
conn->state > OR_CONN_STATE_PROXY_READING) {
|
conn->state > OR_CONN_STATE_PROXY_READING) {
|
||||||
or_connection_t *or_conn = TO_OR_CONN(conn);
|
or_connection_t *or_conn = TO_OR_CONN(conn);
|
||||||
if (conn->state == OR_CONN_STATE_HANDSHAKING) {
|
if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING) {
|
||||||
connection_stop_writing(conn);
|
connection_stop_writing(conn);
|
||||||
if (connection_tls_continue_handshake(or_conn) < 0) {
|
if (connection_tls_continue_handshake(or_conn) < 0) {
|
||||||
/* Don't flush; connection is dead. */
|
/* Don't flush; connection is dead. */
|
||||||
|
@ -524,7 +524,7 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
|
|||||||
int
|
int
|
||||||
connection_tls_start_handshake(or_connection_t *conn, int receiving)
|
connection_tls_start_handshake(or_connection_t *conn, int receiving)
|
||||||
{
|
{
|
||||||
conn->_base.state = OR_CONN_STATE_HANDSHAKING;
|
conn->_base.state = OR_CONN_STATE_TLS_HANDSHAKING;
|
||||||
conn->tls = tor_tls_new(conn->_base.s, receiving);
|
conn->tls = tor_tls_new(conn->_base.s, receiving);
|
||||||
if (!conn->tls) {
|
if (!conn->tls) {
|
||||||
log_warn(LD_BUG,"tor_tls_new failed. Closing.");
|
log_warn(LD_BUG,"tor_tls_new failed. Closing.");
|
||||||
@ -739,12 +739,22 @@ connection_tls_finish_handshake(or_connection_t *conn)
|
|||||||
conn->link_proto = 1;
|
conn->link_proto = 1;
|
||||||
return connection_or_set_state_open(conn);
|
return connection_or_set_state_open(conn);
|
||||||
} else {
|
} else {
|
||||||
/*XXXX020 actually, we'll need to send some kind of authentication. */
|
conn->_base.state = OR_CONN_STATE_OR_HANDSHAKING;
|
||||||
conn->_base.state = OR_CONN_STATE_WAITING_FOR_VERSIONS;
|
conn->handshake_state = tor_malloc_zero(sizeof(or_handshake_state_t));
|
||||||
return connection_or_send_versions(conn);
|
return connection_or_send_versions(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
void
|
||||||
|
or_handshake_state_free(or_handshake_state_t *state)
|
||||||
|
{
|
||||||
|
tor_assert(state);
|
||||||
|
if (state->signing_key)
|
||||||
|
crypto_free_pk_env(state->signing_key);
|
||||||
|
tor_free(state);
|
||||||
|
}
|
||||||
|
|
||||||
/**DOCDOC*/
|
/**DOCDOC*/
|
||||||
int
|
int
|
||||||
connection_or_set_state_open(or_connection_t *conn)
|
connection_or_set_state_open(or_connection_t *conn)
|
||||||
@ -858,6 +868,8 @@ connection_or_send_versions(or_connection_t *conn)
|
|||||||
uint8_t versions[] = { 1 };
|
uint8_t versions[] = { 1 };
|
||||||
int n_versions = sizeof(versions) / sizeof(uint8_t);
|
int n_versions = sizeof(versions) / sizeof(uint8_t);
|
||||||
int i;
|
int i;
|
||||||
|
tor_assert(conn->handshake_state &&
|
||||||
|
!conn->handshake_state->sent_versions_at);
|
||||||
memset(&cell, 0, sizeof(cell_t));
|
memset(&cell, 0, sizeof(cell_t));
|
||||||
cell.command = CELL_VERSIONS;
|
cell.command = CELL_VERSIONS;
|
||||||
set_uint16(cell.payload, htons(n_versions));
|
set_uint16(cell.payload, htons(n_versions));
|
||||||
@ -868,6 +880,7 @@ connection_or_send_versions(or_connection_t *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
connection_or_write_cell_to_buf(&cell, conn);
|
connection_or_write_cell_to_buf(&cell, conn);
|
||||||
|
conn->handshake_state->sent_versions_at = time(NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
35
src/or/or.h
35
src/or/or.h
@ -235,10 +235,11 @@ typedef enum {
|
|||||||
/** State for a connection to an OR: waiting for proxy response. */
|
/** State for a connection to an OR: waiting for proxy response. */
|
||||||
#define OR_CONN_STATE_PROXY_READING 3
|
#define OR_CONN_STATE_PROXY_READING 3
|
||||||
/** State for a connection to an OR: SSL is handshaking, not done yet. */
|
/** State for a connection to an OR: SSL is handshaking, not done yet. */
|
||||||
#define OR_CONN_STATE_HANDSHAKING 4
|
#define OR_CONN_STATE_TLS_HANDSHAKING 4
|
||||||
/** State for a connection to an OR: We sent a VERSIONS cell and want one back
|
/** State for a connection to an OR: We're done with our SSL handshake, but we
|
||||||
|
* haven't yet negotiated link protocol versions and finished authenticating.
|
||||||
*/
|
*/
|
||||||
#define OR_CONN_STATE_WAITING_FOR_VERSIONS 5
|
#define OR_CONN_STATE_OR_HANDSHAKING 5
|
||||||
/** State for a connection to an OR: Ready to send/receive cells. */
|
/** State for a connection to an OR: Ready to send/receive cells. */
|
||||||
#define OR_CONN_STATE_OPEN 6
|
#define OR_CONN_STATE_OPEN 6
|
||||||
#define _OR_CONN_STATE_MAX 6
|
#define _OR_CONN_STATE_MAX 6
|
||||||
@ -857,6 +858,29 @@ typedef struct connection_t {
|
|||||||
|
|
||||||
} connection_t;
|
} connection_t;
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
typedef struct or_handshake_state_t {
|
||||||
|
time_t sent_versions_at;
|
||||||
|
unsigned int received_versions : 1;
|
||||||
|
unsigned int received_netinfo : 1;
|
||||||
|
unsigned int received_certs : 1;
|
||||||
|
unsigned int authenticated : 1;
|
||||||
|
|
||||||
|
/* from tls */
|
||||||
|
char client_random[32];
|
||||||
|
char server_random[32];
|
||||||
|
|
||||||
|
/* from netinfo */
|
||||||
|
long apparent_skew;
|
||||||
|
uint32_t my_apparent_addr;
|
||||||
|
unsigned int apparently_canonical;
|
||||||
|
|
||||||
|
/* from certs */
|
||||||
|
char cert_id_digest[DIGEST_LEN];
|
||||||
|
crypto_pk_env_t *signing_key;
|
||||||
|
|
||||||
|
} or_handshake_state_t;
|
||||||
|
|
||||||
/** Subtype of connection_t for an "OR connection" -- that is, one that speaks
|
/** Subtype of connection_t for an "OR connection" -- that is, one that speaks
|
||||||
* cells over TLS. */
|
* cells over TLS. */
|
||||||
typedef struct or_connection_t {
|
typedef struct or_connection_t {
|
||||||
@ -878,13 +902,14 @@ typedef struct or_connection_t {
|
|||||||
circ_id_type_t circ_id_type:2; /**< When we send CREATE cells along this
|
circ_id_type_t circ_id_type:2; /**< When we send CREATE cells along this
|
||||||
* connection, which half of the space should
|
* connection, which half of the space should
|
||||||
* we use? */
|
* we use? */
|
||||||
unsigned int is_canonical; /**< DOCDOC */
|
unsigned int is_canonical:1; /**< DOCDOC */
|
||||||
uint8_t link_proto; /**< What protocol version are we using? 0 for
|
uint8_t link_proto; /**< What protocol version are we using? 0 for
|
||||||
* "none negotiated yet." */
|
* "none negotiated yet." */
|
||||||
uint16_t next_circ_id; /**< Which circ_id do we try to use next on
|
uint16_t next_circ_id; /**< Which circ_id do we try to use next on
|
||||||
* this connection? This is always in the
|
* this connection? This is always in the
|
||||||
* range 0..1<<15-1. */
|
* range 0..1<<15-1. */
|
||||||
|
|
||||||
|
or_handshake_state_t *handshake_state;/**< DOCDOC */
|
||||||
time_t timestamp_lastempty; /**< When was the outbuf last completely empty?*/
|
time_t timestamp_lastempty; /**< When was the outbuf last completely empty?*/
|
||||||
|
|
||||||
/* bandwidth* and read_bucket only used by ORs in OPEN state: */
|
/* bandwidth* and read_bucket only used by ORs in OPEN state: */
|
||||||
@ -2517,6 +2542,7 @@ int connection_ap_handshake_attach_circuit(edge_connection_t *conn);
|
|||||||
/********************************* command.c ***************************/
|
/********************************* command.c ***************************/
|
||||||
|
|
||||||
void command_process_cell(cell_t *cell, or_connection_t *conn);
|
void command_process_cell(cell_t *cell, or_connection_t *conn);
|
||||||
|
void connection_or_act_on_netinfo(or_connection_t *conn);
|
||||||
|
|
||||||
extern uint64_t stats_n_padding_cells_processed;
|
extern uint64_t stats_n_padding_cells_processed;
|
||||||
extern uint64_t stats_n_create_cells_processed;
|
extern uint64_t stats_n_create_cells_processed;
|
||||||
@ -2743,6 +2769,7 @@ or_connection_t *connection_or_connect(uint32_t addr, uint16_t port,
|
|||||||
int connection_tls_start_handshake(or_connection_t *conn, int receiving);
|
int connection_tls_start_handshake(or_connection_t *conn, int receiving);
|
||||||
int connection_tls_continue_handshake(or_connection_t *conn);
|
int connection_tls_continue_handshake(or_connection_t *conn);
|
||||||
|
|
||||||
|
void or_handshake_state_free(or_handshake_state_t *state);
|
||||||
int connection_or_set_state_open(or_connection_t *conn);
|
int connection_or_set_state_open(or_connection_t *conn);
|
||||||
void connection_or_write_cell_to_buf(const cell_t *cell,
|
void connection_or_write_cell_to_buf(const cell_t *cell,
|
||||||
or_connection_t *conn);
|
or_connection_t *conn);
|
||||||
|
Loading…
Reference in New Issue
Block a user