Ctrl K
ComunidadGuías…

config/ip.go

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package config

import (
	"context"
	"fmt"
	"net"
	"strings"
	"time"

	"github.com/screego/server/config/ipdns"
)

func parseIPProvider(ips []string, config string) (ipdns.Provider, []FutureLog) {
	if len(ips) == 0 {
		panic("must have at least one ip")
	}

	first := ips[0]
	if strings.HasPrefix(first, "dns:") {
		if len(ips) > 1 {
			return nil, []FutureLog{futureFatal(fmt.Sprintf("invalid %s: when dns server is specified, only one value is allowed", config))}
		}

		return parseDNS(strings.TrimPrefix(first, "dns:")), nil
	}

	return parseStatic(ips, config)
}

func parseStatic(ips []string, config string) (*ipdns.Static, []FutureLog) {
	var static ipdns.Static

	firstV4, errs := applyIPTo(config, ips[0], &static)
	if errs != nil {
		return nil, errs
	}

	if len(ips) == 1 {
		return &static, nil
	}

	secondV4, errs := applyIPTo(config, ips[1], &static)
	if errs != nil {
		return nil, errs
	}

	if firstV4 == secondV4 {
		return nil, []FutureLog{futureFatal(fmt.Sprintf("invalid %s: the ips must be of different type ipv4/ipv6", config))}
	}

	if len(ips) > 2 {
		return nil, []FutureLog{futureFatal(fmt.Sprintf("invalid %s: too many ips supplied", config))}
	}

	return &static, nil
}

func applyIPTo(config, ip string, static *ipdns.Static) (bool, []FutureLog) {
	parsed := net.ParseIP(ip)
	if parsed == nil || ip == "0.0.0.0" {
		return false, []FutureLog{futureFatal(fmt.Sprintf("invalid %s: %s", config, ip))}
	}

	v4 := parsed.To4() != nil
	if v4 {
		static.V4 = parsed
	} else {
		static.V6 = parsed
	}
	return v4, nil
}

func parseDNS(dnsString string) *ipdns.DNS {
	var dns ipdns.DNS

	parts := strings.SplitN(dnsString, "@", 2)

	dns.Domain = parts[0]
	dns.DNS = "system"
	if len(parts) == 2 {
		dns.DNS = parts[1]
		dns.Resolver = &net.Resolver{
			PreferGo: true,
			Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
				d := net.Dialer{Timeout: 10 * time.Second}
				return d.DialContext(ctx, network, parts[1])
			},
		}
	}

	return &dns
}