0

I'm trying to make a simple console app client (starter.exe) on c# .NET Framework 4.6 to make a WireGuard protocol based connection using Wireguard source code.

What is done:

  • Downloaded wireguard source code from here: git://git.zx2c4.com/wireguard-windows
  • Successfuly built Tunnel.dll in ..\embeddable-dll-service\amd64\tunnel.dll via build.bat
  • Created a project in Visual Studio 2015.using the c# code from ..\embeddable-dll-service\csharp

Starting from here some strange thing are happenning:

  • if launching starter.exe \service <path to *.conf> I receive the error

Service run error: The service process could not connect to the service controller.

  • if launching starter.exe without parameters everything works fine until I remove the if{} block:

Unhandled Exception: System.ComponentModel.Win32Exception: The service did not respond to the start or control request in a timely fashion
at WireGuardTunnel.Service.Add(String configFile) in D:\Depository\BitBucket\WireGuard_Tunnel_Repository\WireGuardTunnel_proj\Launcher\Service.cs:line 69 at WireGuardTunnel.Program.Main(String[] args) in D:\Depository\BitBucket\WireGuard_Tunnel_Repository\WireGuardTunnel_proj\Launcher\Program.cs:line 83

That means even if the code in if{} block is not executed it influencese somehow the application behaviour.

  • Next, as I want to make my app work with parameters I solved the issue by removing return afer Service.Run and passing args[1] to Service.Add(args[1]). It works OK, but I have an extra log line (the first one due to Service.Run perpetual error described above) in the log:

Service run error: The service process could not connect to the service controller.
235660: [TUN] [chicago4] Watching network interfaces
245661: [TUN] [chicago4] Resolving DNS names
245661: [TUN] [chicago4] Creating Wintun interface
225660: [TUN] [chicago4] Starting WireGuard/0.3.1 (Windows 6.1.7601; amd64)

So finally the questions:

  1. Why Service.Run(confFile) does not work
  2. Why Service.Run(confFile) influences the Service.Add(confFile)
  3. Why if{} block is executed when I launch starte.exe with no parameters

The original Program.cs without modification:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.InteropServices;

namespace Tunnel
{
    class Program
    {

        [DllImport("kernel32.dll")]
        private static extern bool SetConsoleCtrlHandler(SetConsoleCtrlEventHandler handler, bool add);
        private delegate bool SetConsoleCtrlEventHandler(UInt32 signal);

        public static void Main(string[] args)
        {
            string baseDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
            string configFile = Path.Combine(baseDirectory, "demobox.conf");
            string logFile = Path.Combine(baseDirectory, "log.bin");

            if (args.Length == 2 && args[0] == "/service")
            {
                configFile = args[1];
                Service.Run(configFile);
                return;
            }

            try { File.Delete(logFile); } catch { }
            Ringlogger log = new Ringlogger(logFile, "GUI");

            var logPrintingThread = new Thread(() =>
            {
                var cursor = Ringlogger.CursorAll;
                while (Thread.CurrentThread.IsAlive)
                {
                    var lines = log.FollowFromCursor(ref cursor);
                    foreach (var line in lines)
                        Console.WriteLine(line);
                    Thread.Sleep(300);
                }
            });

            logPrintingThread.Start();

            SetConsoleCtrlHandler(delegate
            {
                Service.Remove(configFile);
                Environment.Exit(0);
                return true;
            }, true);

            try
            {
                Service.Add(configFile);
                logPrintingThread.Join();
            }
            finally
            {
                Service.Remove(configFile);
            }
        }
    }
}
kirpi4
  • 143
  • 1
  • 1
  • 11
  • How were you able to build the DLL? I am unable to do so in the latest commit. – Macindows Dec 31 '20 at 03:44
  • Any update on this? How did you achieve this? Is there any opensource code of yours where I can take a look at it? Can you please help me? @https://stackoverflow.com/users/1532494/kirpi4 – SANDEEP MACHIRAJU Feb 08 '21 at 21:30
  • @Macindows unfortunately I didn't try to build on commits after 03 december 2020. – kirpi4 Mar 29 '21 at 09:04
  • @SANDEEPMACHIRAJU well my code is working but I still don't have the answer to my question. I've just used the logic as it is. Unformtunately I cannot share the final code - it's too huge and it's for corporate purpose but I can certainly say that the sources provided in WireGuard_Repository\embeddable-dll-service\ are enought to make it work even if it works not hoa I am expecting. – kirpi4 Mar 29 '21 at 09:27
  • Thanks for the response kirpi4 – SANDEEP MACHIRAJU Mar 30 '21 at 16:50

1 Answers1

1

Bit late to the party but I was having the exact same issue as above and discovered that in order to get everything working correctly you have to have Tunnel.Service.Run("path to config") defined on application initialization either in your main loop or your constructor then you can run Tunnel.Service.Add("path to config", true) which will create the service and start the VPN connection. It's also good practice to destroy the service on close using Tunnel.Service.Remove("path to config", true) as the service will continue to run and you will still be connected to your VPN until it is stopped manually.

James
  • 61
  • 1
  • 9