src/models/constants.go
Rama main · réplica de lectura del repositorio original.
package models
import (
"context"
"fmt"
"net"
"os"
"path"
"time"
log "github.com/schollz/croc/v11/src/logger"
"github.com/schollz/croc/v11/src/utils"
)
// TCP_BUFFER_SIZE is the maximum packet size
const TCP_BUFFER_SIZE = 1024 * 64
// Default relay addresses retain their hostnames until dialing so proxies can
// resolve them remotely. DEFAULT_RELAY can be overridden using --relay.
var (
DEFAULT_RELAY = "croc.schollz.com:9009"
DEFAULT_RELAY6 = "croc6.schollz.com:9009"
DEFAULT_PORT = "9009"
DEFAULT_PASSPHRASE = "pass123"
INTERNAL_DNS = false
)
// publicDNS are servers to be queried if a local lookup fails
var publicDNS = []string{
"1.0.0.1", // Cloudflare
"1.1.1.1", // Cloudflare
"[2606:4700:4700::1111]", // Cloudflare
"[2606:4700:4700::1001]", // Cloudflare
"8.8.4.4", // Google
"8.8.8.8", // Google
"[2001:4860:4860::8844]", // Google
"[2001:4860:4860::8888]", // Google
"9.9.9.9", // Quad9
"149.112.112.112", // Quad9
"[2620:fe::fe]", // Quad9
"[2620:fe::fe:9]", // Quad9
"8.26.56.26", // Comodo
"8.20.247.20", // Comodo
"208.67.220.220", // Cisco OpenDNS
"208.67.222.222", // Cisco OpenDNS
"[2620:119:35::35]", // Cisco OpenDNS
"[2620:119:53::53]", // Cisco OpenDNS
}
func getConfigFile(requireValidPath bool) (fname string, err error) {
configFile, err := utils.GetConfigDir(requireValidPath)
if err != nil {
return
}
fname = path.Join(configFile, "internal-dns")
return
}
func init() {
log.SetLevel("info")
log.SetOutput(os.Stderr)
doRemember := false
for _, flag := range os.Args {
if flag == "--internal-dns" {
INTERNAL_DNS = true
break
}
if flag == "--remember" {
doRemember = true
}
}
if doRemember {
// save in config file
fname, err := getConfigFile(true)
if err == nil {
f, _ := os.Create(fname)
f.Close()
}
}
if !INTERNAL_DNS {
fname, err := getConfigFile(false)
if err == nil {
INTERNAL_DNS = utils.Exists(fname)
}
}
log.Trace("Using internal DNS: ", INTERNAL_DNS)
}
// ResolveRelayAddress applies the optional built-in DNS resolver to a direct
// connection. Proxy connections must keep the hostname for proxy-side DNS.
func ResolveRelayAddress(ctx context.Context, address string) (string, error) {
if !INTERNAL_DNS {
return address, nil
}
host, port, err := net.SplitHostPort(address)
if err != nil {
return "", err
}
if net.ParseIP(host) != nil {
return address, nil
}
ip, err := lookup(ctx, host)
if err != nil {
return "", err
}
return net.JoinHostPort(ip, port), nil
}
// Resolve a hostname to an IP address using DNS.
func lookup(ctx context.Context, address string) (ipaddress string, err error) {
if err := ctx.Err(); err != nil {
return "", err
}
ctx, cancel := context.WithCancel(ctx)
defer cancel()
if !INTERNAL_DNS {
log.Tracef("Using local DNS to resolve %s", address)
return localLookupIPContext(ctx, address)
}
type Result struct {
s string
err error
}
result := make(chan Result, len(publicDNS))
for _, dns := range publicDNS {
go func(dns string) {
var r Result
r.s, r.err = remoteLookupIPContext(ctx, address, dns)
log.Tracef("Resolved %s to %s using %s", address, r.s, dns)
result <- r
}(dns)
}
for range publicDNS {
select {
case <-ctx.Done():
return "", ctx.Err()
case resolved := <-result:
ipaddress = resolved.s
}
log.Tracef("Resolved %s to %s", address, ipaddress)
if ipaddress != "" {
return
}
}
err = fmt.Errorf("failed to resolve %s: all DNS servers exhausted", address)
return
}
// localLookupIP returns a host's IP address using the local DNS configuration.
func localLookupIP(address string) (ipaddress string, err error) {
return localLookupIPContext(context.Background(), address)
}
func localLookupIPContext(ctx context.Context, address string) (ipaddress string, err error) {
ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
defer cancel()
r := &net.Resolver{}
// Use the context with timeout in the LookupHost function
ip, err := r.LookupHost(ctx, address)
if err != nil {
return
}
ipaddress = ip[0]
return
}
// remoteLookupIP returns a host's IP address based on a remote DNS server.
func remoteLookupIP(address, dns string) (ipaddress string, err error) {
return remoteLookupIPContext(context.Background(), address, dns)
}
func remoteLookupIPContext(ctx context.Context, address, dns string) (ipaddress string, err error) {
ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
defer cancel()
r := &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, _ string) (net.Conn, error) {
d := new(net.Dialer)
return d.DialContext(ctx, network, dns+":53")
},
}
ip, err := r.LookupHost(ctx, address)
if err != nil {
return
}
ipaddress = ip[0]
return
}