diff --git a/AutoTunnel/AutoTunnel.csproj b/AutoTunnel/AutoTunnel.csproj index 1ba1b64..924adb0 100644 --- a/AutoTunnel/AutoTunnel.csproj +++ b/AutoTunnel/AutoTunnel.csproj @@ -138,8 +138,8 @@ - - tunnel_estabilishing.png + + tunnel_establishing.png diff --git a/AutoTunnel/BaseSender.cs b/AutoTunnel/BaseSender.cs index 1a5b0ab..8b3a28e 100644 --- a/AutoTunnel/BaseSender.cs +++ b/AutoTunnel/BaseSender.cs @@ -55,10 +55,11 @@ private void StartInternal() int packetLen = 0; while (!_isExiting) { + var oldHandle = _handle; if (!WinDivert.WinDivertRecv(_handle, packet, packet.Length, ref addr, ref packetLen)) { - // showing error only if handle is not removed - if (_handle != IntPtr.Zero) + // showing error only if handle is not removed and not changed + if (_handle != IntPtr.Zero && oldHandle == _handle) { LogHelper.Log.WriteLine("Cannot receive network data: " + Marshal.GetLastWin32Error()); Thread.Sleep(1000); diff --git a/AutoTunnel/ClientSender.cs b/AutoTunnel/ClientSender.cs index 40dff41..97ebd10 100644 --- a/AutoTunnel/ClientSender.cs +++ b/AutoTunnel/ClientSender.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text; using System.Threading; @@ -119,7 +120,7 @@ private void InitInternal() _connectEP = destEP; - Storage.IncrementEstabilishing(); + Storage.IncrementEstablishing(); Storage.AddSession(new byte[16], destEP).IsClientSession = true; if (proxyEP != null) @@ -177,7 +178,7 @@ private void InitInternal() period = Math.Min(period + 2000, 1000 * 60); LogHelper.Log.WriteLine("No response from server " + destEP); - if (DateTime.UtcNow.Subtract(_lastInitRequest).TotalSeconds > 60) + if (!_config.ConnectOnStart && DateTime.UtcNow.Subtract(_lastInitRequest).TotalSeconds > 60) { LogHelper.Log.WriteLine("Stopping connect atteptions to " + destEP + " until another request will occur"); } @@ -185,7 +186,7 @@ private void InitInternal() if (recLength < 4 || _receiveBuffer[0] != (byte)StateFlags.ConnectAnswer) { - Console.Error.WriteLine("Invalid server response"); + LogHelper.Log.WriteLine("Invalid server response"); Storage.RemoveSession(destEP); return; } @@ -193,7 +194,7 @@ private void InitInternal() var decLen = decryptHelper.Decrypt(_receiveBuffer, 4); if (decLen < 9) { - Console.Error.WriteLine("Invalid server response"); + LogHelper.Log.WriteLine("Invalid server response"); Storage.RemoveSession(destEP); return; } @@ -206,11 +207,14 @@ private void InitInternal() LogHelper.Log.WriteLine("Initialized connection to " + destEP); _isInited = true; _initingEvent.Set(); + + // after connect - sending packet to estabilish backward connection + using (var p = new Ping()) p.Send(DstAddr, 1); } finally { Interlocked.Exchange(ref _isIniting, 0); - Storage.DecrementEstabilishing(); + Storage.DecrementEstablishing(); } } diff --git a/AutoTunnel/Encryption/EncryptHelper.cs b/AutoTunnel/Encryption/EncryptHelper.cs index 830b32d..adedfe1 100644 --- a/AutoTunnel/Encryption/EncryptHelper.cs +++ b/AutoTunnel/Encryption/EncryptHelper.cs @@ -33,16 +33,11 @@ public EncryptHelper(byte[] key) public int Encrypt(byte[] data, int len) { var hb = _headerBuf; - // _random.GetBytes(hb); + _random.GetBytes(hb); hb[0] = (byte)(len & 0xff); hb[1] = (byte)((len >> 8) & 0xff); hb[2] = (byte)((len >> 16) & 0xff); hb[3] = (byte)((len >> 24) & 0xff); - // var c = Interlocked.Increment(ref _counter); - /*_headerBuf[4] = (byte)(c & 0xff); - _headerBuf[5] = (byte)((c >> 8) & 0xff); - _headerBuf[6] = (byte)((c >> 16) & 0xff); - _headerBuf[7] = (byte)((c >> 24) & 0xff);*/ hb[4] = 0x1; hb[5] = 0x0; hb[6] = (byte)'A'; diff --git a/AutoTunnel/Listener.cs b/AutoTunnel/Listener.cs index 44e01d8..7aaf6aa 100644 --- a/AutoTunnel/Listener.cs +++ b/AutoTunnel/Listener.cs @@ -78,7 +78,7 @@ private void StartInternal() { if (inBuf[0] == (byte)StateFlags.Connecting) { - LogHelper.Log.WriteLine("Estabilishing connection from " + ep); + LogHelper.Log.WriteLine("Establishing connection from " + ep); int dataLen = -1; DecryptHelper decryptHelper = null; EncryptHelper encryptHelper = null; @@ -116,7 +116,7 @@ private void StartInternal() s.SendTo(initBuf, initBuf.Length, SocketFlags.None, ep); var descr = selectedRemoteClient != null ? (!string.IsNullOrEmpty(selectedRemoteClient.Description) ? " as " + selectedRemoteClient.BinaryKey : string.Empty) : string.Empty; - LogHelper.Log.WriteLine("Estabilished connection from " + ep + descr); + LogHelper.Log.WriteLine("Established connection from " + ep + descr); continue; } @@ -167,7 +167,7 @@ private void StartInternal() // var sourceIp = decBuf[12] + "." + decBuf[13] + "." + decBuf[14] + "." + decBuf[15]; var sourceIp = new IPAddress(decBuf[12] | (decBuf[13] << 8) | (decBuf[14] << 16) | (decBuf[15] << 24)); - // if we already has option to estabilish connection to this ip, do not add additional sender + // if we already has option to establish connection to this ip, do not add additional sender if (!_storage.OutgoingConnectionAdresses.Contains(sourceIp)) { var sender = _storage.GetOrAddSender(sourceIp, () => new ReplySender(session, sourceIp, s, _storage)); diff --git a/AutoTunnel/Properties/AssemblyInfo.cs b/AutoTunnel/Properties/AssemblyInfo.cs index 7c34637..b5909df 100644 --- a/AutoTunnel/Properties/AssemblyInfo.cs +++ b/AutoTunnel/Properties/AssemblyInfo.cs @@ -32,4 +32,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.1.0.2")] \ No newline at end of file diff --git a/AutoTunnel/Service/ConsoleHelper.cs b/AutoTunnel/Service/ConsoleHelper.cs index 7119492..1cc61f4 100644 --- a/AutoTunnel/Service/ConsoleHelper.cs +++ b/AutoTunnel/Service/ConsoleHelper.cs @@ -12,7 +12,7 @@ public static class ConsoleHelper private static extern IntPtr SendMessage(IntPtr hWnd, uint message, int lParam, IntPtr wParam); private static IntPtr _iconActiveHandle = IntPtr.Zero; - private static IntPtr _iconEstabilishingHandle = IntPtr.Zero; + private static IntPtr _iconEstablishingHandle = IntPtr.Zero; private static IntPtr _iconParentHandle = IntPtr.Zero; private static void RestoreOriginalIcon() @@ -26,7 +26,7 @@ private static void RestoreOriginalIcon() public enum IconStatus { Active, - Estabilishing, + Establishing, Default } @@ -38,7 +38,7 @@ public static void SetActiveIcon(IconStatus status) { // ReSharper disable AssignNullToNotNullAttribute _iconActiveHandle = new Bitmap(typeof(ConsoleHelper).Assembly.GetManifestResourceStream("Force.AutoTunnel.tunnel_active.png")).GetHicon(); - _iconEstabilishingHandle = new Bitmap(typeof(ConsoleHelper).Assembly.GetManifestResourceStream("Force.AutoTunnel.tunnel_estabilishing.png")).GetHicon(); + _iconEstablishingHandle = new Bitmap(typeof(ConsoleHelper).Assembly.GetManifestResourceStream("Force.AutoTunnel.tunnel_establishing.png")).GetHicon(); // ReSharper restore AssignNullToNotNullAttribute _iconParentHandle = SendMessage(GetConsoleWindow(), 0x80, 0, _iconActiveHandle); @@ -46,7 +46,7 @@ public static void SetActiveIcon(IconStatus status) var icon = _iconParentHandle; if (status == IconStatus.Active) icon = _iconActiveHandle; - else if (status == IconStatus.Estabilishing) icon = _iconEstabilishingHandle; + else if (status == IconStatus.Establishing) icon = _iconEstablishingHandle; SendMessage(GetConsoleWindow(), 0x80, 0, icon); SendMessage(GetConsoleWindow(), 0x80, 1, icon); } diff --git a/AutoTunnel/TunnelStorage.cs b/AutoTunnel/TunnelStorage.cs index 6d5e24c..c873431 100644 --- a/AutoTunnel/TunnelStorage.cs +++ b/AutoTunnel/TunnelStorage.cs @@ -93,25 +93,25 @@ public bool HasSession(ulong key) return _sessions.ContainsKey(key); } - private int _estabilishingCount; + private int _establishingCount; - public void IncrementEstabilishing() + public void IncrementEstablishing() { - Interlocked.Increment(ref _estabilishingCount); + Interlocked.Increment(ref _establishingCount); SetIcon(); } - public void DecrementEstabilishing() + public void DecrementEstablishing() { - Interlocked.Decrement(ref _estabilishingCount); + Interlocked.Decrement(ref _establishingCount); SetIcon(); } private void SetIcon() { - if (_estabilishingCount > 0) + if (_establishingCount > 0) { - ConsoleHelper.SetActiveIcon(ConsoleHelper.IconStatus.Estabilishing); + ConsoleHelper.SetActiveIcon(ConsoleHelper.IconStatus.Establishing); } else { diff --git a/README.md b/README.md index 4f65257..764ba84 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Secured network tunnel for connecting two computers. Main usage: connecting trav ## Differences from IPSec * No need to specify both endpoints to static addresses -* Only one UDP port for usage (insted of ESP, AH protocols and 500 and 4500 UDP ports) +* Only one UDP port for usage (instead of ESP, AH protocols and 500 and 4500 UDP ports) * Just some settings to make tunnel works, you no need to specify lot of parameters in different configs and phases * Currently, no IPv6 support @@ -34,7 +34,7 @@ Secured network tunnel for connecting two computers. Main usage: connecting trav AutoTunnel uses [WinDivert](https://reqrypt.org/windivert.html) library to catch outgoing network packets, transfers it to another computer and puts them back, as normal packets. So, this packets looks like usual network packets, but you do not need to specify routing tables between computers. These computers are in virtual local network. -After estabilishing connection with another computer, it begin to catch packets to source computer and transfers it back to it through estabilished tunnel. +After establishing connection with another computer, it begins to catch packets to source computer and transfers it back to it through established tunnel. ## Encryption Tunnel is encrypted with AES256 with PFS support. Currently, for auth you can use only preshared keys (I think, it simple and good variant for authentication, because one key can be changed to another in some seconds, you do not need to regenerate certificates or private keys). @@ -47,10 +47,10 @@ There are two types of computers: * Server - listens incoming connections * Client - connects to server -Any computer can be server for others computers and client for anothers. There are no need to use separate program. +Any computer can be server for others computers and client for another. There is no need to use separate program. So, despite only two computers can use one tunnel, you can create a lot of tunnels between pairs of different computers. -Also, you can estabilish connection between two computers in client mode. Two tunnels will be created, but packets will be passed correctly. +Also, you can establish connection between two computers in client mode. Two tunnels will be created, but packets will be passed correctly. # Installation and running @@ -61,7 +61,7 @@ You need: * Enabled .NET Framework 4.0 * [VC Redist 2012](https://www.microsoft.com/en-us/download/details.aspx?id=30679) -Program can be runned in console or work as a service. Service can be installed in next way: +Program can be started in console or work as a service. Service can be installed in next way: ``` AutoTunnel.exe service install sc start AutoTunnel @@ -109,18 +109,18 @@ remoteServers | null | Servers for connecting as client remoteServers.tunnelHost | null | IP address or host name of remote computer. If any packets will be send to this computer, it will be passed through tunnel remoteServers.connectHost | null | IP address or host with port of remote computer to connect. If skipped - tunnel host data can be used. You can specify it, it target computer has different IP addresses and you want to connect to one of them, but pass data for another remoteServers.proxyHost | null | IP address or host with port of proxy. Proxy can be used to connect to server which is not available from outer network -remoteServers.key | null | Pre-shared key to estabilish connection with remote server +remoteServers.key | null | Pre-shared key to establish connection with remote server remoteServers.keepAlive | false | Send special keep alive packets to keep connection alive. If you need permament connection, you can set it to true remoteServers.connectOnStart | false | Connect to another computer on application start or only when first packet will be sent to it # Proxy -If target computer is unavailabe from outer network but you have separate computer which can transfer packets from local network to outer network, you can use special proxy program. +If target computer is unavailable from outer network but you have separate computer which can transfer packets from local network to outer network, you can use special proxy program. Full scheme of connection can be similar: ``` -Client computer (gray ip, NAT) <-> Router <-> (Internet) <-> Router <-> Proxy <-> Server (NAT) +Client computer (gray ip, NAT) <-> Router <-> (Internet) <-> Router <-> Proxy <-> Server (NAT) 192.168.1.42 <-> 192.168.1.1|91.10.20.42 <-> (Internet) <-> 82.40.10.1 <-> 82.40.10.54 <-> 10.0.1.15 ``` diff --git a/tunnel_estabilishing.png b/tunnel_establishing.png similarity index 100% rename from tunnel_estabilishing.png rename to tunnel_establishing.png