Back to index

tor  0.2.3.19-rc
Defines | Functions
config.h File Reference

Header file for config.c. More...

Go to the source code of this file.

Defines

#define get_datadir_fname2_suffix(sub1, sub2, suffix)   options_get_datadir_fname2_suffix(get_options(), (sub1), (sub2), (suffix))
#define get_datadir_fname(sub1)   get_datadir_fname2_suffix((sub1), NULL, NULL)
 Return a newly allocated string containing datadir/sub1.
#define get_datadir_fname2(sub1, sub2)   get_datadir_fname2_suffix((sub1), (sub2), NULL)
 Return a newly allocated string containing datadir/sub1/sub2.
#define get_datadir_fname_suffix(sub1, suffix)   get_datadir_fname2_suffix((sub1), NULL, (suffix))
 Return a newly allocated string containing datadir/sub1suffix.
#define get_primary_or_port()   (get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER, AF_INET))
#define get_primary_dir_port()   (get_first_advertised_port_by_type_af(CONN_TYPE_DIR_LISTENER, AF_INET))

Functions

const char * get_dirportfrontpage (void)
 Return the contents of our frontpage string, or NULL if not configured.
const or_options_tget_options (void)
 Returns the currently configured options.
or_options_tget_options_mutable (void)
 Return the currently configured options.
int set_options (or_options_t *new_val, char **msg)
 Change the current global options to contain new_val instead of their current value; take action based on the new value; free the old value as necessary.
void config_free_all (void)
 Release all memory and resources held by global configuration structures.
const char * safe_str_client (const char *address)
 Make address -- a piece of information related to our operation as a client -- safe to log according to the settings in options->SafeLogging, and return it.
const char * safe_str (const char *address)
 Make address -- a piece of information of unspecified sensitivity -- safe to log according to the settings in options->SafeLogging, and return it.
const char * escaped_safe_str_client (const char *address)
 Equivalent to escaped(safe_str_client(address)).
const char * escaped_safe_str (const char *address)
 Equivalent to escaped(safe_str(address)).
const char * get_version (void)
 Return the current Tor version.
const char * get_short_version (void)
 Return the current Tor version, without any git tag.
int config_get_lines (const char *string, config_line_t **result, int extended)
 Helper: parse the config string and strdup into key/value strings.
void config_free_lines (config_line_t *front)
 Free all the configuration lines on the linked list front.
setopt_err_t options_trial_assign (config_line_t *list, int use_defaults, int clear_first, char **msg)
 Try assigning list to the global options.
int resolve_my_address (int warn_severity, const or_options_t *options, uint32_t *addr, char **hostname_out)
 Based on options->Address, guess our public IP address and put it (in host order) into *addr_out.
int is_local_addr (const tor_addr_t *addr)
 Return true iff addr is judged to be on the same network as us, or on a private network.
void options_init (or_options_t *options)
 Set options to hold reasonable defaults for most options.
char * options_dump (const or_options_t *options, int minimal)
 Return a string containing a possible configuration file that would give the configuration in options.
int options_init_from_torrc (int argc, char **argv)
 Read a configuration file into options, finding the configuration file location based on the command line.
setopt_err_t options_init_from_string (const char *cf_defaults, const char *cf, int command, const char *command_arg, char **msg)
 Load the options from the configuration in cf, validate them for consistency and take actions based on them.
int option_is_recognized (const char *key)
 Return true iff key is a valid configuration option.
const char * option_get_canonical_name (const char *key)
 Return the canonical name of a configuration option, or NULL if no such option exists.
config_line_toption_get_assignment (const or_options_t *options, const char *key)
 Return a canonical list of the options assigned for key.
int options_save_current (void)
 Save the current configuration file value to disk.
const char * get_torrc_fname (int defaults_fname)
 Return the location for our configuration file.
char * options_get_datadir_fname2_suffix (const or_options_t *options, const char *sub1, const char *sub2, const char *suffix)
 Return a newly allocated string holding a filename relative to the data directory.
int get_num_cpus (const or_options_t *options)
 Return the number of cpus configured in options.
or_state_tget_or_state (void)
 Return the persistent state struct for this Tor.
int did_last_state_file_write_fail (void)
 Return whether the state file failed to write last time we tried.
int or_state_save (time_t now)
 Write the persistent state to disk.
const smartlist_tget_configured_ports (void)
 Return a list of port_cfg_t for client ports parsed from the options.
int get_first_advertised_port_by_type_af (int listener_type, int address_family)
 Return the first advertised port of type listener_type in address_family.
char * get_first_listener_addrport_string (int listener_type)
 Return an address:port string representation of the address where the first listener_type listener waits for connections.
int options_need_geoip_info (const or_options_t *options, const char **reason_out)
 If we need to have a GEOIP ip-to-country map to run with our configured options, return 1 and set *reason_out to a description of why.
void save_transport_to_state (const char *transport_name, const tor_addr_t *addr, uint16_t port)
 Save transport listening on addr:port to state.
char * get_stored_bindaddr_for_server_transport (const char *transport)
 Return a string containing the address:port that a proxy transport should bind on.
int getinfo_helper_config (control_connection_t *conn, const char *question, char **answer, const char **errmsg)
 Helper to implement GETINFO functions about configuration variables (not their values).
const char * tor_get_digests (void)
 Return a string describing the digest of the source files in src/or/.
uint32_t get_effective_bwrate (const or_options_t *options)
 Return the bandwidthrate that we are going to report to the authorities based on the config options.
uint32_t get_effective_bwburst (const or_options_t *options)
 Return the bandwidthburst that we are going to report to the authorities based on the config options.
void config_register_addressmaps (const or_options_t *options)
 Adjust the address map based on the MapAddress elements in the configuration options

Detailed Description

Header file for config.c.

Definition in file config.h.


Define Documentation

#define get_datadir_fname (   sub1)    get_datadir_fname2_suffix((sub1), NULL, NULL)

Return a newly allocated string containing datadir/sub1.

See get_datadir_fname2_suffix.

Definition at line 52 of file config.h.

#define get_datadir_fname2 (   sub1,
  sub2 
)    get_datadir_fname2_suffix((sub1), (sub2), NULL)

Return a newly allocated string containing datadir/sub1/sub2.

See get_datadir_fname2_suffix.

Definition at line 55 of file config.h.

#define get_datadir_fname2_suffix (   sub1,
  sub2,
  suffix 
)    options_get_datadir_fname2_suffix(get_options(), (sub1), (sub2), (suffix))

Definition at line 48 of file config.h.

#define get_datadir_fname_suffix (   sub1,
  suffix 
)    get_datadir_fname2_suffix((sub1), NULL, (suffix))

Return a newly allocated string containing datadir/sub1suffix.

See get_datadir_fname2_suffix.

Definition at line 59 of file config.h.

Definition at line 73 of file config.h.

Definition at line 71 of file config.h.


Function Documentation

void config_free_all ( void  )

Release all memory and resources held by global configuration structures.

Definition at line 853 of file config.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void config_free_lines ( config_line_t front)

Free all the configuration lines on the linked list front.

Definition at line 2032 of file config.c.

{
  config_line_t *tmp;

  while (front) {
    tmp = front;
    front = tmp->next;

    tor_free(tmp->key);
    tor_free(tmp->value);
    tor_free(tmp);
  }
}

Here is the caller graph for this function:

int config_get_lines ( const char *  string,
config_line_t **  result,
int  extended 
)

Helper: parse the config string and strdup into key/value strings.

Set *result to the list, or NULL if parsing the string failed. Return 0 on success, -1 on failure. Warn and ignore any misformatted lines.

If extended is set, then treat keys beginning with / and with + as indicating "clear" and "append" respectively.

Definition at line 1977 of file config.c.

{
  config_line_t *list = NULL, **next;
  char *k, *v;

  next = &list;
  do {
    k = v = NULL;
    string = parse_config_line_from_str(string, &k, &v);
    if (!string) {
      config_free_lines(list);
      tor_free(k);
      tor_free(v);
      return -1;
    }
    if (k && v) {
      unsigned command = CONFIG_LINE_NORMAL;
      if (extended) {
        if (k[0] == '+') {
          char *k_new = tor_strdup(k+1);
          tor_free(k);
          k = k_new;
          command = CONFIG_LINE_APPEND;
        } else if (k[0] == '/') {
          char *k_new = tor_strdup(k+1);
          tor_free(k);
          k = k_new;
          tor_free(v);
          v = tor_strdup("");
          command = CONFIG_LINE_CLEAR;
        }
      }
      /* This list can get long, so we keep a pointer to the end of it
       * rather than using config_line_append over and over and getting
       * n^2 performance. */
      *next = tor_malloc_zero(sizeof(config_line_t));
      (*next)->key = k;
      (*next)->value = v;
      (*next)->next = NULL;
      (*next)->command = command;
      next = &((*next)->next);
    } else {
      tor_free(k);
      tor_free(v);
    }
  } while (*string);

  *result = list;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void config_register_addressmaps ( const or_options_t options)

Adjust the address map based on the MapAddress elements in the configuration options

Definition at line 4823 of file config.c.

{
  smartlist_t *elts;
  config_line_t *opt;
  char *from, *to;

  addressmap_clear_configured();
  elts = smartlist_new();
  for (opt = options->AddressMap; opt; opt = opt->next) {
    int from_wildcard = 0, to_wildcard = 0;
    smartlist_split_string(elts, opt->value, NULL,
                           SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
    if (smartlist_len(elts) < 2) {
      log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
               opt->value);
      goto cleanup;
    }

    from = smartlist_get(elts,0);
    to = smartlist_get(elts,1);

    if (to[0] == '.' || from[0] == '.') {
      log_warn(LD_CONFIG,"MapAddress '%s' is ambiguous - address starts with a"
              "'.'. Ignoring.",opt->value);
      goto cleanup;
    }

    if (!strcmp(to, "*") || !strcmp(from, "*")) {
      log_warn(LD_CONFIG,"MapAddress '%s' is unsupported - can't remap from "
               "or to *. Ignoring.",opt->value);
      goto cleanup;
    }
    /* Detect asterisks in expressions of type: '*.example.com' */
    if (!strncmp(from,"*.",2)) {
      from += 2;
      from_wildcard = 1;
    }
    if (!strncmp(to,"*.",2)) {
      to += 2;
      to_wildcard = 1;
    }

    if (to_wildcard && !from_wildcard) {
      log_warn(LD_CONFIG,
                "Skipping invalid argument '%s' to MapAddress: "
                "can only use wildcard (i.e. '*.') if 'from' address "
                "uses wildcard also", opt->value);
      goto cleanup;
    }

    if (address_is_invalid_destination(to, 1)) {
      log_warn(LD_CONFIG,
                "Skipping invalid argument '%s' to MapAddress", opt->value);
      goto cleanup;
    }

    addressmap_register(from, tor_strdup(to), 0, ADDRMAPSRC_TORRC,
                        from_wildcard, to_wildcard);

    if (smartlist_len(elts) > 2)
      log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");

  cleanup:
    SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
    smartlist_clear(elts);
  }
  smartlist_free(elts);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Return whether the state file failed to write last time we tried.

Definition at line 6895 of file config.c.

Here is the caller graph for this function:

const char* escaped_safe_str ( const char *  address)

Equivalent to escaped(safe_str(address)).

See reentrancy note on escaped(): don't use this outside the main thread, or twice in the same log statement.

Definition at line 928 of file config.c.

{
  if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
    return "[scrubbed]";
  else
    return escaped(address);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* escaped_safe_str_client ( const char *  address)

Equivalent to escaped(safe_str_client(address)).

See reentrancy note on escaped(): don't use this outside the main thread, or twice in the same log statement.

Definition at line 916 of file config.c.

{
  if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
    return "[scrubbed]";
  else
    return escaped(address);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const smartlist_t* get_configured_ports ( void  )

Return a list of port_cfg_t for client ports parsed from the options.

Definition at line 6126 of file config.c.

Here is the call graph for this function:

Here is the caller graph for this function:

const char* get_dirportfrontpage ( void  )

Return the contents of our frontpage string, or NULL if not configured.

Definition at line 705 of file config.c.

Here is the caller graph for this function:

uint32_t get_effective_bwburst ( const or_options_t options)

Return the bandwidthburst that we are going to report to the authorities based on the config options.

Definition at line 1323 of file config.c.

{
  uint64_t bw = options->BandwidthBurst;
  if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
    bw = options->RelayBandwidthBurst;
  /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
  return (uint32_t)bw;
}

Here is the caller graph for this function:

uint32_t get_effective_bwrate ( const or_options_t options)

Return the bandwidthrate that we are going to report to the authorities based on the config options.

Definition at line 1309 of file config.c.

{
  uint64_t bw = options->BandwidthRate;
  if (bw > options->MaxAdvertisedBandwidth)
    bw = options->MaxAdvertisedBandwidth;
  if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
    bw = options->RelayBandwidthRate;
  /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
  return (uint32_t)bw;
}

Here is the caller graph for this function:

int get_first_advertised_port_by_type_af ( int  listener_type,
int  address_family 
)

Return the first advertised port of type listener_type in address_family.

Definition at line 6195 of file config.c.

{
  if (!configured_ports)
    return 0;
  SMARTLIST_FOREACH_BEGIN(configured_ports, const port_cfg_t *, cfg) {
    if (cfg->type == listener_type &&
        !cfg->no_advertise &&
        (tor_addr_family(&cfg->addr) == address_family ||
         tor_addr_family(&cfg->addr) == AF_UNSPEC)) {
      if (tor_addr_family(&cfg->addr) != AF_UNSPEC ||
          (address_family == AF_INET && !cfg->ipv6_only) ||
          (address_family == AF_INET6 && !cfg->ipv4_only)) {
        return cfg->port;
      }
    }
  } SMARTLIST_FOREACH_END(cfg);
  return 0;
}

Here is the call graph for this function:

char* get_first_listener_addrport_string ( int  listener_type)

Return an address:port string representation of the address where the first listener_type listener waits for connections.

Return NULL if we couldn't find a listener. The string is allocated on the heap and it's the responsibility of the caller to free it after use.

This function is meant to be used by the pluggable transport proxy spawning code, please make sure that it fits your purposes before using it.

Definition at line 6143 of file config.c.

{
  static const char *ipv4_localhost = "127.0.0.1";
  static const char *ipv6_localhost = "[::1]";
  const char *address;
  uint16_t port;
  char *string = NULL;

  if (!configured_ports)
    return NULL;

  SMARTLIST_FOREACH_BEGIN(configured_ports, const port_cfg_t *, cfg) {
    if (cfg->no_listen)
      continue;

    if (cfg->type == listener_type &&
        tor_addr_family(&cfg->addr) != AF_UNSPEC) {

      /* We found the first listener of the type we are interested in! */

      /* If a listener is listening on INADDR_ANY, assume that it's
         also listening on 127.0.0.1, and point the transport proxy
         there: */
      if (tor_addr_is_null(&cfg->addr))
        address = tor_addr_is_v4(&cfg->addr) ? ipv4_localhost : ipv6_localhost;
      else
        address = fmt_and_decorate_addr(&cfg->addr);

      /* If a listener is configured with port 'auto', we are forced
         to iterate all listener connections and find out in which
         port it ended up listening: */
      if (cfg->port == CFG_AUTO_PORT) {
        port = router_get_active_listener_port_by_type(listener_type);
        if (!port)
          return NULL;
      } else {
        port = cfg->port;
      }

      tor_asprintf(&string, "%s:%u", address, port);

      return string;
    }

  } SMARTLIST_FOREACH_END(cfg);

  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int get_num_cpus ( const or_options_t options)

Return the number of cpus configured in options.

If we are told to auto-detect the number of cpus, return the auto-detected number.

Definition at line 6544 of file config.c.

{
  if (options->NumCPUs == 0) {
    int n = compute_num_cpus();
    return (n >= 1) ? n : 1;
  } else {
    return options->NumCPUs;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

const or_options_t* get_options ( void  )

Returns the currently configured options.

Definition at line 730 of file config.c.

{
  return get_options_mutable();
}

Here is the call graph for this function:

Return the currently configured options.

Definition at line 722 of file config.c.

Here is the caller graph for this function:

or_state_t* get_or_state ( void  )

Return the persistent state struct for this Tor.

Definition at line 6596 of file config.c.

Here is the caller graph for this function:

const char* get_short_version ( void  )

Return the current Tor version, without any git tag.

Definition at line 819 of file config.c.

{

  if (the_short_tor_version == NULL) {
#ifdef TOR_BUILD_TAG
    tor_asprintf(&the_short_tor_version, "%s (%s)", VERSION, TOR_BUILD_TAG);
#else
    the_short_tor_version = tor_strdup(VERSION);
#endif
  }
  return the_short_tor_version;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* get_stored_bindaddr_for_server_transport ( const char *  transport)

Return a string containing the address:port that a proxy transport should bind on.

The string is stored on the heap and must be freed by the caller of this function.

If we didn't find references for this pluggable transport in the state file, we should instruct the pluggable transport proxy to listen on INADDR_ANY on a random ephemeral port.

Definition at line 7035 of file config.c.

{
  char *default_addrport = NULL;
  const char *stored_bindaddr = NULL;

  config_line_t *line = get_transport_in_state_by_name(transport);
  if (!line) /* Found no references in state for this transport. */
    goto no_bindaddr_found;

  stored_bindaddr = get_transport_bindaddr(line->value, transport);
  if (stored_bindaddr) /* found stored bindaddr in state file. */
    return tor_strdup(stored_bindaddr);

 no_bindaddr_found:
  tor_asprintf(&default_addrport, "%s:%s", fmt_addr32(INADDR_ANY), "0");
  return default_addrport;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* get_torrc_fname ( int  defaults_fname)

Return the location for our configuration file.

Definition at line 4809 of file config.c.

{
  const char *fname = defaults_fname ? torrc_defaults_fname : torrc_fname;

  if (fname)
    return fname;
  else
    return get_default_conf_file(defaults_fname);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* get_version ( void  )

Return the current Tor version.

Definition at line 804 of file config.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int getinfo_helper_config ( control_connection_t conn,
const char *  question,
char **  answer,
const char **  errmsg 
)

Helper to implement GETINFO functions about configuration variables (not their values).

Given a "config/names" question, set *answer to a new string describing the supported configuration variables and their types.

Definition at line 7142 of file config.c.

{
  (void) conn;
  (void) errmsg;
  if (!strcmp(question, "config/names")) {
    smartlist_t *sl = smartlist_new();
    int i;
    for (i = 0; _option_vars[i].name; ++i) {
      const config_var_t *var = &_option_vars[i];
      const char *type;
      switch (var->type) {
        case CONFIG_TYPE_STRING: type = "String"; break;
        case CONFIG_TYPE_FILENAME: type = "Filename"; break;
        case CONFIG_TYPE_UINT: type = "Integer"; break;
        case CONFIG_TYPE_INT: type = "SignedInteger"; break;
        case CONFIG_TYPE_PORT: type = "Port"; break;
        case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
        case CONFIG_TYPE_MSEC_INTERVAL: type = "TimeMsecInterval"; break;
        case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
        case CONFIG_TYPE_DOUBLE: type = "Float"; break;
        case CONFIG_TYPE_BOOL: type = "Boolean"; break;
        case CONFIG_TYPE_AUTOBOOL: type = "Boolean+Auto"; break;
        case CONFIG_TYPE_ISOTIME: type = "Time"; break;
        case CONFIG_TYPE_ROUTERSET: type = "RouterList"; break;
        case CONFIG_TYPE_CSV: type = "CommaList"; break;
        case CONFIG_TYPE_LINELIST: type = "LineList"; break;
        case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
        case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
        default:
        case CONFIG_TYPE_OBSOLETE:
          type = NULL; break;
      }
      if (!type)
        continue;
      smartlist_add_asprintf(sl, "%s %s\n",var->name,type);
    }
    *answer = smartlist_join_strings(sl, "", 0, NULL);
    SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
    smartlist_free(sl);
  }
  return 0;
}

Here is the call graph for this function:

int is_local_addr ( const tor_addr_t addr)

Return true iff addr is judged to be on the same network as us, or on a private network.

Definition at line 3007 of file config.c.

{
  if (tor_addr_is_internal(addr, 0))
    return 1;
  /* Check whether ip is on the same /24 as we are. */
  if (get_options()->EnforceDistinctSubnets == 0)
    return 0;
  if (tor_addr_family(addr) == AF_INET) {
    /*XXXX023 IP6 what corresponds to an /24? */
    uint32_t ip = tor_addr_to_ipv4h(addr);

    /* It's possible that this next check will hit before the first time
     * resolve_my_address actually succeeds.  (For clients, it is likely that
     * resolve_my_address will never be called at all).  In those cases,
     * last_resolved_addr will be 0, and so checking to see whether ip is on
     * the same /24 as last_resolved_addr will be the same as checking whether
     * it was on net 0, which is already done by is_internal_IP.
     */
    if ((last_resolved_addr & (uint32_t)0xffffff00ul)
        == (ip & (uint32_t)0xffffff00ul))
      return 1;
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

config_line_t* option_get_assignment ( const or_options_t options,
const char *  key 
)

Return a canonical list of the options assigned for key.

Definition at line 2408 of file config.c.

{
  return get_assigned_option(&options_format, options, key, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* option_get_canonical_name ( const char *  key)

Return the canonical name of a configuration option, or NULL if no such option exists.

Definition at line 2399 of file config.c.

{
  const config_var_t *var = config_find_option(&options_format, key);
  return var ? var->name : NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int option_is_recognized ( const char *  key)

Return true iff key is a valid configuration option.

Definition at line 2390 of file config.c.

{
  const config_var_t *var = config_find_option(&options_format, key);
  return (var != NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* options_dump ( const or_options_t options,
int  minimal 
)

Return a string containing a possible configuration file that would give the configuration in options.

If minimal is true, do not include options that are the same as Tor's defaults.

Definition at line 3227 of file config.c.

{
  return config_dump(&options_format, global_default_options,
                     options, minimal, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* options_get_datadir_fname2_suffix ( const or_options_t options,
const char *  sub1,
const char *  sub2,
const char *  suffix 
)

Return a newly allocated string holding a filename relative to the data directory.

If sub1 is present, it is the first path component after the data directory. If sub2 is also present, it is the second path component after the data directory. If suffix is present, it is appended to the filename.

Examples: get_datadir_fname2_suffix("a", NULL, NULL) -> $DATADIR/a get_datadir_fname2_suffix("a", NULL, ".tmp") -> $DATADIR/a.tmp get_datadir_fname2_suffix("a", "b", ".tmp") -> $DATADIR/a/b/.tmp get_datadir_fname2_suffix("a", "b", NULL) -> $DATADIR/a/b

Note: Consider using the get_datadir_fname* macros in or.h.

Definition at line 6617 of file config.c.

{
  char *fname = NULL;
  size_t len;
  tor_assert(options);
  tor_assert(options->DataDirectory);
  tor_assert(sub1 || !sub2); /* If sub2 is present, sub1 must be present. */
  len = strlen(options->DataDirectory);
  if (sub1) {
    len += strlen(sub1)+1;
    if (sub2)
      len += strlen(sub2)+1;
  }
  if (suffix)
    len += strlen(suffix);
  len++;
  fname = tor_malloc(len);
  if (sub1) {
    if (sub2) {
      tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s"PATH_SEPARATOR"%s",
                   options->DataDirectory, sub1, sub2);
    } else {
      tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s",
                   options->DataDirectory, sub1);
    }
  } else {
    strlcpy(fname, options->DataDirectory, len);
  }
  if (suffix)
    strlcat(fname, suffix, len);
  return fname;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void options_init ( or_options_t options)

Set options to hold reasonable defaults for most options.

Each option defaults to zero.

Definition at line 3129 of file config.c.

{
  config_init(&options_format, options);
}

Here is the call graph for this function:

Here is the caller graph for this function:

setopt_err_t options_init_from_string ( const char *  cf_defaults,
const char *  cf,
int  command,
const char *  command_arg,
char **  msg 
)

Load the options from the configuration in cf, validate them for consistency and take actions based on them.

Return 0 if success, negative on error:

  • -1 for general errors.
  • -2 for failure to parse/validate,
  • -3 for transition not allowed
  • -4 for error while setting the new options

Definition at line 4667 of file config.c.

{
  or_options_t *oldoptions, *newoptions, *newdefaultoptions=NULL;
  config_line_t *cl;
  int retval, i;
  setopt_err_t err = SETOPT_ERR_MISC;
  tor_assert(msg);

  oldoptions = global_options; /* get_options unfortunately asserts if
                                  this is the first time we run*/

  newoptions = tor_malloc_zero(sizeof(or_options_t));
  newoptions->_magic = OR_OPTIONS_MAGIC;
  options_init(newoptions);
  newoptions->command = command;
  newoptions->command_arg = command_arg;

  for (i = 0; i < 2; ++i) {
    const char *body = i==0 ? cf_defaults : cf;
    if (!body)
      continue;
    /* get config lines, assign them */
    retval = config_get_lines(body, &cl, 1);
    if (retval < 0) {
      err = SETOPT_ERR_PARSE;
      goto err;
    }
    retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
    config_free_lines(cl);
    if (retval < 0) {
      err = SETOPT_ERR_PARSE;
      goto err;
    }
    if (i==0)
      newdefaultoptions = options_dup(&options_format, newoptions);
  }

  /* Go through command-line variables too */
  retval = config_assign(&options_format, newoptions,
                         global_cmdline_options, 0, 0, msg);
  if (retval < 0) {
    err = SETOPT_ERR_PARSE;
    goto err;
  }

  /* If this is a testing network configuration, change defaults
   * for a list of dependent config options, re-initialize newoptions
   * with the new defaults, and assign all options to it second time. */
  if (newoptions->TestingTorNetwork) {
    /* XXXX this is a bit of a kludge.  perhaps there's a better way to do
     * this?  We could, for example, make the parsing algorithm do two passes
     * over the configuration.  If it finds any "suite" options like
     * TestingTorNetwork, it could change the defaults before its second pass.
     * Not urgent so long as this seems to work, but at any sign of trouble,
     * let's clean it up.  -NM */

    /* Change defaults. */
    int i;
    for (i = 0; testing_tor_network_defaults[i].name; ++i) {
      const config_var_t *new_var = &testing_tor_network_defaults[i];
      config_var_t *old_var =
          config_find_option_mutable(&options_format, new_var->name);
      tor_assert(new_var);
      tor_assert(old_var);
      old_var->initvalue = new_var->initvalue;
    }

    /* Clear newoptions and re-initialize them with new defaults. */
    config_free(&options_format, newoptions);
    config_free(&options_format, newdefaultoptions);
    newdefaultoptions = NULL;
    newoptions = tor_malloc_zero(sizeof(or_options_t));
    newoptions->_magic = OR_OPTIONS_MAGIC;
    options_init(newoptions);
    newoptions->command = command;
    newoptions->command_arg = command_arg;

    /* Assign all options a second time. */
    for (i = 0; i < 2; ++i) {
      const char *body = i==0 ? cf_defaults : cf;
      if (!body)
        continue;
      /* get config lines, assign them */
      retval = config_get_lines(body, &cl, 1);
      if (retval < 0) {
        err = SETOPT_ERR_PARSE;
        goto err;
      }
      retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
      config_free_lines(cl);
      if (retval < 0) {
        err = SETOPT_ERR_PARSE;
        goto err;
      }
      if (i==0)
        newdefaultoptions = options_dup(&options_format, newoptions);
    }
    /* Assign command-line variables a second time too */
    retval = config_assign(&options_format, newoptions,
                           global_cmdline_options, 0, 0, msg);
    if (retval < 0) {
      err = SETOPT_ERR_PARSE;
      goto err;
    }
  }

  /* Validate newoptions */
  if (options_validate(oldoptions, newoptions, 0, msg) < 0) {
    err = SETOPT_ERR_PARSE; /*XXX make this a separate return value.*/
    goto err;
  }

  if (options_transition_allowed(oldoptions, newoptions, msg) < 0) {
    err = SETOPT_ERR_TRANSITION;
    goto err;
  }

  if (set_options(newoptions, msg)) {
    err = SETOPT_ERR_SETTING;
    goto err; /* frees and replaces old options */
  }
  config_free(&options_format, global_default_options);
  global_default_options = newdefaultoptions;

  return SETOPT_OK;

 err:
  config_free(&options_format, newoptions);
  config_free(&options_format, newdefaultoptions);
  if (*msg) {
    char *old_msg = *msg;
    tor_asprintf(msg, "Failed to parse/validate config: %s", old_msg);
    tor_free(old_msg);
  }
  return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int options_init_from_torrc ( int  argc,
char **  argv 
)

Read a configuration file into options, finding the configuration file location based on the command line.

After loading the file call options_init_from_string() to load the config. Return 0 if success, -1 if failure.

Definition at line 4574 of file config.c.

{
  char *cf=NULL, *cf_defaults=NULL;
  int i, command;
  int retval = -1;
  static char **backup_argv;
  static int backup_argc;
  char *command_arg = NULL;
  char *errmsg=NULL;

  if (argv) { /* first time we're called. save command line args */
    backup_argv = argv;
    backup_argc = argc;
  } else { /* we're reloading. need to clean up old options first. */
    argv = backup_argv;
    argc = backup_argc;
  }
  if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
    print_usage();
    exit(0);
  }
  if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
    /* For documenting validating whether we've documented everything. */
    list_torrc_options();
    exit(0);
  }

  if (argc > 1 && (!strcmp(argv[1],"--version"))) {
    printf("Tor version %s.\n",get_version());
    exit(0);
  }
  if (argc > 1 && (!strcmp(argv[1],"--digests"))) {
    printf("Tor version %s.\n",get_version());
    printf("%s", libor_get_digests());
    printf("%s", tor_get_digests());
    exit(0);
  }

  /* Go through command-line variables */
  if (!global_cmdline_options) {
    /* Or we could redo the list every time we pass this place.
     * It does not really matter */
    if (config_get_commandlines(argc, argv, &global_cmdline_options) < 0) {
      goto err;
    }
  }

  command = CMD_RUN_TOR;
  for (i = 1; i < argc; ++i) {
    if (!strcmp(argv[i],"--list-fingerprint")) {
      command = CMD_LIST_FINGERPRINT;
    } else if (!strcmp(argv[i],"--hash-password")) {
      command = CMD_HASH_PASSWORD;
      command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
      ++i;
    } else if (!strcmp(argv[i],"--verify-config")) {
      command = CMD_VERIFY_CONFIG;
    }
  }

  if (command == CMD_HASH_PASSWORD) {
    cf = tor_strdup("");
  } else {
    cf_defaults = load_torrc_from_disk(argc, argv, 1);
    cf = load_torrc_from_disk(argc, argv, 0);
    if (!cf)
      goto err;
  }

  retval = options_init_from_string(cf_defaults, cf, command, command_arg,
                                    &errmsg);

 err:

  tor_free(cf);
  tor_free(cf_defaults);
  if (errmsg) {
    log(LOG_WARN,LD_CONFIG,"%s", errmsg);
    tor_free(errmsg);
  }
  return retval < 0 ? -1 : 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int options_need_geoip_info ( const or_options_t options,
const char **  reason_out 
)

If we need to have a GEOIP ip-to-country map to run with our configured options, return 1 and set *reason_out to a description of why.

Definition at line 1284 of file config.c.

{
  int bridge_usage =
    options->BridgeRelay && options->BridgeRecordUsageByCountry;
  int routerset_usage =
    routerset_needs_geoip(options->EntryNodes) ||
    routerset_needs_geoip(options->ExitNodes) ||
    routerset_needs_geoip(options->ExcludeExitNodes) ||
    routerset_needs_geoip(options->ExcludeNodes);

  if (routerset_usage && reason_out) {
    *reason_out = "We've been configured to use (or avoid) nodes in certain "
      "countries, and we need GEOIP information to figure out which ones they "
      "are.";
  } else if (bridge_usage && reason_out) {
    *reason_out = "We've been configured to see which countries can access "
      "us as a bridge, and we need GEOIP information to tell which countries "
      "clients are in.";
  }
  return bridge_usage || routerset_usage;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int options_save_current ( void  )

Save the current configuration file value to disk.

Return 0 on success, -1 on failure.

Definition at line 6357 of file config.c.

{
  /* This fails if we can't write to our configuration file.
   *
   * If we try falling back to datadirectory or something, we have a better
   * chance of saving the configuration, but a better chance of doing
   * something the user never expected. */
  return write_configuration_file(get_torrc_fname(0), get_options());
}

Here is the call graph for this function:

Here is the caller graph for this function:

setopt_err_t options_trial_assign ( config_line_t list,
int  use_defaults,
int  clear_first,
char **  msg 
)

Try assigning list to the global options.

You do this by duping options, assigning list to the new one, then validating it. If it's ok, then throw out the old one and stick with the new one. Else, revert to old and return failure. Return SETOPT_OK on success, or a setopt_err_t on failure.

If not success, point *msg to a newly allocated string describing what went wrong.

Definition at line 2703 of file config.c.

{
  int r;
  or_options_t *trial_options = options_dup(&options_format, get_options());

  if ((r=config_assign(&options_format, trial_options,
                       list, use_defaults, clear_first, msg)) < 0) {
    config_free(&options_format, trial_options);
    return r;
  }

  if (options_validate(get_options_mutable(), trial_options, 1, msg) < 0) {
    config_free(&options_format, trial_options);
    return SETOPT_ERR_PARSE; /*XXX make this a separate return value. */
  }

  if (options_transition_allowed(get_options(), trial_options, msg) < 0) {
    config_free(&options_format, trial_options);
    return SETOPT_ERR_TRANSITION;
  }

  if (set_options(trial_options, msg)<0) {
    config_free(&options_format, trial_options);
    return SETOPT_ERR_SETTING;
  }

  /* we liked it. put it in place. */
  return SETOPT_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int or_state_save ( time_t  now)

Write the persistent state to disk.

Return 0 for success, <0 on failure.

Definition at line 6910 of file config.c.

{
  char *state, *contents;
  char tbuf[ISO_TIME_LEN+1];
  char *fname;

  tor_assert(global_state);

  if (global_state->next_write > now)
    return 0;

  /* Call everything else that might dirty the state even more, in order
   * to avoid redundant writes. */
  entry_guards_update_state(global_state);
  rep_hist_update_state(global_state);
  circuit_build_times_update_state(&circ_times, global_state);
  if (accounting_is_enabled(get_options()))
    accounting_run_housekeeping(now);

  global_state->LastWritten = now;

  tor_free(global_state->TorVersion);
  tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());

  state = config_dump(&state_format, NULL, global_state, 1, 0);
  format_local_iso_time(tbuf, now);
  tor_asprintf(&contents,
               "# Tor state file last generated on %s local time\n"
               "# Other times below are in GMT\n"
               "# You *do not* need to edit this file.\n\n%s",
               tbuf, state);
  tor_free(state);
  fname = get_datadir_fname("state");
  if (write_str_to_file(fname, contents, 0)<0) {
    log_warn(LD_FS, "Unable to write state to file \"%s\"; "
             "will try again later", fname);
    last_state_file_write_failed = 1;
    tor_free(fname);
    tor_free(contents);
    /* Try again after STATE_WRITE_RETRY_INTERVAL (or sooner, if the state
     * changes sooner). */
    global_state->next_write = now + STATE_WRITE_RETRY_INTERVAL;
    return -1;
  }

  last_state_file_write_failed = 0;
  log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
  tor_free(fname);
  tor_free(contents);

  if (server_mode(get_options()))
    global_state->next_write = now + STATE_RELAY_CHECKPOINT_INTERVAL;
  else
    global_state->next_write = TIME_MAX;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int resolve_my_address ( int  warn_severity,
const or_options_t options,
uint32_t *  addr_out,
char **  hostname_out 
)

Based on options->Address, guess our public IP address and put it (in host order) into *addr_out.

If hostname_out is provided, set *hostname_out to a new string holding the hostname we used to get the address. Return 0 if all is well, or -1 if we can't find a suitable public IP address. XXXX ipv6

Definition at line 2858 of file config.c.

{
  struct in_addr in;
  uint32_t addr; /* host order */
  char hostname[256];
  int explicit_ip=1;
  int explicit_hostname=1;
  int from_interface=0;
  char *addr_string = NULL;
  const char *address = options->Address;
  int notice_severity = warn_severity <= LOG_NOTICE ?
                          LOG_NOTICE : warn_severity;

  tor_assert(addr_out);

  if (address && *address) {
    strlcpy(hostname, address, sizeof(hostname));
  } else { /* then we need to guess our address */
    explicit_ip = 0; /* it's implicit */
    explicit_hostname = 0; /* it's implicit */

    if (gethostname(hostname, sizeof(hostname)) < 0) {
      log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
      return -1;
    }
    log_debug(LD_CONFIG,"Guessed local host name as '%s'",hostname);
  }

  /* now we know hostname. resolve it and keep only the IP address */

  if (tor_inet_aton(hostname, &in) == 0) {
    /* then we have to resolve it */
    explicit_ip = 0;
    if (tor_lookup_hostname(hostname, &addr)) { /* failed to resolve */
      uint32_t interface_ip; /* host order */

      if (explicit_hostname) {
        log_fn(warn_severity, LD_CONFIG,
               "Could not resolve local Address '%s'. Failing.", hostname);
        return -1;
      }
      log_fn(notice_severity, LD_CONFIG,
             "Could not resolve guessed local hostname '%s'. "
             "Trying something else.", hostname);
      if (get_interface_address(warn_severity, &interface_ip)) {
        log_fn(warn_severity, LD_CONFIG,
               "Could not get local interface IP address. Failing.");
        return -1;
      }
      from_interface = 1;
      addr = interface_ip;
      log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
             "local interface. Using that.", fmt_addr32(addr));
      strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
    } else { /* resolved hostname into addr */
      if (!explicit_hostname &&
          is_internal_IP(addr, 0)) {
        uint32_t interface_ip;

        log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
               "resolves to a private IP address (%s). Trying something "
               "else.", hostname, fmt_addr32(addr));

        if (get_interface_address(warn_severity, &interface_ip)) {
          log_fn(warn_severity, LD_CONFIG,
                 "Could not get local interface IP address. Too bad.");
        } else if (is_internal_IP(interface_ip, 0)) {
          log_fn(notice_severity, LD_CONFIG,
                 "Interface IP address '%s' is a private address too. "
                 "Ignoring.", fmt_addr32(interface_ip));
        } else {
          from_interface = 1;
          addr = interface_ip;
          log_fn(notice_severity, LD_CONFIG,
                 "Learned IP address '%s' for local interface."
                 " Using that.", fmt_addr32(addr));
          strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
        }
      }
    }
  } else {
    addr = ntohl(in.s_addr); /* set addr so that addr_string is not
                              * illformed */
  }

  addr_string = tor_dup_ip(addr);
  if (is_internal_IP(addr, 0)) {
    /* make sure we're ok with publishing an internal IP */
    if (!options->DirServers && !options->AlternateDirAuthority) {
      /* if they are using the default dirservers, disallow internal IPs
       * always. */
      log_fn(warn_severity, LD_CONFIG,
             "Address '%s' resolves to private IP address '%s'. "
             "Tor servers that use the default DirServers must have public "
             "IP addresses.", hostname, addr_string);
      tor_free(addr_string);
      return -1;
    }
    if (!explicit_ip) {
      /* even if they've set their own dirservers, require an explicit IP if
       * they're using an internal address. */
      log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
             "IP address '%s'. Please set the Address config option to be "
             "the IP address you want to use.", hostname, addr_string);
      tor_free(addr_string);
      return -1;
    }
  }

  log_debug(LD_CONFIG, "Resolved Address to '%s'.", fmt_addr32(addr));
  *addr_out = addr;
  if (last_resolved_addr && last_resolved_addr != *addr_out) {
    /* Leave this as a notice, regardless of the requested severity,
     * at least until dynamic IP address support becomes bulletproof. */
    log_notice(LD_NET,
               "Your IP address seems to have changed to %s. Updating.",
               addr_string);
    ip_address_changed(0);
  }
  if (last_resolved_addr != *addr_out) {
    const char *method;
    const char *h = hostname;
    if (explicit_ip) {
      method = "CONFIGURED";
      h = NULL;
    } else if (explicit_hostname) {
      method = "RESOLVED";
    } else if (from_interface) {
      method = "INTERFACE";
      h = NULL;
    } else {
      method = "GETHOSTNAME";
    }
    control_event_server_status(LOG_NOTICE,
                                "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
                                addr_string, method, h?"HOSTNAME=":"", h);
  }
  last_resolved_addr = *addr_out;
  if (hostname_out)
    *hostname_out = tor_strdup(hostname);
  tor_free(addr_string);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* safe_str ( const char *  address)

Make address -- a piece of information of unspecified sensitivity -- safe to log according to the settings in options->SafeLogging, and return it.

(We return "[scrubbed]" if SafeLogging is anything besides "0", and address otherwise.)

Definition at line 903 of file config.c.

{
  tor_assert(address);
  if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
    return "[scrubbed]";
  else
    return address;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* safe_str_client ( const char *  address)

Make address -- a piece of information related to our operation as a client -- safe to log according to the settings in options->SafeLogging, and return it.

(We return "[scrubbed]" if SafeLogging is "1", and address otherwise.)

Definition at line 886 of file config.c.

{
  tor_assert(address);
  if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
    return "[scrubbed]";
  else
    return address;
}

Here is the call graph for this function:

void save_transport_to_state ( const char *  transport_name,
const tor_addr_t addr,
uint16_t  port 
)

Save transport listening on addr:port to state.

find where to write on the state

Definition at line 7059 of file config.c.

{
  or_state_t *state = get_or_state();

  char *transport_addrport=NULL;

  config_line_t **next, *line;

  /* see if this transport is already stored in state */
  config_line_t *transport_line =
    get_transport_in_state_by_name(transport);

  if (transport_line) { /* if transport already exists in state... */
    const char *prev_bindaddr = /* get its addrport... */
      get_transport_bindaddr(transport_line->value, transport);
    tor_asprintf(&transport_addrport, "%s:%d", fmt_addr(addr), (int)port);

    /* if transport in state has the same address as this one, life is good */
    if (!strcmp(prev_bindaddr, transport_addrport)) {
      log_info(LD_CONFIG, "Transport seems to have spawned on its usual "
               "address:port.");
      goto done;
    } else { /* if addrport in state is different than the one we got */
      log_info(LD_CONFIG, "Transport seems to have spawned on different "
               "address:port. Let's update the state file with the new "
               "address:port");
      tor_free(transport_line->value); /* free the old line */
      tor_asprintf(&transport_line->value, "%s %s:%d", transport,
                   fmt_addr(addr),
                   (int) port); /* replace old addrport line with new line */
    }
  } else { /* never seen this one before; save it in state for next time */
    log_info(LD_CONFIG, "It's the first time we see this transport. "
             "Let's save its address:port");
    next = &state->TransportProxies;
    /* find the last TransportProxy line in the state and point 'next'
       right after it  */
    line = state->TransportProxies;
    while (line) {
      next = &(line->next);
      line = line->next;
    }

    /* allocate space for the new line and fill it in */
    *next = line = tor_malloc_zero(sizeof(config_line_t));
    line->key = tor_strdup("TransportProxy");
    tor_asprintf(&line->value, "%s %s:%d", transport,
                 fmt_addr(addr), (int) port);

    next = &(line->next);
  }

  if (!get_options()->AvoidDiskWrites)
    or_state_mark_dirty(state, 0);

 done:
  tor_free(transport_addrport);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int set_options ( or_options_t new_val,
char **  msg 
)

Change the current global options to contain new_val instead of their current value; take action based on the new value; free the old value as necessary.

Returns 0 on success, -1 on failure.

Definition at line 740 of file config.c.

{
  int i;
  smartlist_t *elements;
  config_line_t *line;
  or_options_t *old_options = global_options;
  global_options = new_val;
  /* Note that we pass the *old* options below, for comparison. It
   * pulls the new options directly out of global_options. */
  if (options_act_reversible(old_options, msg)<0) {
    tor_assert(*msg);
    global_options = old_options;
    return -1;
  }
  if (options_act(old_options) < 0) { /* acting on the options failed. die. */
    log_err(LD_BUG,
            "Acting on config options left us in a broken state. Dying.");
    exit(1);
  }
  /* Issues a CONF_CHANGED event to notify controller of the change. If Tor is
   * just starting up then the old_options will be undefined. */
  if (old_options && old_options != global_options) {
    elements = smartlist_new();
    for (i=0; options_format.vars[i].name; ++i) {
      const config_var_t *var = &options_format.vars[i];
      const char *var_name = var->name;
      if (var->type == CONFIG_TYPE_LINELIST_S ||
          var->type == CONFIG_TYPE_OBSOLETE) {
        continue;
      }
      if (!option_is_same(&options_format, new_val, old_options, var_name)) {
        line = get_assigned_option(&options_format, new_val, var_name, 1);

        if (line) {
          for (; line; line = line->next) {
            smartlist_add(elements, line->key);
            smartlist_add(elements, line->value);
          }
        } else {
          smartlist_add(elements, (char*)options_format.vars[i].name);
          smartlist_add(elements, NULL);
        }
      }
    }
    control_event_conf_changed(elements);
    smartlist_free(elements);
  }

  if (old_options != global_options)
    config_free(&options_format, old_options);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char * tor_get_digests ( void  )

Return a string describing the digest of the source files in src/or/.

Definition at line 7 of file config_codedigest.c.

{
  return ""
#include "or_sha1.i"
    ;
}

Here is the caller graph for this function: