Merge branch 'master' into 4990-custom-ciphers
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
// accessCtx controls IP and client blocking that takes place before all other
|
||||
// processing. An accessCtx is safe for concurrent use.
|
||||
type accessCtx struct {
|
||||
// TODO(e.burkov): Use map[netip.Addr]struct{} instead.
|
||||
allowedIPs *netutil.IPMap
|
||||
blockedIPs *netutil.IPMap
|
||||
|
||||
|
||||
@@ -123,7 +123,14 @@ type quicConnection interface {
|
||||
func (s *Server) clientIDFromDNSContext(pctx *proxy.DNSContext) (clientID string, err error) {
|
||||
proto := pctx.Proto
|
||||
if proto == proxy.ProtoHTTPS {
|
||||
return clientIDFromDNSContextHTTPS(pctx)
|
||||
clientID, err = clientIDFromDNSContextHTTPS(pctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("checking url: %w", err)
|
||||
} else if clientID != "" {
|
||||
return clientID, nil
|
||||
}
|
||||
|
||||
// Go on and check the domain name as well.
|
||||
} else if proto != proxy.ProtoTLS && proto != proxy.ProtoQUIC {
|
||||
return "", nil
|
||||
}
|
||||
@@ -133,31 +140,9 @@ func (s *Server) clientIDFromDNSContext(pctx *proxy.DNSContext) (clientID string
|
||||
return "", nil
|
||||
}
|
||||
|
||||
cliSrvName := ""
|
||||
switch proto {
|
||||
case proxy.ProtoTLS:
|
||||
conn := pctx.Conn
|
||||
tc, ok := conn.(tlsConn)
|
||||
if !ok {
|
||||
return "", fmt.Errorf(
|
||||
"proxy ctx conn of proto %s is %T, want *tls.Conn",
|
||||
proto,
|
||||
conn,
|
||||
)
|
||||
}
|
||||
|
||||
cliSrvName = tc.ConnectionState().ServerName
|
||||
case proxy.ProtoQUIC:
|
||||
conn, ok := pctx.QUICConnection.(quicConnection)
|
||||
if !ok {
|
||||
return "", fmt.Errorf(
|
||||
"proxy ctx quic conn of proto %s is %T, want quic.Connection",
|
||||
proto,
|
||||
pctx.QUICConnection,
|
||||
)
|
||||
}
|
||||
|
||||
cliSrvName = conn.ConnectionState().TLS.ServerName
|
||||
cliSrvName, err := clientServerName(pctx, proto)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
clientID, err = clientIDFromClientServerName(
|
||||
@@ -171,3 +156,35 @@ func (s *Server) clientIDFromDNSContext(pctx *proxy.DNSContext) (clientID string
|
||||
|
||||
return clientID, nil
|
||||
}
|
||||
|
||||
// clientServerName returns the TLS server name based on the protocol.
|
||||
func clientServerName(pctx *proxy.DNSContext, proto proxy.Proto) (srvName string, err error) {
|
||||
switch proto {
|
||||
case proxy.ProtoHTTPS:
|
||||
if connState := pctx.HTTPRequest.TLS; connState != nil {
|
||||
srvName = pctx.HTTPRequest.TLS.ServerName
|
||||
}
|
||||
case proxy.ProtoQUIC:
|
||||
qConn := pctx.QUICConnection
|
||||
conn, ok := qConn.(quicConnection)
|
||||
if !ok {
|
||||
return "", fmt.Errorf(
|
||||
"proxy ctx quic conn of proto %s is %T, want quic.Connection",
|
||||
proto,
|
||||
qConn,
|
||||
)
|
||||
}
|
||||
|
||||
srvName = conn.ConnectionState().TLS.ServerName
|
||||
case proxy.ProtoTLS:
|
||||
conn := pctx.Conn
|
||||
tc, ok := conn.(tlsConn)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("proxy ctx conn of proto %s is %T, want *tls.Conn", proto, conn)
|
||||
}
|
||||
|
||||
srvName = tc.ConnectionState().ServerName
|
||||
}
|
||||
|
||||
return srvName, nil
|
||||
}
|
||||
|
||||
@@ -160,6 +160,22 @@ func TestServer_clientIDFromDNSContext(t *testing.T) {
|
||||
wantClientID: "insensitive",
|
||||
wantErrMsg: ``,
|
||||
strictSNI: true,
|
||||
}, {
|
||||
name: "https_no_clientid",
|
||||
proto: proxy.ProtoHTTPS,
|
||||
hostSrvName: "example.com",
|
||||
cliSrvName: "example.com",
|
||||
wantClientID: "",
|
||||
wantErrMsg: "",
|
||||
strictSNI: true,
|
||||
}, {
|
||||
name: "https_clientid",
|
||||
proto: proxy.ProtoHTTPS,
|
||||
hostSrvName: "example.com",
|
||||
cliSrvName: "cli.example.com",
|
||||
wantClientID: "cli",
|
||||
wantErrMsg: "",
|
||||
strictSNI: true,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -173,16 +189,32 @@ func TestServer_clientIDFromDNSContext(t *testing.T) {
|
||||
conf: ServerConfig{TLSConfig: tlsConf},
|
||||
}
|
||||
|
||||
var conn net.Conn
|
||||
if tc.proto == proxy.ProtoTLS {
|
||||
conn = testTLSConn{
|
||||
var (
|
||||
conn net.Conn
|
||||
qconn quic.Connection
|
||||
httpReq *http.Request
|
||||
)
|
||||
|
||||
switch tc.proto {
|
||||
case proxy.ProtoHTTPS:
|
||||
u := &url.URL{
|
||||
Path: "/dns-query",
|
||||
}
|
||||
|
||||
connState := &tls.ConnectionState{
|
||||
ServerName: tc.cliSrvName,
|
||||
}
|
||||
|
||||
httpReq = &http.Request{
|
||||
URL: u,
|
||||
TLS: connState,
|
||||
}
|
||||
case proxy.ProtoQUIC:
|
||||
qconn = testQUICConnection{
|
||||
serverName: tc.cliSrvName,
|
||||
}
|
||||
}
|
||||
|
||||
var qconn quic.Connection
|
||||
if tc.proto == proxy.ProtoQUIC {
|
||||
qconn = testQUICConnection{
|
||||
case proxy.ProtoTLS:
|
||||
conn = testTLSConn{
|
||||
serverName: tc.cliSrvName,
|
||||
}
|
||||
}
|
||||
@@ -190,6 +222,7 @@ func TestServer_clientIDFromDNSContext(t *testing.T) {
|
||||
pctx := &proxy.DNSContext{
|
||||
Proto: tc.proto,
|
||||
Conn: conn,
|
||||
HTTPRequest: httpReq,
|
||||
QUICConnection: qconn,
|
||||
}
|
||||
|
||||
@@ -205,56 +238,76 @@ func TestClientIDFromDNSContextHTTPS(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
path string
|
||||
cliSrvName string
|
||||
wantClientID string
|
||||
wantErrMsg string
|
||||
}{{
|
||||
name: "no_clientid",
|
||||
path: "/dns-query",
|
||||
cliSrvName: "example.com",
|
||||
wantClientID: "",
|
||||
wantErrMsg: "",
|
||||
}, {
|
||||
name: "no_clientid_slash",
|
||||
path: "/dns-query/",
|
||||
cliSrvName: "example.com",
|
||||
wantClientID: "",
|
||||
wantErrMsg: "",
|
||||
}, {
|
||||
name: "clientid",
|
||||
path: "/dns-query/cli",
|
||||
cliSrvName: "example.com",
|
||||
wantClientID: "cli",
|
||||
wantErrMsg: "",
|
||||
}, {
|
||||
name: "clientid_slash",
|
||||
path: "/dns-query/cli/",
|
||||
cliSrvName: "example.com",
|
||||
wantClientID: "cli",
|
||||
wantErrMsg: "",
|
||||
}, {
|
||||
name: "clientid_case",
|
||||
path: "/dns-query/InSeNsItIvE",
|
||||
cliSrvName: "example.com",
|
||||
wantClientID: "insensitive",
|
||||
wantErrMsg: ``,
|
||||
}, {
|
||||
name: "bad_url",
|
||||
path: "/foo",
|
||||
cliSrvName: "example.com",
|
||||
wantClientID: "",
|
||||
wantErrMsg: `clientid check: invalid path "/foo"`,
|
||||
}, {
|
||||
name: "extra",
|
||||
path: "/dns-query/cli/foo",
|
||||
cliSrvName: "example.com",
|
||||
wantClientID: "",
|
||||
wantErrMsg: `clientid check: invalid path "/dns-query/cli/foo": extra parts`,
|
||||
}, {
|
||||
name: "invalid_clientid",
|
||||
path: "/dns-query/!!!",
|
||||
cliSrvName: "example.com",
|
||||
wantClientID: "",
|
||||
wantErrMsg: `clientid check: invalid clientid "!!!": bad domain name label rune '!'`,
|
||||
}, {
|
||||
name: "both_ids",
|
||||
path: "/dns-query/right",
|
||||
cliSrvName: "wrong.example.com",
|
||||
wantClientID: "right",
|
||||
wantErrMsg: "",
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
connState := &tls.ConnectionState{
|
||||
ServerName: tc.cliSrvName,
|
||||
}
|
||||
|
||||
r := &http.Request{
|
||||
URL: &url.URL{
|
||||
Path: tc.path,
|
||||
},
|
||||
TLS: connState,
|
||||
}
|
||||
|
||||
pctx := &proxy.DNSContext{
|
||||
|
||||
@@ -81,6 +81,7 @@ type Server struct {
|
||||
tableHostToIP hostToIPTable
|
||||
tableHostToIPLock sync.Mutex
|
||||
|
||||
// TODO(e.burkov): Use map[netip.Addr]struct{} instead.
|
||||
tableIPToHost *netutil.IPMap
|
||||
tableIPToHostLock sync.Mutex
|
||||
|
||||
|
||||
Reference in New Issue
Block a user