| 161 | ) |
| 162 | |
| 163 | func androidLookupHost(host string) string { |
| 164 | dnsMu.Lock() |
| 165 | v, ok := dnsCache[host] |
| 166 | dnsMu.Unlock() |
| 167 | if ok { |
| 168 | return v |
| 169 | } |
| 170 | statDNSStart.Incr(1) |
| 171 | defer statDNSDone.Incr(1) |
| 172 | |
| 173 | // Android has no "dig" or "host" tool, so use "ping -c 1". Ghetto. |
| 174 | // $ ping -c 1 google.com |
| 175 | // PING google.com (74.125.224.64) 56(84) bytes of data. |
| 176 | c := make(chan string, 1) |
| 177 | go func() { |
| 178 | cmd := exec.Command("/system/bin/ping", "-c", "1", host) |
| 179 | stdout, err := cmd.StdoutPipe() |
| 180 | if err != nil { |
| 181 | panic(err) |
| 182 | } |
| 183 | defer stdout.Close() |
| 184 | if err := cmd.Start(); err != nil { |
| 185 | log.Printf("Error resolving %q with ping: %v", host, err) |
| 186 | c <- host |
| 187 | return |
| 188 | } |
| 189 | defer func() { |
| 190 | if p := cmd.Process; p != nil { |
| 191 | p.Kill() |
| 192 | } |
| 193 | }() |
| 194 | br := bufio.NewReader(stdout) |
| 195 | line, err := br.ReadString('\n') |
| 196 | if err != nil { |
| 197 | log.Printf("Failed to resolve %q with ping", host) |
| 198 | c <- host |
| 199 | return |
| 200 | } |
| 201 | if m := pingRx.FindStringSubmatch(line); m != nil { |
| 202 | ip := m[1] |
| 203 | dnsMu.Lock() |
| 204 | dnsCache[host] = ip |
| 205 | dnsMu.Unlock() |
| 206 | c <- ip |
| 207 | return |
| 208 | } |
| 209 | log.Printf("Failed to resolve %q with ping", host) |
| 210 | c <- host |
| 211 | }() |
| 212 | return <-c |
| 213 | } |
| 214 | |
| 215 | type StatsTransport struct { |
| 216 | Rt http.RoundTripper |