Refactor users of buf_datalen to bufferevent-friendly version.

This commit is contained in:
Nick Mathewson 2009-07-31 11:39:31 -04:00
parent 57e7b54b7b
commit 200921dc31
10 changed files with 94 additions and 34 deletions

View File

@ -36,10 +36,6 @@
#include "router.h"
#include "routerparse.h"
#ifdef USE_BUFFEREVENTS
#include <event2/bufferevent.h>
#endif
static connection_t *connection_create_listener(
struct sockaddr *listensockaddr,
socklen_t listensocklen, int type,
@ -381,7 +377,8 @@ _connection_free(connection_t *conn)
"bytes on inbuf, %d on outbuf.",
conn_type_to_string(conn->type),
conn_state_to_string(conn->type, conn->state),
(int)buf_datalen(conn->inbuf), (int)buf_datalen(conn->outbuf));
(int)connection_get_inbuf_len(conn),
(int)connection_get_outbuf_len(conn));
}
if (!connection_is_listener(conn)) {

View File

@ -12,6 +12,11 @@
#ifndef _TOR_CONNECTION_H
#define _TOR_CONNECTION_H
#ifndef USE_BUFFEREVENTS
/* XXXX For buf_datalen in inline function */
#include "buffers.h"
#endif
const char *conn_type_to_string(int type);
const char *conn_state_to_string(int type, int state);
@ -73,6 +78,29 @@ connection_write_to_buf_zlib(const char *string, size_t len,
_connection_write_to_buf_impl(string, len, TO_CONN(conn), done ? -1 : 1);
}
static size_t connection_get_inbuf_len(connection_t *conn);
static size_t connection_get_outbuf_len(connection_t *conn);
static INLINE size_t
connection_get_inbuf_len(connection_t *conn)
{
IF_HAS_BUFFEREVENT(conn, {
return evbuffer_get_length(bufferevent_get_input(conn->bufev));
}) ELSE_IF_NO_BUFFEREVENT {
return buf_datalen(conn->inbuf);
}
}
static INLINE size_t
connection_get_outbuf_len(connection_t *conn)
{
IF_HAS_BUFFEREVENT(conn, {
return evbuffer_get_length(bufferevent_get_output(conn->bufev));
}) ELSE_IF_NO_BUFFEREVENT {
return buf_datalen(conn->outbuf);
}
}
connection_t *connection_get_by_global_id(uint64_t id);
connection_t *connection_get_by_type(int type);

View File

@ -100,7 +100,7 @@ _connection_mark_unattached_ap(edge_connection_t *conn, int endreason,
int
connection_edge_reached_eof(edge_connection_t *conn)
{
if (buf_datalen(conn->_base.inbuf) &&
if (connection_get_inbuf_len(TO_CONN(conn)) &&
connection_state_is_open(TO_CONN(conn))) {
/* it still has stuff to process. don't let it die yet. */
return 0;

View File

@ -248,7 +248,7 @@ connection_or_process_inbuf(or_connection_t *conn)
int
connection_or_flushed_some(or_connection_t *conn)
{
size_t datalen = buf_datalen(conn->_base.outbuf);
size_t datalen = connection_get_outbuf_len(TO_CONN(conn));
/* If we're under the low water mark, add cells until we're just over the
* high water mark. */
if (datalen < OR_CONN_LOWWATER) {
@ -1277,7 +1277,7 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
while (1) {
log_debug(LD_OR,
"%d: starting, inbuf_datalen %d (%d pending in tls object).",
conn->_base.s,(int)buf_datalen(conn->_base.inbuf),
conn->_base.s,(int)connection_get_inbuf_len(TO_CONN(conn)),
tor_tls_get_pending_bytes(conn->tls));
if (connection_fetch_var_cell_from_buf(conn, &var_cell)) {
if (!var_cell)
@ -1288,8 +1288,8 @@ connection_or_process_cells_from_inbuf(or_connection_t *conn)
} else {
char buf[CELL_NETWORK_SIZE];
cell_t cell;
if (buf_datalen(conn->_base.inbuf) < CELL_NETWORK_SIZE) /* whole response
available? */
if (connection_get_inbuf_len(TO_CONN(conn))
< CELL_NETWORK_SIZE) /* whole response available? */
return 0; /* not yet */
circuit_build_times_network_is_live(&circ_times);

View File

@ -141,7 +141,7 @@ connection_cpu_process_inbuf(connection_t *conn)
tor_assert(conn);
tor_assert(conn->type == CONN_TYPE_CPUWORKER);
if (!buf_datalen(conn->inbuf))
if (!connection_get_inbuf_len(conn))
return 0;
if (conn->state == CPUWORKER_STATE_BUSY_ONION) {

View File

@ -2134,7 +2134,7 @@ connection_dir_process_inbuf(dir_connection_t *conn)
return 0;
}
if (buf_datalen(conn->_base.inbuf) > MAX_DIRECTORY_OBJECT_SIZE) {
if (connection_get_inbuf_len(TO_CONN(conn)) > MAX_DIRECTORY_OBJECT_SIZE) {
log_warn(LD_HTTP, "Too much data received from directory connection: "
"denial of service attempt, or you need to upgrade?");
connection_mark_for_close(TO_CONN(conn));

View File

@ -3389,7 +3389,7 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
time_t publish_cutoff = time(NULL)-ROUTER_MAX_AGE_TO_PUBLISH;
while (smartlist_len(conn->fingerprint_stack) &&
buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
connection_get_outbuf_len(TO_CONN(conn)) < DIRSERV_BUFFER_MIN) {
const char *body;
char *fp = smartlist_pop_last(conn->fingerprint_stack);
signed_descriptor_t *sd = NULL;
@ -3489,7 +3489,7 @@ connection_dirserv_add_dir_bytes_to_outbuf(dir_connection_t *conn)
ssize_t bytes;
int64_t remaining;
bytes = DIRSERV_BUFFER_MIN - buf_datalen(conn->_base.outbuf);
bytes = DIRSERV_BUFFER_MIN - connection_get_outbuf_len(TO_CONN(conn));
tor_assert(bytes > 0);
tor_assert(conn->cached_dir);
if (bytes < 8192)
@ -3528,7 +3528,7 @@ static int
connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t *conn)
{
while (buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
while (connection_get_outbuf_len(TO_CONN(conn)) < DIRSERV_BUFFER_MIN) {
if (conn->cached_dir) {
int uncompressing = (conn->zlib_state != NULL);
int r = connection_dirserv_add_dir_bytes_to_outbuf(conn);
@ -3574,7 +3574,7 @@ connection_dirserv_flushed_some(dir_connection_t *conn)
{
tor_assert(conn->_base.state == DIR_CONN_STATE_SERVER_WRITING);
if (buf_datalen(conn->_base.outbuf) >= DIRSERV_BUFFER_MIN)
if (connection_get_outbuf_len(TO_CONN(conn)) >= DIRSERV_BUFFER_MIN)
return 0;
switch (conn->dir_spool_src) {

View File

@ -662,8 +662,8 @@ conn_close_if_marked(int i)
}
log_debug(LD_GENERAL, "Flushed last %d bytes from a linked conn; "
"%d left; flushlen %d; wants-to-flush==%d", retval,
(int)buf_datalen(conn->outbuf),
(int)conn->outbuf_flushlen,
(int)connection_get_outbuf_len(conn),
(int)conn->outbuf_flushlen,
connection_wants_to_flush(conn));
} else if (connection_speaks_cells(conn)) {
if (conn->state == OR_CONN_STATE_OPEN) {
@ -700,7 +700,7 @@ conn_close_if_marked(int i)
"something is wrong with your network connection, or "
"something is wrong with theirs. "
"(fd %d, type %s, state %d, marked at %s:%d).",
(int)buf_datalen(conn->outbuf),
(int)connection_get_outbuf_len(conn),
escaped_safe_str_client(conn->address),
conn->s, conn_type_to_string(conn->type), conn->state,
conn->marked_for_close_file,
@ -793,7 +793,8 @@ run_connection_housekeeping(int i, time_t now)
int past_keepalive =
now >= conn->timestamp_lastwritten + options->KeepalivePeriod;
if (conn->outbuf && !buf_datalen(conn->outbuf) && conn->type == CONN_TYPE_OR)
if (conn->outbuf && !connection_get_outbuf_len(conn) &&
conn->type == CONN_TYPE_OR)
TO_OR_CONN(conn)->timestamp_lastempty = now;
if (conn->marked_for_close) {
@ -813,7 +814,7 @@ run_connection_housekeeping(int i, time_t now)
/* This check is temporary; it's to let us know whether we should consider
* parsing partial serverdesc responses. */
if (conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC &&
buf_datalen(conn->inbuf)>=1024) {
connection_get_inbuf_len(conn) >= 1024) {
log_info(LD_DIR,"Trying to extract information from wedged server desc "
"download.");
connection_dir_reached_eof(TO_DIR_CONN(conn));
@ -852,7 +853,7 @@ run_connection_housekeeping(int i, time_t now)
connection_mark_for_close(conn);
}
} else if (we_are_hibernating() && !or_conn->n_circuits &&
!buf_datalen(conn->outbuf)) {
!connection_get_outbuf_len(conn)) {
/* We're hibernating, there's no circuits, and nothing to flush.*/
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
"[Hibernating or exiting].",
@ -874,10 +875,10 @@ run_connection_housekeeping(int i, time_t now)
"Expiring stuck OR connection to fd %d (%s:%d). (%d bytes to "
"flush; %d seconds since last write)",
conn->s, conn->address, conn->port,
(int)buf_datalen(conn->outbuf),
(int)connection_get_outbuf_len(conn),
(int)(now-conn->timestamp_lastwritten));
connection_mark_for_close(conn);
} else if (past_keepalive && !buf_datalen(conn->outbuf)) {
} else if (past_keepalive && !connection_get_outbuf_len(conn)) {
/* send a padding cell */
log_fn(LOG_DEBUG,LD_OR,"Sending keepalive to (%s:%d)",
conn->address, conn->port);
@ -1768,13 +1769,13 @@ dumpstats(int severity)
log(severity,LD_GENERAL,
"Conn %d: %d bytes waiting on inbuf (len %d, last read %d secs ago)",
i,
(int)buf_datalen(conn->inbuf),
(int)connection_get_inbuf_len(conn),
(int)buf_allocation(conn->inbuf),
(int)(now - conn->timestamp_lastread));
log(severity,LD_GENERAL,
"Conn %d: %d bytes waiting on outbuf "
"(len %d, last written %d secs ago)",i,
(int)buf_datalen(conn->outbuf),
(int)connection_get_outbuf_len(conn),
(int)buf_allocation(conn->outbuf),
(int)(now - conn->timestamp_lastwritten));
if (conn->type == CONN_TYPE_OR) {

View File

@ -83,6 +83,12 @@
#define snprintf _snprintf
#endif
#ifdef USE_BUFFEREVENTS
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#endif
#include "crypto.h"
#include "tortls.h"
#include "../common/torlog.h"
#include "container.h"
@ -1270,17 +1276,45 @@ static INLINE control_connection_t *TO_CONTROL_CONN(connection_t *c)
return DOWNCAST(control_connection_t, c);
}
/* Conditional macros to help write code that works whether bufferevents are
disabled or not.
We can't just write:
if (conn->bufev) {
do bufferevent stuff;
} else {
do other stuff;
}
because the bufferevent stuff won't even compile unless we have a fairly
new version of Libevent. Instead, we say:
IF_HAS_BUFFEREVENT(conn, { do_bufferevent_stuff } );
or:
IF_HAS_BUFFEREVENT(conn, {
do bufferevent stuff;
}) ELSE_IF_NO_BUFFEREVENT {
do non-bufferevent stuff;
}
If we're compiling with bufferevent support, then the macros expand more or
less to:
if (conn->bufev) {
do_bufferevent_stuff;
} else {
do non-bufferevent stuff;
}
and if we aren't using bufferevents, they expand more or less to:
{ do non-bufferevent stuff; }
*/
#ifdef USE_BUFFEREVENTS
#define HAS_BUFFEREVENT(c) (((c)->bufev) != NULL)
#define IF_HAS_BUFFEREVENT(c, stmt) \
do { \
if ((conn)->bufev) do { \
stmt ; \
} while(0); \
#define IF_HAS_BUFFEREVENT(c, stmt) \
if ((c)->bufev) do { \
stmt ; \
} while (0)
#define ELSE_IF_NO_BUFFEREVENT ; else
#else
#define HAS_BUFFEREVENT(c) (0)
#define IF_HAS_BUFFEREVENT(c, stmt) (void)0
#define ELSE_IF_NO_BUFFEREVENT ;
#endif
/** What action type does an address policy indicate: accept or reject? */

View File

@ -1365,7 +1365,7 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
return 0;
}
amount_to_process = buf_datalen(conn->_base.inbuf);
amount_to_process = connection_get_inbuf_len(TO_CONN(conn));
if (!amount_to_process)
return 0;
@ -1384,7 +1384,7 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
connection_fetch_from_buf(payload, length, TO_CONN(conn));
log_debug(domain,"(%d) Packaging %d bytes (%d waiting).", conn->_base.s,
(int)length, (int)buf_datalen(conn->_base.inbuf));
(int)length, (int)connection_get_inbuf_len(TO_CONN(conn)));
if (connection_edge_send_command(conn, RELAY_COMMAND_DATA,
payload, length) < 0 )
@ -2415,7 +2415,7 @@ append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn,
make_circuit_active_on_conn(circ, orconn);
}
if (! buf_datalen(orconn->_base.outbuf)) {
if (! connection_get_outbuf_len(TO_CONN(orconn))) {
/* There is no data at all waiting to be sent on the outbuf. Add a
* cell, so that we can notice when it gets flushed, flushed_some can
* get called, and we can start putting more data onto the buffer then.