mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-01-27 20:14:11 +00:00
DNS DoH: Add h2c Remote mode (with serverNameToVerify)
This commit is contained in:
parent
a0822cb440
commit
7595bc21b1
@ -44,9 +44,11 @@ func NewServer(ctx context.Context, dest net.Destination, dispatcher routing.Dis
|
|||||||
switch {
|
switch {
|
||||||
case strings.EqualFold(u.String(), "localhost"):
|
case strings.EqualFold(u.String(), "localhost"):
|
||||||
return NewLocalNameServer(queryStrategy), nil
|
return NewLocalNameServer(queryStrategy), nil
|
||||||
case strings.EqualFold(u.Scheme, "https"): // DOH Remote mode
|
case strings.EqualFold(u.Scheme, "https"): // DNS-over-HTTPS Remote mode
|
||||||
return NewDoHNameServer(u, dispatcher, queryStrategy)
|
return NewDoHNameServer(u, dispatcher, queryStrategy, false)
|
||||||
case strings.EqualFold(u.Scheme, "https+local"): // DOH Local mode
|
case strings.EqualFold(u.Scheme, "h2c"): // DNS-over-HTTPS h2c Remote mode
|
||||||
|
return NewDoHNameServer(u, dispatcher, queryStrategy, true)
|
||||||
|
case strings.EqualFold(u.Scheme, "https+local"): // DNS-over-HTTPS Local mode
|
||||||
return NewDoHLocalNameServer(u, queryStrategy), nil
|
return NewDoHLocalNameServer(u, queryStrategy), nil
|
||||||
case strings.EqualFold(u.Scheme, "quic+local"): // DNS-over-QUIC Local mode
|
case strings.EqualFold(u.Scheme, "quic+local"): // DNS-over-QUIC Local mode
|
||||||
return NewQUICNameServer(u, queryStrategy)
|
return NewQUICNameServer(u, queryStrategy)
|
||||||
|
@ -3,6 +3,7 @@ package dns
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -23,6 +24,7 @@ import (
|
|||||||
"github.com/xtls/xray-core/features/routing"
|
"github.com/xtls/xray-core/features/routing"
|
||||||
"github.com/xtls/xray-core/transport/internet"
|
"github.com/xtls/xray-core/transport/internet"
|
||||||
"golang.org/x/net/dns/dnsmessage"
|
"golang.org/x/net/dns/dnsmessage"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DoHNameServer implemented DNS over HTTPS (RFC8484) Wire Format,
|
// DoHNameServer implemented DNS over HTTPS (RFC8484) Wire Format,
|
||||||
@ -41,49 +43,59 @@ type DoHNameServer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewDoHNameServer creates DOH server object for remote resolving.
|
// NewDoHNameServer creates DOH server object for remote resolving.
|
||||||
func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, queryStrategy QueryStrategy) (*DoHNameServer, error) {
|
func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, queryStrategy QueryStrategy, h2c bool) (*DoHNameServer, error) {
|
||||||
errors.LogInfo(context.Background(), "DNS: created Remote DOH client for ", url.String())
|
url.Scheme = "https"
|
||||||
|
errors.LogInfo(context.Background(), "DNS: created Remote DNS-over-HTTPS client for ", url.String(), ", with h2c ", h2c)
|
||||||
s := baseDOHNameServer(url, "DOH", queryStrategy)
|
s := baseDOHNameServer(url, "DOH", queryStrategy)
|
||||||
|
|
||||||
s.dispatcher = dispatcher
|
s.dispatcher = dispatcher
|
||||||
tr := &http.Transport{
|
dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
MaxIdleConns: 30,
|
dest, err := net.ParseDestination(network + ":" + addr)
|
||||||
IdleConnTimeout: 90 * time.Second,
|
if err != nil {
|
||||||
TLSHandshakeTimeout: 30 * time.Second,
|
return nil, err
|
||||||
ForceAttemptHTTP2: true,
|
}
|
||||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
link, err := s.dispatcher.Dispatch(toDnsContext(ctx, s.dohURL), dest)
|
||||||
dest, err := net.ParseDestination(network + ":" + addr)
|
select {
|
||||||
if err != nil {
|
case <-ctx.Done():
|
||||||
return nil, err
|
return nil, ctx.Err()
|
||||||
}
|
default:
|
||||||
link, err := s.dispatcher.Dispatch(toDnsContext(ctx, s.dohURL), dest)
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return nil, ctx.Err()
|
|
||||||
default:
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cc := common.ChainedClosable{}
|
cc := common.ChainedClosable{}
|
||||||
if cw, ok := link.Writer.(common.Closable); ok {
|
if cw, ok := link.Writer.(common.Closable); ok {
|
||||||
cc = append(cc, cw)
|
cc = append(cc, cw)
|
||||||
}
|
}
|
||||||
if cr, ok := link.Reader.(common.Closable); ok {
|
if cr, ok := link.Reader.(common.Closable); ok {
|
||||||
cc = append(cc, cr)
|
cc = append(cc, cr)
|
||||||
}
|
}
|
||||||
return cnc.NewConnection(
|
return cnc.NewConnection(
|
||||||
cnc.ConnectionInputMulti(link.Writer),
|
cnc.ConnectionInputMulti(link.Writer),
|
||||||
cnc.ConnectionOutputMulti(link.Reader),
|
cnc.ConnectionOutputMulti(link.Reader),
|
||||||
cnc.ConnectionOnClose(cc),
|
cnc.ConnectionOnClose(cc),
|
||||||
), nil
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
s.httpClient = &http.Client{
|
||||||
|
Timeout: time.Second * 180,
|
||||||
|
Transport: &http.Transport{
|
||||||
|
MaxIdleConns: 30,
|
||||||
|
IdleConnTimeout: 90 * time.Second,
|
||||||
|
TLSHandshakeTimeout: 30 * time.Second,
|
||||||
|
ForceAttemptHTTP2: true,
|
||||||
|
DialContext: dialContext,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
s.httpClient = &http.Client{
|
if h2c {
|
||||||
Timeout: time.Second * 180,
|
s.httpClient.Transport = &http2.Transport{
|
||||||
Transport: tr,
|
IdleConnTimeout: 90 * time.Second,
|
||||||
|
DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
|
||||||
|
return dialContext(ctx, network, addr)
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
@ -118,7 +130,7 @@ func NewDoHLocalNameServer(url *url.URL, queryStrategy QueryStrategy) *DoHNameSe
|
|||||||
Timeout: time.Second * 180,
|
Timeout: time.Second * 180,
|
||||||
Transport: tr,
|
Transport: tr,
|
||||||
}
|
}
|
||||||
errors.LogInfo(context.Background(), "DNS: created Local DOH client for ", url.String())
|
errors.LogInfo(context.Background(), "DNS: created Local DNS-over-HTTPS client for ", url.String())
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,6 +410,7 @@ type TLSConfig struct {
|
|||||||
PinnedPeerCertificatePublicKeySha256 *[]string `json:"pinnedPeerCertificatePublicKeySha256"`
|
PinnedPeerCertificatePublicKeySha256 *[]string `json:"pinnedPeerCertificatePublicKeySha256"`
|
||||||
CurvePreferences *StringList `json:"curvePreferences"`
|
CurvePreferences *StringList `json:"curvePreferences"`
|
||||||
MasterKeyLog string `json:"masterKeyLog"`
|
MasterKeyLog string `json:"masterKeyLog"`
|
||||||
|
ServerNameToVerify string `json:"serverNameToVerify"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build implements Buildable.
|
// Build implements Buildable.
|
||||||
@ -468,6 +469,10 @@ func (c *TLSConfig) Build() (proto.Message, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.MasterKeyLog = c.MasterKeyLog
|
config.MasterKeyLog = c.MasterKeyLog
|
||||||
|
config.ServerNameToVerify = c.ServerNameToVerify
|
||||||
|
if config.ServerNameToVerify != "" && config.Fingerprint == "unsafe" {
|
||||||
|
return nil, errors.New(`serverNameToVerify only works with uTLS for now`)
|
||||||
|
}
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
@ -303,6 +304,14 @@ func (c *Config) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509.Cert
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RandCarrier struct {
|
||||||
|
ServerNameToVerify string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RandCarrier) Read(p []byte) (n int, err error) {
|
||||||
|
return rand.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
// GetTLSConfig converts this Config into tls.Config.
|
// GetTLSConfig converts this Config into tls.Config.
|
||||||
func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
|
func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
|
||||||
root, err := c.getCertPool()
|
root, err := c.getCertPool()
|
||||||
@ -321,6 +330,9 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config := &tls.Config{
|
config := &tls.Config{
|
||||||
|
Rand: &RandCarrier{
|
||||||
|
ServerNameToVerify: c.ServerNameToVerify,
|
||||||
|
},
|
||||||
ClientSessionCache: globalSessionCache,
|
ClientSessionCache: globalSessionCache,
|
||||||
RootCAs: root,
|
RootCAs: root,
|
||||||
InsecureSkipVerify: c.AllowInsecure,
|
InsecureSkipVerify: c.AllowInsecure,
|
||||||
|
@ -214,7 +214,8 @@ type Config struct {
|
|||||||
PinnedPeerCertificatePublicKeySha256 [][]byte `protobuf:"bytes,14,rep,name=pinned_peer_certificate_public_key_sha256,json=pinnedPeerCertificatePublicKeySha256,proto3" json:"pinned_peer_certificate_public_key_sha256,omitempty"`
|
PinnedPeerCertificatePublicKeySha256 [][]byte `protobuf:"bytes,14,rep,name=pinned_peer_certificate_public_key_sha256,json=pinnedPeerCertificatePublicKeySha256,proto3" json:"pinned_peer_certificate_public_key_sha256,omitempty"`
|
||||||
MasterKeyLog string `protobuf:"bytes,15,opt,name=master_key_log,json=masterKeyLog,proto3" json:"master_key_log,omitempty"`
|
MasterKeyLog string `protobuf:"bytes,15,opt,name=master_key_log,json=masterKeyLog,proto3" json:"master_key_log,omitempty"`
|
||||||
// Lists of string as CurvePreferences values.
|
// Lists of string as CurvePreferences values.
|
||||||
CurvePreferences []string `protobuf:"bytes,16,rep,name=curve_preferences,json=curvePreferences,proto3" json:"curve_preferences,omitempty"`
|
CurvePreferences []string `protobuf:"bytes,16,rep,name=curve_preferences,json=curvePreferences,proto3" json:"curve_preferences,omitempty"`
|
||||||
|
ServerNameToVerify string `protobuf:"bytes,17,opt,name=server_name_to_verify,json=serverNameToVerify,proto3" json:"server_name_to_verify,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Config) Reset() {
|
func (x *Config) Reset() {
|
||||||
@ -352,6 +353,13 @@ func (x *Config) GetCurvePreferences() []string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Config) GetServerNameToVerify() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.ServerNameToVerify
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
var File_transport_internet_tls_config_proto protoreflect.FileDescriptor
|
var File_transport_internet_tls_config_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
||||||
@ -383,7 +391,7 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
|||||||
0x4e, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x14, 0x0a,
|
0x4e, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x14, 0x0a,
|
||||||
0x10, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46,
|
0x10, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46,
|
||||||
0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59,
|
0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59,
|
||||||
0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xe0, 0x05, 0x0a, 0x06, 0x43, 0x6f, 0x6e,
|
0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0x93, 0x06, 0x0a, 0x06, 0x43, 0x6f, 0x6e,
|
||||||
0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73,
|
0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73,
|
||||||
0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c,
|
0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c,
|
||||||
0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x63, 0x65,
|
0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x63, 0x65,
|
||||||
@ -429,15 +437,18 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
|||||||
0x52, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x12, 0x2b,
|
0x52, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x12, 0x2b,
|
||||||
0x0a, 0x11, 0x63, 0x75, 0x72, 0x76, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,
|
0x0a, 0x11, 0x63, 0x75, 0x72, 0x76, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,
|
||||||
0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x63, 0x75, 0x72, 0x76, 0x65,
|
0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x63, 0x75, 0x72, 0x76, 0x65,
|
||||||
0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x42, 0x73, 0x0a, 0x1f, 0x63,
|
0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x73,
|
||||||
0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72,
|
0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x76, 0x65,
|
||||||
0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x50, 0x01,
|
0x72, 0x69, 0x66, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x65, 0x72, 0x76,
|
||||||
0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c,
|
0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x54, 0x6f, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x42, 0x73,
|
||||||
0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e,
|
0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73,
|
||||||
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74,
|
0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c,
|
||||||
0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70,
|
0x73, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||||
0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x6c, 0x73,
|
0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74,
|
||||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
|
||||||
|
0x74, 0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61,
|
||||||
|
0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e,
|
||||||
|
0x54, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -87,4 +87,6 @@ message Config {
|
|||||||
|
|
||||||
// Lists of string as CurvePreferences values.
|
// Lists of string as CurvePreferences values.
|
||||||
repeated string curve_preferences = 16;
|
repeated string curve_preferences = 16;
|
||||||
|
|
||||||
|
string server_name_to_verify = 17;
|
||||||
}
|
}
|
||||||
|
@ -134,12 +134,17 @@ func UClient(c net.Conn, config *tls.Config, fingerprint *utls.ClientHelloID) ne
|
|||||||
}
|
}
|
||||||
|
|
||||||
func copyConfig(c *tls.Config) *utls.Config {
|
func copyConfig(c *tls.Config) *utls.Config {
|
||||||
|
serverNameToVerify := ""
|
||||||
|
if r, ok := c.Rand.(*RandCarrier); ok {
|
||||||
|
serverNameToVerify = r.ServerNameToVerify
|
||||||
|
}
|
||||||
return &utls.Config{
|
return &utls.Config{
|
||||||
RootCAs: c.RootCAs,
|
RootCAs: c.RootCAs,
|
||||||
ServerName: c.ServerName,
|
ServerName: c.ServerName,
|
||||||
InsecureSkipVerify: c.InsecureSkipVerify,
|
InsecureSkipVerify: c.InsecureSkipVerify,
|
||||||
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
||||||
KeyLogWriter: c.KeyLogWriter,
|
KeyLogWriter: c.KeyLogWriter,
|
||||||
|
InsecureServerNameToVerify: serverNameToVerify,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user