func genPACFile(w io.Writer) (int, error) { hostsString := "[]" // only bypass sites if proxy all option is unset if !settings.GetProxyAll() { log.Trace("Not proxying all") var hosts []string for k, v := range directHosts { if v { hosts = append(hosts, k) } } hostsString = "['" + strings.Join(hosts, "', '") + "']" } else { log.Trace("Proxying all") } formatter := `var bypassDomains = %s; function FindProxyForURL(url, host) { if (isPlainHostName(host) // including localhost || shExpMatch(host, "*.local")) { return "DIRECT"; } // only checks plain IP addresses to avoid leaking domain name if (/^[0-9.]+$/.test(host)) { if (isInNet(host, "10.0.0.0", "255.0.0.0") || isInNet(host, "172.16.0.0", "255.240.0.0") || isInNet(host, "192.168.0.0", "255.255.0.0") || isInNet(host, "127.0.0.0", "255.255.255.0")) { return "DIRECT"; } } // Lantern desktop version proxies only http(s) and ws(s) if (url.substring(0, 4) != 'http' && (url.substring(0, 2) != 'ws')) { return "DIRECT"; } for (var d in bypassDomains) { if (host == bypassDomains[d]) { return "DIRECT"; } } return "PROXY %s; DIRECT"; }` proxyAddr, ok := client.Addr(5 * time.Minute) if !ok { panic("Unable to get proxy address within 5 minutes") } proxyAddrString := proxyAddr.(string) log.Tracef("Setting proxy address to %v", proxyAddrString) return fmt.Fprintf(w, formatter, hostsString, proxyAddrString) }
// Start starts a HTTP and SOCKS proxies at random addresses. It blocks up till // the given timeout waiting for the proxy to listen, and returns the addresses // at which it is listening (HTTP, SOCKS). If the proxy doesn't start within the // given timeout, this method returns an error. // // If a Lantern proxy is already running within this process, that proxy is // reused. // // Note - this does not wait for the entire initialization sequence to finish, // just for the proxy to be listening. Once the proxy is listening, one can // start to use it, even as it finishes its initialization sequence. However, // initial activity may be slow, so clients with low read timeouts may // time out. func Start(configDir string, timeoutMillis int) (*StartResult, error) { startOnce.Do(func() { go run(configDir) }) start := time.Now() addr, ok := client.Addr(time.Duration(timeoutMillis) * time.Millisecond) if !ok { return nil, fmt.Errorf("HTTP Proxy didn't start within given timeout") } elapsed := time.Now().Sub(start) socksAddr, ok := client.Socks5Addr((time.Duration(timeoutMillis) * time.Millisecond) - elapsed) if !ok { return nil, fmt.Errorf("SOCKS5 Proxy didn't start within given timeout") } return &StartResult{addr.(string), socksAddr.(string)}, nil }