Back to index

tor  0.2.3.18-rc
circuituse.c
Go to the documentation of this file.
00001 /* Copyright (c) 2001 Matej Pfajfar.
00002  * Copyright (c) 2001-2004, Roger Dingledine.
00003  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
00004  * Copyright (c) 2007-2012, The Tor Project, Inc. */
00005 /* See LICENSE for licensing information */
00006 
00012 #include "or.h"
00013 #include "circuitbuild.h"
00014 #include "circuitlist.h"
00015 #include "circuituse.h"
00016 #include "config.h"
00017 #include "connection.h"
00018 #include "connection_edge.h"
00019 #include "control.h"
00020 #include "nodelist.h"
00021 #include "networkstatus.h"
00022 #include "policies.h"
00023 #include "rendclient.h"
00024 #include "rendcommon.h"
00025 #include "rendservice.h"
00026 #include "rephist.h"
00027 #include "router.h"
00028 #include "routerlist.h"
00029 
00030 /********* START VARIABLES **********/
00031 
00032 extern circuit_t *global_circuitlist; /* from circuitlist.c */
00033 
00034 /********* END VARIABLES ************/
00035 
00036 static void circuit_expire_old_circuits_clientside(void);
00037 static void circuit_increment_failure_count(void);
00038 
00042 static int
00043 circuit_is_acceptable(const origin_circuit_t *origin_circ,
00044                       const entry_connection_t *conn,
00045                       int must_be_open, uint8_t purpose,
00046                       int need_uptime, int need_internal,
00047                       time_t now)
00048 {
00049   const circuit_t *circ = TO_CIRCUIT(origin_circ);
00050   const node_t *exitnode;
00051   cpath_build_state_t *build_state;
00052   tor_assert(circ);
00053   tor_assert(conn);
00054   tor_assert(conn->socks_request);
00055 
00056   if (must_be_open && (circ->state != CIRCUIT_STATE_OPEN || !circ->n_conn))
00057     return 0; /* ignore non-open circs */
00058   if (circ->marked_for_close)
00059     return 0;
00060 
00061   /* if this circ isn't our purpose, skip. */
00062   if (purpose == CIRCUIT_PURPOSE_C_REND_JOINED && !must_be_open) {
00063     if (circ->purpose != CIRCUIT_PURPOSE_C_ESTABLISH_REND &&
00064         circ->purpose != CIRCUIT_PURPOSE_C_REND_READY &&
00065         circ->purpose != CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED &&
00066         circ->purpose != CIRCUIT_PURPOSE_C_REND_JOINED)
00067       return 0;
00068   } else if (purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT &&
00069              !must_be_open) {
00070     if (circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCING &&
00071         circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT)
00072       return 0;
00073   } else {
00074     if (purpose != circ->purpose)
00075       return 0;
00076   }
00077 
00078   /* If this is a timed-out hidden service circuit, skip it. */
00079   if (origin_circ->hs_circ_has_timed_out) {
00080     return 0;
00081   }
00082 
00083   if (purpose == CIRCUIT_PURPOSE_C_GENERAL ||
00084       purpose == CIRCUIT_PURPOSE_C_REND_JOINED)
00085     if (circ->timestamp_dirty &&
00086        circ->timestamp_dirty+get_options()->MaxCircuitDirtiness <= now)
00087       return 0;
00088 
00089   /* decide if this circ is suitable for this conn */
00090 
00091   /* for rend circs, circ->cpath->prev is not the last router in the
00092    * circuit, it's the magical extra bob hop. so just check the nickname
00093    * of the one we meant to finish at.
00094    */
00095   build_state = origin_circ->build_state;
00096   exitnode = build_state_get_exit_node(build_state);
00097 
00098   if (need_uptime && !build_state->need_uptime)
00099     return 0;
00100   if (need_internal != build_state->is_internal)
00101     return 0;
00102 
00103   if (purpose == CIRCUIT_PURPOSE_C_GENERAL) {
00104     if (!exitnode && !build_state->onehop_tunnel) {
00105       log_debug(LD_CIRC,"Not considering circuit with unknown router.");
00106       return 0; /* this circuit is screwed and doesn't know it yet,
00107                  * or is a rendezvous circuit. */
00108     }
00109     if (build_state->onehop_tunnel) {
00110       if (!conn->want_onehop) {
00111         log_debug(LD_CIRC,"Skipping one-hop circuit.");
00112         return 0;
00113       }
00114       tor_assert(conn->chosen_exit_name);
00115       if (build_state->chosen_exit) {
00116         char digest[DIGEST_LEN];
00117         if (hexdigest_to_digest(conn->chosen_exit_name, digest) < 0)
00118           return 0; /* broken digest, we don't want it */
00119         if (tor_memneq(digest, build_state->chosen_exit->identity_digest,
00120                           DIGEST_LEN))
00121           return 0; /* this is a circuit to somewhere else */
00122         if (tor_digest_is_zero(digest)) {
00123           /* we don't know the digest; have to compare addr:port */
00124           tor_addr_t addr;
00125           int r = tor_addr_parse(&addr, conn->socks_request->address);
00126           if (r < 0 ||
00127               !tor_addr_eq(&build_state->chosen_exit->addr, &addr) ||
00128               build_state->chosen_exit->port != conn->socks_request->port)
00129             return 0;
00130         }
00131       }
00132     } else {
00133       if (conn->want_onehop) {
00134         /* don't use three-hop circuits -- that could hurt our anonymity. */
00135         return 0;
00136       }
00137     }
00138     if (exitnode && !connection_ap_can_use_exit(conn, exitnode)) {
00139       /* can't exit from this router */
00140       return 0;
00141     }
00142   } else { /* not general */
00143     const edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
00144     if ((edge_conn->rend_data && !origin_circ->rend_data) ||
00145         (!edge_conn->rend_data && origin_circ->rend_data) ||
00146         (edge_conn->rend_data && origin_circ->rend_data &&
00147          rend_cmp_service_ids(edge_conn->rend_data->onion_address,
00148                               origin_circ->rend_data->onion_address))) {
00149       /* this circ is not for this conn */
00150       return 0;
00151     }
00152   }
00153 
00154   if (!connection_edge_compatible_with_circuit(conn, origin_circ)) {
00155     /* conn needs to be isolated from other conns that have already used
00156      * origin_circ */
00157     return 0;
00158   }
00159 
00160   return 1;
00161 }
00162 
00166 static int
00167 circuit_is_better(const origin_circuit_t *oa, const origin_circuit_t *ob,
00168                   const entry_connection_t *conn)
00169 {
00170   const circuit_t *a = TO_CIRCUIT(oa);
00171   const circuit_t *b = TO_CIRCUIT(ob);
00172   const uint8_t purpose = ENTRY_TO_CONN(conn)->purpose;
00173   int a_bits, b_bits;
00174 
00175   switch (purpose) {
00176     case CIRCUIT_PURPOSE_C_GENERAL:
00177       /* if it's used but less dirty it's best;
00178        * else if it's more recently created it's best
00179        */
00180       if (b->timestamp_dirty) {
00181         if (a->timestamp_dirty &&
00182             a->timestamp_dirty > b->timestamp_dirty)
00183           return 1;
00184       } else {
00185         if (a->timestamp_dirty ||
00186             timercmp(&a->timestamp_created, &b->timestamp_created, >))
00187           return 1;
00188         if (ob->build_state->is_internal)
00189           /* XXX023 what the heck is this internal thing doing here. I
00190            * think we can get rid of it. circuit_is_acceptable() already
00191            * makes sure that is_internal is exactly what we need it to
00192            * be. -RD */
00193           return 1;
00194       }
00195       break;
00196     case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
00197       /* the closer it is to ack_wait the better it is */
00198       if (a->purpose > b->purpose)
00199         return 1;
00200       break;
00201     case CIRCUIT_PURPOSE_C_REND_JOINED:
00202       /* the closer it is to rend_joined the better it is */
00203       if (a->purpose > b->purpose)
00204         return 1;
00205       break;
00206   }
00207 
00208   /* XXXX023 Maybe this check should get a higher priority to avoid
00209    *   using up circuits too rapidly. */
00210 
00211   a_bits = connection_edge_update_circuit_isolation(conn,
00212                                                     (origin_circuit_t*)oa, 1);
00213   b_bits = connection_edge_update_circuit_isolation(conn,
00214                                                     (origin_circuit_t*)ob, 1);
00215   /* if x_bits < 0, then we have not used x for anything; better not to dirty
00216    * a connection if we can help it. */
00217   if (a_bits < 0) {
00218     return 0;
00219   } else if (b_bits < 0) {
00220     return 1;
00221   }
00222   a_bits &= ~ oa->isolation_flags_mixed;
00223   a_bits &= ~ ob->isolation_flags_mixed;
00224   if (n_bits_set_u8(a_bits) < n_bits_set_u8(b_bits)) {
00225     /* The fewer new restrictions we need to make on a circuit for stream
00226      * isolation, the better. */
00227     return 1;
00228   }
00229 
00230   return 0;
00231 }
00232 
00249 static origin_circuit_t *
00250 circuit_get_best(const entry_connection_t *conn,
00251                  int must_be_open, uint8_t purpose,
00252                  int need_uptime, int need_internal)
00253 {
00254   circuit_t *circ;
00255   origin_circuit_t *best=NULL;
00256   struct timeval now;
00257   int intro_going_on_but_too_old = 0;
00258 
00259   tor_assert(conn);
00260 
00261   tor_assert(purpose == CIRCUIT_PURPOSE_C_GENERAL ||
00262              purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT ||
00263              purpose == CIRCUIT_PURPOSE_C_REND_JOINED);
00264 
00265   tor_gettimeofday(&now);
00266 
00267   for (circ=global_circuitlist;circ;circ = circ->next) {
00268     origin_circuit_t *origin_circ;
00269     if (!CIRCUIT_IS_ORIGIN(circ))
00270       continue;
00271     origin_circ = TO_ORIGIN_CIRCUIT(circ);
00272     if (!circuit_is_acceptable(origin_circ,conn,must_be_open,purpose,
00273                                need_uptime,need_internal,now.tv_sec))
00274       continue;
00275 
00276     if (purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT &&
00277         !must_be_open && circ->state != CIRCUIT_STATE_OPEN &&
00278         tv_mdiff(&now, &circ->timestamp_created) > circ_times.timeout_ms) {
00279       intro_going_on_but_too_old = 1;
00280       continue;
00281     }
00282 
00283     /* now this is an acceptable circ to hand back. but that doesn't
00284      * mean it's the *best* circ to hand back. try to decide.
00285      */
00286     if (!best || circuit_is_better(origin_circ,best,conn))
00287       best = origin_circ;
00288   }
00289 
00290   if (!best && intro_going_on_but_too_old)
00291     log_info(LD_REND|LD_CIRC, "There is an intro circuit being created "
00292              "right now, but it has already taken quite a while. Starting "
00293              "one in parallel.");
00294 
00295   return best;
00296 }
00297 
00299 static int
00300 count_pending_general_client_circuits(void)
00301 {
00302   const circuit_t *circ;
00303 
00304   int count = 0;
00305 
00306   for (circ = global_circuitlist; circ; circ = circ->next) {
00307     if (circ->marked_for_close ||
00308         circ->state == CIRCUIT_STATE_OPEN ||
00309         circ->purpose != CIRCUIT_PURPOSE_C_GENERAL ||
00310         !CIRCUIT_IS_ORIGIN(circ))
00311       continue;
00312 
00313     ++count;
00314   }
00315 
00316   return count;
00317 }
00318 
00319 #if 0
00320 
00322 /* XXXX currently only checks Exclude{Exit}Nodes; it should check more.
00323  * Also, it doesn't have the right definition of an exit circuit. Also,
00324  * it's never called. */
00325 int
00326 circuit_conforms_to_options(const origin_circuit_t *circ,
00327                             const or_options_t *options)
00328 {
00329   const crypt_path_t *cpath, *cpath_next = NULL;
00330 
00331   /* first check if it includes any excluded nodes */
00332   for (cpath = circ->cpath; cpath_next != circ->cpath; cpath = cpath_next) {
00333     cpath_next = cpath->next;
00334     if (routerset_contains_extendinfo(options->ExcludeNodes,
00335                                       cpath->extend_info))
00336       return 0;
00337   }
00338 
00339   /* then consider the final hop */
00340   if (routerset_contains_extendinfo(options->ExcludeExitNodes,
00341                                     circ->cpath->prev->extend_info))
00342     return 0;
00343 
00344   return 1;
00345 }
00346 #endif
00347 
00351 void
00352 circuit_expire_building(void)
00353 {
00354   circuit_t *victim, *next_circ = global_circuitlist;
00355   /* circ_times.timeout_ms and circ_times.close_ms are from
00356    * circuit_build_times_get_initial_timeout() if we haven't computed
00357    * custom timeouts yet */
00358   struct timeval general_cutoff, begindir_cutoff, fourhop_cutoff,
00359     cannibalize_cutoff, close_cutoff, extremely_old_cutoff,
00360     hs_extremely_old_cutoff;
00361   const or_options_t *options = get_options();
00362   struct timeval now;
00363   cpath_build_state_t *build_state;
00364 
00365   tor_gettimeofday(&now);
00366 #define SET_CUTOFF(target, msec) do {                       \
00367     long ms = tor_lround(msec);                             \
00368     struct timeval diff;                                    \
00369     diff.tv_sec = ms / 1000;                                \
00370     diff.tv_usec = (int)((ms % 1000) * 1000);               \
00371     timersub(&now, &diff, &target);                         \
00372   } while (0)
00373 
00374   SET_CUTOFF(general_cutoff, circ_times.timeout_ms);
00375   SET_CUTOFF(begindir_cutoff, circ_times.timeout_ms / 2.0);
00376   SET_CUTOFF(fourhop_cutoff, circ_times.timeout_ms * (4/3.0));
00377   SET_CUTOFF(cannibalize_cutoff, circ_times.timeout_ms / 2.0);
00378   SET_CUTOFF(close_cutoff, circ_times.close_ms);
00379   SET_CUTOFF(extremely_old_cutoff, circ_times.close_ms*2 + 1000);
00380 
00381   SET_CUTOFF(hs_extremely_old_cutoff,
00382              MAX(circ_times.close_ms*2 + 1000,
00383                  options->SocksTimeout * 1000));
00384 
00385   while (next_circ) {
00386     struct timeval cutoff;
00387     victim = next_circ;
00388     next_circ = next_circ->next;
00389     if (!CIRCUIT_IS_ORIGIN(victim) || /* didn't originate here */
00390         victim->marked_for_close) /* don't mess with marked circs */
00391       continue;
00392 
00393     build_state = TO_ORIGIN_CIRCUIT(victim)->build_state;
00394     if (build_state && build_state->onehop_tunnel)
00395       cutoff = begindir_cutoff;
00396     else if (build_state && build_state->desired_path_len == 4
00397              && !TO_ORIGIN_CIRCUIT(victim)->has_opened)
00398       cutoff = fourhop_cutoff;
00399     else if (TO_ORIGIN_CIRCUIT(victim)->has_opened)
00400       cutoff = cannibalize_cutoff;
00401     else if (victim->purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT)
00402       cutoff = close_cutoff;
00403     else
00404       cutoff = general_cutoff;
00405 
00406     if (TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out)
00407       cutoff = hs_extremely_old_cutoff;
00408 
00409     if (timercmp(&victim->timestamp_created, &cutoff, >))
00410       continue; /* it's still young, leave it alone */
00411 
00412 #if 0
00413     /* some debug logs, to help track bugs */
00414     if (victim->purpose >= CIRCUIT_PURPOSE_C_INTRODUCING &&
00415         victim->purpose <= CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) {
00416       if (!victim->timestamp_dirty)
00417         log_fn(LOG_DEBUG,"Considering %sopen purpose %d to %s (circid %d)."
00418                "(clean).",
00419                victim->state == CIRCUIT_STATE_OPEN ? "" : "non",
00420                victim->purpose, victim->build_state->chosen_exit_name,
00421                victim->n_circ_id);
00422       else
00423         log_fn(LOG_DEBUG,"Considering %sopen purpose %d to %s (circid %d). "
00424                "%d secs since dirty.",
00425                victim->state == CIRCUIT_STATE_OPEN ? "" : "non",
00426                victim->purpose, victim->build_state->chosen_exit_name,
00427                victim->n_circ_id,
00428                (int)(now - victim->timestamp_dirty));
00429     }
00430 #endif
00431 
00432     /* if circ is !open, or if it's open but purpose is a non-finished
00433      * intro or rend, then mark it for close */
00434     if (victim->state == CIRCUIT_STATE_OPEN) {
00435       switch (victim->purpose) {
00436         default: /* most open circuits can be left alone. */
00437           continue; /* yes, continue inside a switch refers to the nearest
00438                      * enclosing loop. C is smart. */
00439         case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
00440         case CIRCUIT_PURPOSE_C_INTRODUCING:
00441         case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
00442           break; /* too old, need to die */
00443         case CIRCUIT_PURPOSE_C_REND_READY:
00444           /* it's a rend_ready circ -- has it already picked a query? */
00445           /* c_rend_ready circs measure age since timestamp_dirty,
00446            * because that's set when they switch purposes
00447            */
00448           if (TO_ORIGIN_CIRCUIT(victim)->rend_data ||
00449               victim->timestamp_dirty > cutoff.tv_sec)
00450             continue;
00451           break;
00452         case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED:
00453         case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
00454           /* rend and intro circs become dirty each time they
00455            * make an introduction attempt. so timestamp_dirty
00456            * will reflect the time since the last attempt.
00457            */
00458           if (victim->timestamp_dirty > cutoff.tv_sec)
00459             continue;
00460           break;
00461       }
00462     } else { /* circuit not open, consider recording failure as timeout */
00463       int first_hop_succeeded = TO_ORIGIN_CIRCUIT(victim)->cpath &&
00464             TO_ORIGIN_CIRCUIT(victim)->cpath->state == CPATH_STATE_OPEN;
00465 
00466       if (TO_ORIGIN_CIRCUIT(victim)->p_streams != NULL) {
00467         log_warn(LD_BUG, "Circuit %d (purpose %d, %s) has timed out, "
00468                  "yet has attached streams!",
00469                  TO_ORIGIN_CIRCUIT(victim)->global_identifier,
00470                  victim->purpose,
00471                  circuit_purpose_to_string(victim->purpose));
00472         tor_fragile_assert();
00473         continue;
00474       }
00475 
00476       if (circuit_timeout_want_to_count_circ(TO_ORIGIN_CIRCUIT(victim)) &&
00477           circuit_build_times_enough_to_compute(&circ_times)) {
00478         /* Circuits are allowed to last longer for measurement.
00479          * Switch their purpose and wait. */
00480         if (victim->purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
00481           control_event_circuit_status(TO_ORIGIN_CIRCUIT(victim),
00482                                        CIRC_EVENT_FAILED,
00483                                        END_CIRC_REASON_TIMEOUT);
00484           circuit_change_purpose(victim, CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT);
00485           /* Record this failure to check for too many timeouts
00486            * in a row. This function does not record a time value yet
00487            * (we do that later); it only counts the fact that we did
00488            * have a timeout. */
00489           circuit_build_times_count_timeout(&circ_times,
00490                                             first_hop_succeeded);
00491           continue;
00492         }
00493 
00494         /*
00495          * If the circuit build time is much greater than we would have cut
00496          * it off at, we probably had a suspend event along this codepath,
00497          * and we should discard the value.
00498          */
00499         if (timercmp(&victim->timestamp_created, &extremely_old_cutoff, <)) {
00500           log_notice(LD_CIRC,
00501                      "Extremely large value for circuit build timeout: %lds. "
00502                      "Assuming clock jump. Purpose %d (%s)",
00503                      (long)(now.tv_sec - victim->timestamp_created.tv_sec),
00504                      victim->purpose,
00505                      circuit_purpose_to_string(victim->purpose));
00506         } else if (circuit_build_times_count_close(&circ_times,
00507                                          first_hop_succeeded,
00508                                          victim->timestamp_created.tv_sec)) {
00509           circuit_build_times_set_timeout(&circ_times);
00510         }
00511       }
00512     }
00513 
00514     /* If this is a hidden service client circuit which is far enough
00515      * along in connecting to its destination, and we haven't already
00516      * flagged it as 'timed out', and the user has not told us to
00517      * close such circs immediately on timeout, flag it as 'timed out'
00518      * so we'll launch another intro or rend circ, but don't mark it
00519      * for close yet.
00520      *
00521      * (Circs flagged as 'timed out' are given a much longer timeout
00522      * period above, so we won't close them in the next call to
00523      * circuit_expire_building.) */
00524     if (!(options->CloseHSClientCircuitsImmediatelyOnTimeout) &&
00525         !(TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out)) {
00526       switch (victim->purpose) {
00527       case CIRCUIT_PURPOSE_C_REND_READY:
00528         /* We only want to spare a rend circ if it has been specified in
00529          * an INTRODUCE1 cell sent to a hidden service.  A circ's
00530          * pending_final_cpath field is non-NULL iff it is a rend circ
00531          * and we have tried to send an INTRODUCE1 cell specifying it.
00532          * Thus, if the pending_final_cpath field *is* NULL, then we
00533          * want to not spare it. */
00534         if (TO_ORIGIN_CIRCUIT(victim)->build_state->pending_final_cpath ==
00535             NULL)
00536           break;
00537       case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
00538       case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED:
00539         /* If we have reached this line, we want to spare the circ for now. */
00540         log_info(LD_CIRC,"Marking circ %d (state %d:%s, purpose %d) "
00541                  "as timed-out HS circ",
00542                  victim->n_circ_id,
00543                  victim->state, circuit_state_to_string(victim->state),
00544                  victim->purpose);
00545         TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out = 1;
00546         continue;
00547       default:
00548         break;
00549       }
00550     }
00551 
00552     /* If this is a service-side rendezvous circuit which is far
00553      * enough along in connecting to its destination, consider sparing
00554      * it. */
00555     if (!(options->CloseHSServiceRendCircuitsImmediatelyOnTimeout) &&
00556         !(TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out) &&
00557         victim->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND) {
00558       log_info(LD_CIRC,"Marking circ %d (state %d:%s, purpose %d) "
00559                "as timed-out HS circ; relaunching rendezvous attempt.",
00560                victim->n_circ_id,
00561                victim->state, circuit_state_to_string(victim->state),
00562                victim->purpose);
00563       TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out = 1;
00564       rend_service_relaunch_rendezvous(TO_ORIGIN_CIRCUIT(victim));
00565       continue;
00566     }
00567 
00568     if (victim->n_conn)
00569       log_info(LD_CIRC,"Abandoning circ %s:%d:%d (state %d:%s, purpose %d)",
00570                victim->n_conn->_base.address, victim->n_conn->_base.port,
00571                victim->n_circ_id,
00572                victim->state, circuit_state_to_string(victim->state),
00573                victim->purpose);
00574     else
00575       log_info(LD_CIRC,"Abandoning circ %d (state %d:%s, purpose %d)",
00576                victim->n_circ_id, victim->state,
00577                circuit_state_to_string(victim->state), victim->purpose);
00578 
00579     circuit_log_path(LOG_INFO,LD_CIRC,TO_ORIGIN_CIRCUIT(victim));
00580     if (victim->purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT)
00581       circuit_mark_for_close(victim, END_CIRC_REASON_MEASUREMENT_EXPIRED);
00582     else
00583       circuit_mark_for_close(victim, END_CIRC_REASON_TIMEOUT);
00584   }
00585 }
00586 
00590 void
00591 circuit_remove_handled_ports(smartlist_t *needed_ports)
00592 {
00593   int i;
00594   uint16_t *port;
00595 
00596   for (i = 0; i < smartlist_len(needed_ports); ++i) {
00597     port = smartlist_get(needed_ports, i);
00598     tor_assert(*port);
00599     if (circuit_stream_is_being_handled(NULL, *port,
00600                                         MIN_CIRCUITS_HANDLING_STREAM)) {
00601 //      log_debug(LD_CIRC,"Port %d is already being handled; removing.", port);
00602       smartlist_del(needed_ports, i--);
00603       tor_free(port);
00604     } else {
00605       log_debug(LD_CIRC,"Port %d is not handled.", *port);
00606     }
00607   }
00608 }
00609 
00615 int
00616 circuit_stream_is_being_handled(entry_connection_t *conn,
00617                                 uint16_t port, int min)
00618 {
00619   circuit_t *circ;
00620   const node_t *exitnode;
00621   int num=0;
00622   time_t now = time(NULL);
00623   int need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts,
00624                                    conn ? conn->socks_request->port : port);
00625 
00626   for (circ=global_circuitlist;circ;circ = circ->next) {
00627     if (CIRCUIT_IS_ORIGIN(circ) &&
00628         !circ->marked_for_close &&
00629         circ->purpose == CIRCUIT_PURPOSE_C_GENERAL &&
00630         (!circ->timestamp_dirty ||
00631          circ->timestamp_dirty + get_options()->MaxCircuitDirtiness > now)) {
00632       cpath_build_state_t *build_state = TO_ORIGIN_CIRCUIT(circ)->build_state;
00633       if (build_state->is_internal || build_state->onehop_tunnel)
00634         continue;
00635 
00636       exitnode = build_state_get_exit_node(build_state);
00637       if (exitnode && (!need_uptime || build_state->need_uptime)) {
00638         int ok;
00639         if (conn) {
00640           ok = connection_ap_can_use_exit(conn, exitnode);
00641         } else {
00642           addr_policy_result_t r;
00643           r = compare_tor_addr_to_node_policy(NULL, port, exitnode);
00644           ok = r != ADDR_POLICY_REJECTED && r != ADDR_POLICY_PROBABLY_REJECTED;
00645         }
00646         if (ok) {
00647           if (++num >= min)
00648             return 1;
00649         }
00650       }
00651     }
00652   }
00653   return 0;
00654 }
00655 
00657 #define MAX_UNUSED_OPEN_CIRCUITS 14
00658 
00663 static void
00664 circuit_predict_and_launch_new(void)
00665 {
00666   circuit_t *circ;
00667   int num=0, num_internal=0, num_uptime_internal=0;
00668   int hidserv_needs_uptime=0, hidserv_needs_capacity=1;
00669   int port_needs_uptime=0, port_needs_capacity=1;
00670   time_t now = time(NULL);
00671   int flags = 0;
00672 
00673   /* First, count how many of each type of circuit we have already. */
00674   for (circ=global_circuitlist;circ;circ = circ->next) {
00675     cpath_build_state_t *build_state;
00676     if (!CIRCUIT_IS_ORIGIN(circ))
00677       continue;
00678     if (circ->marked_for_close)
00679       continue; /* don't mess with marked circs */
00680     if (circ->timestamp_dirty)
00681       continue; /* only count clean circs */
00682     if (circ->purpose != CIRCUIT_PURPOSE_C_GENERAL)
00683       continue; /* only pay attention to general-purpose circs */
00684     build_state = TO_ORIGIN_CIRCUIT(circ)->build_state;
00685     if (build_state->onehop_tunnel)
00686       continue;
00687     num++;
00688     if (build_state->is_internal)
00689       num_internal++;
00690     if (build_state->need_uptime && build_state->is_internal)
00691       num_uptime_internal++;
00692   }
00693 
00694   /* If that's enough, then stop now. */
00695   if (num >= MAX_UNUSED_OPEN_CIRCUITS)
00696     return; /* we already have many, making more probably will hurt */
00697 
00698   /* Second, see if we need any more exit circuits. */
00699   /* check if we know of a port that's been requested recently
00700    * and no circuit is currently available that can handle it. */
00701   if (!circuit_all_predicted_ports_handled(now, &port_needs_uptime,
00702                                            &port_needs_capacity)) {
00703     if (port_needs_uptime)
00704       flags |= CIRCLAUNCH_NEED_UPTIME;
00705     if (port_needs_capacity)
00706       flags |= CIRCLAUNCH_NEED_CAPACITY;
00707     log_info(LD_CIRC,
00708              "Have %d clean circs (%d internal), need another exit circ.",
00709              num, num_internal);
00710     circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags);
00711     return;
00712   }
00713 
00714   /* Third, see if we need any more hidden service (server) circuits. */
00715   if (num_rend_services() && num_uptime_internal < 3) {
00716     flags = (CIRCLAUNCH_NEED_CAPACITY | CIRCLAUNCH_NEED_UPTIME |
00717              CIRCLAUNCH_IS_INTERNAL);
00718     log_info(LD_CIRC,
00719              "Have %d clean circs (%d internal), need another internal "
00720              "circ for my hidden service.",
00721              num, num_internal);
00722     circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags);
00723     return;
00724   }
00725 
00726   /* Fourth, see if we need any more hidden service (client) circuits. */
00727   if (rep_hist_get_predicted_internal(now, &hidserv_needs_uptime,
00728                                       &hidserv_needs_capacity) &&
00729       ((num_uptime_internal<2 && hidserv_needs_uptime) ||
00730         num_internal<2)) {
00731     if (hidserv_needs_uptime)
00732       flags |= CIRCLAUNCH_NEED_UPTIME;
00733     if (hidserv_needs_capacity)
00734       flags |= CIRCLAUNCH_NEED_CAPACITY;
00735     flags |= CIRCLAUNCH_IS_INTERNAL;
00736     log_info(LD_CIRC,
00737              "Have %d clean circs (%d uptime-internal, %d internal), need"
00738              " another hidden service circ.",
00739              num, num_uptime_internal, num_internal);
00740     circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags);
00741     return;
00742   }
00743 
00744   /* Finally, check to see if we still need more circuits to learn
00745    * a good build timeout. But if we're close to our max number we
00746    * want, don't do another -- we want to leave a few slots open so
00747    * we can still build circuits preemptively as needed. */
00748   if (num < MAX_UNUSED_OPEN_CIRCUITS-2 &&
00749       get_options()->LearnCircuitBuildTimeout &&
00750       circuit_build_times_needs_circuits_now(&circ_times)) {
00751     flags = CIRCLAUNCH_NEED_CAPACITY;
00752     log_info(LD_CIRC,
00753              "Have %d clean circs need another buildtime test circ.", num);
00754     circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags);
00755     return;
00756   }
00757 }
00758 
00760 #define TESTING_CIRCUIT_INTERVAL 300
00761 
00767 void
00768 circuit_build_needed_circs(time_t now)
00769 {
00770   static time_t time_to_new_circuit = 0;
00771   const or_options_t *options = get_options();
00772 
00773   /* launch a new circ for any pending streams that need one */
00774   connection_ap_attach_pending();
00775 
00776   /* make sure any hidden services have enough intro points */
00777   rend_services_introduce();
00778 
00779   if (time_to_new_circuit < now) {
00780     circuit_reset_failure_count(1);
00781     time_to_new_circuit = now + options->NewCircuitPeriod;
00782     if (proxy_mode(get_options()))
00783       addressmap_clean(now);
00784     circuit_expire_old_circuits_clientside();
00785 
00786 #if 0 /* disable for now, until predict-and-launch-new can cull leftovers */
00787     circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
00788     if (get_options()->RunTesting &&
00789         circ &&
00790         circ->timestamp_created.tv_sec + TESTING_CIRCUIT_INTERVAL < now) {
00791       log_fn(LOG_INFO,"Creating a new testing circuit.");
00792       circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, 0);
00793     }
00794 #endif
00795   }
00796   if (!options->DisablePredictedCircuits)
00797     circuit_predict_and_launch_new();
00798 }
00799 
00803 void
00804 circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
00805 {
00806   edge_connection_t *prevconn;
00807 
00808   tor_assert(circ);
00809   tor_assert(conn);
00810 
00811   if (conn->_base.type == CONN_TYPE_AP) {
00812     entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
00813     entry_conn->may_use_optimistic_data = 0;
00814   }
00815   conn->cpath_layer = NULL; /* don't keep a stale pointer */
00816   conn->on_circuit = NULL;
00817 
00818   if (CIRCUIT_IS_ORIGIN(circ)) {
00819     origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
00820     if (conn == origin_circ->p_streams) {
00821       origin_circ->p_streams = conn->next_stream;
00822       return;
00823     }
00824 
00825     for (prevconn = origin_circ->p_streams;
00826          prevconn && prevconn->next_stream && prevconn->next_stream != conn;
00827          prevconn = prevconn->next_stream)
00828       ;
00829     if (prevconn && prevconn->next_stream) {
00830       prevconn->next_stream = conn->next_stream;
00831       return;
00832     }
00833   } else {
00834     or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
00835     if (conn == or_circ->n_streams) {
00836       or_circ->n_streams = conn->next_stream;
00837       return;
00838     }
00839     if (conn == or_circ->resolving_streams) {
00840       or_circ->resolving_streams = conn->next_stream;
00841       return;
00842     }
00843 
00844     for (prevconn = or_circ->n_streams;
00845          prevconn && prevconn->next_stream && prevconn->next_stream != conn;
00846          prevconn = prevconn->next_stream)
00847       ;
00848     if (prevconn && prevconn->next_stream) {
00849       prevconn->next_stream = conn->next_stream;
00850       return;
00851     }
00852 
00853     for (prevconn = or_circ->resolving_streams;
00854          prevconn && prevconn->next_stream && prevconn->next_stream != conn;
00855          prevconn = prevconn->next_stream)
00856       ;
00857     if (prevconn && prevconn->next_stream) {
00858       prevconn->next_stream = conn->next_stream;
00859       return;
00860     }
00861   }
00862 
00863   log_warn(LD_BUG,"Edge connection not in circuit's list.");
00864   /* Don't give an error here; it's harmless. */
00865   tor_fragile_assert();
00866 }
00867 
00871 #define IDLE_TIMEOUT_WHILE_LEARNING (10*60)
00872 
00876 static void
00877 circuit_expire_old_circuits_clientside(void)
00878 {
00879   circuit_t *circ;
00880   struct timeval cutoff, now;
00881 
00882   tor_gettimeofday(&now);
00883   cutoff = now;
00884 
00885   if (get_options()->LearnCircuitBuildTimeout &&
00886       circuit_build_times_needs_circuits(&circ_times)) {
00887     /* Circuits should be shorter lived if we need more of them
00888      * for learning a good build timeout */
00889     cutoff.tv_sec -= IDLE_TIMEOUT_WHILE_LEARNING;
00890   } else {
00891     cutoff.tv_sec -= get_options()->CircuitIdleTimeout;
00892   }
00893 
00894   for (circ = global_circuitlist; circ; circ = circ->next) {
00895     if (circ->marked_for_close || !CIRCUIT_IS_ORIGIN(circ))
00896       continue;
00897     /* If the circuit has been dirty for too long, and there are no streams
00898      * on it, mark it for close.
00899      */
00900     if (circ->timestamp_dirty &&
00901         circ->timestamp_dirty + get_options()->MaxCircuitDirtiness <
00902           now.tv_sec &&
00903         !TO_ORIGIN_CIRCUIT(circ)->p_streams /* nothing attached */ ) {
00904       log_debug(LD_CIRC, "Closing n_circ_id %d (dirty %ld sec ago, "
00905                 "purpose %d)",
00906                 circ->n_circ_id, (long)(now.tv_sec - circ->timestamp_dirty),
00907                 circ->purpose);
00908       circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
00909     } else if (!circ->timestamp_dirty && circ->state == CIRCUIT_STATE_OPEN) {
00910       if (timercmp(&circ->timestamp_created, &cutoff, <)) {
00911         if (circ->purpose == CIRCUIT_PURPOSE_C_GENERAL ||
00912                 circ->purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT ||
00913                 circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
00914                 circ->purpose == CIRCUIT_PURPOSE_TESTING ||
00915                 (circ->purpose >= CIRCUIT_PURPOSE_C_INTRODUCING &&
00916                 circ->purpose <= CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) ||
00917                 circ->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND) {
00918           log_debug(LD_CIRC,
00919                     "Closing circuit that has been unused for %ld msec.",
00920                     tv_mdiff(&circ->timestamp_created, &now));
00921           circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
00922         } else if (!TO_ORIGIN_CIRCUIT(circ)->is_ancient) {
00923           /* Server-side rend joined circuits can end up really old, because
00924            * they are reused by clients for longer than normal. The client
00925            * controls their lifespan. (They never become dirty, because
00926            * connection_exit_begin_conn() never marks anything as dirty.)
00927            * Similarly, server-side intro circuits last a long time. */
00928           if (circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED &&
00929               circ->purpose != CIRCUIT_PURPOSE_S_INTRO) {
00930             log_notice(LD_CIRC,
00931                        "Ancient non-dirty circuit %d is still around after "
00932                        "%ld milliseconds. Purpose: %d (%s)",
00933                        TO_ORIGIN_CIRCUIT(circ)->global_identifier,
00934                        tv_mdiff(&circ->timestamp_created, &now),
00935                        circ->purpose,
00936                        circuit_purpose_to_string(circ->purpose));
00937             TO_ORIGIN_CIRCUIT(circ)->is_ancient = 1;
00938           }
00939         }
00940       }
00941     }
00942   }
00943 }
00944 
00960 #define IDLE_ONE_HOP_CIRC_TIMEOUT 60
00961 
00966 void
00967 circuit_expire_old_circuits_serverside(time_t now)
00968 {
00969   circuit_t *circ;
00970   or_circuit_t *or_circ;
00971   time_t cutoff = now - IDLE_ONE_HOP_CIRC_TIMEOUT;
00972 
00973   for (circ = global_circuitlist; circ; circ = circ->next) {
00974     if (circ->marked_for_close || CIRCUIT_IS_ORIGIN(circ))
00975       continue;
00976     or_circ = TO_OR_CIRCUIT(circ);
00977     /* If the circuit has been idle for too long, and there are no streams
00978      * on it, and it ends here, and it used a create_fast, mark it for close.
00979      */
00980     if (or_circ->is_first_hop && !circ->n_conn &&
00981         !or_circ->n_streams && !or_circ->resolving_streams &&
00982         or_circ->p_conn &&
00983         or_circ->p_conn->timestamp_last_added_nonpadding <= cutoff) {
00984       log_info(LD_CIRC, "Closing circ_id %d (empty %d secs ago)",
00985                or_circ->p_circ_id,
00986                (int)(now - or_circ->p_conn->timestamp_last_added_nonpadding));
00987       circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
00988     }
00989   }
00990 }
00991 
00993 #define NUM_PARALLEL_TESTING_CIRCS 4
00994 
00997 static int have_performed_bandwidth_test = 0;
00998 
01001 void
01002 reset_bandwidth_test(void)
01003 {
01004   have_performed_bandwidth_test = 0;
01005 }
01006 
01011 int
01012 circuit_enough_testing_circs(void)
01013 {
01014   circuit_t *circ;
01015   int num = 0;
01016 
01017   if (have_performed_bandwidth_test)
01018     return 1;
01019 
01020   for (circ = global_circuitlist; circ; circ = circ->next) {
01021     if (!circ->marked_for_close && CIRCUIT_IS_ORIGIN(circ) &&
01022         circ->purpose == CIRCUIT_PURPOSE_TESTING &&
01023         circ->state == CIRCUIT_STATE_OPEN)
01024       num++;
01025   }
01026   return num >= NUM_PARALLEL_TESTING_CIRCS;
01027 }
01028 
01035 static void
01036 circuit_testing_opened(origin_circuit_t *circ)
01037 {
01038   if (have_performed_bandwidth_test ||
01039       !check_whether_orport_reachable()) {
01040     /* either we've already done everything we want with testing circuits,
01041      * or this testing circuit became open due to a fluke, e.g. we picked
01042      * a last hop where we already had the connection open due to an
01043      * outgoing local circuit. */
01044     circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_AT_ORIGIN);
01045   } else if (circuit_enough_testing_circs()) {
01046     router_perform_bandwidth_test(NUM_PARALLEL_TESTING_CIRCS, time(NULL));
01047     have_performed_bandwidth_test = 1;
01048   } else
01049     consider_testing_reachability(1, 0);
01050 }
01051 
01053 static void
01054 circuit_testing_failed(origin_circuit_t *circ, int at_last_hop)
01055 {
01056   if (server_mode(get_options()) && check_whether_orport_reachable())
01057     return;
01058 
01059   log_info(LD_GENERAL,
01060            "Our testing circuit (to see if your ORPort is reachable) "
01061            "has failed. I'll try again later.");
01062 
01063   /* These aren't used yet. */
01064   (void)circ;
01065   (void)at_last_hop;
01066 }
01067 
01074 void
01075 circuit_has_opened(origin_circuit_t *circ)
01076 {
01077   control_event_circuit_status(circ, CIRC_EVENT_BUILT, 0);
01078 
01079   /* Remember that this circuit has finished building. Now if we start
01080    * it building again later (e.g. by extending it), we will know not
01081    * to consider its build time. */
01082   circ->has_opened = 1;
01083 
01084   switch (TO_CIRCUIT(circ)->purpose) {
01085     case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
01086       rend_client_rendcirc_has_opened(circ);
01087       /* Start building an intro circ if we don't have one yet. */
01088       connection_ap_attach_pending();
01089       /* This isn't a call to circuit_try_attaching_streams because a
01090        * circuit in _C_ESTABLISH_REND state isn't connected to its
01091        * hidden service yet, thus we can't attach streams to it yet,
01092        * thus circuit_try_attaching_streams would always clear the
01093        * circuit's isolation state.  circuit_try_attaching_streams is
01094        * called later, when the rend circ enters _C_REND_JOINED
01095        * state. */
01096       break;
01097     case CIRCUIT_PURPOSE_C_INTRODUCING:
01098       rend_client_introcirc_has_opened(circ);
01099       break;
01100     case CIRCUIT_PURPOSE_C_GENERAL:
01101       /* Tell any AP connections that have been waiting for a new
01102        * circuit that one is ready. */
01103       circuit_try_attaching_streams(circ);
01104       break;
01105     case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
01106       /* at Bob, waiting for introductions */
01107       rend_service_intro_has_opened(circ);
01108       break;
01109     case CIRCUIT_PURPOSE_S_CONNECT_REND:
01110       /* at Bob, connecting to rend point */
01111       rend_service_rendezvous_has_opened(circ);
01112       break;
01113     case CIRCUIT_PURPOSE_TESTING:
01114       circuit_testing_opened(circ);
01115       break;
01116     /* default:
01117      * This won't happen in normal operation, but might happen if the
01118      * controller did it. Just let it slide. */
01119   }
01120 }
01121 
01124 static int
01125 circuit_try_clearing_isolation_state(origin_circuit_t *circ)
01126 {
01127   if (/* The circuit may have become non-open if it was cannibalized.*/
01128       circ->_base.state == CIRCUIT_STATE_OPEN &&
01129       /* If !isolation_values_set, there is nothing to clear. */
01130       circ->isolation_values_set &&
01131       /* It's not legal to clear a circuit's isolation info if it's ever had
01132        * streams attached */
01133       !circ->isolation_any_streams_attached) {
01134     /* If we have any isolation information set on this circuit, and
01135      * we didn't manage to attach any streams to it, then we can
01136      * and should clear it and try again. */
01137     circuit_clear_isolation(circ);
01138     return 1;
01139   } else {
01140     return 0;
01141   }
01142 }
01143 
01146 void
01147 circuit_try_attaching_streams(origin_circuit_t *circ)
01148 {
01149   /* Attach streams to this circuit if we can. */
01150   connection_ap_attach_pending();
01151 
01152   /* The call to circuit_try_clearing_isolation_state here will do
01153    * nothing and return 0 if we didn't attach any streams to circ
01154    * above. */
01155   if (circuit_try_clearing_isolation_state(circ)) {
01156     /* Maybe *now* we can attach some streams to this circuit. */
01157     connection_ap_attach_pending();
01158   }
01159 }
01160 
01163 void
01164 circuit_build_failed(origin_circuit_t *circ)
01165 {
01166   /* we should examine circ and see if it failed because of
01167    * the last hop or an earlier hop. then use this info below.
01168    */
01169   int failed_at_last_hop = 0;
01170   /* If the last hop isn't open, and the second-to-last is, we failed
01171    * at the last hop. */
01172   if (circ->cpath &&
01173       circ->cpath->prev->state != CPATH_STATE_OPEN &&
01174       circ->cpath->prev->prev->state == CPATH_STATE_OPEN) {
01175     failed_at_last_hop = 1;
01176   }
01177   if (circ->cpath &&
01178       circ->cpath->state != CPATH_STATE_OPEN) {
01179     /* We failed at the first hop. If there's an OR connection
01180      * to blame, blame it. Also, avoid this relay for a while, and
01181      * fail any one-hop directory fetches destined for it. */
01182     const char *n_conn_id = circ->cpath->extend_info->identity_digest;
01183     int already_marked = 0;
01184     if (circ->_base.n_conn) {
01185       or_connection_t *n_conn = circ->_base.n_conn;
01186       if (n_conn->is_bad_for_new_circs) {
01187         /* We only want to blame this router when a fresh healthy
01188          * connection fails. So don't mark this router as newly failed,
01189          * since maybe this was just an old circuit attempt that's
01190          * finally timing out now. Also, there's no need to blow away
01191          * circuits/streams/etc, since the failure of an unhealthy conn
01192          * doesn't tell us much about whether a healthy conn would
01193          * succeed. */
01194         already_marked = 1;
01195       }
01196       log_info(LD_OR,
01197                "Our circuit failed to get a response from the first hop "
01198                "(%s:%d). I'm going to try to rotate to a better connection.",
01199                n_conn->_base.address, n_conn->_base.port);
01200       n_conn->is_bad_for_new_circs = 1;
01201     } else {
01202       log_info(LD_OR,
01203                "Our circuit died before the first hop with no connection");
01204     }
01205     if (n_conn_id && !already_marked) {
01206       entry_guard_register_connect_status(n_conn_id, 0, 1, time(NULL));
01207       /* if there are any one-hop streams waiting on this circuit, fail
01208        * them now so they can retry elsewhere. */
01209       connection_ap_fail_onehop(n_conn_id, circ->build_state);
01210     }
01211   }
01212 
01213   switch (circ->_base.purpose) {
01214     case CIRCUIT_PURPOSE_C_GENERAL:
01215       /* If we never built the circuit, note it as a failure. */
01216       circuit_increment_failure_count();
01217       if (failed_at_last_hop) {
01218         /* Make sure any streams that demand our last hop as their exit
01219          * know that it's unlikely to happen. */
01220         circuit_discard_optional_exit_enclaves(circ->cpath->prev->extend_info);
01221       }
01222       break;
01223     case CIRCUIT_PURPOSE_TESTING:
01224       circuit_testing_failed(circ, failed_at_last_hop);
01225       break;
01226     case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
01227       /* at Bob, waiting for introductions */
01228       if (circ->_base.state != CIRCUIT_STATE_OPEN) {
01229         circuit_increment_failure_count();
01230       }
01231       /* no need to care here, because bob will rebuild intro
01232        * points periodically. */
01233       break;
01234     case CIRCUIT_PURPOSE_C_INTRODUCING:
01235       /* at Alice, connecting to intro point */
01236       /* Don't increment failure count, since Bob may have picked
01237        * the introduction point maliciously */
01238       /* Alice will pick a new intro point when this one dies, if
01239        * the stream in question still cares. No need to act here. */
01240       break;
01241     case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
01242       /* at Alice, waiting for Bob */
01243       circuit_increment_failure_count();
01244       /* Alice will pick a new rend point when this one dies, if
01245        * the stream in question still cares. No need to act here. */
01246       break;
01247     case CIRCUIT_PURPOSE_S_CONNECT_REND:
01248       /* at Bob, connecting to rend point */
01249       /* Don't increment failure count, since Alice may have picked
01250        * the rendezvous point maliciously */
01251       log_info(LD_REND,
01252                "Couldn't connect to Alice's chosen rend point %s "
01253                "(%s hop failed).",
01254                escaped(build_state_get_exit_nickname(circ->build_state)),
01255                failed_at_last_hop?"last":"non-last");
01256       rend_service_relaunch_rendezvous(circ);
01257       break;
01258     /* default:
01259      * This won't happen in normal operation, but might happen if the
01260      * controller did it. Just let it slide. */
01261   }
01262 }
01263 
01267 static int n_circuit_failures = 0;
01270 static int did_circs_fail_last_period = 0;
01271 
01274 #define MAX_CIRCUIT_FAILURES 5
01275 
01278 origin_circuit_t *
01279 circuit_launch(uint8_t purpose, int flags)
01280 {
01281   return circuit_launch_by_extend_info(purpose, NULL, flags);
01282 }
01283 
01291 origin_circuit_t *
01292 circuit_launch_by_extend_info(uint8_t purpose,
01293                               extend_info_t *extend_info,
01294                               int flags)
01295 {
01296   origin_circuit_t *circ;
01297   int onehop_tunnel = (flags & CIRCLAUNCH_ONEHOP_TUNNEL) != 0;
01298 
01299   if (!onehop_tunnel && !router_have_minimum_dir_info()) {
01300     log_debug(LD_CIRC,"Haven't fetched enough directory info yet; canceling "
01301               "circuit launch.");
01302     return NULL;
01303   }
01304 
01305   if ((extend_info || purpose != CIRCUIT_PURPOSE_C_GENERAL) &&
01306       purpose != CIRCUIT_PURPOSE_TESTING && !onehop_tunnel) {
01307     /* see if there are appropriate circs available to cannibalize. */
01308     /* XXX if we're planning to add a hop, perhaps we want to look for
01309      * internal circs rather than exit circs? -RD */
01310     circ = circuit_find_to_cannibalize(purpose, extend_info, flags);
01311     if (circ) {
01312       uint8_t old_purpose = circ->_base.purpose;
01313       struct timeval old_timestamp_created;
01314 
01315       log_info(LD_CIRC,"Cannibalizing circ '%s' for purpose %d (%s)",
01316                build_state_get_exit_nickname(circ->build_state), purpose,
01317                circuit_purpose_to_string(purpose));
01318 
01319       circuit_change_purpose(TO_CIRCUIT(circ), purpose);
01320       /* reset the birth date of this circ, else expire_building
01321        * will see it and think it's been trying to build since it
01322        * began. */
01323       tor_gettimeofday(&circ->_base.timestamp_created);
01324 
01325       control_event_circuit_cannibalized(circ, old_purpose,
01326                                          &old_timestamp_created);
01327 
01328       switch (purpose) {
01329         case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
01330         case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
01331           /* it's ready right now */
01332           break;
01333         case CIRCUIT_PURPOSE_C_INTRODUCING:
01334         case CIRCUIT_PURPOSE_S_CONNECT_REND:
01335         case CIRCUIT_PURPOSE_C_GENERAL:
01336           /* need to add a new hop */
01337           tor_assert(extend_info);
01338           if (circuit_extend_to_new_exit(circ, extend_info) < 0)
01339             return NULL;
01340           break;
01341         default:
01342           log_warn(LD_BUG,
01343                    "unexpected purpose %d when cannibalizing a circ.",
01344                    purpose);
01345           tor_fragile_assert();
01346           return NULL;
01347       }
01348       return circ;
01349     }
01350   }
01351 
01352   if (did_circs_fail_last_period &&
01353       n_circuit_failures > MAX_CIRCUIT_FAILURES) {
01354     /* too many failed circs in a row. don't try. */
01355 //    log_fn(LOG_INFO,"%d failures so far, not trying.",n_circuit_failures);
01356     return NULL;
01357   }
01358 
01359   /* try a circ. if it fails, circuit_mark_for_close will increment
01360    * n_circuit_failures */
01361   return circuit_establish_circuit(purpose, extend_info, flags);
01362 }
01363 
01367 static void
01368 circuit_increment_failure_count(void)
01369 {
01370   ++n_circuit_failures;
01371   log_debug(LD_CIRC,"n_circuit_failures now %d.",n_circuit_failures);
01372 }
01373 
01378 void
01379 circuit_reset_failure_count(int timeout)
01380 {
01381   if (timeout && n_circuit_failures > MAX_CIRCUIT_FAILURES)
01382     did_circs_fail_last_period = 1;
01383   else
01384     did_circs_fail_last_period = 0;
01385   n_circuit_failures = 0;
01386 }
01387 
01394 static int
01395 circuit_get_open_circ_or_launch(entry_connection_t *conn,
01396                                 uint8_t desired_circuit_purpose,
01397                                 origin_circuit_t **circp)
01398 {
01399   origin_circuit_t *circ;
01400   int check_exit_policy;
01401   int need_uptime, need_internal;
01402   int want_onehop;
01403   const or_options_t *options = get_options();
01404 
01405   tor_assert(conn);
01406   tor_assert(circp);
01407   tor_assert(ENTRY_TO_CONN(conn)->state == AP_CONN_STATE_CIRCUIT_WAIT);
01408   check_exit_policy =
01409       conn->socks_request->command == SOCKS_COMMAND_CONNECT &&
01410       !conn->use_begindir &&
01411       !connection_edge_is_rendezvous_stream(ENTRY_TO_EDGE_CONN(conn));
01412   want_onehop = conn->want_onehop;
01413 
01414   need_uptime = !conn->want_onehop && !conn->use_begindir &&
01415                 smartlist_string_num_isin(options->LongLivedPorts,
01416                                           conn->socks_request->port);
01417 
01418   if (desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL)
01419     need_internal = 1;
01420   else if (conn->use_begindir || conn->want_onehop)
01421     need_internal = 1;
01422   else
01423     need_internal = 0;
01424 
01425   circ = circuit_get_best(conn, 1, desired_circuit_purpose,
01426                           need_uptime, need_internal);
01427 
01428   if (circ) {
01429     *circp = circ;
01430     return 1; /* we're happy */
01431   }
01432 
01433   if (!want_onehop && !router_have_minimum_dir_info()) {
01434     if (!connection_get_by_type(CONN_TYPE_DIR)) {
01435       int severity = LOG_NOTICE;
01436       /* FFFF if this is a tunneled directory fetch, don't yell
01437        * as loudly. the user doesn't even know it's happening. */
01438       if (entry_list_is_constrained(options) &&
01439           entries_known_but_down(options)) {
01440         log_fn(severity, LD_APP|LD_DIR,
01441                "Application request when we haven't used client functionality "
01442                "lately. Optimistically trying known %s again.",
01443                options->UseBridges ? "bridges" : "entrynodes");
01444         entries_retry_all(options);
01445       } else if (!options->UseBridges || any_bridge_descriptors_known()) {
01446         log_fn(severity, LD_APP|LD_DIR,
01447                "Application request when we haven't used client functionality "
01448                "lately. Optimistically trying directory fetches again.");
01449         routerlist_retry_directory_downloads(time(NULL));
01450       }
01451     }
01452     /* the stream will be dealt with when router_have_minimum_dir_info becomes
01453      * 1, or when all directory attempts fail and directory_all_unreachable()
01454      * kills it.
01455      */
01456     return 0;
01457   }
01458 
01459   /* Do we need to check exit policy? */
01460   if (check_exit_policy) {
01461     if (!conn->chosen_exit_name) {
01462       struct in_addr in;
01463       tor_addr_t addr, *addrp=NULL;
01464       if (tor_inet_aton(conn->socks_request->address, &in)) {
01465         tor_addr_from_in(&addr, &in);
01466         addrp = &addr;
01467       }
01468       if (router_exit_policy_all_nodes_reject(addrp,
01469                                               conn->socks_request->port,
01470                                               need_uptime)) {
01471         log_notice(LD_APP,
01472                    "No Tor server allows exit to %s:%d. Rejecting.",
01473                    safe_str_client(conn->socks_request->address),
01474                    conn->socks_request->port);
01475         return -1;
01476       }
01477     } else {
01478       /* XXXX024 Duplicates checks in connection_ap_handshake_attach_circuit:
01479        * refactor into a single function? */
01480       const node_t *node = node_get_by_nickname(conn->chosen_exit_name, 1);
01481       int opt = conn->chosen_exit_optional;
01482       if (node && !connection_ap_can_use_exit(conn, node)) {
01483         log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
01484                "Requested exit point '%s' is excluded or "
01485                "would refuse request. %s.",
01486                conn->chosen_exit_name, opt ? "Trying others" : "Closing");
01487         if (opt) {
01488           conn->chosen_exit_optional = 0;
01489           tor_free(conn->chosen_exit_name);
01490           /* Try again. */
01491           return circuit_get_open_circ_or_launch(conn,
01492                                                  desired_circuit_purpose,
01493                                                  circp);
01494         }
01495         return -1;
01496       }
01497     }
01498   }
01499 
01500   /* is one already on the way? */
01501   circ = circuit_get_best(conn, 0, desired_circuit_purpose,
01502                           need_uptime, need_internal);
01503   if (circ)
01504     log_debug(LD_CIRC, "one on the way!");
01505   if (!circ) {
01506     extend_info_t *extend_info=NULL;
01507     uint8_t new_circ_purpose;
01508     const int n_pending = count_pending_general_client_circuits();
01509 
01510     if (n_pending >= options->MaxClientCircuitsPending) {
01511       static ratelim_t delay_limit = RATELIM_INIT(10*60);
01512       char *m;
01513       if ((m = rate_limit_log(&delay_limit, approx_time()))) {
01514         log_notice(LD_APP, "We'd like to launch a circuit to handle a "
01515                    "connection, but we already have %d general-purpose client "
01516                    "circuits pending. Waiting until some finish.",
01517                    n_pending);
01518         tor_free(m);
01519       }
01520       return 0;
01521     }
01522 
01523     if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
01524       /* need to pick an intro point */
01525       rend_data_t *rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data;
01526       tor_assert(rend_data);
01527       extend_info = rend_client_get_random_intro(rend_data);
01528       if (!extend_info) {
01529         log_info(LD_REND,
01530                  "No intro points for '%s': re-fetching service descriptor.",
01531                  safe_str_client(rend_data->onion_address));
01532         rend_client_refetch_v2_renddesc(rend_data);
01533         ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_RENDDESC_WAIT;
01534         return 0;
01535       }
01536       log_info(LD_REND,"Chose %s as intro point for '%s'.",
01537                extend_info_describe(extend_info),
01538                safe_str_client(rend_data->onion_address));
01539     }
01540 
01541     /* If we have specified a particular exit node for our
01542      * connection, then be sure to open a circuit to that exit node.
01543      */
01544     if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_GENERAL) {
01545       if (conn->chosen_exit_name) {
01546         const node_t *r;
01547         int opt = conn->chosen_exit_optional;
01548         r = node_get_by_nickname(conn->chosen_exit_name, 1);
01549         if (r && node_has_descriptor(r)) {
01550           /* We might want to connect to an IPv6 bridge for loading
01551              descriptors so we use the preferred address rather than
01552              the primary.  */
01553           extend_info = extend_info_from_node(r, conn->want_onehop ? 1 : 0);
01554         } else {
01555           log_debug(LD_DIR, "considering %d, %s",
01556                     want_onehop, conn->chosen_exit_name);
01557           if (want_onehop && conn->chosen_exit_name[0] == '$') {
01558             /* We're asking for a one-hop circuit to a router that
01559              * we don't have a routerinfo about. Make up an extend_info. */
01560             char digest[DIGEST_LEN];
01561             char *hexdigest = conn->chosen_exit_name+1;
01562             tor_addr_t addr;
01563             if (strlen(hexdigest) < HEX_DIGEST_LEN ||
01564                 base16_decode(digest,DIGEST_LEN,hexdigest,HEX_DIGEST_LEN)<0) {
01565               log_info(LD_DIR, "Broken exit digest on tunnel conn. Closing.");
01566               return -1;
01567             }
01568             if (tor_addr_parse(&addr, conn->socks_request->address) < 0) {
01569               log_info(LD_DIR, "Broken address %s on tunnel conn. Closing.",
01570                        escaped_safe_str_client(conn->socks_request->address));
01571               return -1;
01572             }
01573             extend_info = extend_info_alloc(conn->chosen_exit_name+1,
01574                                             digest, NULL, &addr,
01575                                             conn->socks_request->port);
01576           } else {
01577             /* We will need an onion key for the router, and we
01578              * don't have one. Refuse or relax requirements. */
01579             log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
01580                    "Requested exit point '%s' is not known. %s.",
01581                    conn->chosen_exit_name, opt ? "Trying others" : "Closing");
01582             if (opt) {
01583               conn->chosen_exit_optional = 0;
01584               tor_free(conn->chosen_exit_name);
01585               /* Try again with no requested exit */
01586               return circuit_get_open_circ_or_launch(conn,
01587                                                      desired_circuit_purpose,
01588                                                      circp);
01589             }
01590             return -1;
01591           }
01592         }
01593       }
01594     }
01595 
01596     if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_REND_JOINED)
01597       new_circ_purpose = CIRCUIT_PURPOSE_C_ESTABLISH_REND;
01598     else if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT)
01599       new_circ_purpose = CIRCUIT_PURPOSE_C_INTRODUCING;
01600     else
01601       new_circ_purpose = desired_circuit_purpose;
01602 
01603     if (options->Tor2webMode &&
01604         (new_circ_purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND ||
01605          new_circ_purpose == CIRCUIT_PURPOSE_C_INTRODUCING)) {
01606       want_onehop = 1;
01607     }
01608 
01609     {
01610       int flags = CIRCLAUNCH_NEED_CAPACITY;
01611       if (want_onehop) flags |= CIRCLAUNCH_ONEHOP_TUNNEL;
01612       if (need_uptime) flags |= CIRCLAUNCH_NEED_UPTIME;
01613       if (need_internal) flags |= CIRCLAUNCH_IS_INTERNAL;
01614       circ = circuit_launch_by_extend_info(new_circ_purpose, extend_info,
01615                                            flags);
01616     }
01617 
01618     extend_info_free(extend_info);
01619 
01620     if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_GENERAL) {
01621       /* We just caused a circuit to get built because of this stream.
01622        * If this stream has caused a _lot_ of circuits to be built, that's
01623        * a bad sign: we should tell the user. */
01624       if (conn->num_circuits_launched < NUM_CIRCUITS_LAUNCHED_THRESHOLD &&
01625           ++conn->num_circuits_launched == NUM_CIRCUITS_LAUNCHED_THRESHOLD)
01626         log_info(LD_CIRC, "The application request to %s:%d has launched "
01627                  "%d circuits without finding one it likes.",
01628                  escaped_safe_str_client(conn->socks_request->address),
01629                  conn->socks_request->port,
01630                  conn->num_circuits_launched);
01631     } else {
01632       /* help predict this next time */
01633       rep_hist_note_used_internal(time(NULL), need_uptime, 1);
01634       if (circ) {
01635         /* write the service_id into circ */
01636         circ->rend_data = rend_data_dup(ENTRY_TO_EDGE_CONN(conn)->rend_data);
01637         if (circ->_base.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND &&
01638             circ->_base.state == CIRCUIT_STATE_OPEN)
01639           rend_client_rendcirc_has_opened(circ);
01640       }
01641     }
01642   } /* endif (!circ) */
01643   if (circ) {
01644     /* Mark the circuit with the isolation fields for this connection.
01645      * When the circuit arrives, we'll clear these flags: this is
01646      * just some internal bookkeeping to make sure that we have
01647      * launched enough circuits.
01648      */
01649     connection_edge_update_circuit_isolation(conn, circ, 0);
01650   } else {
01651     log_info(LD_APP,
01652              "No safe circuit (purpose %d) ready for edge "
01653              "connection; delaying.",
01654              desired_circuit_purpose);
01655   }
01656   *circp = circ;
01657   return 0;
01658 }
01659 
01662 static int
01663 cpath_is_on_circuit(origin_circuit_t *circ, crypt_path_t *crypt_path)
01664 {
01665   crypt_path_t *cpath, *cpath_next = NULL;
01666   for (cpath = circ->cpath; cpath_next != circ->cpath; cpath = cpath_next) {
01667     cpath_next = cpath->next;
01668     if (crypt_path == cpath)
01669       return 1;
01670   }
01671   return 0;
01672 }
01673 
01675 static int
01676 optimistic_data_enabled(void)
01677 {
01678   const or_options_t *options = get_options();
01679   if (options->OptimisticData < 0) {
01680     /* XXX023 consider having auto default to 1 rather than 0 before
01681      * the 0.2.3 branch goes stable. See bug 3617. -RD */
01682     const int32_t enabled =
01683       networkstatus_get_param(NULL, "UseOptimisticData", 0, 0, 1);
01684     return (int)enabled;
01685   }
01686   return options->OptimisticData;
01687 }
01688 
01693 static void
01694 link_apconn_to_circ(entry_connection_t *apconn, origin_circuit_t *circ,
01695                     crypt_path_t *cpath)
01696 {
01697   const node_t *exitnode;
01698 
01699   /* add it into the linked list of streams on this circuit */
01700   log_debug(LD_APP|LD_CIRC, "attaching new conn to circ. n_circ_id %d.",
01701             circ->_base.n_circ_id);
01702   /* reset it, so we can measure circ timeouts */
01703   ENTRY_TO_CONN(apconn)->timestamp_lastread = time(NULL);
01704   ENTRY_TO_EDGE_CONN(apconn)->next_stream = circ->p_streams;
01705   ENTRY_TO_EDGE_CONN(apconn)->on_circuit = TO_CIRCUIT(circ);
01706   /* assert_connection_ok(conn, time(NULL)); */
01707   circ->p_streams = ENTRY_TO_EDGE_CONN(apconn);
01708 
01709   if (connection_edge_is_rendezvous_stream(ENTRY_TO_EDGE_CONN(apconn))) {
01710     /* We are attaching a stream to a rendezvous circuit.  That means
01711      * that an attempt to connect to a hidden service just
01712      * succeeded.  Tell rendclient.c. */
01713     rend_client_note_connection_attempt_ended(
01714                     ENTRY_TO_EDGE_CONN(apconn)->rend_data->onion_address);
01715   }
01716 
01717   if (cpath) { /* we were given one; use it */
01718     tor_assert(cpath_is_on_circuit(circ, cpath));
01719   } else {
01720     /* use the last hop in the circuit */
01721     tor_assert(circ->cpath);
01722     tor_assert(circ->cpath->prev);
01723     tor_assert(circ->cpath->prev->state == CPATH_STATE_OPEN);
01724     cpath = circ->cpath->prev;
01725   }
01726   ENTRY_TO_EDGE_CONN(apconn)->cpath_layer = cpath;
01727 
01728   circ->isolation_any_streams_attached = 1;
01729   connection_edge_update_circuit_isolation(apconn, circ, 0);
01730 
01731   /* See if we can use optimistic data on this circuit */
01732   if (cpath->extend_info &&
01733       (exitnode = node_get_by_id(cpath->extend_info->identity_digest)) &&
01734       exitnode->rs) {
01735     /* Okay; we know what exit node this is. */
01736     if (optimistic_data_enabled() &&
01737         circ->_base.purpose == CIRCUIT_PURPOSE_C_GENERAL &&
01738         exitnode->rs->version_supports_optimistic_data)
01739       apconn->may_use_optimistic_data = 1;
01740     else
01741       apconn->may_use_optimistic_data = 0;
01742     log_info(LD_APP, "Looks like completed circuit to %s %s allow "
01743              "optimistic data for connection to %s",
01744              safe_str_client(node_describe(exitnode)),
01745              apconn->may_use_optimistic_data ? "does" : "doesn't",
01746              safe_str_client(apconn->socks_request->address));
01747   }
01748 }
01749 
01752 int
01753 hostname_in_track_host_exits(const or_options_t *options, const char *address)
01754 {
01755   if (!options->TrackHostExits)
01756     return 0;
01757   SMARTLIST_FOREACH_BEGIN(options->TrackHostExits, const char *, cp) {
01758     if (cp[0] == '.') { /* match end */
01759       if (cp[1] == '\0' ||
01760           !strcasecmpend(address, cp) ||
01761           !strcasecmp(address, &cp[1]))
01762         return 1;
01763     } else if (strcasecmp(cp, address) == 0) {
01764       return 1;
01765     }
01766   } SMARTLIST_FOREACH_END(cp);
01767   return 0;
01768 }
01769 
01774 static void
01775 consider_recording_trackhost(const entry_connection_t *conn,
01776                              const origin_circuit_t *circ)
01777 {
01778   const or_options_t *options = get_options();
01779   char *new_address = NULL;
01780   char fp[HEX_DIGEST_LEN+1];
01781 
01782   /* Search the addressmap for this conn's destination. */
01783   /* If he's not in the address map.. */
01784   if (!options->TrackHostExits ||
01785       addressmap_have_mapping(conn->socks_request->address,
01786                               options->TrackHostExitsExpire))
01787     return; /* nothing to track, or already mapped */
01788 
01789   if (!hostname_in_track_host_exits(options, conn->socks_request->address) ||
01790       !circ->build_state->chosen_exit)
01791     return;
01792 
01793   /* write down the fingerprint of the chosen exit, not the nickname,
01794    * because the chosen exit might not be named. */
01795   base16_encode(fp, sizeof(fp),
01796                 circ->build_state->chosen_exit->identity_digest, DIGEST_LEN);
01797 
01798   /* Add this exit/hostname pair to the addressmap. */
01799   tor_asprintf(&new_address, "%s.%s.exit",
01800                conn->socks_request->address, fp);
01801 
01802   addressmap_register(conn->socks_request->address, new_address,
01803                       time(NULL) + options->TrackHostExitsExpire,
01804                       ADDRMAPSRC_TRACKEXIT, 0, 0);
01805 }
01806 
01812 int
01813 connection_ap_handshake_attach_chosen_circuit(entry_connection_t *conn,
01814                                               origin_circuit_t *circ,
01815                                               crypt_path_t *cpath)
01816 {
01817   connection_t *base_conn = ENTRY_TO_CONN(conn);
01818   tor_assert(conn);
01819   tor_assert(base_conn->state == AP_CONN_STATE_CIRCUIT_WAIT ||
01820              base_conn->state == AP_CONN_STATE_CONTROLLER_WAIT);
01821   tor_assert(conn->socks_request);
01822   tor_assert(circ);
01823   tor_assert(circ->_base.state == CIRCUIT_STATE_OPEN);
01824 
01825   base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
01826 
01827   if (!circ->_base.timestamp_dirty)
01828     circ->_base.timestamp_dirty = time(NULL);
01829 
01830   link_apconn_to_circ(conn, circ, cpath);
01831   tor_assert(conn->socks_request);
01832   if (conn->socks_request->command == SOCKS_COMMAND_CONNECT) {
01833     if (!conn->use_begindir)
01834       consider_recording_trackhost(conn, circ);
01835     if (connection_ap_handshake_send_begin(conn) < 0)
01836       return -1;
01837   } else {
01838     if (connection_ap_handshake_send_resolve(conn) < 0)
01839       return -1;
01840   }
01841 
01842   return 1;
01843 }
01844 
01852 /* XXXX this function should mark for close whenever it returns -1;
01853  * its callers shouldn't have to worry about that. */
01854 int
01855 connection_ap_handshake_attach_circuit(entry_connection_t *conn)
01856 {
01857   connection_t *base_conn = ENTRY_TO_CONN(conn);
01858   int retval;
01859   int conn_age;
01860   int want_onehop;
01861 
01862   tor_assert(conn);
01863   tor_assert(base_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
01864   tor_assert(conn->socks_request);
01865   want_onehop = conn->want_onehop;
01866 
01867   conn_age = (int)(time(NULL) - base_conn->timestamp_created);
01868 
01869   if (conn_age >= get_options()->SocksTimeout) {
01870     int severity = (tor_addr_is_null(&base_conn->addr) && !base_conn->port) ?
01871       LOG_INFO : LOG_NOTICE;
01872     log_fn(severity, LD_APP,
01873            "Tried for %d seconds to get a connection to %s:%d. Giving up.",
01874            conn_age, safe_str_client(conn->socks_request->address),
01875            conn->socks_request->port);
01876     return -1;
01877   }
01878 
01879   if (!connection_edge_is_rendezvous_stream(ENTRY_TO_EDGE_CONN(conn))) {
01880     /* we're a general conn */
01881     origin_circuit_t *circ=NULL;
01882 
01883     if (conn->chosen_exit_name) {
01884       const node_t *node = node_get_by_nickname(conn->chosen_exit_name, 1);
01885       int opt = conn->chosen_exit_optional;
01886       if (!node && !want_onehop) {
01887         /* We ran into this warning when trying to extend a circuit to a
01888          * hidden service directory for which we didn't have a router
01889          * descriptor. See flyspray task 767 for more details. We should
01890          * keep this in mind when deciding to use BEGIN_DIR cells for other
01891          * directory requests as well. -KL*/
01892         log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
01893                "Requested exit point '%s' is not known. %s.",
01894                conn->chosen_exit_name, opt ? "Trying others" : "Closing");
01895         if (opt) {
01896           conn->chosen_exit_optional = 0;
01897           tor_free(conn->chosen_exit_name);
01898           return 0;
01899         }
01900         return -1;
01901       }
01902       if (node && !connection_ap_can_use_exit(conn, node)) {
01903         log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
01904                "Requested exit point '%s' is excluded or "
01905                "would refuse request. %s.",
01906                conn->chosen_exit_name, opt ? "Trying others" : "Closing");
01907         if (opt) {
01908           conn->chosen_exit_optional = 0;
01909           tor_free(conn->chosen_exit_name);
01910           return 0;
01911         }
01912         return -1;
01913       }
01914     }
01915 
01916     /* find the circuit that we should use, if there is one. */
01917     retval = circuit_get_open_circ_or_launch(
01918         conn, CIRCUIT_PURPOSE_C_GENERAL, &circ);
01919     if (retval < 1) // XXX023 if we totally fail, this still returns 0 -RD
01920       return retval;
01921 
01922     log_debug(LD_APP|LD_CIRC,
01923               "Attaching apconn to circ %d (stream %d sec old).",
01924               circ->_base.n_circ_id, conn_age);
01925     /* print the circ's path, so people can figure out which circs are
01926      * sucking. */
01927     circuit_log_path(LOG_INFO,LD_APP|LD_CIRC,circ);
01928 
01929     /* We have found a suitable circuit for our conn. Hurray. */
01930     return connection_ap_handshake_attach_chosen_circuit(conn, circ, NULL);
01931 
01932   } else { /* we're a rendezvous conn */
01933     origin_circuit_t *rendcirc=NULL, *introcirc=NULL;
01934 
01935     tor_assert(!ENTRY_TO_EDGE_CONN(conn)->cpath_layer);
01936 
01937     /* start by finding a rendezvous circuit for us */
01938 
01939     retval = circuit_get_open_circ_or_launch(
01940        conn, CIRCUIT_PURPOSE_C_REND_JOINED, &rendcirc);
01941     if (retval < 0) return -1; /* failed */
01942 
01943     if (retval > 0) {
01944       tor_assert(rendcirc);
01945       /* one is already established, attach */
01946       log_info(LD_REND,
01947                "rend joined circ %d already here. attaching. "
01948                "(stream %d sec old)",
01949                rendcirc->_base.n_circ_id, conn_age);
01950       /* Mark rendezvous circuits as 'newly dirty' every time you use
01951        * them, since the process of rebuilding a rendezvous circ is so
01952        * expensive. There is a tradeoff between linkability and
01953        * feasibility, at this point.
01954        */
01955       rendcirc->_base.timestamp_dirty = time(NULL);
01956       link_apconn_to_circ(conn, rendcirc, NULL);
01957       if (connection_ap_handshake_send_begin(conn) < 0)
01958         return 0; /* already marked, let them fade away */
01959       return 1;
01960     }
01961 
01962     if (rendcirc && (rendcirc->_base.purpose ==
01963                      CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED)) {
01964       log_info(LD_REND,
01965                "pending-join circ %d already here, with intro ack. "
01966                "Stalling. (stream %d sec old)",
01967                 rendcirc->_base.n_circ_id, conn_age);
01968       return 0;
01969     }
01970 
01971     /* it's on its way. find an intro circ. */
01972     retval = circuit_get_open_circ_or_launch(
01973       conn, CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT, &introcirc);
01974     if (retval < 0) return -1; /* failed */
01975 
01976     if (retval > 0) {
01977       /* one has already sent the intro. keep waiting. */
01978       circuit_t *c = NULL;
01979       tor_assert(introcirc);
01980       log_info(LD_REND, "Intro circ %d present and awaiting ack (rend %d). "
01981                "Stalling. (stream %d sec old)",
01982                introcirc->_base.n_circ_id,
01983                rendcirc ? rendcirc->_base.n_circ_id : 0,
01984                conn_age);
01985       /* abort parallel intro circs, if any */
01986       for (c = global_circuitlist; c; c = c->next) {
01987         if (c->purpose == CIRCUIT_PURPOSE_C_INTRODUCING &&
01988             !c->marked_for_close && CIRCUIT_IS_ORIGIN(c)) {
01989           origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(c);
01990           if (oc->rend_data &&
01991               !rend_cmp_service_ids(
01992                             ENTRY_TO_EDGE_CONN(conn)->rend_data->onion_address,
01993                             oc->rend_data->onion_address)) {
01994             log_info(LD_REND|LD_CIRC, "Closing introduction circuit that we "
01995                      "built in parallel.");
01996             circuit_mark_for_close(c, END_CIRC_REASON_TIMEOUT);
01997           }
01998         }
01999       }
02000       return 0;
02001     }
02002 
02003     /* now rendcirc and introcirc are each either undefined or not finished */
02004 
02005     if (rendcirc && introcirc &&
02006         rendcirc->_base.purpose == CIRCUIT_PURPOSE_C_REND_READY) {
02007       log_info(LD_REND,
02008                "ready rend circ %d already here (no intro-ack yet on "
02009                "intro %d). (stream %d sec old)",
02010                rendcirc->_base.n_circ_id,
02011                introcirc->_base.n_circ_id, conn_age);
02012 
02013       tor_assert(introcirc->_base.purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
02014       if (introcirc->_base.state == CIRCUIT_STATE_OPEN) {
02015         log_info(LD_REND,"found open intro circ %d (rend %d); sending "
02016                  "introduction. (stream %d sec old)",
02017                  introcirc->_base.n_circ_id, rendcirc->_base.n_circ_id,
02018                  conn_age);
02019         switch (rend_client_send_introduction(introcirc, rendcirc)) {
02020         case 0: /* success */
02021           rendcirc->_base.timestamp_dirty = time(NULL);
02022           introcirc->_base.timestamp_dirty = time(NULL);
02023           assert_circuit_ok(TO_CIRCUIT(rendcirc));
02024           assert_circuit_ok(TO_CIRCUIT(introcirc));
02025           return 0;
02026         case -1: /* transient error */
02027           return 0;
02028         case -2: /* permanent error */
02029           return -1;
02030         default: /* oops */
02031           tor_fragile_assert();
02032           return -1;
02033         }
02034       }
02035     }
02036 
02037     log_info(LD_REND, "Intro (%d) and rend (%d) circs are not both ready. "
02038              "Stalling conn. (%d sec old)",
02039              introcirc ? introcirc->_base.n_circ_id : 0,
02040              rendcirc ? rendcirc->_base.n_circ_id : 0, conn_age);
02041     return 0;
02042   }
02043 }
02044 
02046 void
02047 circuit_change_purpose(circuit_t *circ, uint8_t new_purpose)
02048 {
02049   uint8_t old_purpose;
02050   /* Don't allow an OR circ to become an origin circ or vice versa. */
02051   tor_assert(!!(CIRCUIT_IS_ORIGIN(circ)) ==
02052              !!(CIRCUIT_PURPOSE_IS_ORIGIN(new_purpose)));
02053 
02054   if (circ->purpose == new_purpose) return;
02055 
02056   if (CIRCUIT_IS_ORIGIN(circ)) {
02057     char old_purpose_desc[80] = "";
02058 
02059     strncpy(old_purpose_desc, circuit_purpose_to_string(circ->purpose), 80-1);
02060     old_purpose_desc[80-1] = '\0';
02061 
02062     log_debug(LD_CIRC,
02063               "changing purpose of origin circ %d "
02064               "from \"%s\" (%d) to \"%s\" (%d)",
02065               TO_ORIGIN_CIRCUIT(circ)->global_identifier,
02066               old_purpose_desc,
02067               circ->purpose,
02068               circuit_purpose_to_string(new_purpose),
02069               new_purpose);
02070   }
02071 
02072   old_purpose = circ->purpose;
02073   circ->purpose = new_purpose;
02074 
02075   if (CIRCUIT_IS_ORIGIN(circ)) {
02076     control_event_circuit_purpose_changed(TO_ORIGIN_CIRCUIT(circ),
02077                                           old_purpose);
02078   }
02079 }
02080