summaryrefslogtreecommitdiff
path: root/tcpproxy.go
diff options
context:
space:
mode:
Diffstat (limited to 'tcpproxy.go')
-rw-r--r--tcpproxy.go47
1 files changed, 35 insertions, 12 deletions
diff --git a/tcpproxy.go b/tcpproxy.go
index 1eee7ea..02b70f5 100644
--- a/tcpproxy.go
+++ b/tcpproxy.go
@@ -69,7 +69,7 @@ import (
// The order that routes are added in matters; each is matched in the order
// registered.
type Proxy struct {
- routes map[string][]route // ip:port => routes
+ configs map[string]*config // ip:port => config
lns []net.Listener
donec chan struct{} // closed before err
@@ -81,7 +81,22 @@ type Proxy struct {
ListenFunc func(net, laddr string) (net.Listener, error)
}
+// config contains the proxying state for one listener.
+type config struct {
+ routes []route
+ acmeTargets []Target // accumulates targets that should be probed for acme.
+ stopACME bool // if true, AddSNIRoute doesn't add targets to acmeTargets.
+}
+
+// A route matches a connection to a target.
type route interface {
+ // match examines the initial bytes of a connection, looking for a
+ // match. If a match is found, match returns a non-nil Target to
+ // which the stream should be proxied. match returns nil if the
+ // connection doesn't match.
+ //
+ // match must not consume bytes from the given bufio.Reader, it
+ // can only Peek.
match(*bufio.Reader) Target
}
@@ -92,11 +107,19 @@ func (p *Proxy) netListen() func(net, laddr string) (net.Listener, error) {
return net.Listen
}
-func (p *Proxy) addRoute(ipPort string, r route) {
- if p.routes == nil {
- p.routes = make(map[string][]route)
+func (p *Proxy) configFor(ipPort string) *config {
+ if p.configs == nil {
+ p.configs = make(map[string]*config)
}
- p.routes[ipPort] = append(p.routes[ipPort], r)
+ if p.configs[ipPort] == nil {
+ p.configs[ipPort] = &config{}
+ }
+ return p.configs[ipPort]
+}
+
+func (p *Proxy) addRoute(ipPort string, r route) {
+ cfg := p.configFor(ipPort)
+ cfg.routes = append(cfg.routes, r)
}
// AddRoute appends an always-matching route to the ipPort listener,
@@ -107,14 +130,14 @@ func (p *Proxy) addRoute(ipPort string, r route) {
//
// The ipPort is any valid net.Listen TCP address.
func (p *Proxy) AddRoute(ipPort string, dest Target) {
- p.addRoute(ipPort, alwaysMatch{dest})
+ p.addRoute(ipPort, fixedTarget{dest})
}
-type alwaysMatch struct {
+type fixedTarget struct {
t Target
}
-func (m alwaysMatch) match(*bufio.Reader) Target { return m.t }
+func (m fixedTarget) match(*bufio.Reader) Target { return m.t }
// Run is calls Start, and then Wait.
//
@@ -155,16 +178,16 @@ func (p *Proxy) Start() error {
return errors.New("already started")
}
p.donec = make(chan struct{})
- errc := make(chan error, len(p.routes))
- p.lns = make([]net.Listener, 0, len(p.routes))
- for ipPort, routes := range p.routes {
+ errc := make(chan error, len(p.configs))
+ p.lns = make([]net.Listener, 0, len(p.configs))
+ for ipPort, config := range p.configs {
ln, err := p.netListen()("tcp", ipPort)
if err != nil {
p.Close()
return err
}
p.lns = append(p.lns, ln)
- go p.serveListener(errc, ln, routes)
+ go p.serveListener(errc, ln, config.routes)
}
go p.awaitFirstError(errc)
return nil