|
@@ -1644,15 +1644,24 @@ circuit_get_ready_rend_circ_by_rend_data(const rend_data_t *rend_data)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- * circuit list after <b>start</b> or at the start of the list if <b>start</b>
|
|
|
- * is NULL. Return NULL if no circuit is found.
|
|
|
+
|
|
|
+ * list after <b>start</b> or at the start of the list if <b>start</b> is
|
|
|
+ * NULL. Return NULL if no circuit is found.
|
|
|
+ *
|
|
|
+ * If <b>want_client_circ</b> is true, then we are looking for client-side
|
|
|
+ * introduction circuits: A client introduction point circuit has a purpose of
|
|
|
+ * either CIRCUIT_PURPOSE_C_INTRODUCING, CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT
|
|
|
+ * or CIRCUIT_PURPOSE_C_INTRODUCE_ACKED. This does not return a circuit marked
|
|
|
+ * for close, but it returns circuits regardless of their circuit state.
|
|
|
*
|
|
|
- * A service introduction point circuit has a purpose of either
|
|
|
- * CIRCUIT_PURPOSE_S_ESTABLISH_INTRO or CIRCUIT_PURPOSE_S_INTRO. This does not
|
|
|
- * return a circuit marked for close and its state must be open. */
|
|
|
+ * If <b>want_client_circ</b> is false, then we are looking for service-side
|
|
|
+ * introduction circuits: A service introduction point circuit has a purpose of
|
|
|
+ * either CIRCUIT_PURPOSE_S_ESTABLISH_INTRO or CIRCUIT_PURPOSE_S_INTRO. This
|
|
|
+ * does not return circuits marked for close, or in any state other than open.
|
|
|
+ */
|
|
|
origin_circuit_t *
|
|
|
-circuit_get_next_service_intro_circ(origin_circuit_t *start)
|
|
|
+circuit_get_next_intro_circ(const origin_circuit_t *start,
|
|
|
+ bool want_client_circ)
|
|
|
{
|
|
|
int idx = 0;
|
|
|
smartlist_t *lst = circuit_get_global_list();
|
|
@@ -1664,13 +1673,29 @@ circuit_get_next_service_intro_circ(origin_circuit_t *start)
|
|
|
for ( ; idx < smartlist_len(lst); ++idx) {
|
|
|
circuit_t *circ = smartlist_get(lst, idx);
|
|
|
|
|
|
-
|
|
|
- * intro point or if the state is not open. */
|
|
|
- if (circ->marked_for_close || circ->state != CIRCUIT_STATE_OPEN ||
|
|
|
- (circ->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO &&
|
|
|
- circ->purpose != CIRCUIT_PURPOSE_S_INTRO)) {
|
|
|
+
|
|
|
+ if (circ->marked_for_close) {
|
|
|
continue;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ * circuits with other purposes. */
|
|
|
+ if (want_client_circ) {
|
|
|
+ if (circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCING &&
|
|
|
+ circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT &&
|
|
|
+ circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACKED) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (circ->state != CIRCUIT_STATE_OPEN) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (circ->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO &&
|
|
|
+ circ->purpose != CIRCUIT_PURPOSE_S_INTRO) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
* following is valid. */
|
|
|
return TO_ORIGIN_CIRCUIT(circ);
|