Improve online status and location checks
This commit is contained in:
@@ -241,7 +241,7 @@ func addLocation(dl *DeviceLocation) {
|
||||
func GetApproximateInternetLocation() (net.IP, error) {
|
||||
loc, ok := GetInternetLocation()
|
||||
if !ok || loc.Best() == nil {
|
||||
return nil, errors.New("no location data available")
|
||||
return nil, errors.New("no device location data available")
|
||||
}
|
||||
return loc.Best().IP, nil
|
||||
}
|
||||
@@ -259,7 +259,7 @@ func GetInternetLocation() (deviceLocations *DeviceLocations, ok bool) {
|
||||
// Get all assigned addresses.
|
||||
v4s, v6s, err := GetAssignedAddresses()
|
||||
if err != nil {
|
||||
log.Warningf("netenv: failed to get assigned addresses: %s", err)
|
||||
log.Warningf("netenv: failed to get assigned addresses for device location: %s", err)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
@@ -267,27 +267,24 @@ func GetInternetLocation() (deviceLocations *DeviceLocations, ok bool) {
|
||||
v4ok, v6ok := getLocationFromInterfaces()
|
||||
|
||||
// Try other methods for missing locations.
|
||||
if len(v4s) > 0 {
|
||||
if !v4ok {
|
||||
_, err = getLocationFromTraceroute()
|
||||
if err != nil {
|
||||
log.Warningf("netenv: failed to get IPv4 from traceroute: %s", err)
|
||||
} else {
|
||||
v4ok = true
|
||||
}
|
||||
if len(v4s) > 0 && !v4ok {
|
||||
_, err = getLocationFromTraceroute()
|
||||
if err != nil {
|
||||
log.Warningf("netenv: failed to get IPv4 device location from traceroute: %s", err)
|
||||
} else {
|
||||
v4ok = true
|
||||
}
|
||||
|
||||
// Get location from timezone as final fallback.
|
||||
if !v4ok {
|
||||
v4ok = getLocationFromTimezone(packet.IPv4)
|
||||
getLocationFromTimezone(packet.IPv4)
|
||||
}
|
||||
}
|
||||
if len(v6s) > 0 && !v6ok {
|
||||
// TODO
|
||||
log.Warningf("netenv: could not get IPv6 location")
|
||||
}
|
||||
// TODO: Find more ways to get IPv6 device location
|
||||
|
||||
// Check if we have any locations.
|
||||
if !v4ok && !v6ok {
|
||||
return nil, false
|
||||
// Get location from timezone as final fallback.
|
||||
getLocationFromTimezone(packet.IPv6)
|
||||
}
|
||||
|
||||
// Return gathered locations.
|
||||
|
||||
@@ -145,6 +145,7 @@ var (
|
||||
onlineStatusInvestigationTrigger = make(chan struct{}, 1)
|
||||
onlineStatusInvestigationInProgress = abool.NewBool(false)
|
||||
onlineStatusInvestigationWg sync.WaitGroup
|
||||
onlineStatusNotification *notifications.Notification
|
||||
|
||||
captivePortal = &CaptivePortal{}
|
||||
captivePortalLock sync.Mutex
|
||||
@@ -186,7 +187,7 @@ func CheckAndGetOnlineStatus() OnlineStatus {
|
||||
func updateOnlineStatus(status OnlineStatus, portalURL *url.URL, comment string) {
|
||||
changed := false
|
||||
|
||||
// status
|
||||
// Update online status.
|
||||
currentStatus := atomic.LoadInt32(onlineStatus)
|
||||
if status != OnlineStatus(currentStatus) && atomic.CompareAndSwapInt32(onlineStatus, currentStatus, int32(status)) {
|
||||
// status changed!
|
||||
@@ -196,10 +197,10 @@ func updateOnlineStatus(status OnlineStatus, portalURL *url.URL, comment string)
|
||||
changed = true
|
||||
}
|
||||
|
||||
// captive portal
|
||||
// Update captive portal.
|
||||
setCaptivePortal(portalURL)
|
||||
|
||||
// trigger event
|
||||
// Trigger events.
|
||||
if changed {
|
||||
module.TriggerEvent(OnlineStatusChangedEvent, status)
|
||||
if status == StatusPortal {
|
||||
@@ -209,6 +210,9 @@ func updateOnlineStatus(status OnlineStatus, portalURL *url.URL, comment string)
|
||||
}
|
||||
triggerNetworkChangeCheck()
|
||||
|
||||
// Notify user.
|
||||
notifyOnlineStatus(status)
|
||||
|
||||
// Trigger update check when coming (semi) online.
|
||||
if Online() {
|
||||
_ = updates.TriggerUpdate(false)
|
||||
@@ -216,11 +220,54 @@ func updateOnlineStatus(status OnlineStatus, portalURL *url.URL, comment string)
|
||||
}
|
||||
}
|
||||
|
||||
func notifyOnlineStatus(status OnlineStatus) {
|
||||
var eventID, title, message string
|
||||
|
||||
// Check if status is worth notifying.
|
||||
switch status {
|
||||
case StatusOffline:
|
||||
eventID = "netenv:online-status:offline"
|
||||
title = "Device is Offline"
|
||||
message = "Portmaster did not detect any network connectivity."
|
||||
case StatusLimited:
|
||||
eventID = "netenv:online-status:limited"
|
||||
title = "Limited network connectivity."
|
||||
message = "Portmaster did detect local network connectivity, but could not detect connectivity to the Internet."
|
||||
default:
|
||||
// Delete notification, if present.
|
||||
if onlineStatusNotification != nil {
|
||||
onlineStatusNotification.Delete()
|
||||
onlineStatusNotification = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Update notification if not present or online status changed.
|
||||
switch {
|
||||
case onlineStatusNotification == nil:
|
||||
// Continue creating new notification.
|
||||
case onlineStatusNotification.EventID == eventID:
|
||||
// Notification stays the same, stick with the old one.
|
||||
return
|
||||
default:
|
||||
// Delete old notification before triggering updated one.
|
||||
onlineStatusNotification.Delete()
|
||||
}
|
||||
|
||||
// Create update status notification.
|
||||
onlineStatusNotification = notifications.Notify(¬ifications.Notification{
|
||||
EventID: eventID,
|
||||
Type: notifications.Info,
|
||||
Title: title,
|
||||
Message: message,
|
||||
})
|
||||
}
|
||||
|
||||
func setCaptivePortal(portalURL *url.URL) {
|
||||
captivePortalLock.Lock()
|
||||
defer captivePortalLock.Unlock()
|
||||
|
||||
// delete
|
||||
// Delete captive portal if no url is supplied.
|
||||
if portalURL == nil {
|
||||
captivePortal = &CaptivePortal{}
|
||||
if captivePortalNotification != nil {
|
||||
@@ -230,12 +277,12 @@ func setCaptivePortal(portalURL *url.URL) {
|
||||
return
|
||||
}
|
||||
|
||||
// return if unchanged
|
||||
if portalURL.String() == captivePortal.URL {
|
||||
// Only set captive portal once per detection.
|
||||
if captivePortal.URL != "" {
|
||||
return
|
||||
}
|
||||
|
||||
// set
|
||||
// Compile captive portal data.
|
||||
captivePortal = &CaptivePortal{
|
||||
URL: portalURL.String(),
|
||||
}
|
||||
@@ -247,7 +294,7 @@ func setCaptivePortal(portalURL *url.URL) {
|
||||
captivePortal.Domain = portalURL.Hostname()
|
||||
}
|
||||
|
||||
// notify
|
||||
// Notify user about portal.
|
||||
captivePortalNotification = notifications.Notify(¬ifications.Notification{
|
||||
EventID: "netenv:captive-portal",
|
||||
Type: notifications.Info,
|
||||
|
||||
Reference in New Issue
Block a user