Skip to content

Commit 8de9853

Browse files
authored
Support of address reuse in server reload (#6)
* Support of address reuse in server reload Update server reload logic to support multiple servers having the same address Signed-off-by: Gleb Kogtev <[email protected]> * Fix issue with multiple servers with different addresses Signed-off-by: Gleb Kogtev <[email protected]> --------- Signed-off-by: Gleb Kogtev <[email protected]>
1 parent b1ad5f2 commit 8de9853

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

caddy.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Copyright 2015 Light Code Labs, LLC
22
//
3+
// Copyright 2024 MWS
4+
//
35
// Licensed under the Apache License, Version 2.0 (the "License");
46
// you may not use this file except in compliance with the License.
57
// You may obtain a copy of the License at
@@ -218,22 +220,22 @@ func (i *Instance) Restart(newCaddyfile Input) (*Instance, error) {
218220
}
219221

220222
// Add file descriptors of all the sockets that are capable of it
221-
restartFds := make(map[string]restartTriple)
223+
restartFds := make(map[string][]restartTriple)
222224
for _, s := range i.servers {
223225
gs, srvOk := s.server.(GracefulServer)
224226
ln, lnOk := s.listener.(Listener)
225227
pc, pcOk := s.packet.(PacketConn)
226228
if srvOk {
227229
if lnOk && pcOk {
228-
restartFds[gs.Address()] = restartTriple{server: gs, listener: ln, packet: pc}
230+
restartFds[gs.Address()] = append(restartFds[gs.Address()], restartTriple{server: gs, listener: ln, packet: pc})
229231
continue
230232
}
231233
if lnOk {
232-
restartFds[gs.Address()] = restartTriple{server: gs, listener: ln}
234+
restartFds[gs.Address()] = append(restartFds[gs.Address()], restartTriple{server: gs, listener: ln})
233235
continue
234236
}
235237
if pcOk {
236-
restartFds[gs.Address()] = restartTriple{server: gs, packet: pc}
238+
restartFds[gs.Address()] = append(restartFds[gs.Address()], restartTriple{server: gs, packet: pc})
237239
continue
238240
}
239241
}
@@ -484,7 +486,7 @@ func Start(cdyfile Input) (*Instance, error) {
484486
return inst, nil
485487
}
486488

487-
func startWithListenerFds(cdyfile Input, inst *Instance, restartFds map[string]restartTriple) error {
489+
func startWithListenerFds(cdyfile Input, inst *Instance, restartFds map[string][]restartTriple) error {
488490
// save this instance in the list now so that
489491
// plugins can access it if need be, for example
490492
// the caddytls package, so it can perform cert
@@ -684,7 +686,7 @@ func executeDirectives(inst *Instance, filename string,
684686
return nil
685687
}
686688

687-
func startServers(serverList []Server, inst *Instance, restartFds map[string]restartTriple) error {
689+
func startServers(serverList []Server, inst *Instance, restartFds map[string][]restartTriple) error {
688690
errChan := make(chan error, len(serverList))
689691

690692
// used for signaling to error logging goroutine to terminate
@@ -734,7 +736,16 @@ func startServers(serverList []Server, inst *Instance, restartFds map[string]res
734736
// reuse the listener for a graceful restart.
735737
if gs, ok := s.(GracefulServer); ok && restartFds != nil {
736738
addr := gs.Address()
737-
if old, ok := restartFds[addr]; ok {
739+
// Multiple servers may use the same addr (SO_REUSEPORT option set), so it's important to ensure
740+
// that we don't reuse the same listener/packetconn.
741+
// We'll create new listeners in case there are no more available triples for the same address.
742+
if triples, ok := restartFds[addr]; ok && len(triples) > 0 {
743+
// Take first available triple
744+
old := triples[0]
745+
// Remove reused triple from restartFds
746+
triples[0] = triples[len(triples)-1]
747+
restartFds[addr] = triples[:len(triples)-1]
748+
738749
// listener
739750
if old.listener != nil {
740751
file, err := old.listener.File()

0 commit comments

Comments
 (0)