diff --git a/app/plugins/networkCheck.go b/app/plugins/networkCheck.go index 1437616..3bcfcfe 100644 --- a/app/plugins/networkCheck.go +++ b/app/plugins/networkCheck.go @@ -2,6 +2,7 @@ package plugins import ( "cwtch.im/cwtch/event" + "cwtch.im/cwtch/protocol/connections" "git.openprivacy.ca/openprivacy/libricochet-go/connectivity" "git.openprivacy.ca/openprivacy/libricochet-go/log" "git.openprivacy.ca/openprivacy/libricochet-go/policies" @@ -16,6 +17,7 @@ type networkCheck struct { onionsToCheck []string breakChan chan bool running bool + offline bool } // NewNetworkCheck returns a Plugin that when started will attempt various network tests @@ -34,6 +36,8 @@ func (nc *networkCheck) run() { nc.bus.Subscribe(event.NewMessageFromPeer, nc.queue) nc.bus.Subscribe(event.PeerAcknowledgement, nc.queue) nc.bus.Subscribe(event.EncryptedGroupMessage, nc.queue) + nc.bus.Subscribe(event.PeerStateChange, nc.queue) + nc.bus.Subscribe(event.ServerStateChange, nc.queue) var lastMessageReceived time.Time for { select { @@ -48,13 +52,26 @@ func (nc *networkCheck) run() { case event.ProtocolEngineStartListen: log.Debugf("initiating connection check for %v", e.Data[event.Onion]) nc.onionsToCheck = append(nc.onionsToCheck, e.Data[event.Onion]) + case event.PeerStateChange: + fallthrough + case event.ServerStateChange: + // if we successfully connect / authenticated to a remote server / peer then we obviously have internet + connectionState := e.Data[event.ConnectionState] + if nc.offline && (connectionState == connections.ConnectionStateName[connections.AUTHENTICATED] || connectionState == connections.ConnectionStateName[connections.CONNECTED]) { + lastMessageReceived = time.Now() + nc.bus.Publish(event.NewEvent(event.NetworkStatus, map[event.Field]string{event.Error: "", event.Status: "Success"})) + nc.offline = false + } default: // if we receive either an encrypted group message or a peer acknowledgement we can assume the network // is up and running (our onion service might still not be available, but we would aim to detect that // through other actions // we reset out timer lastMessageReceived = time.Now() - nc.bus.Publish(event.NewEvent(event.NetworkStatus, map[event.Field]string{event.Error: "", event.Status: "Success"})) + if nc.offline { + nc.bus.Publish(event.NewEvent(event.NetworkStatus, map[event.Field]string{event.Error: "", event.Status: "Success"})) + nc.offline = false + } } case <-time.After(tickTime): // if we haven't received an action in the last minute...kick off a set of testing @@ -91,8 +108,10 @@ func (nc *networkCheck) checkConnection(onion string) { if err != nil { log.Debugf("publishing network error for %v", onion) nc.bus.Publish(event.NewEvent(event.NetworkStatus, map[event.Field]string{event.Onion: onion, event.Error: err.Error(), event.Status: "Error"})) + nc.offline = false } else { log.Debugf("publishing network success for %v", onion) nc.bus.Publish(event.NewEvent(event.NetworkStatus, map[event.Field]string{event.Onion: onion, event.Error: "", event.Status: "Success"})) + nc.offline = true } } diff --git a/testing/cwtch_peer_server_integration_test.go b/testing/cwtch_peer_server_integration_test.go index 6d01de7..184d095 100644 --- a/testing/cwtch_peer_server_integration_test.go +++ b/testing/cwtch_peer_server_integration_test.go @@ -410,7 +410,7 @@ func TestCwtchPeerIntegration(t *testing.T) { fmt.Println("Shutting down ACN...") acn.Close() - time.Sleep(time.Second * 2) // Server ^^ has a 5 second loop attempting reconnect before exiting + time.Sleep(time.Second * 2) // Server ^^ has a 5 second loop attempting reconnect before exiting time.Sleep(time.Second * 30) // the network status plugin might keep goroutines alive for a minute before killing them numGoRoutinesPostACN := runtime.NumGoroutine()