~ Some ISP resolvers will reply with a dummy IP to queries that would otherwise * result in an NXDOMAIN reply. This just checks whether we have one such * resolver upstream and remembers its reply so we can try to filter future * dummies out. */
| 96 | * dummies out. |
| 97 | */ |
| 98 | static bool broken_resolver(struct daemon *daemon) |
| 99 | { |
| 100 | struct addrinfo *addrinfo; |
| 101 | struct addrinfo hints; |
| 102 | const char *hostname = "nxdomain-test.doesntexist"; |
| 103 | int err; |
| 104 | |
| 105 | /* If they told us to never do DNS queries, don't even do this one and |
| 106 | * also not if we just say that we don't */ |
| 107 | if (!daemon->use_dns || daemon->always_use_proxy) { |
| 108 | daemon->broken_resolver_response = NULL; |
| 109 | return false; |
| 110 | } |
| 111 | |
| 112 | memset(&hints, 0, sizeof(hints)); |
| 113 | hints.ai_family = AF_UNSPEC; |
| 114 | hints.ai_socktype = SOCK_STREAM; |
| 115 | hints.ai_protocol = 0; |
| 116 | hints.ai_flags = AI_ADDRCONFIG; |
| 117 | err = getaddrinfo(hostname, tal_fmt(tmpctx, "%d", 42), |
| 118 | &hints, &addrinfo); |
| 119 | |
| 120 | /*~ Note the use of tal_dup here: it is a memdup for tal, but it's |
| 121 | * type-aware so it's less error-prone. */ |
| 122 | if (err == 0) { |
| 123 | daemon->broken_resolver_response |
| 124 | = tal_dup(daemon, struct sockaddr, addrinfo->ai_addr); |
| 125 | freeaddrinfo(addrinfo); |
| 126 | } else |
| 127 | daemon->broken_resolver_response = NULL; |
| 128 | |
| 129 | return daemon->broken_resolver_response != NULL; |
| 130 | } |
| 131 | |
| 132 | /*~ Here we see our first tal destructor: in this case the 'struct connect' |
| 133 | * simply removes itself from the list of all 'connect' structs. */ |