mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
more futzing towards tls
not there yet svn:r429
This commit is contained in:
parent
99035f3520
commit
3fa170e11f
@ -129,6 +129,7 @@ int flush_buf(int s, char **buf, int *buflen, int *buf_flushlen, int *buf_datale
|
||||
// log_fn(LOG_DEBUG,"flushed %d bytes, %d ready to flush, %d remain.",
|
||||
// write_result,*buf_flushlen,*buf_datalen);
|
||||
return *buf_flushlen;
|
||||
/* XXX USE_TLS should change to return write_result like any sane function would */
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,8 +137,9 @@ int flush_buf_tls(tor_tls *tls, char **buf, int *buflen, int *buf_flushlen, int
|
||||
{
|
||||
int r;
|
||||
assert(tls && *buf && buflen && buf_datalen);
|
||||
if (*buf_flushlen == 0)
|
||||
return 0;
|
||||
|
||||
/* we want to let tls write even if flushlen is zero, because it might
|
||||
* have a partial record pending */
|
||||
r = tor_tls_write(tls, *buf, *buf_flushlen);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
|
@ -92,7 +92,7 @@ connection_t *connection_new(int type) {
|
||||
conn->timestamp_lastread = now.tv_sec;
|
||||
conn->timestamp_lastwritten = now.tv_sec;
|
||||
|
||||
#ifndef TOR_TLS
|
||||
#ifndef USE_TLS
|
||||
if (connection_speaks_cells(conn)) {
|
||||
conn->f_crypto = crypto_new_cipher_env(CONNECTION_CIPHER);
|
||||
if (!conn->f_crypto) {
|
||||
@ -107,7 +107,6 @@ connection_t *connection_new(int type) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
conn->done_sending = conn->done_receiving = 0;
|
||||
return conn;
|
||||
}
|
||||
|
||||
@ -123,9 +122,9 @@ void connection_free(connection_t *conn) {
|
||||
|
||||
if(connection_speaks_cells(conn)) {
|
||||
directory_set_dirty();
|
||||
#ifdef TOR_TLS
|
||||
if (conn->SSL)
|
||||
crypt_SSL_free(conn->SSL);
|
||||
#ifdef USE_TLS
|
||||
if (conn->tls)
|
||||
tor_tls_free(conn->tls);
|
||||
#else
|
||||
if (conn->f_crypto)
|
||||
crypto_free_cipher_env(conn->f_crypto);
|
||||
@ -245,10 +244,8 @@ int connection_handle_listener_read(connection_t *conn, int new_type, int new_st
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* start all connections that should be up but aren't */
|
||||
int retry_all_connections(uint16_t or_listenport, uint16_t ap_listenport, uint16_t dir_listenport) {
|
||||
|
||||
/* start all connections that should be up but aren't */
|
||||
|
||||
struct sockaddr_in bindaddr; /* where to bind */
|
||||
|
||||
if(or_listenport) {
|
||||
@ -316,12 +313,13 @@ int connection_handle_read(connection_t *conn) {
|
||||
log_fn(LOG_DEBUG,"receiver bucket reached 0 before handshake finished. Closing.");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} /* end switch */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return -1 if we want to break conn, else return 0 */
|
||||
int connection_read_to_buf(connection_t *conn) {
|
||||
int read_result;
|
||||
int result;
|
||||
int at_most;
|
||||
|
||||
assert((connection_speaks_cells(conn) && conn->receiver_bucket >= 0) ||
|
||||
@ -344,27 +342,51 @@ int connection_read_to_buf(connection_t *conn) {
|
||||
if(conn->receiver_bucket >= 0 && at_most > conn->receiver_bucket)
|
||||
at_most = conn->receiver_bucket;
|
||||
|
||||
read_result = read_to_buf(conn->s, at_most, &conn->inbuf, &conn->inbuflen,
|
||||
&conn->inbuf_datalen, &conn->inbuf_reached_eof);
|
||||
// log(LOG_DEBUG,"connection_read_to_buf(): read_to_buf returned %d.",read_result);
|
||||
if(read_result >= 0) {
|
||||
global_read_bucket -= read_result; assert(global_read_bucket >= 0);
|
||||
if(connection_speaks_cells(conn))
|
||||
conn->receiver_bucket -= read_result;
|
||||
if(conn->receiver_bucket == 0 || global_read_bucket == 0) {
|
||||
log_fn(LOG_DEBUG,"buckets (%d, %d) exhausted. Pausing.", global_read_bucket, conn->receiver_bucket);
|
||||
conn->wants_to_read = 1;
|
||||
connection_stop_reading(conn);
|
||||
|
||||
/* If we're not in 'open' state here, then we're never going to finish the
|
||||
* handshake, because we'll never increment the receiver_bucket. But we
|
||||
* can't check for that here, because the buf we just read might have enough
|
||||
* on it to finish the handshake. So we check for that in connection_handle_read().
|
||||
*/
|
||||
#ifdef USE_TLS
|
||||
if(connection_speaks_cells(conn) && conn->state != OR_CONN_STATE_CONNECTING) {
|
||||
if(conn->state == OR_CONN_STATE_HANDSHAKING) {
|
||||
result = tor_tls_handshake(conn->tls)
|
||||
if(result == TOR_TLS_DONE) {
|
||||
conn->state = OR_CONN_STATE_OPEN;
|
||||
log_fn(LOG_DEBUG,"tls handshake done, now open.");
|
||||
}
|
||||
} else { /* open, or closing */
|
||||
result = read_to_buf_tls(conn->tls, at_most, &conn->inbuf,
|
||||
&conn->inbuflen, &conn->inbuf_datalen);
|
||||
}
|
||||
|
||||
switch(result) {
|
||||
case TOR_TLS_ERROR:
|
||||
case TOR_TLS_CLOSE:
|
||||
log_fn(LOG_DEBUG,"tls error. breaking.");
|
||||
return -1; /* XXX deal with close better */
|
||||
case TOR_TLS_WANT_WRITE:
|
||||
connection_start_writing(conn);
|
||||
return 0;
|
||||
case TOR_TLS_WANT_READ: /* we're already reading */
|
||||
case TOR_TLS_DONE: /* no data read, so nothing to process */
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
result = read_to_buf(conn->s, at_most, &conn->inbuf, &conn->inbuflen,
|
||||
&conn->inbuf_datalen, &conn->inbuf_reached_eof);
|
||||
// log(LOG_DEBUG,"connection_read_to_buf(): read_to_buf returned %d.",read_result);
|
||||
|
||||
if(result < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read_result;
|
||||
global_read_bucket -= result; assert(global_read_bucket >= 0);
|
||||
if(connection_speaks_cells(conn))
|
||||
conn->receiver_bucket -= result;
|
||||
if(conn->receiver_bucket == 0 || global_read_bucket == 0) {
|
||||
log_fn(LOG_DEBUG,"buckets (%d, %d) exhausted. Pausing.", global_read_bucket, conn->receiver_bucket);
|
||||
conn->wants_to_read = 1;
|
||||
connection_stop_reading(conn);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int connection_fetch_from_buf(char *string, int len, connection_t *conn) {
|
||||
@ -388,9 +410,10 @@ int connection_flush_buf(connection_t *conn) {
|
||||
&conn->outbuf_flushlen, &conn->outbuf_datalen);
|
||||
}
|
||||
|
||||
/* return -1 if you want to break the conn, else return 0 */
|
||||
int connection_handle_write(connection_t *conn) {
|
||||
struct timeval now;
|
||||
int retval;
|
||||
int result;
|
||||
|
||||
if(connection_is_listener(conn)) {
|
||||
log_fn(LOG_DEBUG,"Got a listener socket. Can't happen!");
|
||||
@ -400,25 +423,57 @@ int connection_handle_write(connection_t *conn) {
|
||||
my_gettimeofday(&now);
|
||||
conn->timestamp_lastwritten = now.tv_sec;
|
||||
|
||||
#ifdef TOR_TLS
|
||||
if(connection_speaks_cells(conn)) {
|
||||
retval = flush_buf_SSL(conn->SSL, &conn->outbuf, &conn->outbuflen,
|
||||
&conn->outbuf_flushlen, &conn->outbuf_datalen);
|
||||
...
|
||||
#ifdef USE_TLS
|
||||
if(connection_speaks_cells(conn) && conn->state != OR_CONN_STATE_CONNECTING) {
|
||||
if(conn->state == OR_CONN_STATE_HANDSHAKING) {
|
||||
result = tor_tls_handshake(conn->tls)
|
||||
if(result == TOR_TLS_DONE) {
|
||||
conn->state = OR_CONN_STATE_OPEN;
|
||||
log_fn(LOG_DEBUG,"tls handshake done, now open.");
|
||||
}
|
||||
} else { /* open, or closing */
|
||||
result = flush_buf_tls(conn->tls, &conn->outbuf, &conn->outbuflen,
|
||||
&conn->outbuf_flushlen, &conn->outbuf_datalen);
|
||||
}
|
||||
|
||||
switch(result) {
|
||||
case TOR_TLS_ERROR:
|
||||
case TOR_TLS_CLOSE:
|
||||
log_fn(LOG_DEBUG,"tls error. breaking.");
|
||||
return -1; /* XXX deal with close better */
|
||||
case TOR_TLS_WANT_WRITE:
|
||||
/* we're already writing */
|
||||
return 0;
|
||||
case TOR_TLS_WANT_READ:
|
||||
/* Make sure to avoid a loop if the receive buckets are empty. */
|
||||
if(!connection_is_reading(conn)) {
|
||||
connection_stop_writing(conn);
|
||||
conn->wants_to_write = 1;
|
||||
/* we'll start reading again when the next second arrives,
|
||||
* and then also start writing again.
|
||||
*/
|
||||
}
|
||||
/* else no problem, we're already reading */
|
||||
return 0;
|
||||
case TOR_TLS_DONE:
|
||||
/* for TOR_TLS_DONE, fall through to check if the flushlen
|
||||
* is empty, so we can stop writing.
|
||||
*/
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
retval = flush_buf(conn->s, &conn->outbuf, &conn->outbuflen,
|
||||
&conn->outbuf_flushlen, &conn->outbuf_datalen);
|
||||
/* conns in CONNECTING state will fall through... */
|
||||
|
||||
if(retval == 0) { /* it's done flushing */
|
||||
retval = connection_finished_flushing(conn); /* ...and get handled here. */
|
||||
}
|
||||
if(flush_buf(conn->s, &conn->outbuf, &conn->outbuflen,
|
||||
&conn->outbuf_flushlen, &conn->outbuf_datalen) < 0)
|
||||
return -1;
|
||||
/* conns in CONNECTING state will fall through... */
|
||||
}
|
||||
|
||||
return retval;
|
||||
if(!connection_wants_to_flush(conn)) /* it's done flushing */
|
||||
if(connection_finished_flushing(conn) < 0) /* ...and get handled here. */
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int connection_write_to_buf(char *string, int len, connection_t *conn) {
|
||||
@ -496,13 +551,16 @@ int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn) {
|
||||
|
||||
cell_pack(n, cellp);
|
||||
|
||||
#ifndef USE_TLS
|
||||
if(connection_encrypt_cell(n,conn)<0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return connection_write_to_buf(n, CELL_NETWORK_SIZE, conn);
|
||||
}
|
||||
|
||||
#ifndef USE_TLS
|
||||
int connection_encrypt_cell(char *cellp, connection_t *conn) {
|
||||
char cryptcell[CELL_NETWORK_SIZE];
|
||||
#if 0
|
||||
@ -535,6 +593,7 @@ int connection_encrypt_cell(char *cellp, connection_t *conn) {
|
||||
memcpy(cellp,cryptcell,CELL_NETWORK_SIZE);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int connection_process_inbuf(connection_t *conn) {
|
||||
|
||||
@ -705,18 +764,20 @@ int connection_finished_flushing(connection_t *conn) {
|
||||
|
||||
int connection_process_cell_from_inbuf(connection_t *conn) {
|
||||
/* check if there's a whole cell there.
|
||||
* if yes, pull it off, decrypt it, and process it.
|
||||
* if yes, pull it off, decrypt it if we're not doing TLS, and process it.
|
||||
*/
|
||||
char crypted[CELL_NETWORK_SIZE];
|
||||
char outbuf[1024];
|
||||
char networkcell[CELL_NETWORK_SIZE];
|
||||
char buf[CELL_NETWORK_SIZE];
|
||||
// int x;
|
||||
cell_t cell;
|
||||
|
||||
if(conn->inbuf_datalen < CELL_NETWORK_SIZE) /* entire response available? */
|
||||
return 0; /* not yet */
|
||||
|
||||
connection_fetch_from_buf(crypted,CELL_NETWORK_SIZE,conn);
|
||||
|
||||
#ifdef USE_TLS
|
||||
connection_fetch_from_buf(buf, CELL_NETWORK_SIZE, conn);
|
||||
#else
|
||||
connection_fetch_from_buf(networkcell, CELL_NETWORK_SIZE, conn);
|
||||
#if 0
|
||||
printf("Cell header crypttext: ");
|
||||
for(x=0;x<8;x++) {
|
||||
@ -725,7 +786,7 @@ int connection_process_cell_from_inbuf(connection_t *conn) {
|
||||
printf("\n");
|
||||
#endif
|
||||
/* decrypt */
|
||||
if(crypto_cipher_decrypt(conn->b_crypto,crypted,CELL_NETWORK_SIZE,outbuf)) {
|
||||
if(crypto_cipher_decrypt(conn->b_crypto, networkcell, CELL_NETWORK_SIZE, buf)) {
|
||||
log_fn(LOG_ERR,"Decryption failed, dropping.");
|
||||
return connection_process_inbuf(conn); /* process the remainder of the buffer */
|
||||
}
|
||||
@ -736,10 +797,11 @@ int connection_process_cell_from_inbuf(connection_t *conn) {
|
||||
printf("%u ",outbuf[x]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* retrieve cell info from outbuf (create the host-order struct from the network-order string) */
|
||||
cell_unpack(&cell, outbuf);
|
||||
/* retrieve cell info from buf (create the host-order struct from the network-order string) */
|
||||
cell_unpack(&cell, buf);
|
||||
|
||||
// log_fn(LOG_DEBUG,"Decrypted cell is of type %u (ACI %u).",cellp->command,cellp->aci);
|
||||
command_process_cell(&cell, conn);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
|
||||
#ifndef TOR_TLS
|
||||
#ifndef USE_TLS
|
||||
static int or_handshake_op_send_keys(connection_t *conn);
|
||||
static int or_handshake_op_finished_sending_keys(connection_t *conn);
|
||||
|
||||
@ -35,17 +35,18 @@ int connection_or_process_inbuf(connection_t *conn) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
assert(conn->state == OR_CONN_STATE_OPEN);
|
||||
return connection_process_cell_from_inbuf(conn);
|
||||
#else
|
||||
// log(LOG_DEBUG,"connection_or_process_inbuf(): state %d.",conn->state);
|
||||
|
||||
switch(conn->state) {
|
||||
#ifndef TOR_TLS
|
||||
case OR_CONN_STATE_CLIENT_AUTH_WAIT:
|
||||
return or_handshake_client_process_auth(conn);
|
||||
case OR_CONN_STATE_SERVER_AUTH_WAIT:
|
||||
return or_handshake_server_process_auth(conn);
|
||||
case OR_CONN_STATE_SERVER_NONCE_WAIT:
|
||||
return or_handshake_server_process_nonce(conn);
|
||||
#endif
|
||||
case OR_CONN_STATE_OPEN:
|
||||
return connection_process_cell_from_inbuf(conn);
|
||||
default:
|
||||
@ -53,6 +54,7 @@ int connection_or_process_inbuf(connection_t *conn) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int connection_or_finished_flushing(connection_t *conn) {
|
||||
@ -61,9 +63,13 @@ int connection_or_finished_flushing(connection_t *conn) {
|
||||
assert(conn && conn->type == CONN_TYPE_OR);
|
||||
|
||||
switch(conn->state) {
|
||||
#ifndef USE_TLS
|
||||
case OR_CONN_STATE_OP_SENDING_KEYS:
|
||||
return or_handshake_op_finished_sending_keys(conn);
|
||||
case OR_CONN_STATE_CLIENT_CONNECTING:
|
||||
#else
|
||||
case OR_CONN_STATE_CONNECTING:
|
||||
#endif
|
||||
if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) { /* not yet */
|
||||
if(!ERRNO_CONN_EINPROGRESS(errno)){
|
||||
/* yuck. kill it. */
|
||||
@ -78,6 +84,9 @@ int connection_or_finished_flushing(connection_t *conn) {
|
||||
log_fn(LOG_DEBUG,"OR connection to router %s:%u established.",
|
||||
conn->address,conn->port);
|
||||
|
||||
#ifdef USE_TLS
|
||||
call TLS new, and start the TLS handshake
|
||||
#else
|
||||
if(options.OnionRouter)
|
||||
return or_handshake_client_send_auth(conn);
|
||||
else
|
||||
@ -98,17 +107,14 @@ int connection_or_finished_flushing(connection_t *conn) {
|
||||
conn->state = OR_CONN_STATE_SERVER_NONCE_WAIT;
|
||||
connection_watch_events(conn, POLLIN);
|
||||
return 0;
|
||||
#endif
|
||||
case OR_CONN_STATE_OPEN:
|
||||
/* FIXME down the road, we'll clear out circuits that are pending to close */
|
||||
connection_stop_writing(conn);
|
||||
return 0;
|
||||
default:
|
||||
log_fn(LOG_DEBUG,"BUG: called in unexpected state.");
|
||||
log_fn(LOG_ERR,"BUG: called in unexpected state.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*********************/
|
||||
@ -659,7 +665,7 @@ connection_or_set_open(connection_t *conn) {
|
||||
connection_watch_events(conn, POLLIN);
|
||||
}
|
||||
|
||||
#ifndef TOR_TLS
|
||||
#ifndef USE_TLS
|
||||
static void
|
||||
conn_or_init_crypto(connection_t *conn) {
|
||||
//int x;
|
||||
|
@ -212,6 +212,10 @@ void connection_watch_events(connection_t *conn, short events) {
|
||||
poll_array[conn->poll_index].events = events;
|
||||
}
|
||||
|
||||
int connection_is_reading(connection_t *conn) {
|
||||
return poll_array[conn->poll_index].events & POLLIN;
|
||||
}
|
||||
|
||||
void connection_stop_reading(connection_t *conn) {
|
||||
|
||||
assert(conn && conn->poll_index < nfds);
|
||||
@ -312,8 +316,7 @@ static void check_conn_marked(int i) {
|
||||
|
||||
static int prepare_for_poll(void) {
|
||||
int i;
|
||||
// connection_t *conn = NULL;
|
||||
connection_t *tmpconn;
|
||||
connection_t *conn;
|
||||
struct timeval now; //soonest;
|
||||
static long current_second = 0; /* from previous calls to gettimeofday */
|
||||
static long time_to_fetch_directory = 0;
|
||||
@ -355,37 +358,41 @@ static int prepare_for_poll(void) {
|
||||
|
||||
/* do housekeeping for each connection */
|
||||
for(i=0;i<nfds;i++) {
|
||||
tmpconn = connection_array[i];
|
||||
if(connection_receiver_bucket_should_increase(tmpconn)) {
|
||||
tmpconn->receiver_bucket += tmpconn->bandwidth;
|
||||
// log_fn(LOG_DEBUG,"Receiver bucket %d now %d.", i, tmpconn->receiver_bucket);
|
||||
conn = connection_array[i];
|
||||
if(connection_receiver_bucket_should_increase(conn)) {
|
||||
conn->receiver_bucket += conn->bandwidth;
|
||||
// log_fn(LOG_DEBUG,"Receiver bucket %d now %d.", i, conn->receiver_bucket);
|
||||
}
|
||||
|
||||
if(tmpconn->wants_to_read == 1 /* it's marked to turn reading back on now */
|
||||
if(conn->wants_to_read == 1 /* it's marked to turn reading back on now */
|
||||
&& global_read_bucket > 0 /* and we're allowed to read */
|
||||
&& tmpconn->receiver_bucket != 0) { /* and either an edge conn or non-empty bucket */
|
||||
tmpconn->wants_to_read = 0;
|
||||
connection_start_reading(tmpconn);
|
||||
&& conn->receiver_bucket != 0) { /* and either an edge conn or non-empty bucket */
|
||||
conn->wants_to_read = 0;
|
||||
connection_start_reading(conn);
|
||||
if(conn->wants_to_write == 1) {
|
||||
conn->wants_to_write = 0;
|
||||
connection_start_writing(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/* check connections to see whether we should send a keepalive, expire, or wait */
|
||||
if(!connection_speaks_cells(tmpconn))
|
||||
if(!connection_speaks_cells(conn))
|
||||
continue; /* this conn type doesn't send cells */
|
||||
if(now.tv_sec >= tmpconn->timestamp_lastwritten + options.KeepalivePeriod) {
|
||||
if((!options.OnionRouter && !circuit_get_by_conn(tmpconn)) ||
|
||||
(!connection_state_is_open(tmpconn))) {
|
||||
if(now.tv_sec >= conn->timestamp_lastwritten + options.KeepalivePeriod) {
|
||||
if((!options.OnionRouter && !circuit_get_by_conn(conn)) ||
|
||||
(!connection_state_is_open(conn))) {
|
||||
/* we're an onion proxy, with no circuits; or our handshake has expired. kill it. */
|
||||
log(LOG_DEBUG,"prepare_for_poll(): Expiring connection to %d (%s:%d).",
|
||||
i,tmpconn->address, tmpconn->port);
|
||||
tmpconn->marked_for_close = 1;
|
||||
i,conn->address, conn->port);
|
||||
conn->marked_for_close = 1;
|
||||
} else {
|
||||
/* either a full router, or we've got a circuit. send a padding cell. */
|
||||
// log(LOG_DEBUG,"prepare_for_poll(): Sending keepalive to (%s:%d)",
|
||||
// tmpconn->address, tmpconn->port);
|
||||
// conn->address, conn->port);
|
||||
memset(&cell,0,sizeof(cell_t));
|
||||
cell.command = CELL_PADDING;
|
||||
if(connection_write_cell_to_buf(&cell, tmpconn) < 0)
|
||||
tmpconn->marked_for_close = 1;
|
||||
if(connection_write_cell_to_buf(&cell, conn) < 0)
|
||||
conn->marked_for_close = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -442,6 +449,10 @@ static int do_main_loop(void) {
|
||||
set_signing_privatekey(prkey);
|
||||
}
|
||||
|
||||
#ifdef USE_TLS
|
||||
make the tls context here
|
||||
#endif
|
||||
|
||||
/* start up the necessary connections based on which ports are
|
||||
* non-zero. This is where we try to connect to all the other ORs,
|
||||
* and start the listeners.
|
||||
|
@ -283,6 +283,9 @@ struct connection_t {
|
||||
uint8_t wants_to_read; /* should we start reading again once
|
||||
* the bandwidth throttler allows it?
|
||||
*/
|
||||
uint8_t wants_to_write; /* should we start writing again once
|
||||
* the bandwidth throttler allows reads?
|
||||
*/
|
||||
int s; /* our socket */
|
||||
int poll_index; /* index of this conn into the poll_array */
|
||||
int marked_for_close; /* should we close this conn on the next
|
||||
@ -642,7 +645,9 @@ int connection_state_is_open(connection_t *conn);
|
||||
|
||||
int connection_send_destroy(aci_t aci, connection_t *conn);
|
||||
int connection_send_connected(aci_t aci, connection_t *conn);
|
||||
#ifndef USE_TLS
|
||||
int connection_encrypt_cell(char *cellp, connection_t *conn);
|
||||
#endif
|
||||
int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn);
|
||||
|
||||
int connection_process_inbuf(connection_t *conn);
|
||||
@ -751,6 +756,7 @@ connection_t *connection_get_by_type_state(int type, int state);
|
||||
connection_t *connection_get_by_type_state_lastwritten(int type, int state);
|
||||
|
||||
void connection_watch_events(connection_t *conn, short events);
|
||||
int connection_is_reading(connection_t *conn);
|
||||
void connection_stop_reading(connection_t *conn);
|
||||
void connection_start_reading(connection_t *conn);
|
||||
void connection_stop_writing(connection_t *conn);
|
||||
|
Loading…
Reference in New Issue
Block a user