@@ -94,7 +94,7 @@ func equals(want string) Matcher {
9494
9595// config contains the proxying state for one listener.
9696type config struct {
97- sync.Mutex // protect r/ w of routes
97+ sync.Mutex // protect w of routes
9898 nextRouteId int
9999 routes map [int ]route
100100 acmeTargets []Target // accumulates targets that should be probed for acme.
@@ -104,6 +104,7 @@ type config struct {
104104func NewConfig () (cfg * config ) {
105105 cfg = & config {}
106106 cfg .routes = make (map [int ]route )
107+ cfg .nextRouteId = 1
107108 return
108109}
109110
@@ -137,18 +138,28 @@ func (p *Proxy) configFor(ipPort string) *config {
137138}
138139
139140func (p * Proxy ) addRoute (ipPort string , r route ) (routeId int ) {
140- cfg := p .configFor (ipPort )
141- cfg .Lock ()
142- defer cfg .Unlock ()
143- routeId = cfg .nextRouteId
144- cfg .nextRouteId ++
145- cfg .routes [routeId ] = r
141+ var cfg * config
142+ if p .donec != nil {
143+ // NOTE: Do not create config file if the server is listening.
144+ // This saves the handling of bringing up and tearing down
145+ // listeners when add or remove route.
146+ cfg = p .configs [ipPort ]
147+ } else {
148+ cfg = p .configFor (ipPort )
149+ }
150+ if cfg != nil {
151+ cfg .Lock ()
152+ routeId = cfg .nextRouteId
153+ cfg .nextRouteId ++
154+ cfg .routes [routeId ] = r
155+ cfg .Unlock ()
156+ }
146157 return
147158}
148159
149160// AddRoute appends an always-matching route to the ipPort listener,
150161// directing any connection to dest. The added route's id is returned
151- // for future removal.
162+ // for future removal. If routeId is zero, the route is not registered.
152163//
153164// This is generally used as either the only rule (for simple TCP
154165// proxies), or as the final fallback rule for an ipPort.
@@ -164,9 +175,7 @@ func (p *Proxy) AddRoute(ipPort string, dest Target) (routeId int) {
164175// Both AddRoute and RemoveRoute is go-routine safe.
165176func (p * Proxy ) RemoveRoute (ipPort string , routeId int ) (err error ) {
166177 cfg := p .configFor (ipPort )
167- cfg .Lock ()
168- defer cfg .Unlock ()
169- delete (cfg .routes , routeId )
178+ cfg .routes [routeId ] = nil
170179 return
171180}
172181
@@ -250,9 +259,10 @@ func (p *Proxy) serveListener(ret chan<- error, ln net.Listener, cfg *config) {
250259// It returns whether it matched purely for testing.
251260func (p * Proxy ) serveConn (c net.Conn , cfg * config ) bool {
252261 br := bufio .NewReader (c )
253- cfg .Lock ()
254- defer cfg .Unlock ()
255262 for _ , route := range cfg .routes {
263+ if route == nil {
264+ continue
265+ }
256266 if target := route .match (br ); target != nil {
257267 if n := br .Buffered (); n > 0 {
258268 peeked , _ := br .Peek (br .Buffered ())
0 commit comments