To link connections only if they ready
connection_exit_connect_dir and connection_ap_make_link creates linked pair for connections that can be freed before connection_unlink thus invalidates linked_conn.
connection_link_connections(partner, base_conn);
if (connection_add(base_conn) < 0) { /* no space, forget it */
connection_free(base_conn);
return NULL;
}
connection_link_connections(TO_CONN(dirconn), TO_CONN(exitconn));
if (connection_add(TO_CONN(exitconn))<0) {
connection_edge_end(exitconn, END_STREAM_REASON_RESOURCELIMIT);
connection_free(TO_CONN(exitconn));
connection_free(TO_CONN(dirconn));
return 0;
}
/* link exitconn to circ, now that we know we can use it. */
exitconn->next_stream = circ->n_streams;
circ->n_streams = exitconn;
if (connection_add(TO_CONN(dirconn))<0) {
connection_edge_end(exitconn, END_STREAM_REASON_RESOURCELIMIT);
connection_close_immediate(TO_CONN(exitconn));
connection_mark_for_close(TO_CONN(exitconn));
connection_free(TO_CONN(dirconn));
return 0;
}
If connection_add fails then linked_conn from another connection is broken. (currently it can to fail only if BUFFEREVENTS used by code)