impl connection recovery
This commit is contained in:
@@ -26,6 +26,7 @@ type blackholeRelay struct {
|
||||
addr string
|
||||
backend string
|
||||
gen atomic.Uint64
|
||||
down atomic.Bool
|
||||
mu sync.Mutex
|
||||
held []net.Conn
|
||||
}
|
||||
@@ -59,6 +60,10 @@ func newBlackholeRelay(t *testing.T, backend string) *blackholeRelay {
|
||||
|
||||
func (r *blackholeRelay) handle(cli net.Conn) {
|
||||
born := r.gen.Load()
|
||||
if r.down.Load() {
|
||||
_ = cli.Close()
|
||||
return
|
||||
}
|
||||
up, err := net.Dial("tcp", r.backend)
|
||||
if err != nil {
|
||||
_ = cli.Close()
|
||||
@@ -89,6 +94,34 @@ func (r *blackholeRelay) handle(cli net.Conn) {
|
||||
// unaffected.
|
||||
func (r *blackholeRelay) blackhole() { r.gen.Add(1) }
|
||||
|
||||
// dropAll hard-resets every currently-established pair: a real FIN/RST reaches
|
||||
// both ends immediately, as when a middlebox is restarted or a route flaps,
|
||||
// rather than the silent stranding blackhole models. Later connections are
|
||||
// carried normally.
|
||||
//
|
||||
// stop takes the relay out of service: new connections are refused rather than
|
||||
// carried, so the tunnel stays down until restore is called. Models an outage
|
||||
// the client cannot immediately reconnect through.
|
||||
func (r *blackholeRelay) stop() { r.down.Store(true) }
|
||||
|
||||
// restore puts the relay back in service. Flows stranded before it are still
|
||||
// dead — only fresh connections are carried, which is what a client gets after
|
||||
// a middlebox or upstream link comes back.
|
||||
func (r *blackholeRelay) restore() { r.down.Store(false) }
|
||||
|
||||
// This is the fast path into stream resumption: the client learns the conn is
|
||||
// gone at once instead of waiting out a heartbeat timeout.
|
||||
func (r *blackholeRelay) dropAll() {
|
||||
r.gen.Add(1)
|
||||
r.mu.Lock()
|
||||
held := r.held
|
||||
r.held = nil
|
||||
r.mu.Unlock()
|
||||
for _, c := range held {
|
||||
_ = c.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// TestBlackholedPathRecovers is the end-to-end regression guard for the
|
||||
// stability bug this hardening was written for: with the tunnel's path silently
|
||||
// dropped, the client used to notice nothing at all. Its read loops parked
|
||||
|
||||
Reference in New Issue
Block a user