Tor  0.4.5.0-alpha-dev
relay_find_addr.c
Go to the documentation of this file.
1 /* Copyright (c) 2001-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
4 /**
5  * \file relay_find_addr.c
6  * \brief Implement mechanism for a relay to find its address.
7  **/
8 
9 #include "core/or/or.h"
10 
11 #include "app/config/config.h"
13 
14 #include "core/mainloop/mainloop.h"
15 
19 #include "feature/relay/router.h"
21 
22 /** The most recently guessed value of our IP address, based on directory
23  * headers. */
24 static tor_addr_t last_guessed_ip = TOR_ADDR_NULL;
25 
26 /** We failed to resolve our address locally, but we'd like to build
27  * a descriptor and publish / test reachability. If we have a guess
28  * about our address based on directory headers, answer it and return
29  * 0; else return -1. */
30 static int
32 {
35  return 0;
36  }
37  return -1;
38 }
39 
40 /** A directory server <b>d_conn</b> told us our IP address is
41  * <b>suggestion</b>.
42  * If this address is different from the one we think we are now, and
43  * if our computer doesn't actually know its IP address, then switch. */
44 void
45 router_new_address_suggestion(const char *suggestion,
46  const dir_connection_t *d_conn)
47 {
48  tor_addr_t addr, my_addr, last_resolved_addr;
49  const or_options_t *options = get_options();
50 
51  /* first, learn what the IP address actually is */
52  if (tor_addr_parse(&addr, suggestion) == -1) {
53  log_debug(LD_DIR, "Malformed X-Your-Address-Is header %s. Ignoring.",
54  escaped(suggestion));
55  return;
56  }
57 
58  log_debug(LD_DIR, "Got X-Your-Address-Is: %s.", suggestion);
59 
60  if (!server_mode(options)) {
62  return;
63  }
64 
65  /* XXXX ipv6 */
66  resolved_addr_get_last(AF_INET, &last_resolved_addr);
67  if (!tor_addr_is_null(&last_resolved_addr)) {
68  /* Lets use this one. */
69  tor_addr_copy(&last_guessed_ip, &last_resolved_addr);
70  return;
71  }
72 
73  /* Attempt to find our address. */
74  if (find_my_address(options, AF_INET, LOG_INFO, &my_addr, NULL, NULL)) {
75  /* We're all set -- we already know our address. Great. */
76  tor_addr_copy(&last_guessed_ip, &my_addr); /* store it in case we
77  need it later */
78  return;
79  }
80 
81  /* Consider the suggestion from the directory. */
82  if (tor_addr_is_internal(&addr, 0)) {
83  /* Don't believe anybody who says our IP is, say, 127.0.0.1. */
84  return;
85  }
86  if (tor_addr_eq(&d_conn->base_.addr, &addr)) {
87  /* Don't believe anybody who says our IP is their IP. */
88  log_debug(LD_DIR, "A directory server told us our IP address is %s, "
89  "but they are just reporting their own IP address. Ignoring.",
90  suggestion);
91  return;
92  }
93 
94  /* Okay. We can't resolve our own address, and X-Your-Address-Is is giving
95  * us an answer different from what we had the last time we managed to
96  * resolve it. */
97  if (!tor_addr_eq(&last_guessed_ip, &addr)) {
99  "EXTERNAL_ADDRESS ADDRESS=%s METHOD=DIRSERV",
100  suggestion);
102  d_conn->base_.address);
104  tor_addr_copy(&last_guessed_ip, &addr); /* router_rebuild_descriptor()
105  will fetch it */
106  }
107 }
108 
109 /** Make a current best guess at our address, either because
110  * it's configured in torrc, or because we've learned it from
111  * dirserver headers. Place the answer in *<b>addr</b> and return
112  * 0 on success, else return -1 if we have no guess.
113  *
114  * If <b>cache_only</b> is true, just return any cached answers, and
115  * don't try to get any new answers.
116  */
117 MOCK_IMPL(int,
118 router_pick_published_address, (const or_options_t *options, uint32_t *addr,
119  int cache_only))
120 {
121  tor_addr_t last_resolved_addr;
122 
123  /* First, check the cached output from find_my_address(). */
124  resolved_addr_get_last(AF_INET, &last_resolved_addr);
125  if (!tor_addr_is_null(&last_resolved_addr)) {
126  *addr = tor_addr_to_ipv4h(&last_resolved_addr);
127  return 0;
128  }
129 
130  /* Second, consider doing a resolve attempt right here. */
131  if (!cache_only) {
132  tor_addr_t my_addr;
133  if (find_my_address(options, AF_INET, LOG_INFO, &my_addr, NULL, NULL)) {
134  log_info(LD_CONFIG,"Success: chose address '%s'.", fmt_addr(&my_addr));
135  *addr = tor_addr_to_ipv4h(&my_addr);
136  return 0;
137  }
138  }
139 
140  /* Third, check the cached output from router_new_address_suggestion(). */
142  return 0;
143 
144  /* We have no useful cached answers. Return failure. */
145  return -1;
146 }
routermode.h
Header file for routermode.c.
router_pick_published_address
int router_pick_published_address(const or_options_t *options, uint32_t *addr, int cache_only)
Definition: relay_find_addr.c:119
tor_addr_t
Definition: address.h:68
LOG_NOTICE
#define LOG_NOTICE
Definition: log.h:50
connection_t::address
char * address
Definition: connection_st.h:125
MOCK_IMPL
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
relay_find_addr.h
Header file for relay_find_addr.c.
router.h
Header file for router.c.
router_guess_address_from_dir_headers
static int router_guess_address_from_dir_headers(uint32_t *guess)
Definition: relay_find_addr.c:31
mainloop.h
Header file for mainloop.c.
log_addr_has_changed
void log_addr_has_changed(int severity, const tor_addr_t *prev, const tor_addr_t *cur, const char *source)
Definition: router.c:2564
tor_addr_to_ipv4h
static uint32_t tor_addr_to_ipv4h(const tor_addr_t *a)
Definition: address.h:160
control_event_server_status
int control_event_server_status(int severity, const char *format,...)
Definition: control_events.c:1777
last_guessed_ip
static tor_addr_t last_guessed_ip
Definition: relay_find_addr.c:24
escaped
const char * escaped(const char *s)
Definition: escape.c:126
connection_t::addr
tor_addr_t addr
Definition: connection_st.h:112
LD_CONFIG
#define LD_CONFIG
Definition: log.h:68
find_my_address
bool find_my_address(const or_options_t *options, int family, int warn_severity, tor_addr_t *addr_out, const char **method_out, char **hostname_out)
Attempt to find our IP address that can be used as our external reachable address.
Definition: resolve_addr.c:582
tor_addr_parse
int tor_addr_parse(tor_addr_t *addr, const char *src)
Definition: address.c:1340
LOG_INFO
#define LOG_INFO
Definition: log.h:45
fmt_addr
#define fmt_addr(a)
Definition: address.h:239
control_events.h
Header file for control_events.c.
get_options
const or_options_t * get_options(void)
Definition: config.c:926
resolve_addr.h
Header file for resolve_addr.c.
ip_address_changed
void ip_address_changed(int on_client_conn)
Definition: mainloop.c:2286
server_mode
int server_mode(const or_options_t *options)
Definition: routermode.c:34
tor_addr_is_null
int tor_addr_is_null(const tor_addr_t *addr)
Definition: address.c:771
dir_connection_st.h
Client/server directory connection structure.
config.h
Header file for config.c.
router_new_address_suggestion
void router_new_address_suggestion(const char *suggestion, const dir_connection_t *d_conn)
Definition: relay_find_addr.c:45
or_options_t
Definition: or_options_st.h:39
resolved_addr_get_last
void resolved_addr_get_last(int family, tor_addr_t *addr_out)
Definition: resolve_addr.c:68
dir_connection_t
Definition: dir_connection_st.h:21
LD_DIR
#define LD_DIR
Definition: log.h:88
tor_addr_eq
#define tor_addr_eq(a, b)
Definition: address.h:280
tor_addr_copy
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
Definition: address.c:924
or.h
Master header file for Tor-specific functionality.