#define connection_mark_for_close(c) \
_connection_mark_for_close((c), __LINE__, _SHORT_FILE_)
+#define connection_mark_and_flush(c) \
+ do { \
+ connection_t *tmp_conn_ = (c); \
+ _connection_mark_for_close(tmp_conn_, __LINE__, _SHORT_FILE_); \
+ tmp_conn_->hold_open_until_flushed = 1; \
+ IF_HAS_BUFFEREVENT(tmp_conn_, \
+ connection_start_writing(tmp_conn_)); \
+ } while (0)
+
void connection_expire_held_open(void);
int connection_connect(connection_t *conn, const char *address,
_connection_mark_for_close(TO_CONN(conn), line, file);
conn->_base.hold_open_until_flushed = 1;
+ IF_HAS_BUFFEREVENT(TO_CONN(conn), connection_start_writing(TO_CONN(conn)));
conn->end_reason = endreason;
}
conn->edge_has_sent_end = 1;
conn->end_reason = END_STREAM_REASON_DESTROY;
conn->end_reason |= END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED;
- connection_mark_for_close(TO_CONN(conn));
- conn->_base.hold_open_until_flushed = 1;
+ connection_mark_and_flush(TO_CONN(conn));
}
}
conn->cpath_layer = NULL;
case AP_CONN_STATE_CIRCUIT_WAIT:
case AP_CONN_STATE_CONNECT_WAIT:
case AP_CONN_STATE_CONTROLLER_WAIT:
+ case AP_CONN_STATE_RESOLVE_WAIT:
return 0;
default:
log_warn(LD_BUG, "Called in unexpected state %d.",conn->_base.state);
conn->conn_array_index = smartlist_len(connection_array);
smartlist_add(connection_array, conn);
+#ifdef USE_BUFFEREVENTS
+ if (conn->type == CONN_TYPE_AP && conn->s >= 0 && !conn->linked) {
+ conn->bufev = bufferevent_socket_new(
+ tor_libevent_get_base(),
+ conn->s,
+ BEV_OPT_DEFER_CALLBACKS);
+
+ connection_configure_bufferevent_callbacks(conn);
+ }
+#endif
+
if (!HAS_BUFFEREVENT(conn) && (conn->s >= 0 || conn->linked)) {
conn->read_event = tor_event_new(tor_libevent_get_base(),
conn->s, EV_READ|EV_PERSIST, conn_read_callback, conn);
IF_HAS_BUFFEREVENT(conn, {
short ev = ((short)events) & (EV_READ|EV_WRITE);
short old_ev = bufferevent_get_enabled(conn->bufev);
- if ((ev & ~old_ev) != 0)
+ if ((ev & ~old_ev) != 0) {
bufferevent_enable(conn->bufev, ev);
- if ((old_ev & ~ev) != 0)
+ }
+ if ((old_ev & ~ev) != 0) {
bufferevent_disable(conn->bufev, old_ev & ~ev);
+ }
return;
});
if (events & READ_EVENT)
connection_start_writing(connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->write_event);
IF_HAS_BUFFEREVENT(conn, {
bufferevent_enable(conn->bufev, EV_WRITE);
return;
});
+ tor_assert(conn->write_event);
+
if (conn->linked) {
conn->writing_to_linked_conn = 1;
if (conn->linked_conn &&
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
"[Hibernating or exiting].",
conn->s,conn->address, conn->port);
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
+ connection_mark_and_flush(conn);
} else if (!or_conn->n_circuits &&
now >= or_conn->timestamp_last_added_nonpadding +
IDLE_OR_CONN_TIMEOUT) {
"[idle %d].", conn->s,conn->address, conn->port,
(int)(now - or_conn->timestamp_last_added_nonpadding));
connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
} else if (
now >= or_conn->timestamp_lastempty + options->KeepalivePeriod*10 &&
now >= conn->timestamp_lastwritten + options->KeepalivePeriod*10) {