diff --git a/DesktopEdge/Assets/Images/Success.png b/DesktopEdge/Assets/Images/Success.png new file mode 100644 index 00000000..d9532ab4 Binary files /dev/null and b/DesktopEdge/Assets/Images/Success.png differ diff --git a/DesktopEdge/MainMenu.xaml b/DesktopEdge/MainMenu.xaml index e6fc069e..36ba6a25 100644 --- a/DesktopEdge/MainMenu.xaml +++ b/DesktopEdge/MainMenu.xaml @@ -58,6 +58,16 @@ + + + + + + + + + + @@ -71,7 +81,8 @@ - + + diff --git a/DesktopEdge/MainMenu.xaml.cs b/DesktopEdge/MainMenu.xaml.cs index cc7f772b..b96e4c47 100644 --- a/DesktopEdge/MainMenu.xaml.cs +++ b/DesktopEdge/MainMenu.xaml.cs @@ -10,6 +10,9 @@ using System.Reflection; using System.Web; using System.Net.Mail; using System.IO; +using System.Net; +using Newtonsoft.Json.Linq; +using System.Threading.Tasks; namespace ZitiDesktopEdge { @@ -21,12 +24,18 @@ namespace ZitiDesktopEdge public delegate void AttachementChanged(bool attached); public event AttachementChanged OnAttachmentChange; + public delegate void LogLevelChanged(string level); + public event LogLevelChanged OnLogLevelChanged; public string menuState = "Main"; public string licenseData = "it's open source."; + public string LogLevel = ""; + private string _updateUrl = "https://api.github.com/repos/openziti/desktop-edge-win/releases/latest"; + private string _downloadUrl = ""; public MainMenu() { InitializeComponent(); LicensesItems.Text = licenseData; + CheckUpdates(); } private void HideMenu(object sender, MouseButtonEventArgs e) { @@ -39,6 +48,10 @@ namespace ZitiDesktopEdge Application.Current.Shutdown(); } + private void DoUpdate(object sender, MouseButtonEventArgs e) { + System.Diagnostics.Process.Start(_downloadUrl); + } + private void ShowAbout(object sender, MouseButtonEventArgs e) { menuState = "About"; UpdateState(); @@ -64,6 +77,39 @@ namespace ZitiDesktopEdge menuState = "UILogs"; UpdateState(); } + private void SetLogLevel(object sender, MouseButtonEventArgs e) { + menuState = "LogLevel"; + UpdateState(); + } + + private void CheckUpdates() { + HttpWebRequest httpWebRequest = WebRequest.CreateHttp(_updateUrl); + httpWebRequest.Method = "GET"; + httpWebRequest.ContentType = "application/json"; + httpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"; + HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); + StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()); + string result = streamReader.ReadToEnd(); + JObject json = JObject.Parse(result); + string currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); + string serverVersion = json.Property("tag_name").Value.ToString() + ".0"; + + Version installed = new Version(currentVersion); + Version published = new Version(serverVersion); + int compare = installed.CompareTo(published); + if (compare<0) { + UpdateAvailable.Content = "An Upgrade is available, click to download"; + UpdateAvailable.Visibility = Visibility.Visible; + } else if (compare>0) { + UpdateAvailable.Content = "Your version is newer than the released version"; + UpdateAvailable.Visibility = Visibility.Visible; + } + JArray assets = JArray.Parse(json.Property("assets").Value.ToString()); + foreach (JObject asset in assets.Children()) { + _downloadUrl = asset.Property("browser_download_url").Value.ToString(); + break; + } + } private void UpdateState() { MainItems.Visibility = Visibility.Collapsed; @@ -75,16 +121,23 @@ namespace ZitiDesktopEdge LicensesItems.Visibility = Visibility.Collapsed; LogsItems.Visibility = Visibility.Collapsed; ConfigItems.Visibility = Visibility.Collapsed; + LogLevelItems.Visibility = Visibility.Collapsed; - if (menuState=="About") { + if (menuState == "About") { MenuTitle.Content = "About"; AboutItemsArea.Visibility = Visibility.Visible; AboutItems.Visibility = Visibility.Visible; BackArrow.Visibility = Visibility.Visible; - // Service Version - Lose the snapshot - string version = File.ReadAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "OpenZiti", "Service", "Version.txt")); - if (version.IndexOf("-") > 0) version = version.Split('-')[0]; + string version = ""; + try { + ServiceClient.TunnelStatus s = (ServiceClient.TunnelStatus)Application.Current.Properties["CurrentTunnelStatus"]; + version = $"{s.ServiceVersion.Version}@{s.ServiceVersion.Revision}"; + } catch (Exception e) { +#if DEBUG + Debug.WriteLine(e.ToString()); +#endif + } // Interface Version VersionInfo.Content = "App: " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()+" Service: "+ version; @@ -108,6 +161,12 @@ namespace ZitiDesktopEdge LogsItems.Text = UILog.GetLogs(); LogsItems.Visibility = Visibility.Visible; BackArrow.Visibility = Visibility.Visible; + } else if (menuState == "LogLevel") { + ResetLevels(); + + MenuTitle.Content = "Set Log Level"; + LogLevelItems.Visibility = Visibility.Visible; + BackArrow.Visibility = Visibility.Visible; } else if (menuState=="Config") { MenuTitle.Content = "Tunnel Configuration"; ConfigItems.Visibility = Visibility.Visible; @@ -215,5 +274,32 @@ namespace ZitiDesktopEdge OnAttachmentChange(true); } } + + private void ResetLevels() { + if (this.LogLevel == "") this.LogLevel = "error"; + LogVerbose.IsSelected = false; + LogDebug.IsSelected = false; + LogInfo.IsSelected = false; + LogError.IsSelected = false; + LogFatal.IsSelected = false; + LogWarn.IsSelected = false; + LogTrace.IsSelected = false; + if (this.LogLevel == "verbose") LogVerbose.IsSelected = true; + else if (this.LogLevel == "debug") LogDebug.IsSelected = true; + else if (this.LogLevel == "info") LogInfo.IsSelected = true; + else if (this.LogLevel == "error") LogError.IsSelected = true; + else if (this.LogLevel == "fatal") LogFatal.IsSelected = true; + else if (this.LogLevel == "warn") LogWarn.IsSelected = true; + else if (this.LogLevel == "trace") LogTrace.IsSelected = true; + } + + private void SetLevel(object sender, MouseButtonEventArgs e) { + SubOptionItem item = (SubOptionItem)sender; + this.LogLevel = item.Label.ToLower(); + if (OnLogLevelChanged != null) { + OnLogLevelChanged(this.LogLevel); + } + ResetLevels(); + } } } diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs index badd9d52..86d821bb 100644 --- a/DesktopEdge/MainWindow.xaml.cs +++ b/DesktopEdge/MainWindow.xaml.cs @@ -4,21 +4,11 @@ using System.Windows; using System.Windows.Input; using System.IO; using ZitiDesktopEdge.Models; -using System.IO.Compression; - using ZitiDesktopEdge.ServiceClient; using System.ServiceProcess; using System.Linq; -using System.Runtime.Remoting.Messaging; using System.Diagnostics; -using System.Security.Principal; -using System.Net; using System.Windows.Controls; -using System.Threading.Tasks; -using System.Threading; -using System.Text; -using System.Runtime.InteropServices; -using System.Windows.Interop; namespace ZitiDesktopEdge { @@ -75,7 +65,6 @@ namespace ZitiDesktopEdge { LaunchOrInstall(); SetNotifyIcon("white"); - InitializeComponent(); } private void MainWindow_Activated(object sender, EventArgs e) { @@ -140,6 +129,7 @@ namespace ZitiDesktopEdge { Application.Current.Properties.Add("ServiceClient", serviceClient); Application.Current.Properties.Add("Identities", new List()); MainMenu.OnAttachmentChange += AttachmentChanged; + MainMenu.OnLogLevelChanged += LogLevelChanged; IdentityMenu.OnError += IdentityMenu_OnError; try { @@ -154,6 +144,10 @@ namespace ZitiDesktopEdge { IdentityMenu.OnForgot += IdentityForgotten; } + private void LogLevelChanged(string level) { + serviceClient.SetLogLevel(level); + } + private void IdentityMenu_OnError(string message) { ShowError("Identity Error", message); } @@ -253,12 +247,14 @@ namespace ZitiDesktopEdge { private void ServiceClient_OnTunnelStatusEvent(object sender, TunnelStatusEvent e) { if (e == null) return; //just skip it for now... Debug.WriteLine($"==== TunnelStatusEvent: "); + Application.Current.Properties.Add("CurrentTunnelStatus", e.Status); + e.Status.Dump(Console.Out); this.Dispatcher.Invoke(() => { if(e.ApiVersion != Client.EXPECTED_API_VERSION) { SetCantDisplay("Version mismatch!", "The version of the Service is not compatible"); return; } - + this.MainMenu.LogLevel = e.Status.LogLevel; InitializeTimer((int)e.Status.Duration); LoadStatusFromService(e.Status); LoadIdentities(false); @@ -406,6 +402,7 @@ namespace ZitiDesktopEdge { try { Identity createdId = serviceClient.AddIdentity(System.IO.Path.GetFileName(jwtDialog.FileName), false, fileContent); ServiceClient.Client client = (ServiceClient.Client)Application.Current.Properties["ServiceClient"]; + client.IdentityOnOff(createdId.FingerPrint, true); if (createdId != null) { identities.Add(ZitiIdentity.FromClient(createdId)); @@ -546,5 +543,22 @@ namespace ZitiDesktopEdge { private void Label_MouseDoubleClick(object sender, MouseButtonEventArgs e) { Placement(); } + + private void Button_Click(object sender, RoutedEventArgs e) + { + serviceClient.SetLogLevel(NextLevel()); + } + + int cur = 0; + LogLevelEnum[] levels = new LogLevelEnum[] { LogLevelEnum.FATAL, LogLevelEnum.ERROR, LogLevelEnum.WARN, LogLevelEnum.INFO, LogLevelEnum.DEBUG, LogLevelEnum.TRACE, LogLevelEnum.VERBOSE }; + public LogLevelEnum NextLevel() + { + cur++; + if (cur > 6) + { + cur = 0; + } + return levels[cur]; + } } } diff --git a/DesktopEdge/Properties/AssemblyInfo.cs b/DesktopEdge/Properties/AssemblyInfo.cs index 9155285a..73575b2d 100644 --- a/DesktopEdge/Properties/AssemblyInfo.cs +++ b/DesktopEdge/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ 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.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.2.7.0")] +[assembly: AssemblyFileVersion("1.2.7.0")] diff --git a/DesktopEdge/ServiceClient/ClientImpl.cs b/DesktopEdge/ServiceClient/ClientImpl.cs index a656335c..e2cb9c03 100644 --- a/DesktopEdge/ServiceClient/ClientImpl.cs +++ b/DesktopEdge/ServiceClient/ClientImpl.cs @@ -24,8 +24,20 @@ using System.Windows.Documents; /// namespace ZitiDesktopEdge.ServiceClient { + public enum LogLevelEnum + { + FATAL = 0, + ERROR = 1, + WARN = 2, + INFO = 3, + DEBUG = 4, + TRACE = 5, + VERBOSE = 6, + } + internal class Client { + public const int EXPECTED_API_VERSION = 1; public event EventHandler OnTunnelStatusEvent; @@ -378,6 +390,34 @@ namespace ZitiDesktopEdge.ServiceClient } } + public void SetLogLevel(string level) { + try { + send(new SetLogLevelFunction(level)); + SvcResponse resp = read(ipcReader); + return; + } catch (IOException ioe) { + //almost certainly a problem with the pipe - recreate the pipe... + //setupPipe(); + throw ioe; + } + } + + public void SetLogLevel(LogLevelEnum level) + { + try + { + send(new SetLogLevelFunction(Enum.GetName(level.GetType(), level))); + SvcResponse resp = read(ipcReader); + return; + } + catch (IOException ioe) + { + //almost certainly a problem with the pipe - recreate the pipe... + //setupPipe(); + throw ioe; + } + } + public Identity IdentityOnOff(string fingerprint, bool onOff) { try diff --git a/DesktopEdge/ServiceClient/DataStructures.cs b/DesktopEdge/ServiceClient/DataStructures.cs index 2487e0a6..d4e163d6 100644 --- a/DesktopEdge/ServiceClient/DataStructures.cs +++ b/DesktopEdge/ServiceClient/DataStructures.cs @@ -73,6 +73,10 @@ namespace ZitiDesktopEdge.ServiceClient public bool OnOff { get; set; } public string Fingerprint { get; set; } } + public class SetLogLevelPayload + { + public string Level { get; set; } + } public class IdentityToggleFunction : ServiceFunction { @@ -88,6 +92,19 @@ namespace ZitiDesktopEdge.ServiceClient public IdentityTogglePayload Payload { get; set; } } + public class SetLogLevelFunction : ServiceFunction + { + public SetLogLevelFunction(string level) + { + this.Function = "SetLogLevel"; + this.Payload = new SetLogLevelPayload() + { + Level = level + }; + } + public SetLogLevelPayload Payload { get; set; } + } + public class FingerprintPayload { public string Fingerprint { get; set; } @@ -148,6 +165,18 @@ namespace ZitiDesktopEdge.ServiceClient public string DNS { get; set; } } + class ServiceVersion + { + public string Version { get; set; } + public string Revision { get; set; } + public string BuildDate { get; set; } + + public override string ToString() + { + return $"Version: {Version}, Revision: {Revision}, BuildDate: {BuildDate}"; + } + } + class ZitiTunnelStatus : SvcResponse { public TunnelStatus Status { get; set; } @@ -163,21 +192,44 @@ namespace ZitiDesktopEdge.ServiceClient public IpInfo IpInfo { get; set; } + public string LogLevel { get; set; } + + public ServiceVersion ServiceVersion { get; set; } + public void Dump(System.IO.TextWriter writer) { - writer.WriteLine($"Tunnel Active: {Active}"); - foreach (Identity id in Identities) - { - writer.WriteLine($" FingerPrint: {id.FingerPrint}"); - writer.WriteLine($" Name: {id.Name}"); - writer.WriteLine($" Active: {id.Active}"); - writer.WriteLine($" Status: {id.Status}"); - writer.WriteLine($" Services:"); - foreach (Service s in id.Services) - { - writer.WriteLine($" Name: {s.Name} HostName: {s.InterceptHost} Port: {s.InterceptPort}"); + try { + writer.WriteLine($"Tunnel Active: {Active}"); + writer.WriteLine($" LogLevel : {LogLevel}"); + writer.WriteLine($" EvaluatedLogLevel: {EvaluateLogLevel()}"); + foreach (Identity id in Identities) { + writer.WriteLine($" FingerPrint: {id.FingerPrint}"); + writer.WriteLine($" Name : {id.Name}"); + writer.WriteLine($" Active : {id.Active}"); + writer.WriteLine($" Status : {id.Status}"); + writer.WriteLine($" Services:"); + foreach (Service s in id.Services) { + writer.WriteLine($" Name: {s.Name} HostName: {s.InterceptHost} Port: {s.InterceptPort}"); + } + writer.WriteLine("============================================="); } - writer.WriteLine("============================================="); + } catch (Exception e) { + if (writer!=null) writer.WriteLine(e.ToString()); + } + + } + + public LogLevelEnum EvaluateLogLevel() + { + try + { + LogLevelEnum l = (LogLevelEnum) Enum.Parse(typeof(LogLevelEnum), LogLevel.ToUpper()); + return l; + } + catch + { + System.Diagnostics.Debug.WriteLine("Could not parse response LogLevel from sevice - guessing INFO? " + LogLevel); + return LogLevelEnum.INFO; } } } diff --git a/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml b/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml new file mode 100644 index 00000000..07088256 --- /dev/null +++ b/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml.cs b/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml.cs new file mode 100644 index 00000000..8a4467e8 --- /dev/null +++ b/DesktopEdge/Views/ItemRenderers/SubOptionItem.xaml.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace ZitiDesktopEdge { + /// + /// Interaction logic for MenuItem.xaml + /// + public partial class SubOptionItem : UserControl { + + private string _label = ""; + private bool _isSelected = false; + + public string Label { + get { + return _label; + } + set { + this._label = value; + MainLabel.Content = this._label; + } + } + + public bool IsSelected { + get { + return _isSelected; + } + set { + this._isSelected = value; + if (this._isSelected) SelectedCheck.Visibility = Visibility.Visible; + else SelectedCheck.Visibility = Visibility.Collapsed; + } + } + + public SubOptionItem() { + InitializeComponent(); + } + } +} diff --git a/DesktopEdge/ZitiDesktopEdge.csproj b/DesktopEdge/ZitiDesktopEdge.csproj index d745cd13..76aca7dd 100644 --- a/DesktopEdge/ZitiDesktopEdge.csproj +++ b/DesktopEdge/ZitiDesktopEdge.csproj @@ -34,7 +34,7 @@ Ziti true 0 - 1.2.1.%2a + 1.2.7.%2a false true true @@ -147,6 +147,9 @@ RegistrationScreen.xaml + + SubOptionItem.xaml + SubMenuItem.xaml @@ -201,6 +204,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + MSBuild:Compile Designer @@ -353,5 +360,8 @@ + + + \ No newline at end of file diff --git a/ZitiDesktopEdge.aip b/ZitiDesktopEdge.aip new file mode 100644 index 00000000..95885b86 --- /dev/null +++ b/ZitiDesktopEdge.aip @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ZitiWintunInstaller.sln b/ZitiWintunInstaller.sln index 1b2d63b6..56f0a223 100644 --- a/ZitiWintunInstaller.sln +++ b/ZitiWintunInstaller.sln @@ -11,8 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "ZitiWintunInstaller", "ZitiWintunInstaller\ZitiWintunInstaller.wixproj", "{1A5D850F-2E38-4524-8745-29A96FA62683}" EndProject -Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "OpenZitiWintunInstaller", "OpenZitiWintunInstaller\OpenZitiWintunInstaller.wapproj", "{84DBA1A4-D8E9-4282-94FF-121809B48F1F}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -28,47 +26,19 @@ Global EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1A5D850F-2E38-4524-8745-29A96FA62683}.Debug|Any CPU.ActiveCfg = Debug|x86 + {1A5D850F-2E38-4524-8745-29A96FA62683}.Debug|Any CPU.Build.0 = Debug|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Debug|ARM.ActiveCfg = Debug|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Debug|ARM64.ActiveCfg = Debug|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Debug|x64.ActiveCfg = Debug|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Debug|x86.ActiveCfg = Debug|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Debug|x86.Build.0 = Debug|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Release|Any CPU.ActiveCfg = Release|x86 + {1A5D850F-2E38-4524-8745-29A96FA62683}.Release|Any CPU.Build.0 = Release|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Release|ARM.ActiveCfg = Release|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Release|ARM64.ActiveCfg = Release|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Release|x64.ActiveCfg = Release|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Release|x86.ActiveCfg = Release|x86 {1A5D850F-2E38-4524-8745-29A96FA62683}.Release|x86.Build.0 = Release|x86 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|ARM.ActiveCfg = Debug|ARM - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|ARM.Build.0 = Debug|ARM - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|ARM.Deploy.0 = Debug|ARM - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|ARM64.Build.0 = Debug|ARM64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|x64.ActiveCfg = Debug|x64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|x64.Build.0 = Debug|x64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|x64.Deploy.0 = Debug|x64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|x86.ActiveCfg = Debug|x86 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|x86.Build.0 = Debug|x86 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Debug|x86.Deploy.0 = Debug|x86 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|Any CPU.Build.0 = Release|Any CPU - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|Any CPU.Deploy.0 = Release|Any CPU - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|ARM.ActiveCfg = Release|ARM - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|ARM.Build.0 = Release|ARM - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|ARM.Deploy.0 = Release|ARM - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|ARM64.ActiveCfg = Release|ARM64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|ARM64.Build.0 = Release|ARM64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|ARM64.Deploy.0 = Release|ARM64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|x64.ActiveCfg = Release|x64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|x64.Build.0 = Release|x64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|x64.Deploy.0 = Release|x64 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|x86.ActiveCfg = Release|x86 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|x86.Build.0 = Release|x86 - {84DBA1A4-D8E9-4282-94FF-121809B48F1F}.Release|x86.Deploy.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/release-notes-service.md b/release-notes-service.md index 1ed783a7..1dad7035 100644 --- a/release-notes-service.md +++ b/release-notes-service.md @@ -1,12 +1,24 @@ These release notes will catalog the changes in the Windows service. For UI changes or installer changes see [release-notes.md]() +# Release 0.0.30 + +* What's New + + * Continually improved logging + * changed ip from 169.254.0.0/16 to 100.64.0.0/10 + * [#120](https://github.com/openziti/desktop-edge-win/issues/120) - Allow UI/client to get and set log level dynamically via ipc + +* Bug fixes + + * [#116](https://github.com/openziti/desktop-edge-win/issues/116) - Removes information from the config that wasn't needed in config.json + # Release 0.0.29 * What's New - * Continually improved logging - * Add support for 'verbose' logging along with error, warn, info, debug, trace + * Continually improved logging + * Add support for 'verbose' logging along with error, warn, info, debug, trace * Bug fixes @@ -17,8 +29,8 @@ For UI changes or installer changes see [release-notes.md]() * What's New - * Continually improved logging - * Better DNS removal when services are no longer available or when an identity is removed + * Continually improved logging + * Better DNS removal when services are no longer available or when an identity is removed * Bug fixes diff --git a/release-notes.md b/release-notes.md index 12652b80..12b27a73 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,6 +1,18 @@ These release notes will try to cover the changes made for the installer. For changes made to the Windows service see [release-notes-service.md]() +# Release 1.2.6 + +* What's New + + * 'About' updated to reflect actual service version + * Added ability to set the log level of the service dynamically through Advanced Setttings + * + +* Bug fixes + + * [#102](https://github.com/openziti/desktop-edge-win/pull/102) - DNS requests with "connection-specific local domain" would not resolve + # Release 1.0.4 * What's New diff --git a/service/build.bat b/service/build.bat index e9d8cb2f..707a992b 100644 --- a/service/build.bat +++ b/service/build.bat @@ -34,7 +34,7 @@ echo changing to service folder: %SVC_ROOT_DIR% cd %SVC_ROOT_DIR% SET REPO_URL=https://github.com/openziti/ziti-tunneler-sdk-c.git -SET ZITI_TUNNEL_REPO_BRANCH=v0.6.8 +SET ZITI_TUNNEL_REPO_BRANCH=v0.6.9 SET TUNNELER_SDK_DIR=%SVC_ROOT_DIR%deps\ziti-tunneler-sdk-c\ SET CGO_CFLAGS=-DNOGDI -I %TUNNELER_SDK_DIR%install\include SET CGO_LDFLAGS=-L %TUNNELER_SDK_DIR%install\lib diff --git a/service/cziti/dns-proxy.go b/service/cziti/dns-proxy.go index 03a3f557..c081e2e7 100644 --- a/service/cziti/dns-proxy.go +++ b/service/cziti/dns-proxy.go @@ -28,12 +28,12 @@ import ( ) var domains []string // get any connection-specific local domains +const MaxDnsRequests = 64 +var reqch = make(chan dnsreq, MaxDnsRequests) +var proxiedRequests = make(chan *proxiedReq, MaxDnsRequests) +var respChan = make(chan []byte, MaxDnsRequests) -var reqch = make(chan dnsreq, 64) -var proxiedRequests = make(chan *proxiedReq, 64) -var respChan = make(chan []byte, 64) - -func processDNSquery(packet []byte, p *net.UDPAddr, s *net.UDPConn) { +func processDNSquery(packet []byte, p *net.UDPAddr, s *net.UDPConn, ipVer int) { q := &dns.Msg{} if err := q.Unpack(packet); err != nil { log.Errorf("ERROR", err) @@ -101,14 +101,15 @@ func processDNSquery(packet []byte, p *net.UDPAddr, s *net.UDPConn) { } } else { // log.Debug("proxying ", dns.Type(query.Qtype), query.Name, q.Id, " for ", p) - proxyDNS(q, p, s) + proxyDNS(q, p, s, ipVer) } } type dnsreq struct { - q []byte - s *net.UDPConn - p *net.UDPAddr + q []byte + s *net.UDPConn + p *net.UDPAddr + ifId int } func RunDNSserver(dnsBind []net.IP, ready chan bool) { @@ -124,7 +125,7 @@ func RunDNSserver(dnsBind []net.IP, ready chan bool) { ready <- true for req := range reqch { - processDNSquery(req.q, req.p, req.s) + processDNSquery(req.q, req.p, req.s, req.ifId) } } @@ -136,8 +137,10 @@ func runListener(ip net.IP, port int, reqch chan dnsreq) { Zone: "", } + id := 6 network := "udp6" if len(ip.To4()) == net.IPv4len { + id = 4 network = "udp4" } @@ -152,36 +155,39 @@ func runListener(ip net.IP, port int, reqch chan dnsreq) { if err != nil { if err == io.EOF || err == os.ErrClosed || strings.HasSuffix(err.Error(), "use of closed network connection") { log.Warnf("DNS listener closing.") - server.Close() + _ = server.Close() break } else { - server.Close() + _ = server.Close() panic(err) } } reqch <- dnsreq{ - q: b[:nb], - s: server, - p: peer, + q: b[:nb], + s: server, + p: peer, + ifId: id, } } } /*******************************************************************/ type proxiedReq struct { - req *dns.Msg - peer *net.UDPAddr - s *net.UDPConn - exp time.Time + req *dns.Msg + peer *net.UDPAddr + s *net.UDPConn + exp time.Time + ipVer int } -func proxyDNS(req *dns.Msg, peer *net.UDPAddr, serv *net.UDPConn) { +func proxyDNS(req *dns.Msg, peer *net.UDPAddr, serv *net.UDPConn, ipVer int) { proxiedRequests <- &proxiedReq{ - req: req, - peer: peer, - s: serv, - exp: time.Now().Add(30 * time.Second), + req: req, + peer: peer, + s: serv, + exp: time.Now().Add(30 * time.Second), + ipVer: ipVer, } } @@ -224,14 +230,14 @@ func runDNSproxy(dnsServers []string) { } for _, proxy := range dnsUpstreams { - go func() { + go func(p *net.UDPConn) { resp := make([]byte, 1024) //make a buffer which is reused for { - n, err := proxy.Read(resp) + n, err := p.Read(resp) if err != nil { // something is wrong with the DNS connection panic and let DNS recovery kick in if err == io.EOF || err == os.ErrClosed || strings.HasSuffix(err.Error(), "use of closed network connection") { - log.Errorf("error receiving from ip: %v. error %v", proxy.RemoteAddr(), err) + log.Errorf("error receiving from ip: %v. error %v", p.RemoteAddr(), err) return } else { log.Warnf("odd error: %v", err) @@ -240,7 +246,7 @@ func runDNSproxy(dnsServers []string) { respChan <- resp[:n] } } - }() + }(proxy) } reqs := make(map[uint32]*proxiedReq) @@ -255,7 +261,7 @@ func runDNSproxy(dnsServers []string) { if _, err := proxy.Write(b); err != nil { //TODO: if this happens -does this mean the next dns server is not available? - proxy.Close() //first thing - close the proxy connection + _ = proxy.Close() //first thing - close the proxy connection // when this hits - it never seems to recover. throw a panic which will get recovered // via the defer specified above and try to recreate the connections. this is a heavy @@ -266,7 +272,7 @@ func runDNSproxy(dnsServers []string) { proxy.RemoteAddr(), err) } else { - log.Tracef("Proxied request sent to %v from %v", proxy.RemoteAddr(), proxy.LocalAddr()) + log.Tracef("Proxied request sent to %v from ipv%d listener", proxy.RemoteAddr(), pr.ipVer) } } @@ -277,11 +283,15 @@ func runDNSproxy(dnsServers []string) { req, found := reqs[id] if found { delete(reqs, id) - log.Tracef("proxy resolved %v from %v", reply.Question[0].Name, req.s.RemoteAddr()) - req.s.WriteMsgUDP(rep, nil, req.peer) + log.Tracef("proxy resolved request for %v id:%d", reply.Question[0].Name, reply.Id) + n, oobn, err := req.s.WriteMsgUDP(rep, nil, req.peer) + if err != nil { + log.Errorf("an error has occurred while trying to write a udp message. n:%d, oobn:%d, err:%v", n, oobn, err) + } } else { - log.Tracef("matching request was not found for %s %s", - dns.Type(reply.Question[0].Qtype), reply.Question[0].Name) + // keep this log but leave commented out. When two listeners are enabled (ipv4/v6) this msg will + // just mean some other request was processed successfully and removed the entry from the map + //log.Tracef("matching request was not found for id:%d. %s %s", reply.Id, dns.Type(reply.Question[0].Qtype), reply.Question[0].Name) } } case <-time.After(time.Minute): diff --git a/service/cziti/dns.go b/service/cziti/dns.go index 1eb2834e..43c4a030 100644 --- a/service/cziti/dns.go +++ b/service/cziti/dns.go @@ -21,6 +21,8 @@ import "C" import ( "encoding/binary" "fmt" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/constants" + "net" "strings" "sync" @@ -35,9 +37,6 @@ type DnsManager interface { GetService(ip net.IP, port uint16) (*CZitiCtx, string, error) } -const defaultCidr = "169.254.0.0" -const defaultMaskBits = 16 - var initOnce = sync.Once{} var DNS = &dnsImpl{} @@ -80,7 +79,7 @@ func normalizeDnsName(dnsName string) string { // assigned to a hostname an error will also be returned indicating why. func (dns *dnsImpl) RegisterService(svcId string, dnsNameToReg string, port uint16, ctx *CZitiCtx, svcName string) (net.IP, error) { log.Infof("adding DNS entry for service name %s@%s:%d", svcName, dnsNameToReg, port) - DnsInit(defaultCidr, defaultMaskBits) + DnsInit(constants.Ipv4ip, constants.Ipv4DefaultMask) dnsName := normalizeDnsName(dnsNameToReg) key := fmt.Sprint(dnsName, ':', port) diff --git a/service/cziti/sdk.go b/service/cziti/sdk.go index ec27966a..28b33bf5 100644 --- a/service/cziti/sdk.go +++ b/service/cziti/sdk.go @@ -178,9 +178,20 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, t ZitiContext: ctx, } } else { - log.Warnf("could not find a service with id: %s, name: %s", service.id, service.name) + log.Warnf("could not remove service? service not found with id: %s, name: %s in context %d", service.id, service.name, &ctx) } } else if status == C.ZITI_OK { + //first thing's first - determine if the service is already in this runtime + //if it is that means this is 'probably' a config change. to make it easy + //just dereg/disconnect the service and then let the rest of this code execute + found, ok := ctx.Services.Load(svcId) + if ok && found != nil { + log.Infof("service with id: %s, name: %s exists. updating service.", service.id, service.name) + DNS.DeregisterService(ctx, name) + ctx.Services.Delete(svcId) + } else { + log.Debugf("service not found with id: %s, name: %s in context %d", svcId, name, &ctx) + } if C.ZITI_CAN_BIND == ( service.perm_flags & C.ZITI_CAN_BIND ) { var v1Config C.ziti_server_cfg_v1 diff --git a/service/ziti-tunnel/constants/consts.go b/service/ziti-tunnel/constants/consts.go new file mode 100644 index 00000000..809cb599 --- /dev/null +++ b/service/ziti-tunnel/constants/consts.go @@ -0,0 +1,7 @@ +package constants + +const( + Ipv4ip = "100.64.0.0" + Ipv4MaxMask = 10 + Ipv4DefaultMask = 24 +) \ No newline at end of file diff --git a/service/ziti-tunnel/dto/dtos.go b/service/ziti-tunnel/dto/dtos.go index 13a724e7..d543a434 100644 --- a/service/ziti-tunnel/dto/dtos.go +++ b/service/ziti-tunnel/dto/dtos.go @@ -83,13 +83,20 @@ func (id *Identity) Path() string { } type TunnelStatus struct { - Active bool - Duration int64 - Identities []*Identity - IpInfo *TunIpInfo `json:"IpInfo,omitempty"` - LogLevel string - TunIpv4 string - TunIpv4Mask int + Active bool + Duration int64 + Identities []*Identity + IpInfo *TunIpInfo `json:"IpInfo,omitempty"` + LogLevel string + ServiceVersion ServiceVersion + TunIpv4 string + TunIpv4Mask int +} + +type ServiceVersion struct { + Version string + Revision string + BuildDate string } type ZitiTunnelStatus struct { diff --git a/service/ziti-tunnel/main.go b/service/ziti-tunnel/main.go index d1a4c2ec..ac96141f 100644 --- a/service/ziti-tunnel/main.go +++ b/service/ziti-tunnel/main.go @@ -20,21 +20,26 @@ package main import ( "fmt" + "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/debug" "golang.org/x/sys/windows/svc/eventlog" "os" "strings" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/globals" - "golang.org/x/sys/windows/svc" "github.com/openziti/desktop-edge-win/service/ziti-tunnel/service" + "golang.org/x/sys/windows/svc" ) -var log = globals.Logger() +var log = logging.Logger() func main() { - l, _ := globals.ParseLevel("info") - globals.InitLogger(l) + service.Version = dto.ServiceVersion{ + Version: Version, + Revision: Revision, + BuildDate: BuildDate, + } + logging.InitLogger("info") //if len(os.Args) < 2 { // // if no args supplied - expect to run as service @@ -52,9 +57,9 @@ func main() { var err error if hasArgs { - globals.Elog = debug.New(service.SvcName) + logging.Elog = debug.New(service.SvcName) } else { - globals.Elog, err = eventlog.Open(service.SvcName) + logging.Elog, err = eventlog.Open(service.SvcName) if err != nil { return } @@ -69,9 +74,9 @@ func main() { usage("no command specified") } - defer globals.Elog.Close() + defer logging.Elog.Close() - elog := globals.Elog + elog := logging.Elog cmd := strings.ToLower(os.Args[1]) switch cmd { diff --git a/service/ziti-tunnel/service/ipc.go b/service/ziti-tunnel/service/ipc.go index 3a1b3f4a..037c01bb 100644 --- a/service/ziti-tunnel/service/ipc.go +++ b/service/ziti-tunnel/service/ipc.go @@ -23,14 +23,16 @@ import ( "encoding/json" "fmt" "github.com/Microsoft/go-winio" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/constants" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/util/idutil" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/util/logging" "github.com/openziti/foundation/identity/identity" idcfg "github.com/openziti/sdk-golang/ziti/config" "github.com/openziti/sdk-golang/ziti/enroll" "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/dto" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/globals" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/idutil" + "github.com/sirupsen/logrus" "golang.org/x/sys/windows/svc" "golang.zx2c4.com/wireguard/tun" "io" @@ -63,10 +65,11 @@ func SubMain(ops chan string, changes chan<- svc.Status) error { rts.LoadConfig() l := rts.state.LogLevel - logLevel, czitiLevel := globals.ParseLevel(l) - globals.InitLogger(logLevel) + _, czitiLevel := logging.ParseLevel(l) - _ = globals.Elog.Info(InformationEvent, SvcName+" starting. log file located at "+config.LogFile()) + logging.InitLogger(l ) + + _ = logging.Elog.Info(InformationEvent, SvcName+" starting. log file located at "+config.LogFile()) // create a channel for notifying any connections that they are to be interrupted interrupt = make(chan struct{}, 8) @@ -99,7 +102,7 @@ func SubMain(ops chan string, changes chan<- svc.Status) error { // notify the service is running changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} - _ = globals.Elog.Info(InformationEvent, SvcName+" status set to running") + _ = logging.Elog.Info(InformationEvent, SvcName+" status set to running") log.Info(SvcName + " status set to running. starting cancel loop") waitForStopRequest(ops) @@ -244,12 +247,12 @@ func initialize(ipv4 string, ipv4mask int) error { func setTunInfo(s *dto.TunnelStatus, ipv4 string, ipv4mask int) { if strings.TrimSpace(ipv4) == "" { log.Infof("ip not provided using default: %v", ipv4) - ipv4 = Ipv4ip + ipv4 = constants.Ipv4ip rts.UpdateIpv4(ipv4) } - if ipv4mask < 8 || ipv4mask > 24 { - log.Warnf("provided mask is invalid: %d. using default value: %d", ipv4mask, Ipv4mask) - ipv4mask = Ipv4mask + if ipv4mask < 8 || ipv4mask > constants.Ipv4MaxMask { + log.Warnf("provided mask is invalid: %d. using default value: %d", ipv4mask, constants.Ipv4DefaultMask) + ipv4mask = constants.Ipv4DefaultMask rts.UpdateIpv4Mask(ipv4mask) } _, ipnet, err := net.ParseCIDR(fmt.Sprintf("%s/%d", ipv4, ipv4mask)) @@ -294,7 +297,7 @@ func accept(p net.Listener, serveFunction func(net.Conn), debug string) { c, err := p.Accept() if err != nil { if err != winio.ErrPipeListenerClosed { - log.Errorf("unexpected error while accepting a connection. exiting loop. %v", err) + log.Errorf("%v unexpected error while accepting a connection. exiting loop. %v", debug, err) } return } @@ -331,7 +334,7 @@ func serveIpc(conn net.Conn) { select { case <-interrupt: log.Info("request to interrupt read loop received") - conn.Close() + _ = conn.Close() log.Info("read loop interrupted") case <-done: log.Debug("loop finished normally") @@ -406,6 +409,8 @@ func serveIpc(conn net.Conn) { onOff := cmd.Payload["OnOff"].(bool) fingerprint := cmd.Payload["Fingerprint"].(string) toggleIdentity(enc, fingerprint, onOff) + case "SetLogLevel": + setLogLevel(enc, cmd.Payload["Level"].(string)) case "Debug": dbg() respond(enc, dto.Response{ @@ -426,6 +431,15 @@ func serveIpc(conn net.Conn) { } } +func setLogLevel(out *json.Encoder, level string) { + goLevel, cLevel := logging.ParseLevel(level) + logrus.Infof("Setting logger levels to %s", goLevel) + logrus.SetLevel(goLevel) + cziti.SetLogLevel(cLevel) + rts.state.LogLevel = goLevel.String() + respond(out, dto.Response{Message: "log level set", Code: SUCCESS, Error: "", Payload: nil}) +} + func serveLogs(conn net.Conn) { log.Debug("accepted a logs connection, writing logs to pipe") w := bufio.NewWriter(conn) @@ -590,7 +604,7 @@ func toggleIdentity(out *json.Encoder, fingerprint string, onOff bool) { if onOff { connectIdentity(id) } else { - disconnectIdentity(id) + _ = disconnectIdentity(id) } respond(out, dto.Response{Message: "identity toggled", Code: SUCCESS, Error: "", Payload: idutil.Clean(*id)}) @@ -836,7 +850,7 @@ func acceptServices() { switch c.Operation { case cziti.ADDED: //add the service to the identity - svc := dto.Service{ + s := dto.Service{ Name: c.Service.Name, InterceptHost: c.Service.InterceptHost, InterceptPort: c.Service.InterceptPort, @@ -844,22 +858,22 @@ func acceptServices() { AssignedIP: c.Service.AssignedIP, OwnsIntercept: c.Service.OwnsIntercept, } - id.Services = append(id.Services, &svc) + id.Services = append(id.Services, &s) events.broadcast <- dto.ServiceEvent{ ActionEvent: SERVICE_ADDED, Fingerprint: id.FingerPrint, - Service: svc, + Service: s, } log.Debug("dispatched added service change event") case cziti.REMOVED: - for idx, svc := range id.Services { - if svc.Name == c.Service.Name { + for idx, s := range id.Services { + if s.Name == c.Service.Name { id.Services = append(id.Services[:idx], id.Services[idx+1:]...) events.broadcast <- dto.ServiceEvent{ ActionEvent: SERVICE_REMOVED, Fingerprint: id.FingerPrint, - Service: *svc, + Service: *s, } log.Debug(" dispatched remove service change event") } diff --git a/service/ziti-tunnel/service/pkg-vars.go b/service/ziti-tunnel/service/pkg-vars.go index 564bada3..de1934da 100644 --- a/service/ziti-tunnel/service/pkg-vars.go +++ b/service/ziti-tunnel/service/pkg-vars.go @@ -18,13 +18,13 @@ package service import ( + "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" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/globals" ) - +var Version dto.ServiceVersion var pipeBase = `\\.\pipe\NetFoundry\tunneler\` var activeIds = make(map[string]*dto.Identity) @@ -39,7 +39,7 @@ var eventsConnections int var Debug bool var TunStarted time.Time -var log = globals.Logger() +var log = logging.Logger() var events = newTopic() @@ -87,8 +87,6 @@ const ( NF_GROUP_NAME = "NetFoundry Tunneler Users" TunName = "ZitiTUN" - Ipv4ip = "169.254.1.1" - Ipv4mask = 24 Ipv4dns = "127.0.0.1" // use lo -- don't pass DNS queries through tunneler SDK // IPv6 CIDR fe80:6e66:7a69:7469::/64 diff --git a/service/ziti-tunnel/service/service.go b/service/ziti-tunnel/service/service.go index 5583f3a6..a9b52130 100644 --- a/service/ziti-tunnel/service/service.go +++ b/service/ziti-tunnel/service/service.go @@ -21,12 +21,11 @@ package service import ( "fmt" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/util/logging" "golang.org/x/sys/windows/svc" "golang.org/x/sys/windows/svc/debug" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/globals" ) - type zitiService struct{} func (m *zitiService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) { @@ -52,26 +51,26 @@ loop: switch c.Cmd { case svc.Interrogate: changes <- c.CurrentStatus - _ = globals.Elog.Info(InterrogateEvent, "interrogate request received") + _ = logging.Elog.Info(InterrogateEvent, "interrogate request received") changes <- c.CurrentStatus case svc.Stop: - _ = globals.Elog.Info(StopEvent, "issuing stop") + _ = logging.Elog.Info(StopEvent, "issuing stop") control <- "stop" - _ = globals.Elog.Info(StopEvent, "stop issued") + _ = logging.Elog.Info(StopEvent, "stop issued") break loop case svc.Shutdown: - _ = globals.Elog.Info(ShutdownEvent, "issuing shutdown") + _ = logging.Elog.Info(ShutdownEvent, "issuing shutdown") control <- "stop" - _ = globals.Elog.Info(ShutdownEvent, "shutdown issued") + _ = logging.Elog.Info(ShutdownEvent, "shutdown issued") break loop case svc.Pause: changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted} - _ = globals.Elog.Info(PauseEvent, "request to pause service received. todo - unimplemented") + _ = logging.Elog.Info(PauseEvent, "request to pause service received. todo - unimplemented") case svc.Continue: changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} - _ = globals.Elog.Info(ContinueEvent, "request to continue service received. todo - unimplemented") + _ = logging.Elog.Info(ContinueEvent, "request to continue service received. todo - unimplemented") default: - _ = globals.Elog.Error(1, fmt.Sprintf("unexpected control request #%d", c)) + _ = logging.Elog.Error(1, fmt.Sprintf("unexpected control request #%d", c)) } } } @@ -86,7 +85,7 @@ loop: } func RunService(isDebug bool) { - _ = globals.Elog.Info(InformationEvent, fmt.Sprintf("starting %s service", SvcStartName)) + _ = logging.Elog.Info(InformationEvent, fmt.Sprintf("starting %s service", SvcStartName)) run := svc.Run if isDebug { log.Info("debug specified. using debug.run") @@ -95,8 +94,8 @@ func RunService(isDebug bool) { err := run(SvcStartName, &zitiService{}) if err != nil { - _ = globals.Elog.Error(ErrorEvent, fmt.Sprintf("%s service failed: %v", SvcStartName, err)) + _ = logging.Elog.Error(ErrorEvent, fmt.Sprintf("%s service failed: %v", SvcStartName, err)) return } - _ = globals.Elog.Info(StopEvent, fmt.Sprintf("%s service stopped", SvcStartName)) + _ = logging.Elog.Info(StopEvent, fmt.Sprintf("%s service stopped", SvcStartName)) } diff --git a/service/ziti-tunnel/service/state.go b/service/ziti-tunnel/service/state.go index 3d0e27aa..d7a3aa90 100644 --- a/service/ziti-tunnel/service/state.go +++ b/service/ziti-tunnel/service/state.go @@ -23,8 +23,9 @@ import ( "fmt" "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" "github.com/openziti/desktop-edge-win/service/ziti-tunnel/dto" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/idutil" + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/util/idutil" "golang.org/x/sys/windows/registry" "golang.zx2c4.com/wireguard/tun" "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" @@ -77,7 +78,7 @@ func (t *RuntimeState) SaveState() { w := bufio.NewWriter(bufio.NewWriter(cfg)) enc := json.NewEncoder(w) enc.SetIndent("", " ") - _ = enc.Encode(t.state) + _ = enc.Encode(t.ToStatus()) _ = w.Flush() err = cfg.Close() @@ -100,10 +101,14 @@ func (t *RuntimeState) ToStatus() dto.TunnelStatus { } clean := dto.TunnelStatus{ - Active: t.state.Active, - Duration: uptime, - Identities: make([]*dto.Identity, idCount), - IpInfo: t.state.IpInfo, + Active: t.state.Active, + Duration: uptime, + Identities: make([]*dto.Identity, idCount), + IpInfo: t.state.IpInfo, + LogLevel: t.state.LogLevel, + ServiceVersion: Version, + TunIpv4: t.state.TunIpv4, + TunIpv4Mask: t.state.TunIpv4Mask, } for i, id := range t.state.Identities { @@ -143,11 +148,11 @@ func (t *RuntimeState) CreateTun(ipv4 string, ipv4mask int) error { if strings.TrimSpace(ipv4) == "" { log.Infof("ip not provided using default: %v", ipv4) - ipv4 = Ipv4ip + ipv4 = constants.Ipv4ip } - if ipv4mask < 8 || ipv4mask > 24 { - log.Warnf("provided mask is invalid: %d. using default value: %d", ipv4mask, Ipv4mask) - ipv4mask = Ipv4mask + if ipv4mask < 8 || ipv4mask > constants.Ipv4MaxMask { + log.Warnf("provided mask is invalid: %d. using default value: %d", ipv4mask, constants.Ipv4DefaultMask) + ipv4mask = constants.Ipv4DefaultMask rts.UpdateIpv4Mask(ipv4mask) } ip, ipnet, err := net.ParseCIDR(fmt.Sprintf("%s/%d", ipv4, ipv4mask)) diff --git a/service/ziti-tunnel/ipchanges/detect-ip-changes.go b/service/ziti-tunnel/util/detect-ip-changes.go similarity index 99% rename from service/ziti-tunnel/ipchanges/detect-ip-changes.go rename to service/ziti-tunnel/util/detect-ip-changes.go index 4c7511cb..51623cb2 100644 --- a/service/ziti-tunnel/ipchanges/detect-ip-changes.go +++ b/service/ziti-tunnel/util/detect-ip-changes.go @@ -1,4 +1,4 @@ -package ipchanges +package util import ( "github.com/michaelquigley/pfxlog" diff --git a/service/ziti-tunnel/idutil/identity.go b/service/ziti-tunnel/util/idutil/identity.go similarity index 100% rename from service/ziti-tunnel/idutil/identity.go rename to service/ziti-tunnel/util/idutil/identity.go diff --git a/service/ziti-tunnel/globals/loghelper.go b/service/ziti-tunnel/util/logging/loghelper.go similarity index 87% rename from service/ziti-tunnel/globals/loghelper.go rename to service/ziti-tunnel/util/logging/loghelper.go index de47197b..28cf343f 100644 --- a/service/ziti-tunnel/globals/loghelper.go +++ b/service/ziti-tunnel/util/logging/loghelper.go @@ -15,14 +15,14 @@ * */ -package globals +package logging import ( rotatelogs "github.com/lestrrat-go/file-rotatelogs" "github.com/michaelquigley/pfxlog" + "github.com/openziti/desktop-edge-win/service/cziti" "github.com/sirupsen/logrus" "golang.org/x/sys/windows/svc/debug" - "golang.org/x/sys/windows/svc/eventlog" "io" "os" "strings" @@ -43,8 +43,9 @@ func Logger() *logrus.Entry { var loggerInitialized = false -func InitLogger(logLevel logrus.Level) { - logrus.SetLevel(logLevel) +func InitLogger(level string) { + l, _ := ParseLevel(level) + logrus.SetLevel(l) rl, _ := rotatelogs.New(config.LogFile() + ".%Y%m%d%H%M.log", rotatelogs.WithRotationTime(24 * time.Hour), @@ -65,6 +66,12 @@ func InitLogger(logLevel logrus.Level) { } } +func SetLogLevel(goLevel logrus.Level, cLevel int) { + logrus.Infof("Setting logger levels to %s", goLevel) + logrus.SetLevel(goLevel) + cziti.SetLogLevel(cLevel) +} + func ParseLevel(lvl string) (logrus.Level, int) { switch strings.ToLower(lvl) { case "panic": @@ -87,16 +94,4 @@ func ParseLevel(lvl string) (logrus.Level, int) { logrus.Warnf("level not recognized: [%s]. Using Info", lvl) return logrus.InfoLevel, 3 } -} - -func InitEventLog(svcName string, interactive bool) { - var err error - if !interactive { - Elog = debug.New(svcName) - } else { - Elog, err = eventlog.Open(svcName) - if err != nil { - return - } - } -} +} \ No newline at end of file diff --git a/version b/version index 369bd4c2..f092e2be 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.0.29 +0.0.30 diff --git a/ziti.ico b/ziti.ico new file mode 100644 index 00000000..141e513d Binary files /dev/null and b/ziti.ico differ