From 3aa325edec82d34345b23f93ba78e85a3853da5f Mon Sep 17 00:00:00 2001 From: York Xiang Date: Fri, 16 Jan 2015 23:01:06 +0800 Subject: [PATCH 01/25] =?UTF-8?q?=E8=A7=A3=E5=86=B3=20QRcode=20=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E8=A7=A3=E6=9E=90=E4=B8=AD=E5=AF=86=E7=A0=81=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E5=B8=A6@=E7=AC=A6=E5=8F=B7=E3=80=81=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E5=90=8D=E5=8F=AF=E8=83=BD=E5=B8=A6=E5=86=92?= =?UTF-8?q?=E5=8F=B7=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 关掉 https://github.com/shadowsocks/shadowsocks-csharp/issues/131 我就是爱用中文,哼~ --- shadowsocks-csharp/Model/Server.cs | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index b4486db9..18f28aff 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Text; using System.IO; @@ -50,7 +50,8 @@ namespace Shadowsocks.Model string[] r1 = Regex.Split(ssURL, "ss://", RegexOptions.IgnoreCase); string base64 = r1[1].ToString(); byte[] bytes = null; - for (var i = 0; i < 3; i++) { + for (var i = 0; i < 3; i++) + { try { bytes = System.Convert.FromBase64String(base64); @@ -64,11 +65,25 @@ namespace Shadowsocks.Model { throw new FormatException(); } - string[] parts = Encoding.UTF8.GetString(bytes).Split(new char[2] { ':', '@' }); - this.method = parts[0].ToString(); - this.password = parts[1].ToString(); - this.server = parts[2].ToString(); - this.server_port = int.Parse(parts[3].ToString()); + try + { + string data = Encoding.UTF8.GetString(bytes); + int indexLastAt = data.LastIndexOf('@'); + + string afterAt = data.Substring(indexLastAt + 1); + int indexLastComma = afterAt.LastIndexOf(':'); + this.server_port = int.Parse(afterAt.Substring(indexLastComma + 1)); + this.server = afterAt.Substring(0, indexLastComma); + + string beforeAt = data.Substring(0, indexLastAt); + string[] parts = beforeAt.Split(new[] { ':' }); + this.method = parts[0]; + this.password = parts[1]; + } + catch (IndexOutOfRangeException) + { + throw new FormatException(); + } } } } From 32941478d7cb87147ed3478d1e3daf7de5b9968f Mon Sep 17 00:00:00 2001 From: York Xiang Date: Fri, 16 Jan 2015 23:19:19 +0800 Subject: [PATCH 02/25] =?UTF-8?q?=E5=86=92=E5=8F=B7=E5=86=99=E6=88=90?= =?UTF-8?q?=E9=80=97=E5=8F=B7=E4=BA=86=EF=BC=8C=E6=88=91=E9=94=99=E4=BA=86?= =?UTF-8?q?=E2=80=A6=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shadowsocks-csharp/Model/Server.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index 18f28aff..00209d11 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -71,9 +71,9 @@ namespace Shadowsocks.Model int indexLastAt = data.LastIndexOf('@'); string afterAt = data.Substring(indexLastAt + 1); - int indexLastComma = afterAt.LastIndexOf(':'); - this.server_port = int.Parse(afterAt.Substring(indexLastComma + 1)); - this.server = afterAt.Substring(0, indexLastComma); + int indexLastColon = afterAt.LastIndexOf(':'); + this.server_port = int.Parse(afterAt.Substring(indexLastColon + 1)); + this.server = afterAt.Substring(0, indexLastColon); string beforeAt = data.Substring(0, indexLastAt); string[] parts = beforeAt.Split(new[] { ':' }); From d4bdd2e598949bb712e03e82d2a45c13e685229e Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 04:01:20 +0800 Subject: [PATCH 03/25] bump --- CHANGES | 3 +++ shadowsocks-csharp/Controller/UpdateChecker.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 0fc9e1f9..64f5ee1c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2.2.1 2015-01-18 +- Fix QR Code compatibility + 2.2 2015-01-14 - Support updating PAC from GFWList - Support adding server by scanning QR Code diff --git a/shadowsocks-csharp/Controller/UpdateChecker.cs b/shadowsocks-csharp/Controller/UpdateChecker.cs index 3fe76f98..870db9d5 100755 --- a/shadowsocks-csharp/Controller/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/UpdateChecker.cs @@ -17,7 +17,7 @@ namespace Shadowsocks.Controller public string LatestVersionURL; public event EventHandler NewVersionFound; - public const string Version = "2.2"; + public const string Version = "2.2.1"; public void CheckUpdate() { From fb51f30fd97d39aa47f01445e553d16b0f086fcf Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 14:15:57 +0800 Subject: [PATCH 04/25] rename Enable --- shadowsocks-csharp/Data/cn.txt | 2 +- shadowsocks-csharp/View/MenuViewController.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index ed6dfbd8..34db8f0f 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -1,5 +1,5 @@ Shadowsocks=Shadowsocks -Enable=启用代理 +Enable System Proxy=启用系统代理 Mode=代理模式 PAC=PAC 模式 Global=全局模式 diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 9fe27bec..b7b6ae36 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -131,7 +131,7 @@ namespace Shadowsocks.View private void LoadMenu() { this.contextMenu1 = new ContextMenu(new MenuItem[] { - this.enableItem = CreateMenuItem("Enable", new EventHandler(this.EnableItem_Click)), + this.enableItem = CreateMenuItem("Enable System Proxy", new EventHandler(this.EnableItem_Click)), CreateMenuGroup("Mode", new MenuItem[] { this.PACModeItem = CreateMenuItem("PAC", new EventHandler(this.PACModeItem_Click)), this.globalModeItem = CreateMenuItem("Global", new EventHandler(this.GlobalModeItem_Click)) From 42c3776aa5ea150bc4d4a5365ddad105c1045c85 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 14:30:48 +0800 Subject: [PATCH 05/25] move proxy port out of group box --- shadowsocks-csharp/View/ConfigForm.Designer.cs | 94 +++++++++++++++++--------- 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 57e1441b..83dae64a 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -33,8 +33,6 @@ this.RemarksLabel = new System.Windows.Forms.Label(); this.IPLabel = new System.Windows.Forms.Label(); this.ServerPortLabel = new System.Windows.Forms.Label(); - this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); - this.ProxyPortLabel = new System.Windows.Forms.Label(); this.PasswordLabel = new System.Windows.Forms.Label(); this.IPTextBox = new System.Windows.Forms.TextBox(); this.ServerPortTextBox = new System.Windows.Forms.TextBox(); @@ -49,11 +47,15 @@ this.ServerGroupBox = new System.Windows.Forms.GroupBox(); this.ServersListBox = new System.Windows.Forms.ListBox(); this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel(); + this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); + this.ProxyPortLabel = new System.Windows.Forms.Label(); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel1.SuspendLayout(); this.ServerGroupBox.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); + this.tableLayoutPanel5.SuspendLayout(); this.tableLayoutPanel3.SuspendLayout(); this.tableLayoutPanel4.SuspendLayout(); this.SuspendLayout(); @@ -69,8 +71,6 @@ this.tableLayoutPanel1.Controls.Add(this.RemarksLabel, 0, 5); this.tableLayoutPanel1.Controls.Add(this.IPLabel, 0, 0); this.tableLayoutPanel1.Controls.Add(this.ServerPortLabel, 0, 1); - this.tableLayoutPanel1.Controls.Add(this.ProxyPortTextBox, 1, 4); - this.tableLayoutPanel1.Controls.Add(this.ProxyPortLabel, 0, 4); this.tableLayoutPanel1.Controls.Add(this.PasswordLabel, 0, 2); this.tableLayoutPanel1.Controls.Add(this.IPTextBox, 1, 0); this.tableLayoutPanel1.Controls.Add(this.ServerPortTextBox, 1, 1); @@ -88,13 +88,13 @@ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(238, 163); + this.tableLayoutPanel1.Size = new System.Drawing.Size(238, 137); this.tableLayoutPanel1.TabIndex = 0; // // RemarksTextBox // this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.RemarksTextBox.Location = new System.Drawing.Point(72, 137); + this.RemarksTextBox.Location = new System.Drawing.Point(72, 111); this.RemarksTextBox.MaxLength = 32; this.RemarksTextBox.Name = "RemarksTextBox"; this.RemarksTextBox.Size = new System.Drawing.Size(160, 20); @@ -105,7 +105,7 @@ // this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.RemarksLabel.AutoSize = true; - this.RemarksLabel.Location = new System.Drawing.Point(17, 140); + this.RemarksLabel.Location = new System.Drawing.Point(17, 114); this.RemarksLabel.Name = "RemarksLabel"; this.RemarksLabel.Size = new System.Drawing.Size(49, 13); this.RemarksLabel.TabIndex = 9; @@ -131,26 +131,6 @@ this.ServerPortLabel.TabIndex = 1; this.ServerPortLabel.Text = "Server Port"; // - // ProxyPortTextBox - // - this.ProxyPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyPortTextBox.Location = new System.Drawing.Point(72, 111); - this.ProxyPortTextBox.MaxLength = 10; - this.ProxyPortTextBox.Name = "ProxyPortTextBox"; - this.ProxyPortTextBox.Size = new System.Drawing.Size(160, 20); - this.ProxyPortTextBox.TabIndex = 4; - this.ProxyPortTextBox.WordWrap = false; - // - // ProxyPortLabel - // - this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.ProxyPortLabel.AutoSize = true; - this.ProxyPortLabel.Location = new System.Drawing.Point(11, 114); - this.ProxyPortLabel.Name = "ProxyPortLabel"; - this.ProxyPortLabel.Size = new System.Drawing.Size(55, 13); - this.ProxyPortLabel.TabIndex = 3; - this.ProxyPortLabel.Text = "Proxy Port"; - // // PasswordLabel // this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; @@ -292,7 +272,7 @@ this.ServerGroupBox.Location = new System.Drawing.Point(178, 0); this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(12, 0, 0, 0); this.ServerGroupBox.Name = "ServerGroupBox"; - this.ServerGroupBox.Size = new System.Drawing.Size(249, 200); + this.ServerGroupBox.Size = new System.Drawing.Size(249, 174); this.ServerGroupBox.TabIndex = 6; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; @@ -315,6 +295,7 @@ this.tableLayoutPanel2.ColumnCount = 2; this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel5, 1, 1); this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel3, 1, 2); this.tableLayoutPanel2.Controls.Add(this.ServersListBox, 0, 0); this.tableLayoutPanel2.Controls.Add(this.ServerGroupBox, 1, 0); @@ -326,9 +307,53 @@ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.Size = new System.Drawing.Size(427, 264); + this.tableLayoutPanel2.Size = new System.Drawing.Size(427, 238); this.tableLayoutPanel2.TabIndex = 7; // + // tableLayoutPanel5 + // + this.tableLayoutPanel5.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.tableLayoutPanel5.AutoSize = true; + this.tableLayoutPanel5.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel5.ColumnCount = 2; + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel5.Controls.Add(this.ProxyPortTextBox, 1, 0); + this.tableLayoutPanel5.Controls.Add(this.ProxyPortLabel, 0, 0); + this.tableLayoutPanel5.Location = new System.Drawing.Point(241, 174); + this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel5.Name = "tableLayoutPanel5"; + this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(3); + this.tableLayoutPanel5.RowCount = 1; + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F)); + this.tableLayoutPanel5.Size = new System.Drawing.Size(186, 32); + this.tableLayoutPanel5.TabIndex = 9; + // + // ProxyPortTextBox + // + this.ProxyPortTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.ProxyPortTextBox.Location = new System.Drawing.Point(67, 6); + this.ProxyPortTextBox.MaxLength = 10; + this.ProxyPortTextBox.Name = "ProxyPortTextBox"; + this.ProxyPortTextBox.Size = new System.Drawing.Size(113, 20); + this.ProxyPortTextBox.TabIndex = 4; + this.ProxyPortTextBox.WordWrap = false; + // + // ProxyPortLabel + // + this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.ProxyPortLabel.AutoSize = true; + this.ProxyPortLabel.Location = new System.Drawing.Point(6, 9); + this.ProxyPortLabel.Name = "ProxyPortLabel"; + this.ProxyPortLabel.Size = new System.Drawing.Size(55, 13); + this.ProxyPortLabel.TabIndex = 3; + this.ProxyPortLabel.Text = "Proxy Port"; + // // tableLayoutPanel3 // this.tableLayoutPanel3.AutoSize = true; @@ -340,7 +365,7 @@ this.tableLayoutPanel3.Controls.Add(this.MyCancelButton, 1, 0); this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0); this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right; - this.tableLayoutPanel3.Location = new System.Drawing.Point(268, 235); + this.tableLayoutPanel3.Location = new System.Drawing.Point(268, 209); this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); this.tableLayoutPanel3.Name = "tableLayoutPanel3"; this.tableLayoutPanel3.RowCount = 1; @@ -358,7 +383,7 @@ this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0); this.tableLayoutPanel4.Controls.Add(this.AddButton, 0, 0); this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 200); + this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 174); this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; this.tableLayoutPanel4.RowCount = 1; @@ -393,6 +418,8 @@ this.ServerGroupBox.PerformLayout(); this.tableLayoutPanel2.ResumeLayout(false); this.tableLayoutPanel2.PerformLayout(); + this.tableLayoutPanel5.ResumeLayout(false); + this.tableLayoutPanel5.PerformLayout(); this.tableLayoutPanel3.ResumeLayout(false); this.tableLayoutPanel4.ResumeLayout(false); this.ResumeLayout(false); @@ -406,11 +433,9 @@ private System.Windows.Forms.Label IPLabel; private System.Windows.Forms.Label ServerPortLabel; private System.Windows.Forms.Label PasswordLabel; - private System.Windows.Forms.Label ProxyPortLabel; private System.Windows.Forms.TextBox IPTextBox; private System.Windows.Forms.TextBox ServerPortTextBox; private System.Windows.Forms.TextBox PasswordTextBox; - private System.Windows.Forms.TextBox ProxyPortTextBox; private System.Windows.Forms.Label EncryptionLabel; private System.Windows.Forms.ComboBox EncryptionSelect; private System.Windows.Forms.Panel panel2; @@ -425,6 +450,9 @@ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5; + private System.Windows.Forms.TextBox ProxyPortTextBox; + private System.Windows.Forms.Label ProxyPortLabel; } } From 444fabaa795b7cbc5a4014b86ddf110785d62840 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 14:44:54 +0800 Subject: [PATCH 06/25] local port now is the same for different servers --- shadowsocks-csharp/Controller/Local.cs | 21 +++++++++++---------- shadowsocks-csharp/Controller/PolipoRunner.cs | 4 ++-- .../Controller/ShadowsocksController.cs | 2 +- shadowsocks-csharp/Model/Configuration.cs | 9 +++++++-- shadowsocks-csharp/Model/Server.cs | 2 -- shadowsocks-csharp/View/ConfigForm.cs | 8 +++++--- 6 files changed, 26 insertions(+), 20 deletions(-) diff --git a/shadowsocks-csharp/Controller/Local.cs b/shadowsocks-csharp/Controller/Local.cs index cd6d2f96..8802b4e1 100755 --- a/shadowsocks-csharp/Controller/Local.cs +++ b/shadowsocks-csharp/Controller/Local.cs @@ -11,13 +11,13 @@ namespace Shadowsocks.Controller class Local { - private Server _server; + private Configuration _config; private bool _shareOverLAN; //private Encryptor encryptor; Socket _listener; public Local(Configuration config) { - this._server = config.GetCurrentServer(); + this._config = config; _shareOverLAN = config.shareOverLan; //this.encryptor = new Encryptor(config.method, config.password); } @@ -32,11 +32,11 @@ namespace Shadowsocks.Controller IPEndPoint localEndPoint = null; if (_shareOverLAN) { - localEndPoint = new IPEndPoint(IPAddress.Any, _server.local_port); + localEndPoint = new IPEndPoint(IPAddress.Any, _config.localPort); } else { - localEndPoint = new IPEndPoint(IPAddress.Loopback, _server.local_port); + localEndPoint = new IPEndPoint(IPAddress.Loopback, _config.localPort); } // Bind the socket to the local endpoint and listen for incoming connections. @@ -74,8 +74,9 @@ namespace Shadowsocks.Controller Handler handler = new Handler(); handler.connection = conn; - handler.encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); - handler.config = _server; + Server server = _config.GetCurrentServer(); + handler.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password); + handler.server = server; handler.Start(); } @@ -104,7 +105,7 @@ namespace Shadowsocks.Controller { //public Encryptor encryptor; public IEncryptor encryptor; - public Server config; + public Server server; // Client socket. public Socket remote; public Socket connection; @@ -134,13 +135,13 @@ namespace Shadowsocks.Controller { // TODO async resolving IPAddress ipAddress; - bool parsed = IPAddress.TryParse(config.server, out ipAddress); + bool parsed = IPAddress.TryParse(server.server, out ipAddress); if (!parsed) { - IPHostEntry ipHostInfo = Dns.GetHostEntry(config.server); + IPHostEntry ipHostInfo = Dns.GetHostEntry(server.server); ipAddress = ipHostInfo.AddressList[0]; } - IPEndPoint remoteEP = new IPEndPoint(ipAddress, config.server_port); + IPEndPoint remoteEP = new IPEndPoint(ipAddress, server.server_port); remote = new Socket(ipAddress.AddressFamily, diff --git a/shadowsocks-csharp/Controller/PolipoRunner.cs b/shadowsocks-csharp/Controller/PolipoRunner.cs index 42bf3bfa..1b91783b 100755 --- a/shadowsocks-csharp/Controller/PolipoRunner.cs +++ b/shadowsocks-csharp/Controller/PolipoRunner.cs @@ -45,8 +45,8 @@ namespace Shadowsocks.Controller Console.WriteLine(e.ToString()); } } - string polipoConfig = Resources.polipo_config; - polipoConfig = polipoConfig.Replace("__SOCKS_PORT__", server.local_port.ToString()); + string polipoConfig = Resources.polipo_config; + polipoConfig = polipoConfig.Replace("__SOCKS_PORT__", configuration.localPort.ToString()); polipoConfig = polipoConfig.Replace("__POLIPO_BIND_IP__", configuration.shareOverLan ? "0.0.0.0" : "127.0.0.1"); FileManager.ByteArrayToFile(temppath + "/polipo.conf", System.Text.Encoding.UTF8.GetBytes(polipoConfig)); diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 113242a7..abd6b518 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -74,7 +74,7 @@ namespace Shadowsocks.Controller return Configuration.Load(); } - public void SaveServers(List servers) + public void SaveServers(List servers, int localPort) { _config.configs = servers; SaveConfig(_config); diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 4b6e0ecb..56c91759 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -16,6 +16,7 @@ namespace Shadowsocks.Model public bool enabled; public bool shareOverLan; public bool isDefault; + public int localPort; private static string CONFIG_FILE = "gui-config.json"; @@ -33,7 +34,6 @@ namespace Shadowsocks.Model public static void CheckServer(Server server) { - CheckPort(server.local_port); CheckPort(server.server_port); CheckPassword(server.password); CheckServer(server.server); @@ -46,6 +46,10 @@ namespace Shadowsocks.Model string configContent = File.ReadAllText(CONFIG_FILE); Configuration config = SimpleJson.SimpleJson.DeserializeObject(configContent, new JsonSerializerStrategy()); config.isDefault = false; + if (config.localPort == 0) + { + config.localPort = 1080; + } return config; } catch (Exception e) @@ -58,6 +62,7 @@ namespace Shadowsocks.Model { index = 0, isDefault = true, + localPort = 1080, configs = new List() { GetDefaultServer() @@ -105,7 +110,7 @@ namespace Shadowsocks.Model } } - private static void CheckPort(int port) + public static void CheckPort(int port) { if (port <= 0 || port > 65535) { diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index 00209d11..4acc3a0e 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -14,7 +14,6 @@ namespace Shadowsocks.Model { public string server; public int server_port; - public int local_port; public string password; public string method; public string remarks; @@ -39,7 +38,6 @@ namespace Shadowsocks.Model { this.server = ""; this.server_port = 8388; - this.local_port = 1080; this.method = "aes-256-cfb"; this.password = ""; this.remarks = ""; diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index ecc9bf1f..574fafd5 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -79,12 +79,14 @@ namespace Shadowsocks.View server = IPTextBox.Text, server_port = int.Parse(ServerPortTextBox.Text), password = PasswordTextBox.Text, - local_port = int.Parse(ProxyPortTextBox.Text), method = EncryptionSelect.Text, remarks = RemarksTextBox.Text }; + int localPort = int.Parse(ProxyPortTextBox.Text); Configuration.CheckServer(server); + Configuration.CheckPort(localPort); _modifiedConfiguration.configs[_oldSelectedIndex] = server; + _modifiedConfiguration.localPort = localPort; return true; } @@ -108,7 +110,7 @@ namespace Shadowsocks.View IPTextBox.Text = server.server; ServerPortTextBox.Text = server.server_port.ToString(); PasswordTextBox.Text = server.password; - ProxyPortTextBox.Text = server.local_port.ToString(); + ProxyPortTextBox.Text = _modifiedConfiguration.localPort.ToString(); EncryptionSelect.Text = server.method ?? "aes-256-cfb"; RemarksTextBox.Text = server.remarks; ServerGroupBox.Visible = true; @@ -202,7 +204,7 @@ namespace Shadowsocks.View MessageBox.Show(I18N.GetString("Please add at least one server")); return; } - controller.SaveServers(_modifiedConfiguration.configs); + controller.SaveServers(_modifiedConfiguration.configs, _modifiedConfiguration.localPort); this.Close(); } From aa6c38ece3154716757e89ce234e0d34ab360f87 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 15:53:45 +0800 Subject: [PATCH 07/25] move local to listener service --- shadowsocks-csharp/Controller/Local.cs | 123 ++++----------------- .../Controller/ShadowsocksController.cs | 18 +-- shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + 3 files changed, 34 insertions(+), 108 deletions(-) diff --git a/shadowsocks-csharp/Controller/Local.cs b/shadowsocks-csharp/Controller/Local.cs index 8802b4e1..bba7a02f 100755 --- a/shadowsocks-csharp/Controller/Local.cs +++ b/shadowsocks-csharp/Controller/Local.cs @@ -9,96 +9,30 @@ using Shadowsocks.Model; namespace Shadowsocks.Controller { - class Local + class Local : Listener.Service { private Configuration _config; - private bool _shareOverLAN; - //private Encryptor encryptor; - Socket _listener; public Local(Configuration config) { this._config = config; - _shareOverLAN = config.shareOverLan; - //this.encryptor = new Encryptor(config.method, config.password); } - public void Start() + public bool GoodForMe(byte[] firstPacket, int length) { - try - { - // Create a TCP/IP socket. - _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - _listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - IPEndPoint localEndPoint = null; - if (_shareOverLAN) - { - localEndPoint = new IPEndPoint(IPAddress.Any, _config.localPort); - } - else - { - localEndPoint = new IPEndPoint(IPAddress.Loopback, _config.localPort); - } - - // Bind the socket to the local endpoint and listen for incoming connections. - _listener.Bind(localEndPoint); - _listener.Listen(100); - - - // Start an asynchronous socket to listen for connections. - Console.WriteLine("Shadowsocks started"); - _listener.BeginAccept( - new AsyncCallback(AcceptCallback), - _listener); - } - catch(SocketException) - { - _listener.Close(); - throw; - } - - } - - public void Stop() - { - _listener.Close(); + return true; } - - - public void AcceptCallback(IAsyncResult ar) + + public void Handle(byte[] firstPacket, int length, Socket socket) { - Socket listener = (Socket)ar.AsyncState; - try - { - Socket conn = listener.EndAccept(ar); - conn.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); - - Handler handler = new Handler(); - handler.connection = conn; - Server server = _config.GetCurrentServer(); - handler.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password); - handler.server = server; - - handler.Start(); - } - catch - { - //Console.WriteLine(e.Message); - } - finally - { - try - { - listener.BeginAccept( - new AsyncCallback(AcceptCallback), - listener); - } - catch - { - //Console.WriteLine(e.Message); - } - } + socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); + Handler handler = new Handler(); + handler.connection = socket; + Server server = _config.GetCurrentServer(); + handler.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password); + handler.server = server; + + handler.Start(firstPacket, length); } - } class Handler @@ -109,6 +43,9 @@ namespace Shadowsocks.Controller // Client socket. public Socket remote; public Socket connection; + + private byte[] _firstPacket; + private int _firstPacketLength; // Size of receive buffer. public const int RecvSize = 16384; public const int BufferSize = RecvSize + 32; @@ -129,8 +66,10 @@ namespace Shadowsocks.Controller private object encryptionLock = new object(); private object decryptionLock = new object(); - public void Start() + public void Start(byte[] firstPacket, int length) { + this._firstPacket = firstPacket; + this._firstPacketLength = length; try { // TODO async resolving @@ -241,33 +180,15 @@ namespace Shadowsocks.Controller } try { - connection.BeginReceive(connetionRecvBuffer, 0, 256, 0, - new AsyncCallback(HandshakeReceiveCallback), null); - } - catch (Exception e) - { - Logging.LogUsefulException(e); - this.Close(); - } - } - - private void HandshakeReceiveCallback(IAsyncResult ar) - { - if (closed) - { - return; - } - try - { - int bytesRead = connection.EndReceive(ar); + int bytesRead = _firstPacketLength; if (bytesRead > 1) { byte[] response = { 5, 0 }; - if (connetionRecvBuffer[0] != 5) + if (_firstPacket[0] != 5) { // reject socks 4 - response = new byte[]{ 0, 91 }; + response = new byte[] { 0, 91 }; Console.WriteLine("socks 5 protocol error"); } connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(HandshakeSendCallback), null); diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index abd6b518..e5049ee5 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -17,7 +17,7 @@ namespace Shadowsocks.Controller private Thread _ramThread; - private Local local; + private Listener _listener; private PACServer pacServer; private Configuration _config; private PolipoRunner polipoRunner; @@ -77,6 +77,7 @@ namespace Shadowsocks.Controller public void SaveServers(List servers, int localPort) { _config.configs = servers; + _config.localPort = localPort; SaveConfig(_config); } @@ -142,9 +143,9 @@ namespace Shadowsocks.Controller return; } stopped = true; - if (local != null) + if (_listener != null) { - local.Stop(); + _listener.Stop(); } if (polipoRunner != null) { @@ -204,9 +205,9 @@ namespace Shadowsocks.Controller pacServer.Stop(); - if (local != null) + if (_listener != null) { - local.Stop(); + _listener.Stop(); } // don't put polipoRunner.Start() before pacServer.Stop() @@ -218,8 +219,11 @@ namespace Shadowsocks.Controller { polipoRunner.Start(_config); - local = new Local(_config); - local.Start(); + Local local = new Local(_config); + List services = new List(); + services.Add(local); + _listener = new Listener(services); + _listener.Start(_config); pacServer.Start(_config); } catch (Exception e) diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 61820eaa..e22a9fbd 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -127,6 +127,7 @@ + From e81b87e7dfc28fd4ecd7e353e0cf29b929c8d92d Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 16:26:12 +0800 Subject: [PATCH 08/25] move pac server to listener --- shadowsocks-csharp/Controller/Local.cs | 12 +- shadowsocks-csharp/Controller/PACServer.cs | 159 ++++++--------------- .../Controller/ShadowsocksController.cs | 14 +- 3 files changed, 57 insertions(+), 128 deletions(-) diff --git a/shadowsocks-csharp/Controller/Local.cs b/shadowsocks-csharp/Controller/Local.cs index bba7a02f..5489ea52 100755 --- a/shadowsocks-csharp/Controller/Local.cs +++ b/shadowsocks-csharp/Controller/Local.cs @@ -17,13 +17,12 @@ namespace Shadowsocks.Controller this._config = config; } - public bool GoodForMe(byte[] firstPacket, int length) - { - return true; - } - - public void Handle(byte[] firstPacket, int length, Socket socket) + public bool Handle(byte[] firstPacket, int length, Socket socket) { + if (length < 2 || firstPacket[0] != 5) + { + return false; + } socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); Handler handler = new Handler(); handler.connection = socket; @@ -32,6 +31,7 @@ namespace Shadowsocks.Controller handler.server = server; handler.Start(firstPacket, length); + return true; } } diff --git a/shadowsocks-csharp/Controller/PACServer.cs b/shadowsocks-csharp/Controller/PACServer.cs index b2456e18..6ffcb7fd 100755 --- a/shadowsocks-csharp/Controller/PACServer.cs +++ b/shadowsocks-csharp/Controller/PACServer.cs @@ -12,59 +12,61 @@ using System.Text; namespace Shadowsocks.Controller { - class PACServer + class PACServer : Listener.Service { private static int PORT = 8093; public static string PAC_FILE = "pac.txt"; - private static Configuration config; - Socket _listener; FileSystemWatcher watcher; public event EventHandler PACFileChanged; - public void Start(Configuration configuration) + public PACServer() + { + this.WatchPacFile(); + } + + public bool Handle(byte[] firstPacket, int length, Socket socket) { try { - config = configuration; - // Create a TCP/IP socket. - _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - _listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - IPEndPoint localEndPoint = null; - if (configuration.shareOverLan) + string request = Encoding.UTF8.GetString(firstPacket, 0, length); + string[] lines = request.Split('\r', '\n'); + bool hostMatch = false, pathMatch = false; + foreach (string line in lines) { - localEndPoint = new IPEndPoint(IPAddress.Any, PORT); + string[] kv = line.Split(new char[]{':'}, 2); + if (kv.Length == 2) + { + if (kv[0] == "Host") + { + if (kv[1].Trim() == ((IPEndPoint)socket.LocalEndPoint).ToString()) + { + hostMatch = true; + } + } + } + else if (kv.Length == 1) + { + if (line.IndexOf("pac") >= 0) + { + pathMatch = true; + } + } } - else + if (hostMatch && pathMatch) { - localEndPoint = new IPEndPoint(IPAddress.Loopback, PORT); + SendResponse(firstPacket, length, socket); + return true; } - - // Bind the socket to the local endpoint and listen for incoming connections. - _listener.Bind(localEndPoint); - _listener.Listen(100); - _listener.BeginAccept( - new AsyncCallback(AcceptCallback), - _listener); - - WatchPacFile(); + return false; } - catch (SocketException) + catch (ArgumentException) { - _listener.Close(); - throw; + return false; } } - public void Stop() - { - if (_listener != null) - { - _listener.Close(); - _listener = null; - } - } public string TouchPACFile() { @@ -79,50 +81,6 @@ namespace Shadowsocks.Controller } } - // we don't even use it - static byte[] requestBuf = new byte[2048]; - - public void AcceptCallback(IAsyncResult ar) - { - Socket listener = (Socket)ar.AsyncState; - try - { - Socket conn = listener.EndAccept(ar); - - object[] state = new object[] { - conn, - requestBuf - }; - - conn.BeginReceive(requestBuf, 0, requestBuf.Length, 0, - new AsyncCallback(ReceiveCallback), state); - } - catch (ObjectDisposedException) - { - } - catch (Exception e) - { - Console.WriteLine(e); - } - finally - { - try - { - listener.BeginAccept( - new AsyncCallback(AcceptCallback), - listener); - } - catch (ObjectDisposedException) - { - // do nothing - } - catch (Exception e) - { - Logging.LogUsefulException(e); - } - } - } - private string GetPACContent() { if (File.Exists(PAC_FILE)) @@ -135,46 +93,33 @@ namespace Shadowsocks.Controller } } - private void ReceiveCallback(IAsyncResult ar) + public void SendResponse(byte[] firstPacket, int length, Socket socket) { - object[] state = (object[])ar.AsyncState; - - Socket conn = (Socket)state[0]; - byte[] requestBuf = (byte[])state[1]; try { - int bytesRead = conn.EndReceive(ar); - string pac = GetPACContent(); - IPEndPoint localEndPoint = (IPEndPoint)conn.LocalEndPoint; + IPEndPoint localEndPoint = (IPEndPoint)socket.LocalEndPoint; - string proxy = GetPACAddress(requestBuf, localEndPoint); + string proxy = GetPACAddress(firstPacket, length, localEndPoint); pac = pac.Replace("__PROXY__", proxy); - if (bytesRead > 0) - { - string text = String.Format(@"HTTP/1.1 200 OK + string text = String.Format(@"HTTP/1.1 200 OK Server: Shadowsocks Content-Type: application/x-ns-proxy-autoconfig Content-Length: {0} Connection: Close ", System.Text.Encoding.UTF8.GetBytes(pac).Length) + pac; - byte[] response = System.Text.Encoding.UTF8.GetBytes(text); - conn.BeginSend(response, 0, response.Length, 0, new AsyncCallback(SendCallback), conn); - Util.Utils.ReleaseMemory(); - } - else - { - conn.Close(); - } + byte[] response = System.Text.Encoding.UTF8.GetBytes(text); + socket.BeginSend(response, 0, response.Length, 0, new AsyncCallback(SendCallback), socket); + Util.Utils.ReleaseMemory(); } catch (Exception e) { Console.WriteLine(e); - conn.Close(); + socket.Close(); } } @@ -213,23 +158,9 @@ Connection: Close } } - private string GetPACAddress(byte[] requestBuf, IPEndPoint localEndPoint) + private string GetPACAddress(byte[] requestBuf, int length, IPEndPoint localEndPoint) { - string proxy = "PROXY " + localEndPoint.Address + ":8123;"; - //try - //{ - // string requestString = Encoding.UTF8.GetString(requestBuf); - // if (requestString.IndexOf("AppleWebKit") >= 0) - // { - // string address = "" + localEndPoint.Address + ":" + config.GetCurrentServer().local_port; - // proxy = "SOCKS5 " + address + "; SOCKS " + address + ";"; - // } - //} - //catch (Exception e) - //{ - // Console.WriteLine(e); - //} - return proxy; + return "PROXY " + localEndPoint.Address + ":8123;"; } } } diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index e5049ee5..06f04f61 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -18,7 +18,7 @@ namespace Shadowsocks.Controller private Thread _ramThread; private Listener _listener; - private PACServer pacServer; + private PACServer _pacServer; private Configuration _config; private PolipoRunner polipoRunner; private GFWListUpdater gfwListUpdater; @@ -159,7 +159,7 @@ namespace Shadowsocks.Controller public void TouchPACFile() { - string pacFilename = pacServer.TouchPACFile(); + string pacFilename = _pacServer.TouchPACFile(); if (PACFileReadyToOpen != null) { PACFileReadyToOpen(this, new PathEventArgs() { Path = pacFilename }); @@ -191,10 +191,10 @@ namespace Shadowsocks.Controller { polipoRunner = new PolipoRunner(); } - if (pacServer == null) + if (_pacServer == null) { - pacServer = new PACServer(); - pacServer.PACFileChanged += pacServer_PACFileChanged; + _pacServer = new PACServer(); + _pacServer.PACFileChanged += pacServer_PACFileChanged; } if (gfwListUpdater == null) { @@ -203,8 +203,6 @@ namespace Shadowsocks.Controller gfwListUpdater.Error += pacServer_PACUpdateError; } - pacServer.Stop(); - if (_listener != null) { _listener.Stop(); @@ -222,9 +220,9 @@ namespace Shadowsocks.Controller Local local = new Local(_config); List services = new List(); services.Add(local); + services.Add(_pacServer); _listener = new Listener(services); _listener.Start(_config); - pacServer.Start(_config); } catch (Exception e) { From edde91c17dd010107177b4291bf00f3d6aa2ec5f Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 16:27:08 +0800 Subject: [PATCH 09/25] lint code --- shadowsocks-csharp/Controller/PACServer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/PACServer.cs b/shadowsocks-csharp/Controller/PACServer.cs index 6ffcb7fd..a4589e92 100755 --- a/shadowsocks-csharp/Controller/PACServer.cs +++ b/shadowsocks-csharp/Controller/PACServer.cs @@ -14,7 +14,6 @@ namespace Shadowsocks.Controller { class PACServer : Listener.Service { - private static int PORT = 8093; public static string PAC_FILE = "pac.txt"; FileSystemWatcher watcher; From 788d74cefd89db8a8dd0d490962b405dace1236e Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 16:44:09 +0800 Subject: [PATCH 10/25] add port forwarder --- shadowsocks-csharp/Controller/Listener.cs | 143 +++++++++++ shadowsocks-csharp/Controller/PortForwarder.cs | 265 +++++++++++++++++++++ .../Controller/ShadowsocksController.cs | 1 + shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + 4 files changed, 410 insertions(+) create mode 100755 shadowsocks-csharp/Controller/Listener.cs create mode 100755 shadowsocks-csharp/Controller/PortForwarder.cs diff --git a/shadowsocks-csharp/Controller/Listener.cs b/shadowsocks-csharp/Controller/Listener.cs new file mode 100755 index 00000000..923bc0e7 --- /dev/null +++ b/shadowsocks-csharp/Controller/Listener.cs @@ -0,0 +1,143 @@ +using Shadowsocks.Model; +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Text; + +namespace Shadowsocks.Controller +{ + public class Listener + { + public interface Service + { + bool Handle(byte[] firstPacket, int length, Socket socket); + } + + Configuration _config; + bool _shareOverLAN; + Socket _socket; + IList _services; + + public Listener(IList services) + { + this._services = services; + } + + public void Start(Configuration config) + { + this._config = config; + this._shareOverLAN = config.shareOverLan; + try + { + // Create a TCP/IP socket. + _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + IPEndPoint localEndPoint = null; + if (_shareOverLAN) + { + localEndPoint = new IPEndPoint(IPAddress.Any, _config.localPort); + } + else + { + localEndPoint = new IPEndPoint(IPAddress.Loopback, _config.localPort); + } + + // Bind the socket to the local endpoint and listen for incoming connections. + _socket.Bind(localEndPoint); + _socket.Listen(1024); + + + // Start an asynchronous socket to listen for connections. + Console.WriteLine("Shadowsocks started"); + _socket.BeginAccept( + new AsyncCallback(AcceptCallback), + _socket); + } + catch (SocketException) + { + _socket.Close(); + throw; + } + } + + public void Stop() + { + if (_socket != null) + { + _socket.Close(); + _socket = null; + } + } + + public void AcceptCallback(IAsyncResult ar) + { + Socket listener = (Socket)ar.AsyncState; + try + { + Socket conn = listener.EndAccept(ar); + + byte[] buf = new byte[4096]; + object[] state = new object[] { + conn, + buf + }; + + conn.BeginReceive(buf, 0, buf.Length, 0, + new AsyncCallback(ReceiveCallback), state); + } + catch (ObjectDisposedException) + { + } + catch (Exception e) + { + Console.WriteLine(e); + } + finally + { + try + { + listener.BeginAccept( + new AsyncCallback(AcceptCallback), + listener); + } + catch (ObjectDisposedException) + { + // do nothing + } + catch (Exception e) + { + Logging.LogUsefulException(e); + } + } + } + + + private void ReceiveCallback(IAsyncResult ar) + { + object[] state = (object[])ar.AsyncState; + + Socket conn = (Socket)state[0]; + byte[] buf = (byte[])state[1]; + try + { + int bytesRead = conn.EndReceive(ar); + foreach (Service service in _services) + { + if (service.Handle(buf, bytesRead, conn)) + { + return; + } + } + // no service found for this + // shouldn't happen + conn.Close(); + } + catch (Exception e) + { + Console.WriteLine(e); + conn.Close(); + } + } + } +} diff --git a/shadowsocks-csharp/Controller/PortForwarder.cs b/shadowsocks-csharp/Controller/PortForwarder.cs new file mode 100755 index 00000000..ce7d1048 --- /dev/null +++ b/shadowsocks-csharp/Controller/PortForwarder.cs @@ -0,0 +1,265 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Text; + +namespace Shadowsocks.Controller +{ + class PortForwarder : Listener.Service + { + int _targetPort; + + public PortForwarder(int targetPort) + { + this._targetPort = targetPort; + } + + public bool Handle(byte[] firstPacket, int length, Socket socket) + { + new Handler().Start(firstPacket, length, socket, this._targetPort); + return true; + } + + class Handler + { + private byte[] _firstPacket; + private int _firstPacketLength; + private Socket _local; + private Socket _remote; + private bool _closed = false; + private bool _localShutdown = false; + private bool _remoteShutdown = false; + public const int RecvSize = 16384; + // remote receive buffer + private byte[] remoteRecvBuffer = new byte[RecvSize]; + // connection receive buffer + private byte[] connetionRecvBuffer = new byte[RecvSize]; + + public void Start(byte[] firstPacket, int length, Socket socket, int targetPort) + { + this._firstPacket = firstPacket; + this._firstPacketLength = length; + this._local = socket; + try + { + // TODO async resolving + IPAddress ipAddress; + bool parsed = IPAddress.TryParse("127.0.0.1", out ipAddress); + IPEndPoint remoteEP = new IPEndPoint(ipAddress, targetPort); + + + _remote = new Socket(ipAddress.AddressFamily, + SocketType.Stream, ProtocolType.Tcp); + _remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); + + // Connect to the remote endpoint. + _remote.BeginConnect(remoteEP, + new AsyncCallback(ConnectCallback), null); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + this.Close(); + } + } + + private void ConnectCallback(IAsyncResult ar) + { + if (_closed) + { + return; + } + try + { + _remote.EndConnect(ar); + HandshakeReceive(); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + this.Close(); + } + } + + private void HandshakeReceive() + { + if (_closed) + { + return; + } + try + { + _remote.BeginSend(_firstPacket, 0, _firstPacketLength, 0, new AsyncCallback(StartPipe), null); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + this.Close(); + } + } + + + private void StartPipe(IAsyncResult ar) + { + if (_closed) + { + return; + } + try + { + _remote.EndSend(ar); + _remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, + new AsyncCallback(PipeRemoteReceiveCallback), null); + _local.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, + new AsyncCallback(PipeConnectionReceiveCallback), null); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + this.Close(); + } + } + + private void PipeRemoteReceiveCallback(IAsyncResult ar) + { + if (_closed) + { + return; + } + try + { + int bytesRead = _remote.EndReceive(ar); + + if (bytesRead > 0) + { + int bytesToSend; + _local.BeginSend(remoteRecvBuffer, 0, bytesRead, 0, new AsyncCallback(PipeConnectionSendCallback), null); + } + else + { + //Console.WriteLine("bytesRead: " + bytesRead.ToString()); + _local.Shutdown(SocketShutdown.Send); + _localShutdown = true; + CheckClose(); + } + } + catch (Exception e) + { + Logging.LogUsefulException(e); + this.Close(); + } + } + + private void PipeConnectionReceiveCallback(IAsyncResult ar) + { + if (_closed) + { + return; + } + try + { + int bytesRead = _local.EndReceive(ar); + + if (bytesRead > 0) + { + _remote.BeginSend(connetionRecvBuffer, 0, bytesRead, 0, new AsyncCallback(PipeRemoteSendCallback), null); + } + else + { + _remote.Shutdown(SocketShutdown.Send); + _remoteShutdown = true; + CheckClose(); + } + } + catch (Exception e) + { + Logging.LogUsefulException(e); + this.Close(); + } + } + + private void PipeRemoteSendCallback(IAsyncResult ar) + { + if (_closed) + { + return; + } + try + { + _remote.EndSend(ar); + _local.BeginReceive(this.connetionRecvBuffer, 0, RecvSize, 0, + new AsyncCallback(PipeConnectionReceiveCallback), null); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + this.Close(); + } + } + + private void PipeConnectionSendCallback(IAsyncResult ar) + { + if (_closed) + { + return; + } + try + { + _local.EndSend(ar); + _remote.BeginReceive(this.remoteRecvBuffer, 0, RecvSize, 0, + new AsyncCallback(PipeRemoteReceiveCallback), null); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + this.Close(); + } + } + + private void CheckClose() + { + if (_localShutdown && _remoteShutdown) + { + this.Close(); + } + } + + public void Close() + { + lock (this) + { + if (_closed) + { + return; + } + _closed = true; + } + if (_local != null) + { + try + { + _local.Shutdown(SocketShutdown.Both); + _local.Close(); + } + catch (Exception e) + { + Logging.LogUsefulException(e); + } + } + if (_remote != null) + { + try + { + _remote.Shutdown(SocketShutdown.Both); + _remote.Close(); + } + catch (SocketException e) + { + Logging.LogUsefulException(e); + } + } + } + } + } +} diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 06f04f61..fde74419 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -221,6 +221,7 @@ namespace Shadowsocks.Controller List services = new List(); services.Add(local); services.Add(_pacServer); + services.Add(new PortForwarder(8123)); _listener = new Listener(services); _listener.Start(_config); } diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index e22a9fbd..3d51fabb 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -129,6 +129,7 @@ + From 18e6daf47dd7f949da865ab38606dd39817dbdc8 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:01:37 +0800 Subject: [PATCH 11/25] update system proxy --- shadowsocks-csharp/Controller/PortForwarder.cs | 1 - .../Controller/ShadowsocksController.cs | 6 +-- shadowsocks-csharp/Controller/SystemProxy.cs | 49 ++++++++++------------ 3 files changed, 25 insertions(+), 31 deletions(-) diff --git a/shadowsocks-csharp/Controller/PortForwarder.cs b/shadowsocks-csharp/Controller/PortForwarder.cs index ce7d1048..1057143f 100755 --- a/shadowsocks-csharp/Controller/PortForwarder.cs +++ b/shadowsocks-csharp/Controller/PortForwarder.cs @@ -133,7 +133,6 @@ namespace Shadowsocks.Controller if (bytesRead > 0) { - int bytesToSend; _local.BeginSend(remoteRecvBuffer, 0, bytesRead, 0, new AsyncCallback(PipeConnectionSendCallback), null); } else diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index fde74419..4ec92381 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -153,7 +153,7 @@ namespace Shadowsocks.Controller } if (_config.enabled) { - SystemProxy.Disable(); + SystemProxy.Update(_config, true); } } @@ -262,7 +262,7 @@ namespace Shadowsocks.Controller { if (_config.enabled) { - SystemProxy.Enable(_config.global); + SystemProxy.Update(_config, false); _systemProxyIsDirty = true; } else @@ -270,7 +270,7 @@ namespace Shadowsocks.Controller // only switch it off if we have switched it on if (_systemProxyIsDirty) { - SystemProxy.Disable(); + SystemProxy.Update(_config, false); _systemProxyIsDirty = false; } } diff --git a/shadowsocks-csharp/Controller/SystemProxy.cs b/shadowsocks-csharp/Controller/SystemProxy.cs index c8cc6f8d..dfbc4bc1 100755 --- a/shadowsocks-csharp/Controller/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/SystemProxy.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.IO; +using Shadowsocks.Model; namespace Shadowsocks.Controller { @@ -25,24 +26,39 @@ namespace Shadowsocks.Controller _refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0); } - public static void Enable(bool global) + public static void Update(Configuration config, bool forceDisable) { + bool global = config.global; + bool enabled = config.enabled; + if (forceDisable) + { + enabled = false; + } try { RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true); - if (global) + if (enabled) { - registry.SetValue("ProxyEnable", 1); - registry.SetValue("ProxyServer", "127.0.0.1:8123"); - registry.SetValue("AutoConfigURL", ""); + if (global) + { + registry.SetValue("ProxyEnable", 1); + registry.SetValue("ProxyServer", "127.0.0.1:" + config.localPort.ToString()); + registry.SetValue("AutoConfigURL", ""); + } + else + { + registry.SetValue("ProxyEnable", 0); + registry.SetValue("ProxyServer", ""); + registry.SetValue("AutoConfigURL", "http://127.0.0.1:" + config.localPort.ToString() + "/pac?t=" + GetTimestamp(DateTime.Now)); + } } else { registry.SetValue("ProxyEnable", 0); registry.SetValue("ProxyServer", ""); - registry.SetValue("AutoConfigURL", "http://127.0.0.1:8093/pac?t=" + GetTimestamp(DateTime.Now)); + registry.SetValue("AutoConfigURL", ""); } SystemProxy.NotifyIE(); //Must Notify IE first, or the connections do not chanage @@ -56,27 +72,6 @@ namespace Shadowsocks.Controller } } - public static void Disable() - { - try - { - RegistryKey registry = - Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", - true); - registry.SetValue("ProxyEnable", 0); - registry.SetValue("ProxyServer", ""); - registry.SetValue("AutoConfigURL", ""); - SystemProxy.NotifyIE(); - CopyProxySettingFromLan(); - } - catch (Exception e) - { - Logging.LogUsefulException(e); - // TODO this should be moved into views - MessageBox.Show(I18N.GetString("Failed to update registry")); - } - } - private static void CopyProxySettingFromLan() { RegistryKey registry = From 65f0257e6da04d24b056a12e3a76e10ff830981e Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:02:28 +0800 Subject: [PATCH 12/25] bump --- shadowsocks-csharp/Controller/UpdateChecker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/UpdateChecker.cs b/shadowsocks-csharp/Controller/UpdateChecker.cs index 870db9d5..a6f5b154 100755 --- a/shadowsocks-csharp/Controller/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/UpdateChecker.cs @@ -17,7 +17,7 @@ namespace Shadowsocks.Controller public string LatestVersionURL; public event EventHandler NewVersionFound; - public const string Version = "2.2.1"; + public const string Version = "2.3"; public void CheckUpdate() { From 43a952d3d7ae5c2274c0e8aaa32cc04b47e37b9e Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:03:38 +0800 Subject: [PATCH 13/25] update readme --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7b05714a..6d1c41ad 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,10 @@ For >= Windows 8, download Shadowsocks-win-dotnet4.0-x.x.x.zip, unless you have 1. Find Shadowsocks icon in notification tray 2. You can add multiple servers in servers menu -3. Select Enable menu to enable system proxy -4. Leave Enable menu unchecked, Shadowsocks will still provide an HTTP proxy at 127.0.0.1:8123 -5. After you saved PAC file with any editor, Shadowsocks will notify browsers +3. Select Enable System Proxy menu to enable system proxy +4. After you saved PAC file with any editor, Shadowsocks will notify browsers about the change automatically -6. Please disable other proxy addons in your browser, or set them to use +5. Please disable other proxy addons in your browser, or set them to use system proxy ### Develop From 5aa28229048d83c51dd83b33a9d94a3cc3f2784c Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:12:59 +0800 Subject: [PATCH 14/25] use local port in pac --- shadowsocks-csharp/Controller/PACServer.cs | 8 +++++++- shadowsocks-csharp/Controller/ShadowsocksController.cs | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/PACServer.cs b/shadowsocks-csharp/Controller/PACServer.cs index a4589e92..3f84f933 100755 --- a/shadowsocks-csharp/Controller/PACServer.cs +++ b/shadowsocks-csharp/Controller/PACServer.cs @@ -17,6 +17,7 @@ namespace Shadowsocks.Controller public static string PAC_FILE = "pac.txt"; FileSystemWatcher watcher; + private Configuration _config; public event EventHandler PACFileChanged; @@ -25,6 +26,11 @@ namespace Shadowsocks.Controller this.WatchPacFile(); } + public void UpdateConfiguration(Configuration config) + { + this._config = config; + } + public bool Handle(byte[] firstPacket, int length, Socket socket) { try @@ -159,7 +165,7 @@ Connection: Close private string GetPACAddress(byte[] requestBuf, int length, IPEndPoint localEndPoint) { - return "PROXY " + localEndPoint.Address + ":8123;"; + return "PROXY " + localEndPoint.Address + ":" + this._config.localPort + ";"; } } } diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 4ec92381..16231025 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -196,6 +196,7 @@ namespace Shadowsocks.Controller _pacServer = new PACServer(); _pacServer.PACFileChanged += pacServer_PACFileChanged; } + _pacServer.UpdateConfiguration(_config); if (gfwListUpdater == null) { gfwListUpdater = new GFWListUpdater(); From 3e56b3d3a488cbd392e182b8ef55e87f2b0f814f Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:15:06 +0800 Subject: [PATCH 15/25] use local port in update checker --- shadowsocks-csharp/Controller/UpdateChecker.cs | 7 ++++--- shadowsocks-csharp/View/MenuViewController.cs | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/shadowsocks-csharp/Controller/UpdateChecker.cs b/shadowsocks-csharp/Controller/UpdateChecker.cs index a6f5b154..3cad242a 100755 --- a/shadowsocks-csharp/Controller/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/UpdateChecker.cs @@ -1,4 +1,5 @@ -using System; +using Shadowsocks.Model; +using System; using System.Collections; using System.Collections.Generic; using System.Net; @@ -19,11 +20,11 @@ namespace Shadowsocks.Controller public const string Version = "2.3"; - public void CheckUpdate() + public void CheckUpdate(Configuration config) { // TODO test failures WebClient http = new WebClient(); - http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), 8123); + http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort); http.DownloadStringCompleted += http_DownloadStringCompleted; http.DownloadStringAsync(new Uri(UpdateURL)); } diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index b7b6ae36..6d00bd07 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -63,7 +63,7 @@ namespace Shadowsocks.View LoadCurrentConfiguration(); - updateChecker.CheckUpdate(); + updateChecker.CheckUpdate(controller.GetConfiguration()); if (controller.GetConfiguration().isDefault) { From 8c8c947356f2e5a19b6193f471e0b3334adb4c29 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:16:01 +0800 Subject: [PATCH 16/25] use local port in gfwlist updater --- shadowsocks-csharp/Controller/GfwListUpdater.cs | 5 +++-- shadowsocks-csharp/Controller/ShadowsocksController.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/shadowsocks-csharp/Controller/GfwListUpdater.cs b/shadowsocks-csharp/Controller/GfwListUpdater.cs index 7abe9445..77be9c03 100644 --- a/shadowsocks-csharp/Controller/GfwListUpdater.cs +++ b/shadowsocks-csharp/Controller/GfwListUpdater.cs @@ -6,6 +6,7 @@ using System.IO; using Shadowsocks.Properties; using SimpleJson; using Shadowsocks.Util; +using Shadowsocks.Model; namespace Shadowsocks.Controller { @@ -42,10 +43,10 @@ namespace Shadowsocks.Controller } } - public void UpdatePACFromGFWList() + public void UpdatePACFromGFWList(Configuration config) { WebClient http = new WebClient(); - http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), 8123); + http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort); http.DownloadStringCompleted += http_DownloadStringCompleted; http.DownloadStringAsync(new Uri(GFWLIST_URL)); } diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 16231025..a313d424 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -178,7 +178,7 @@ namespace Shadowsocks.Controller { if (gfwListUpdater != null) { - gfwListUpdater.UpdatePACFromGFWList(); + gfwListUpdater.UpdatePACFromGFWList(_config); } } From 5463b2859a24527f8bb4c4bb26e9ecfd5aceae66 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:30:42 +0800 Subject: [PATCH 17/25] no hard code 8123 --- shadowsocks-csharp/Controller/PolipoRunner.cs | 23 ++++++++++++++++++++++ .../Controller/ShadowsocksController.cs | 2 +- shadowsocks-csharp/Data/polipo_config.txt | 3 ++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/shadowsocks-csharp/Controller/PolipoRunner.cs b/shadowsocks-csharp/Controller/PolipoRunner.cs index 1b91783b..d24ad367 100755 --- a/shadowsocks-csharp/Controller/PolipoRunner.cs +++ b/shadowsocks-csharp/Controller/PolipoRunner.cs @@ -6,6 +6,8 @@ using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Text; +using System.Net.NetworkInformation; +using System.Net; namespace Shadowsocks.Controller { @@ -47,6 +49,7 @@ namespace Shadowsocks.Controller } string polipoConfig = Resources.polipo_config; polipoConfig = polipoConfig.Replace("__SOCKS_PORT__", configuration.localPort.ToString()); + polipoConfig = polipoConfig.Replace("__POLIPO_BIND_PORT__", this.GetFreePort().ToString()); polipoConfig = polipoConfig.Replace("__POLIPO_BIND_IP__", configuration.shareOverLan ? "0.0.0.0" : "127.0.0.1"); FileManager.ByteArrayToFile(temppath + "/polipo.conf", System.Text.Encoding.UTF8.GetBytes(polipoConfig)); @@ -79,5 +82,25 @@ namespace Shadowsocks.Controller _process = null; } } + + private int GetFreePort() + { + IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties(); + IPEndPoint[] tcpEndPoints = properties.GetActiveTcpListeners(); + + List usedPorts = new List(); + foreach (IPEndPoint endPoint in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners()) + { + usedPorts.Add(endPoint.Port); + } + for (int port = 8123; port < 65535; port++) + { + if (!usedPorts.Contains(port)) + { + return port; + } + } + throw new Exception("No free port found."); + } } } diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index a313d424..2c0ace5c 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -222,7 +222,7 @@ namespace Shadowsocks.Controller List services = new List(); services.Add(local); services.Add(_pacServer); - services.Add(new PortForwarder(8123)); + services.Add(new PortForwarder(_config.localPort)); _listener = new Listener(services); _listener.Start(_config); } diff --git a/shadowsocks-csharp/Data/polipo_config.txt b/shadowsocks-csharp/Data/polipo_config.txt index 5a18557f..fabeab66 100755 --- a/shadowsocks-csharp/Data/polipo_config.txt +++ b/shadowsocks-csharp/Data/polipo_config.txt @@ -1,4 +1,5 @@ -proxyAddress = "__POLIPO_BIND_IP__" +proxyAddress = "__POLIPO_BIND_IP__" +proxyPort = 8123 socksParentProxy = "127.0.0.1:__SOCKS_PORT__" socksProxyType = socks5 From b2b11bb97b801680cf6673aaf11f968034614409 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:37:52 +0800 Subject: [PATCH 18/25] add fallback for access denied --- shadowsocks-csharp/Controller/PolipoRunner.cs | 32 ++++++++++++++++++--------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/shadowsocks-csharp/Controller/PolipoRunner.cs b/shadowsocks-csharp/Controller/PolipoRunner.cs index d24ad367..de63dd42 100755 --- a/shadowsocks-csharp/Controller/PolipoRunner.cs +++ b/shadowsocks-csharp/Controller/PolipoRunner.cs @@ -85,21 +85,31 @@ namespace Shadowsocks.Controller private int GetFreePort() { - IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties(); - IPEndPoint[] tcpEndPoints = properties.GetActiveTcpListeners(); - - List usedPorts = new List(); - foreach (IPEndPoint endPoint in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners()) - { - usedPorts.Add(endPoint.Port); - } - for (int port = 8123; port < 65535; port++) + int defaultPort = 8123; + try { - if (!usedPorts.Contains(port)) + IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties(); + IPEndPoint[] tcpEndPoints = properties.GetActiveTcpListeners(); + + List usedPorts = new List(); + foreach (IPEndPoint endPoint in IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners()) + { + usedPorts.Add(endPoint.Port); + } + for (int port = defaultPort; port < 65535; port++) { - return port; + if (!usedPorts.Contains(port)) + { + return port; + } } } + catch (Exception e) + { + // in case access denied + Logging.LogUsefulException(e); + return defaultPort; + } throw new Exception("No free port found."); } } From 3a34bad62f2571f1bacd09ed5025e694ae91cf91 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:38:27 +0800 Subject: [PATCH 19/25] fix port range --- shadowsocks-csharp/Controller/PolipoRunner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shadowsocks-csharp/Controller/PolipoRunner.cs b/shadowsocks-csharp/Controller/PolipoRunner.cs index de63dd42..d5cc2792 100755 --- a/shadowsocks-csharp/Controller/PolipoRunner.cs +++ b/shadowsocks-csharp/Controller/PolipoRunner.cs @@ -96,7 +96,7 @@ namespace Shadowsocks.Controller { usedPorts.Add(endPoint.Port); } - for (int port = defaultPort; port < 65535; port++) + for (int port = defaultPort; port <= 65535; port++) { if (!usedPorts.Contains(port)) { From 1a0f4807c23416ed8753310c803929c14bd861ac Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 17:56:43 +0800 Subject: [PATCH 20/25] use polipo port in port forwarder --- shadowsocks-csharp/Controller/PACServer.cs | 32 ++++++++++++++++++---- shadowsocks-csharp/Controller/PolipoRunner.cs | 12 +++++++- .../Controller/ShadowsocksController.cs | 2 +- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/shadowsocks-csharp/Controller/PACServer.cs b/shadowsocks-csharp/Controller/PACServer.cs index 3f84f933..b0ccf4d3 100755 --- a/shadowsocks-csharp/Controller/PACServer.cs +++ b/shadowsocks-csharp/Controller/PACServer.cs @@ -37,7 +37,7 @@ namespace Shadowsocks.Controller { string request = Encoding.UTF8.GetString(firstPacket, 0, length); string[] lines = request.Split('\r', '\n'); - bool hostMatch = false, pathMatch = false; + bool hostMatch = false, pathMatch = false, useSocks = false; foreach (string line in lines) { string[] kv = line.Split(new char[]{':'}, 2); @@ -50,6 +50,13 @@ namespace Shadowsocks.Controller hostMatch = true; } } + else if (kv[0] == "User-Agent") + { + if (kv[1].IndexOf("Chrome") >= 0) + { + useSocks = true; + } + } } else if (kv.Length == 1) { @@ -61,7 +68,7 @@ namespace Shadowsocks.Controller } if (hostMatch && pathMatch) { - SendResponse(firstPacket, length, socket); + SendResponse(firstPacket, length, socket, useSocks); return true; } return false; @@ -98,7 +105,7 @@ namespace Shadowsocks.Controller } } - public void SendResponse(byte[] firstPacket, int length, Socket socket) + public void SendResponse(byte[] firstPacket, int length, Socket socket, bool useSocks) { try { @@ -106,7 +113,7 @@ namespace Shadowsocks.Controller IPEndPoint localEndPoint = (IPEndPoint)socket.LocalEndPoint; - string proxy = GetPACAddress(firstPacket, length, localEndPoint); + string proxy = GetPACAddress(firstPacket, length, localEndPoint, useSocks); pac = pac.Replace("__PROXY__", proxy); @@ -163,9 +170,22 @@ Connection: Close } } - private string GetPACAddress(byte[] requestBuf, int length, IPEndPoint localEndPoint) + private string GetPACAddress(byte[] requestBuf, int length, IPEndPoint localEndPoint, bool useSocks) { - return "PROXY " + localEndPoint.Address + ":" + this._config.localPort + ";"; + //try + //{ + // string requestString = Encoding.UTF8.GetString(requestBuf); + // if (requestString.IndexOf("AppleWebKit") >= 0) + // { + // string address = "" + localEndPoint.Address + ":" + config.GetCurrentServer().local_port; + // proxy = "SOCKS5 " + address + "; SOCKS " + address + ";"; + // } + //} + //catch (Exception e) + //{ + // Console.WriteLine(e); + //} + return (useSocks ? "SOCKS5 " : "PROXY ") + localEndPoint.Address + ":" + this._config.localPort + ";"; } } } diff --git a/shadowsocks-csharp/Controller/PolipoRunner.cs b/shadowsocks-csharp/Controller/PolipoRunner.cs index d5cc2792..ae0b46f1 100755 --- a/shadowsocks-csharp/Controller/PolipoRunner.cs +++ b/shadowsocks-csharp/Controller/PolipoRunner.cs @@ -15,6 +15,7 @@ namespace Shadowsocks.Controller { private Process _process; private static string temppath; + private int _runningPort; static PolipoRunner() { @@ -29,6 +30,14 @@ namespace Shadowsocks.Controller } } + public int RunningPort + { + get + { + return _runningPort; + } + } + public void Start(Configuration configuration) { Server server = configuration.GetCurrentServer(); @@ -48,8 +57,9 @@ namespace Shadowsocks.Controller } } string polipoConfig = Resources.polipo_config; + _runningPort = this.GetFreePort(); polipoConfig = polipoConfig.Replace("__SOCKS_PORT__", configuration.localPort.ToString()); - polipoConfig = polipoConfig.Replace("__POLIPO_BIND_PORT__", this.GetFreePort().ToString()); + polipoConfig = polipoConfig.Replace("__POLIPO_BIND_PORT__", _runningPort.ToString()); polipoConfig = polipoConfig.Replace("__POLIPO_BIND_IP__", configuration.shareOverLan ? "0.0.0.0" : "127.0.0.1"); FileManager.ByteArrayToFile(temppath + "/polipo.conf", System.Text.Encoding.UTF8.GetBytes(polipoConfig)); diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 2c0ace5c..4e343c96 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -222,7 +222,7 @@ namespace Shadowsocks.Controller List services = new List(); services.Add(local); services.Add(_pacServer); - services.Add(new PortForwarder(_config.localPort)); + services.Add(new PortForwarder(polipoRunner.RunningPort)); _listener = new Listener(services); _listener.Start(_config); } From 24e5235d595b07abf4b57543ffa58287906b5cf1 Mon Sep 17 00:00:00 2001 From: Jenkins CI Bot Date: Sun, 18 Jan 2015 18:54:36 +0800 Subject: [PATCH 21/25] Update CONTRIBUTING.md --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ace27628..520eb59f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,6 +20,7 @@ a pull request, or ask some of your friends to do so. 3. We don't answer questions of any other types here. Since very few people are watching the issue tracker here, you'll probably get no help from here. Read [Troubleshooting] and get help from forums or [mailing lists]. +4. Issues in languages other than English will be Google translated into English. [Troubleshooting]: https://github.com/clowwindy/shadowsocks/wiki/Troubleshooting From 25386c2f8c838b509e4a9ede02dbce41eaa53a92 Mon Sep 17 00:00:00 2001 From: Jenkins CI Bot Date: Sun, 18 Jan 2015 19:02:42 +0800 Subject: [PATCH 22/25] Update CONTRIBUTING.md --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 520eb59f..c88855b2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,8 @@ a pull request, or ask some of your friends to do so. 3. We don't answer questions of any other types here. Since very few people are watching the issue tracker here, you'll probably get no help from here. Read [Troubleshooting] and get help from forums or [mailing lists]. -4. Issues in languages other than English will be Google translated into English. +4. Issues in languages other than English will be Google translated into English +later. [Troubleshooting]: https://github.com/clowwindy/shadowsocks/wiki/Troubleshooting From fe991db6da72edc887d2a1e110f931d619529046 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Sun, 18 Jan 2015 20:29:22 +0800 Subject: [PATCH 23/25] filter prerelase version --- shadowsocks-csharp/Controller/UpdateChecker.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shadowsocks-csharp/Controller/UpdateChecker.cs b/shadowsocks-csharp/Controller/UpdateChecker.cs index 3cad242a..00aab2a0 100755 --- a/shadowsocks-csharp/Controller/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/UpdateChecker.cs @@ -75,6 +75,10 @@ namespace Shadowsocks.Controller private bool IsNewVersion(string url) { + if (url.IndexOf("prerelease") >= 0) + { + return false; + } // check dotnet 4.0 AssemblyName[] references = Assembly.GetExecutingAssembly().GetReferencedAssemblies(); Version dotNetVersion = Environment.Version; From b57edeb082a5ee63eaff1df3513fe751f96d232b Mon Sep 17 00:00:00 2001 From: Gang Zhuo Date: Mon, 19 Jan 2015 05:34:01 -0500 Subject: [PATCH 24/25] fix https://github.com/shadowsocks/shadowsocks-csharp/issues/137 --- shadowsocks-csharp/Data/abp.js.gz | Bin 4461 -> 4644 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/shadowsocks-csharp/Data/abp.js.gz b/shadowsocks-csharp/Data/abp.js.gz index e049c0a42c42adc3f42601e8535f3c48f93daf99..89ce8339a4f7cf961278c93dbe9a4ab6a5cbb8ba 100755 GIT binary patch literal 4644 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 aIsQG_z4n`7KEi~;82w-2h^CcpSO5SD1qnX@ literal 4461 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 From ce53273f3321fcf04d86e633510a0102943419f1 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 19 Jan 2015 23:13:22 +0800 Subject: [PATCH 25/25] gzip more --- shadowsocks-csharp/Data/abp.js.gz | Bin 4644 -> 4467 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/shadowsocks-csharp/Data/abp.js.gz b/shadowsocks-csharp/Data/abp.js.gz index 89ce8339a4f7cf961278c93dbe9a4ab6a5cbb8ba..0577c7f5c14d22f0a4f0c744f3284da191c04cf1 100755 GIT binary patch literal 4467 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 F007W`%bNfI literal 4644 zcmV+<65H(`iwFpL+`Lo(17TutE^2cC?L2E!8q2odQ*3U~gK%wZ^^xtOv5)(9fYGftz^`9bt7sI4<6x^=y|%;Ab!Yj2z`LKJ9aQM`&RVB`e(&`P+hWY0I5>c@Uaxg=+&J&`=ty<>^{Zvn z9@zmJ+73qWKDPW2c|%kmTsdC<2Aw&R0DU5?04ElEIEH5x&%dsIE))2DZ#?tu>rse` z`z5qit8KhntF5l1#teJt>+RJMOd|6Xl!T;@F$%n4IJJDdg=XFa^(`0qcmNCY?W;)$ z9EHeo2UX7}VzGxaf(M>W+yVAcIKn8z{%t@QCSSgOyWk>r(Anh5vHR%Q?qe6EdWZeM z_FVKHSph*ZCd0vqX@bBW5^l~pH|Wp<5>^Nhl@#t{CI>`&1jWc314AP#BrHyC$3a&Z zO#(ceI8;zD8U4|0ADv#bQT^L@^hdqbs()*L--gNI$b(UQhZ!pScI?=I8JO`cH=Mx= z35JtKYySv9>U+)OX8St=xg0jz-x}xV=gcTAYB%>Uj_WOScF{UJJ#SPHI>&@9 zOc2bG(2xol);_?YWjldb_;=7t0NgnPG_vk6=%1l71_i0Z58e@{`wdxMm4TO+kv23 z48h1^0}5e}sE|j1pS*2LkAV;75dcl}*STZ{%MdA27uW#97B%fMd!V3DMndl#!mN9} zC7DHl_^Ks*PQ9=C{OKG>byH)ITr`>m#D-Ye}QW3s)#RK@NXy*-P!Jx<<`E#ZD--aT zXk!Z9H^nF5lu-_S@3ze>B2tZNG{nTI&Dg@K6eXnU(J;3|@MsZ|1$v=uL9EgrS$;h% z)=Fpxa-pSykqnOj``+y>c0<|ZbHpnK&t$0y!-T`M96&)WmH2DChG-k2d(gJxmQDB0 za_oV`Dv6C&AcuKQsc$(>kvKyc$?Q<~U?7w#`M^At?y+y7c83)?47^**c7ufk!C=n4iQlIi7DJ)%BvVR=Lxxu(79YTnNn5aE zC}Z}u3mI11hx`g++JOgA5H=QEPNHlE7h~88_N@T04=pf5J_(YM1IFvzkjM)H;_IpD z3zJNNFTEh|g2bB$c>4auZIw)t;2u>DIBGT7io8`B$EIPqFY7jsCGS45J1$f*(XGH69GCy?$C@P%1|v^%ujgfcVeQbjPO%@G@4 zrJ5@w+$jf>oYWli5HDTAByBf=iM-=EoFMPND625`b+D>Ifr|WFyi^6ZNNK&WyPlm534Q{QPr9gq28|!P8Qb>4 z1G6Buf>u)$W0F8@IFAXZb!PJ%*X*yc6%*G?I*IJCiupd*AOF@y9;IA^To!Dwe$8yz zUICGiBV3ZWpaGI^+B`A;Bs0mMfg%P8D+cR{70j^8Fz=FR-hsL0c0N)}MH401nyo1(=Z7XAHMqDkVO)w!Orpv+14G9LsdvDCxR74^tR_!jvzg8;i zn%RYzg0@h>Rw4`Ub#Zd+Lypd#1QrQZ{wldn)FqOgri|2{k)c-pWlke*_`0v9W`S_s$ z|80=(oAmqU;pM}dl8pTapno9$D3^eL+9kd8t!}rvQrumFw-TWX)2f#%-EO6{n}ANP zugh2cMwwgeR=Ue2wy(yI+0*29o92Q6kM7U)EJ^vQ$8qzNV(}JQTV3B=|M-4meUpzy zgw=j$946HhBRTZxPH-L-PcP#JBCh@tM-ZVty+^97HJzM}TdkZn717Tq zLJc{Z$hnlWqxkr?P@`Rk!f%AVf<7<%z>U}wy<7pwy4t=WBc5+xw-ZOW(YaZawSM_h zpxbyYDP0M(+_g4DYMWd5Dy zObn4HQnN^eD251atdAXI$3O%7ypyMMAXwofxHL6XT3bNXVFI{T)>e>liln27_V#yV zSMM3u%3*A^j;oN!a$=3Mm#vpsJ4)@50Zd-1Z`blQTxFn#9V6=a~o zUr(l&(IH7AcyM}BZ+@dTL!{;nc~BsyuH^FR(01`)q0?6izc?f9qh{-%N3L~#&p}RY zFg#7v&!G53Veg+FAJ@-vsaD#zpSZlI5qsjw&YSJV?~U)zw<9Ub$!SQLD8&U+r~}oz zMIujxjpo9ox0b|qMB14=c!b`uH;qn!GFy;RD{3i9B1vD>5JO2PRf%K95M4Pq-M=_# zd~5RqERj3`u*h1X+(1k%u%jvhumpwngSh6lRb?dtP1npd#r#;WiT4??T@qcMSRP41 z&9p;*W?Y33eP&fdtYVK(PM8I2*FLEiT#lS7n&~Gw{UU`m_cp z8XCnp+z3l`(4$_}aYe?LV^7;hjaJ+TJl}6M&)QpPjel>R)W0^i(7G6Ie?M-VA2k{< zfUY?~BGc z;itB)((3`0Xmq{yFG2jEeGp?gX&f}`gtPY_1$ERHBVgeB72>;OffDNNtI8mIY+m4N~2sf5G|F ze?)4rShN)xDMew{tmYMB1g{WnC{gNDdxS|?|3%#{DIOIyl|X4)|gP zPg*}n_??^^Lc;dsFjrsW2yTdunY$=zay_luVTaadQ{BrRk z<|f}M{xnzH1MJ`s=SH4azwA;bYur(0L~5Q?wcy!apkYT*lICb1Gq|$3IcK_Goxfv~ zXCOpCXYC2E=>8Gf#mtegxY)PG-TSian8 z&uFM?Ov&AJ1MR2u$Mw5V(xCEA}vpDBMiYmL<~zahF{+N!A}7w)GN48KGY5d$wSha8w+s-k&8 zc^FuEamg%1BmVi_x#LZ93nywr(d0i zaShRgEYf!^=l^SozS$sDPAT(6T3*M-w2S1}XK*w}D9j^50<8 z)}1u)WZ;ulSyQA<%PyvJjdMeCxue&tda3vy&OJ?tsi4qK(t8p(S5~$Y#-sLsS;$o`aLC+&E2qXObZ#>F0V#AT=O9_U0m!>3Z aIsQG_z4n`7KEi~;82w-2h^CcpSO5SD1qnX@