Skip to content

Commit cfba6a1

Browse files
committed
Handle the case when adding route after server starts
- returns null routeId to indicate a failed registration
1 parent 26f8927 commit cfba6a1

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

tcpproxy.go

+23-13
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func equals(want string) Matcher {
9494

9595
// config contains the proxying state for one listener.
9696
type 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 {
104104
func 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

139140
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+
}
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.
165176
func (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.
251260
func (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

Comments
 (0)