diff --git a/integration/fixtures/tcp/mixed.toml b/integration/fixtures/tcp/mixed.toml index 38d852e7..0e02b45f 100644 --- a/integration/fixtures/tcp/mixed.toml +++ b/integration/fixtures/tcp/mixed.toml @@ -56,6 +56,13 @@ entryPoints = [ "tcp" ] [tcp.routers.to-whoami-no-cert.tls] + [tcp.routers.to-whoami-wildcard] + rule = "HostSNI(`*.whoami-a.test`)" + service = "whoami-a" + entryPoints = [ "tcp" ] + [tcp.routers.to-whoami-wildcard.tls] + passthrough = true + [tcp.services.whoami-a.loadBalancer] [[tcp.services.whoami-a.loadBalancer.servers]] address = "localhost:8081" diff --git a/integration/tcp_test.go b/integration/tcp_test.go index 16b1c8e4..dc834abc 100644 --- a/integration/tcp_test.go +++ b/integration/tcp_test.go @@ -50,6 +50,11 @@ func (s *TCPSuite) TestMixed(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "whoami-no-cert") + // Traefik passes through, termination of wildcard match handled by whoami-a + out, err = guessWho("127.0.0.1:8093", "wildcard.whoami-a.test", true) + c.Assert(err, checker.IsNil) + c.Assert(out, checker.Contains, "whoami-a") + tr1 := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, diff --git a/pkg/tcp/router.go b/pkg/tcp/router.go index ea0f406e..c3ca22ce 100644 --- a/pkg/tcp/router.go +++ b/pkg/tcp/router.go @@ -69,7 +69,7 @@ func (r *Router) ServeTCP(conn WriteCloser) { // FIXME Optimize and test the routing table before helloServerName serverName = types.CanonicalDomain(serverName) if r.routingTable != nil && serverName != "" { - if target, ok := r.routingTable[serverName]; ok { + if target, ok := r.GetTarget(serverName); ok { target.ServeTCP(r.GetConn(conn, peeked)) return } @@ -88,6 +88,21 @@ func (r *Router) ServeTCP(conn WriteCloser) { } } +// GetTarget finds a matching target allowing for wildcard domains. +func (r *Router) GetTarget(serverName string) (Handler, bool) { + if target, ok := r.routingTable[serverName]; ok { + return target, true + } + + for targetName, target := range r.routingTable { + if strings.HasPrefix(targetName, "*.") && strings.HasSuffix(serverName, targetName[1:]) { + return target, true + } + } + + return nil, false +} + // AddRoute defines a handler for a given sniHost (* is the only valid option). func (r *Router) AddRoute(sniHost string, target Handler) { if r.routingTable == nil {