Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions services/wireguard/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ func (c *Connection) State() <-chan connectionstate.State {
return c.stateCh
}

// sendState safely sends a state to the state channel, preventing panics from sends on closed channel.
func (c *Connection) sendState(state connectionstate.State) {
select {
case c.stateCh <- state:
case <-c.done:
// Connection is stopped, don't send
}
}

// Statistics returns connection statistics channel.
func (c *Connection) Statistics() (connectionstate.Statistics, error) {
stats, err := c.connectionEndpoint.PeerStats()
Expand Down Expand Up @@ -128,7 +137,7 @@ func (c *Connection) start(ctx context.Context, start startConn, options connect
}
}()

c.stateCh <- connectionstate.Connecting
c.sendState(connectionstate.Connecting)

if options.ProviderNATConn != nil {
options.ProviderNATConn.Close()
Expand Down Expand Up @@ -170,7 +179,7 @@ func (c *Connection) start(ctx context.Context, start startConn, options connect
return errors.Wrap(err, "failed while waiting for a peer handshake")
}

c.stateCh <- connectionstate.Connected
c.sendState(connectionstate.Connected)
return nil
}

Expand Down Expand Up @@ -224,7 +233,7 @@ func (c *Connection) GetConfig() (connection.ConsumerConfig, error) {
func (c *Connection) Stop() {
c.stopOnce.Do(func() {
log.Info().Msg("Stopping WireGuard connection")
c.stateCh <- connectionstate.Disconnecting
c.sendState(connectionstate.Disconnecting)

if c.removeAllowedIPRule != nil {
c.removeAllowedIPRule()
Expand All @@ -236,9 +245,14 @@ func (c *Connection) Stop() {
}
}

c.stateCh <- connectionstate.NotConnected
// Send final state before closing channels
select {
case c.stateCh <- connectionstate.NotConnected:
default:
}

close(c.stateCh)
// Close done first so sendState calls will bail out instead of sending on closed stateCh
close(c.done)
close(c.stateCh)
})
}
Loading