diff --git a/examples/masque/client.json b/examples/masque/client.json index e7cd985e..40cff115 100644 --- a/examples/masque/client.json +++ b/examples/masque/client.json @@ -36,6 +36,9 @@ "auth_token": "", "license_key": "" }, + // Optional: override the endpoint instead of using the one returned by Cloudflare + "address": "", + "port": 0, "udp_timeout": "5m0s", "udp_keepalive_period": "30s", "udp_initial_packet_size": 0, diff --git a/option/masque.go b/option/masque.go index 65053d1a..94c7048e 100644 --- a/option/masque.go +++ b/option/masque.go @@ -14,6 +14,8 @@ type MASQUEOutboundOptions struct { UseHTTP2 bool `json:"use_http2,omitempty"` UseIPv6 bool `json:"use_ipv6,omitempty"` Profile CloudflareProfile `json:"profile,omitempty"` + Address string `json:"address,omitempty"` + Port uint16 `json:"port,omitempty"` UDPTimeout badoption.Duration `json:"udp_timeout,omitempty"` UDPKeepalivePeriod badoption.Duration `json:"udp_keepalive_period,omitempty"` UDPInitialPacketSize uint16 `json:"udp_initial_packet_size,omitempty"` diff --git a/protocol/masque/outbound.go b/protocol/masque/outbound.go index d8314323..fe80cb40 100644 --- a/protocol/masque/outbound.go +++ b/protocol/masque/outbound.go @@ -111,10 +111,28 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL logger.ErrorContext(ctx, E.New("failed to prepare TLS config: ", err)) return } - endpoint, err := appConfig.SelectEndpointFromConfig(options.UseHTTP2, options.UseIPv6, 443) - if err != nil { - logger.ErrorContext(ctx, E.New("failed to select endpoint: ", err)) - return + var endpoint net.Addr + if options.Address != "" { + endpointPort := options.Port + if endpointPort == 0 { + endpointPort = 443 + } + endpointIP := net.ParseIP(options.Address) + if endpointIP == nil { + logger.ErrorContext(ctx, E.New("invalid endpoint address: ", options.Address)) + return + } + if options.UseHTTP2 { + endpoint = &net.TCPAddr{IP: endpointIP, Port: int(endpointPort)} + } else { + endpoint = &net.UDPAddr{IP: endpointIP, Port: int(endpointPort)} + } + } else { + endpoint, err = appConfig.SelectEndpointFromConfig(options.UseHTTP2, options.UseIPv6, 443) + if err != nil { + logger.ErrorContext(ctx, E.New("failed to select endpoint: ", err)) + return + } } var udpTimeout time.Duration if options.UDPTimeout != 0 {