mirror of
https://github.com/qdm12/gluetun.git
synced 2026-06-25 21:37:31 +02:00
64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
package restrictednet
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/qdm12/dns/v2/pkg/provider"
|
|
)
|
|
|
|
// Client is a client for making restricted network requests,
|
|
// such as opening temporary firewall rules for HTTPS connections.
|
|
// It is not meant to be high performance, although it can be used for
|
|
// multiple requests and concurrently.
|
|
type Client struct {
|
|
ipv6Supported bool
|
|
firewall Firewall
|
|
outboundInterface string
|
|
dohServers []provider.DoHServer
|
|
httpsPort uint16
|
|
}
|
|
|
|
func New(firewall Firewall, defaultInterface string, ipv6Supported bool,
|
|
upstreamResolvers []provider.Provider,
|
|
) (*Client, error) {
|
|
dohServers := make([]provider.DoHServer, len(upstreamResolvers))
|
|
for i, upstreamResolver := range upstreamResolvers {
|
|
dohServers[i] = upstreamResolver.DoH
|
|
}
|
|
|
|
const defaultHTTPSPort = 443
|
|
return &Client{
|
|
firewall: firewall,
|
|
outboundInterface: defaultInterface,
|
|
ipv6Supported: ipv6Supported,
|
|
dohServers: dohServers,
|
|
httpsPort: defaultHTTPSPort,
|
|
}, nil
|
|
}
|
|
|
|
func (c *Client) OpenHTTPSByDomain(ctx context.Context, domain string) (
|
|
httpClient *http.Client, cleanup func() error, err error,
|
|
) {
|
|
resolvedIPs, err := c.ResolveName(ctx, domain)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("resolving name: %w", err)
|
|
} else if len(resolvedIPs) == 0 {
|
|
return nil, nil, fmt.Errorf("no IP address found for name %q", domain)
|
|
}
|
|
|
|
errs := make([]error, 0, len(resolvedIPs))
|
|
for _, ip := range resolvedIPs {
|
|
httpClient, cleanup, err := c.OpenHTTPS(ctx, domain, ip)
|
|
if err != nil {
|
|
errs = append(errs, fmt.Errorf("for %s: %w", ip, err))
|
|
continue
|
|
}
|
|
return httpClient, cleanup, nil
|
|
}
|
|
|
|
return nil, nil, fmt.Errorf("opening HTTPS to %s: %w", domain, errors.Join(errs...))
|
|
}
|