@@ -94,7 +94,7 @@ func equals(want string) Matcher {
94
94
95
95
// config contains the proxying state for one listener.
96
96
type config struct {
97
- sync.Mutex // protect r/ w of routes
97
+ sync.Mutex // protect w of routes
98
98
nextRouteId int
99
99
routes map [int ]route
100
100
acmeTargets []Target // accumulates targets that should be probed for acme.
@@ -104,6 +104,7 @@ type config struct {
104
104
func NewConfig () (cfg * config ) {
105
105
cfg = & config {}
106
106
cfg .routes = make (map [int ]route )
107
+ cfg .nextRouteId = 1
107
108
return
108
109
}
109
110
@@ -137,18 +138,28 @@ func (p *Proxy) configFor(ipPort string) *config {
137
138
}
138
139
139
140
func (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
+ }
146
157
return
147
158
}
148
159
149
160
// AddRoute appends an always-matching route to the ipPort listener,
150
161
// 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.
152
163
//
153
164
// This is generally used as either the only rule (for simple TCP
154
165
// proxies), or as the final fallback rule for an ipPort.
@@ -164,9 +175,7 @@ func (p *Proxy) AddRoute(ipPort string, dest Target) (routeId int) {
164
175
// Both AddRoute and RemoveRoute is go-routine safe.
165
176
func (p * Proxy ) RemoveRoute (ipPort string , routeId int ) (err error ) {
166
177
cfg := p .configFor (ipPort )
167
- cfg .Lock ()
168
- defer cfg .Unlock ()
169
- delete (cfg .routes , routeId )
178
+ cfg .routes [routeId ] = nil
170
179
return
171
180
}
172
181
@@ -250,9 +259,10 @@ func (p *Proxy) serveListener(ret chan<- error, ln net.Listener, cfg *config) {
250
259
// It returns whether it matched purely for testing.
251
260
func (p * Proxy ) serveConn (c net.Conn , cfg * config ) bool {
252
261
br := bufio .NewReader (c )
253
- cfg .Lock ()
254
- defer cfg .Unlock ()
255
262
for _ , route := range cfg .routes {
263
+ if route == nil {
264
+ continue
265
+ }
256
266
if target := route .match (br ); target != nil {
257
267
if n := br .Buffered (); n > 0 {
258
268
peeked , _ := br .Peek (br .Buffered ())
0 commit comments