diff --git a/DesktopEdge/Properties/AssemblyInfo.cs b/DesktopEdge/Properties/AssemblyInfo.cs
index 7841b0c5..206acfd2 100644
--- a/DesktopEdge/Properties/AssemblyInfo.cs
+++ b/DesktopEdge/Properties/AssemblyInfo.cs
@@ -50,6 +50,6 @@ using System.Windows;
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.7.6.0")]
-[assembly: AssemblyVersion("1.7.6.0")]
-[assembly: AssemblyFileVersion("1.7.6.0")]
+// [assembly: AssemblyVersion("1.7.8.0")]
+[assembly: AssemblyVersion("1.7.8.0")]
+[assembly: AssemblyFileVersion("1.7.8.0")]
diff --git a/Installer/ZitiDesktopEdge.aip b/Installer/ZitiDesktopEdge.aip
index 73373d6d..c1fcd02f 100644
--- a/Installer/ZitiDesktopEdge.aip
+++ b/Installer/ZitiDesktopEdge.aip
@@ -22,10 +22,10 @@
-
+
-
+
@@ -50,10 +50,12 @@
+
+
@@ -87,6 +89,8 @@
+
+
@@ -248,6 +252,8 @@
+
+
diff --git a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
index 81053e52..70a4ebe2 100644
--- a/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
+++ b/ZitiDesktopEdge.Client/ServiceClient/AbstractClient.cs
@@ -227,12 +227,12 @@ namespace ZitiDesktopEdge.ServiceClient {
return respAsString;
} catch (IOException ioe) {
//almost certainly a problem with the pipe
- Logger.Debug("io error in read: " + ioe.Message);
+ Logger.Error(ioe, "io error in read: " + ioe.Message);
ClientDisconnected(null);
throw ioe;
} catch (Exception ee) {
//almost certainly a problem with the pipe
- Logger.Debug("unexpected error in read: " + ee.Message);
+ Logger.Error(ee, "unexpected error in read: " + ee.Message);
ClientDisconnected(null);
throw ee;
}
diff --git a/ZitiUpdateService/Properties/AssemblyInfo.cs b/ZitiUpdateService/Properties/AssemblyInfo.cs
index 49d06c1f..6c862ebf 100644
--- a/ZitiUpdateService/Properties/AssemblyInfo.cs
+++ b/ZitiUpdateService/Properties/AssemblyInfo.cs
@@ -30,6 +30,6 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.7.6.0")]
-[assembly: AssemblyVersion("1.7.6.0")]
-[assembly: AssemblyFileVersion("1.7.6.0")]
+// [assembly: AssemblyVersion("1.7.8.0")]
+[assembly: AssemblyVersion("1.7.8.0")]
+[assembly: AssemblyFileVersion("1.7.8.0")]
diff --git a/ZitiUpdateService/UpdateService.cs b/ZitiUpdateService/UpdateService.cs
index ee8a7442..5a7d2b08 100644
--- a/ZitiUpdateService/UpdateService.cs
+++ b/ZitiUpdateService/UpdateService.cs
@@ -17,6 +17,8 @@ using ZitiDesktopEdge.Utility;
using NLog;
using Newtonsoft.Json;
+using DnsClient;
+using System.Net;
namespace ZitiUpdateService {
public partial class UpdateService : ServiceBase {
@@ -55,6 +57,9 @@ namespace ZitiUpdateService {
Task eventServer = null;
checkers.UpdateCheck check = null;
+ private Timer dnsProbeTimer = new Timer();
+ private IPAddress dnsIpAddress = null;
+
public UpdateService() {
InitializeComponent();
@@ -355,6 +360,9 @@ namespace ZitiUpdateService {
AccessUtils.GrantAccessToFile(Path.Combine(exeLocation, "ZitiDesktopEdge.exe.config")); //allow anyone to change the config file
AccessUtils.GrantAccessToFile(Path.Combine(exeLocation, "ZitiDesktopEdge-log.config")); //allow anyone to change the log file config
+ dnsProbeTimer.Elapsed += DnsProbe_Elapsed;
+ dnsProbeTimer.Interval = dnsProbeIntervalInSeconds * 1000;
+
Logger.Info("starting ipc server");
ipcServer = svr.startIpcServerAsync(onIpcClientAsync);
Logger.Info("starting events server");
@@ -371,7 +379,58 @@ namespace ZitiUpdateService {
base.OnStart(args);
}
- async private Task onEventsClientAsync(StreamWriter writer) {
+ IPAddress lh = IPAddress.Parse("127.0.0.1"); //expected result
+ int dnsProbeFailCount = 0;
+ int dnsProbeIntervalInSeconds = 15;
+ bool dnsProbeStarted = false;
+
+ private void DnsProbe_Elapsed(object sender, ElapsedEventArgs e) {
+ if (dnsProbeStarted) return; //skip out if it's already going...
+ dnsProbeStarted = true;
+ Logger.Trace("dns probe started");
+ try {
+ if (dnsIpAddress != null) {
+ DnsQuestion q = new DnsQuestion("dew-dns-probe.openziti.org", QueryType.A);
+ var dnsEp = new IPEndPoint(dnsIpAddress, 53);
+ var dnsProbe = new LookupClient(dnsEp);
+
+ foreach (DnsClient.Protocol.ARecord arec in dnsProbe.Query(q).AllRecords) {
+ if (arec.Address.Equals(lh)) {
+ dnsProbeFailCount = 0;
+ Logger.Debug("dns probe success");
+ } else {
+ dnsProbeFailCount++;
+ logDnsProbeFailure(null);
+ }
+ }
+ }
+ } catch(Exception dnse) {
+ //don't really care but it probably means a timeout happened. but might as well log a trace error anyway...
+ //it's expected that this is due to the service shutting down...
+ dnsProbeFailCount++;
+ logDnsProbeFailure(dnse);
+ }
+ dnsProbeStarted = false;
+ }
+
+ private void logDnsProbeFailure(Exception e) {
+ bool logit = false;
+ if (dnsProbeFailCount <= 4) {
+ logit = true;
+ } else {
+ //else log it every 5 minutes...
+ logit = dnsProbeFailCount % (5 * 60 / dnsProbeIntervalInSeconds) == 0;
+ }
+ if (logit) {
+ if (e != null) {
+ Logger.Warn(e, "dns probe failed due to error. This has happened {0} times", dnsProbeFailCount);
+ } else {
+ Logger.Warn("dns probe failed. This has happened {0} times", dnsProbeFailCount);
+ }
+ }
+ }
+
+ async private Task onEventsClientAsync(StreamWriter writer) {
Logger.Info("a new events client was connected");
//reset to release stream
//initial status when connecting the event stream
@@ -711,18 +770,30 @@ namespace ZitiUpdateService {
EventRegistry.SendEventToConsumers(status);
}
- private static void Svc_OnTunnelStatusEvent(object sender, TunnelStatusEvent e) {
+ private void Svc_OnTunnelStatusEvent(object sender, TunnelStatusEvent e) {
string dns = e?.Status?.IpInfo?.DNS;
string version = e?.Status?.ServiceVersion.Version;
string op = e?.Op;
Logger.Info($"Operation {op}. running dns: {dns} at version {version}");
+
+ try {
+ dnsIpAddress = IPAddress.Parse(dns);
+ } catch {
+ //ignore it
+ }
}
- private static void Svc_OnClientConnected(object sender, object e) {
+ private void Svc_OnClientConnected(object sender, object e) {
Logger.Info("successfully connected to service");
+ if (!dnsProbeTimer.Enabled) {
+ dnsProbeTimer.Enabled = true;
+ dnsProbeTimer.Start();
+ Logger.Info("DNS Probe enabled");
+ }
}
private void Svc_OnClientDisconnected(object sender, object e) {
+ //dnsProbeTimer.Stop();
DataClient svc = (DataClient)sender;
if (svc.CleanShutdown) {
//then this is fine and expected - the service is shutting down
diff --git a/ZitiUpdateService/ZitiUpdateService.csproj b/ZitiUpdateService/ZitiUpdateService.csproj
index d2e99b4e..a2e7c843 100644
--- a/ZitiUpdateService/ZitiUpdateService.csproj
+++ b/ZitiUpdateService/ZitiUpdateService.csproj
@@ -76,6 +76,9 @@
bin\Releases\
+
+ ..\packages\DnsClient.1.3.2\lib\net471\DnsClient.dll
+
..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
@@ -83,6 +86,9 @@
..\packages\NLog.4.7.6\lib\net45\NLog.dll
+
+ ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll
+
diff --git a/ZitiUpdateService/checkers/GithubCheck.cs b/ZitiUpdateService/checkers/GithubCheck.cs
index 352aa6db..eeca9452 100644
--- a/ZitiUpdateService/checkers/GithubCheck.cs
+++ b/ZitiUpdateService/checkers/GithubCheck.cs
@@ -15,7 +15,6 @@ namespace ZitiUpdateService.checkers {
string url;
string downloadUrl = null;
string downloadFileName = null;
- string currentResponse = null;
Version nextVersion = null;
public GithubCheck(string url) {
diff --git a/ZitiUpdateService/packages.config b/ZitiUpdateService/packages.config
index 04f986fe..18c2b3df 100644
--- a/ZitiUpdateService/packages.config
+++ b/ZitiUpdateService/packages.config
@@ -1,6 +1,8 @@
+
+
\ No newline at end of file
diff --git a/release-notes.md b/release-notes.md
index 0e5ff903..d213cdbe 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -1,3 +1,34 @@
+# Release 1.7.9
+
+## What's New
+* nothing
+
+## Other changes:
+* none
+
+## Bugs fixed:
+* [#310](https://github.com/openziti/desktop-edge-win/pull/310) Restore identities moved by Windows after Windows system update
+
+## Dependency Updates
+* Tunneler SDK to v0.8.21/CSDK 0.20.13
+
+# Release 1.7.8
+
+## What's New
+* a new DNS probe record was added to the DNS server to allow DNS-related testing
+* ziti-monitor service now probes the DNS server for diagnostic reasons
+* added code to check upgrade status - only useful when the ziti-monitor service is not running
+
+## Other changes:
+* minor logging updates
+
+## Bugs fixed:
+* fixed an issue with hosting connections after channel failure [CSDK #233](https://github.com/openziti/ziti-sdk-c/pull/233)
+* fixed a UI issue when no identites existed
+
+## Dependency Updates
+* Tunneler SDK to v0.8.17/CSDK 0.20.12
+
# Release 1.7.7
## What's New
@@ -11,6 +42,7 @@
## Dependency Updates
* Tunneler SDK to v0.8.15
+
# Release 1.7.6
## What's New
diff --git a/service/cziti/dns.go b/service/cziti/dns.go
index b7ce7a0a..627867c6 100644
--- a/service/cziti/dns.go
+++ b/service/cziti/dns.go
@@ -274,6 +274,15 @@ func DnsInit(tun api.DesktopEdgeIface, ip string, maskBits int) {
dnsMgrPrivate.serviceMap = make(map[string]*ctxService)
//DNS.ipMap = make(map[uint32]string)
dnsMgrPrivate.hostnameMap = make(map[string]*ctxIp)
+ //register the test dns entry:
+ dnsMgrPrivate.hostnameMap[normalizeDnsName("dew-dns-probe.openziti.org")] = &ctxIp{
+ //ctx: nil,
+ ip: net.ParseIP("127.0.0.1"),
+ //network: "",
+ dnsEnabled: true,
+ refCount: 0,
+ }
+
dnsip = net.ParseIP(ip).To4()
mask := net.CIDRMask(maskBits, 32)
dnsMgrPrivate.cidr = binary.BigEndian.Uint32(dnsip) & binary.BigEndian.Uint32(mask)
diff --git a/service/ziti-tunnel/service/orphaned-identities.go b/service/ziti-tunnel/service/orphaned-identities.go
new file mode 100644
index 00000000..af6f5c10
--- /dev/null
+++ b/service/ziti-tunnel/service/orphaned-identities.go
@@ -0,0 +1,101 @@
+package service
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/openziti/desktop-edge-win/service/ziti-tunnel/config"
+)
+
+// After System update, the identity files are not getting copied to the config path
+// So we are adding a function to scan for identities in the backtup location
+func scanForIdentitiesPostWindowsUpdate() error {
+ srcBackUpPaths := [2]string{"Windows.~BT\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\NetFoundry",
+ "Windows.old\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\NetFoundry"}
+ systemDrivePath := os.Getenv("SystemDrive")
+ if systemDrivePath == "" {
+ return nil
+ }
+ for _, srcPath := range srcBackUpPaths {
+ sourcePath := filepath.Join(systemDrivePath, string(os.PathSeparator), srcPath)
+ _, err := os.Stat(sourcePath)
+ if err != nil {
+ log.Debugf("Folder %s does not exist", sourcePath)
+ continue
+ }
+ err = searchAndCopyFilesFromBackup(sourcePath)
+ if err != nil {
+ log.Debugf("Copy files from %s failed, %v", sourcePath, err)
+ }
+ }
+ return nil
+}
+
+func searchAndCopyFilesFromBackup(srcPath string) error {
+ err := filepath.Walk(srcPath, copyFilesFromBackUp)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func copyFilesFromBackUp(path string, f os.FileInfo, err error) error {
+ if !f.IsDir() {
+ log.Infof("Found: %s", path)
+ destinationFile := filepath.Join(config.Path(), string(os.PathSeparator), f.Name())
+ //check if the file is present in the destination folder
+ _, err := os.Stat(destinationFile)
+ if err == nil && !strings.Contains(f.Name(), ConfigFileName) {
+ log.Debugf("File %s is already present in the config path and it is not %s, So not transfering", f.Name(), ConfigFileName)
+ deleteFile(path)
+ return nil
+ }
+ _, err = copy(path, destinationFile)
+ if err != nil {
+ log.Errorf("Error occurred while copying the Windows backup folder %s --> %s %v", f.Name(), destinationFile, err)
+ return nil
+ } else {
+ log.Infof("Found backup file at %s. Restored this file to %s", path, destinationFile)
+ deleteFile(path)
+ }
+ }
+ return nil
+}
+func deleteFile(path string) {
+ log.Infof("Removing file %s", path)
+ err := os.Remove(path)
+ if err != nil {
+ log.Errorf("Error occured while removing the file %s, %v", path, err)
+ } else {
+ log.Infof("Removed file %s", path)
+ }
+}
+
+func copy(src, dst string) (int64, error) {
+ sourceFileStat, err := os.Stat(src)
+ if err != nil {
+ return 0, err
+ }
+
+ if !sourceFileStat.Mode().IsRegular() {
+ return 0, errors.New(fmt.Sprintf("%s is not a regular file", src))
+ }
+
+ source, err := os.Open(src)
+ if err != nil {
+ return 0, err
+ }
+ defer source.Close()
+
+ destination, err := os.Create(dst)
+ if err != nil {
+ return 0, err
+ }
+ defer destination.Close()
+ nBytes, err := io.Copy(destination, source)
+ return nBytes, err
+}
diff --git a/service/ziti-tunnel/service/pkg-vars.go b/service/ziti-tunnel/service/pkg-vars.go
index 339b69a3..8636deb6 100644
--- a/service/ziti-tunnel/service/pkg-vars.go
+++ b/service/ziti-tunnel/service/pkg-vars.go
@@ -18,12 +18,14 @@
package service
import (
+ "sync"
+ "time"
+
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/util/logging"
"golang.org/x/sys/windows/svc"
- "sync"
- "time"
)
+
var Version dto.ServiceVersion
var pipeBase = `\\.\pipe\OpenZiti\ziti\`
@@ -42,7 +44,7 @@ var Debug bool
var TunStarted time.Time
var log = logging.Logger()
-var events = newTopic(32)
+var events = newTopic(32)
const (
API_VERSION = 1
@@ -60,13 +62,13 @@ const (
cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
InformationEvent = 0 //1
- ContinueEvent = 0 //2
- PauseEvent = 0 //3
- InstallEvent = 0 //4
+ ContinueEvent = 0 //2
+ PauseEvent = 0 //3
+ InstallEvent = 0 //4
InterrogateEvent = 0 //5
- StopEvent = 0 //6
- ShutdownEvent = 0 //7
- ErrorEvent = 0 //1000
+ StopEvent = 0 //6
+ ShutdownEvent = 0 //7
+ ErrorEvent = 0 //1000
// This is the name you will use for the NET START command
SvcStartName = "ziti"
@@ -88,7 +90,9 @@ const (
LocalService = "(A;;FA;;;LS)"
NF_GROUP_NAME = "NetFoundry Tunneler Users"
- TunName = "ZitiTUN"
+ TunName = "ZitiTUN"
STATUS_ENROLLED = "enrolled"
+
+ ConfigFileName = "config.json"
)
diff --git a/service/ziti-tunnel/service/state.go b/service/ziti-tunnel/service/state.go
index 4453dad5..9e83ec1c 100644
--- a/service/ziti-tunnel/service/state.go
+++ b/service/ziti-tunnel/service/state.go
@@ -21,6 +21,14 @@ import (
"bufio"
"encoding/json"
"fmt"
+ "io"
+ "io/ioutil"
+ "net"
+ "os"
+ "path"
+ "strings"
+ "time"
+
"github.com/openziti/desktop-edge-win/service/cziti"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/config"
"github.com/openziti/desktop-edge-win/service/ziti-tunnel/constants"
@@ -29,13 +37,6 @@ import (
"golang.org/x/sys/windows/registry"
"golang.zx2c4.com/wireguard/tun"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- "io"
- "io/ioutil"
- "net"
- "os"
- "path"
- "strings"
- "time"
)
type RuntimeState struct {
@@ -58,7 +59,7 @@ func (t *RuntimeState) SaveState() {
_ = os.MkdirAll(config.Path(), 0644)
log.Debugf("backing up config")
- backup,err := backupConfig()
+ backup, err := backupConfig()
if err != nil {
log.Warnf("could not backup config file! %v", err)
} else {
@@ -141,16 +142,16 @@ func (t *RuntimeState) ToStatus(onlyInitialized bool) dto.TunnelStatus {
func (t *RuntimeState) ToMetrics() dto.TunnelStatus {
clean := dto.TunnelStatus{
- Identities: make([]*dto.Identity, len(t.ids)),
+ Identities: make([]*dto.Identity, len(t.ids)),
}
i := 0
for _, id := range t.ids {
AddMetrics(id)
clean.Identities[i] = &dto.Identity{
- Name: id.Name,
- FingerPrint: id.FingerPrint,
- Metrics: id.Metrics,
+ Name: id.Name,
+ FingerPrint: id.FingerPrint,
+ Metrics: id.Metrics,
}
i++
}
@@ -160,7 +161,7 @@ func (t *RuntimeState) ToMetrics() dto.TunnelStatus {
func (t *RuntimeState) CreateTun(ipv4 string, ipv4mask int) (net.IP, *tun.Device, error) {
log.Infof("creating TUN device: %s", TunName)
- tunDevice, err := tun.CreateTUN(TunName, 64*1024 - 1)
+ tunDevice, err := tun.CreateTUN(TunName, 64*1024-1)
if err == nil {
t.tun = &tunDevice
tunName, err2 := tunDevice.Name()
@@ -201,7 +202,7 @@ func (t *RuntimeState) CreateTun(ipv4 string, ipv4mask int) (net.IP, *tun.Device
return nil, nil, fmt.Errorf("failed to set IP address to %v: (%v)", ip, err)
}
- dnsServers := []net.IP{ ip }
+ dnsServers := []net.IP{ip}
log.Infof("adding DNS servers to TUN: %s", dnsServers)
err = luid.AddDNS(dnsServers)
@@ -217,7 +218,7 @@ func (t *RuntimeState) CreateTun(ipv4 string, ipv4mask int) (net.IP, *tun.Device
log.Infof("TUN dns servers set to: %s", dns)
log.Infof("setting routes for cidr: %s. Next Hop: %s", ipnet.String(), ipnet.IP.String())
- err = luid.SetRoutes([]*winipcfg.RouteData{{ Destination: *ipnet, NextHop: ipnet.IP, Metric: 0}})
+ err = luid.SetRoutes([]*winipcfg.RouteData{{Destination: *ipnet, NextHop: ipnet.IP, Metric: 0}})
if err != nil {
return nil, nil, fmt.Errorf("failed to SetRoutes: (%v)", err)
}
@@ -233,7 +234,7 @@ func (t *RuntimeState) LoadIdentity(id *Id, refreshInterval int) {
}
_, err := os.Stat(id.Path())
- if err != nil{
+ if err != nil {
if os.IsNotExist(err) {
//file does not exist. TODO remove this from the list
} else {
@@ -244,7 +245,7 @@ func (t *RuntimeState) LoadIdentity(id *Id, refreshInterval int) {
log.Infof("loading identity %s[%s]", id.Name, id.FingerPrint)
- sc := func(status int){
+ sc := func(status int) {
log.Infof("status change! %d", status)
id.ControllerVersion = id.CId.Version
@@ -267,7 +268,7 @@ func (t *RuntimeState) LoadIdentity(id *Id, refreshInterval int) {
events.broadcast <- dto.IdentityEvent{
ActionEvent: IDENTITY_ADDED,
- Id: id.Identity,
+ Id: id.Identity,
}
log.Infof("connecting identity completed: %s[%s]", id.Name, id.FingerPrint)
}
@@ -278,6 +279,7 @@ func (t *RuntimeState) LoadIdentity(id *Id, refreshInterval int) {
}
func (t *RuntimeState) LoadConfig() {
+ scanForIdentitiesPostWindowsUpdate()
err := readConfig(t, config.File())
if err != nil {
err = readConfig(t, config.BackupFile())
@@ -319,7 +321,7 @@ func (t *RuntimeState) scanForOrphanedIdentities(folder string) {
fingerprint := strings.Split(f.Name(), ".")[0]
var found *dto.Identity
for _, sid := range t.state.Identities {
- if sid.FingerPrint == fingerprint{
+ if sid.FingerPrint == fingerprint {
found = sid
break
}
@@ -387,11 +389,11 @@ func readConfig(t *RuntimeState, filename string) error {
return nil
}
-func (t *RuntimeState) UpdateIpv4Mask(ipv4mask int){
+func (t *RuntimeState) UpdateIpv4Mask(ipv4mask int) {
rts.state.TunIpv4Mask = ipv4mask
rts.SaveState()
}
-func (t *RuntimeState) UpdateIpv4(ipv4 string){
+func (t *RuntimeState) UpdateIpv4(ipv4 string) {
rts.state.TunIpv4 = ipv4
rts.SaveState()
}
@@ -447,7 +449,7 @@ func (t *RuntimeState) Close() {
t.RemoveZitiTun()
}
-func(t *RuntimeState) RemoveZitiTun() {
+func (t *RuntimeState) RemoveZitiTun() {
log.Infof("Removing existing interface: %s", TunName)
wt, err := tun.WintunPool.OpenAdapter(TunName)
if err == nil {
diff --git a/version b/version
index 91c74a58..f65dc1e2 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-1.7.7
+1.7.9