Resolving domain name through socks5 proxy and dual-mode sockettags/3.3
@@ -1,6 +1,7 @@ | |||||
using System; | using System; | ||||
using System.Net; | using System.Net; | ||||
using System.Net.Sockets; | using System.Net.Sockets; | ||||
using Shadowsocks.Util; | |||||
namespace Shadowsocks.Controller | namespace Shadowsocks.Controller | ||||
{ | { | ||||
@@ -45,14 +46,9 @@ namespace Shadowsocks.Controller | |||||
this._local = socket; | this._local = socket; | ||||
try | try | ||||
{ | { | ||||
// TODO async resolving | |||||
IPAddress ipAddress; | |||||
bool parsed = IPAddress.TryParse("127.0.0.1", out ipAddress); | |||||
IPEndPoint remoteEP = new IPEndPoint(ipAddress, targetPort); | |||||
EndPoint remoteEP = SocketUtil.GetEndPoint("localhost", targetPort); | |||||
_remote = new Socket(ipAddress.AddressFamily, | |||||
SocketType.Stream, ProtocolType.Tcp); | |||||
_remote = SocketUtil.CreateSocket(remoteEP); | |||||
_remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | _remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | ||||
// Connect to the remote endpoint. | // Connect to the remote endpoint. | ||||
@@ -9,6 +9,7 @@ using Shadowsocks.Controller.Strategy; | |||||
using Shadowsocks.Encryption; | using Shadowsocks.Encryption; | ||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
using Shadowsocks.Proxy; | using Shadowsocks.Proxy; | ||||
using Shadowsocks.Util; | |||||
namespace Shadowsocks.Controller | namespace Shadowsocks.Controller | ||||
{ | { | ||||
@@ -302,7 +303,6 @@ namespace Shadowsocks.Controller | |||||
if (ar.AsyncState != null) | if (ar.AsyncState != null) | ||||
{ | { | ||||
connection.EndSend(ar); | connection.EndSend(ar); | ||||
Logging.Debug(remote.LocalEndPoint, remote.DestEndPoint, RecvSize, "TCP Relay"); | |||||
connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null); | connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null); | ||||
} | } | ||||
else | else | ||||
@@ -310,7 +310,6 @@ namespace Shadowsocks.Controller | |||||
int bytesRead = connection.EndReceive(ar); | int bytesRead = connection.EndReceive(ar); | ||||
if (bytesRead > 0) | if (bytesRead > 0) | ||||
{ | { | ||||
Logging.Debug(remote.LocalEndPoint, remote.DestEndPoint, RecvSize, "TCP Relay"); | |||||
connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null); | connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null); | ||||
} | } | ||||
else | else | ||||
@@ -341,6 +340,7 @@ namespace Shadowsocks.Controller | |||||
// inner class | // inner class | ||||
private class ProxyTimer : Timer | private class ProxyTimer : Timer | ||||
{ | { | ||||
public IProxy Proxy; | |||||
public EndPoint DestEndPoint; | public EndPoint DestEndPoint; | ||||
public Server Server; | public Server Server; | ||||
@@ -361,34 +361,17 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
CreateRemote(); | CreateRemote(); | ||||
// TODO async resolving | |||||
IPAddress ipAddress; | |||||
bool parsed = IPAddress.TryParse(server.server, out ipAddress); | |||||
if (!parsed) | |||||
{ | |||||
IPHostEntry ipHostInfo = Dns.GetHostEntry(server.server); | |||||
ipAddress = ipHostInfo.AddressList[0]; | |||||
} | |||||
IPEndPoint destEP = new IPEndPoint(ipAddress, server.server_port); | |||||
// Setting up proxy | // Setting up proxy | ||||
IPEndPoint proxyEP; | |||||
EndPoint proxyEP; | |||||
if (_config.useProxy) | if (_config.useProxy) | ||||
{ | { | ||||
parsed = IPAddress.TryParse(_config.proxyServer, out ipAddress); | |||||
if (!parsed) | |||||
{ | |||||
IPHostEntry ipHostInfo = Dns.GetHostEntry(_config.proxyServer); | |||||
ipAddress = ipHostInfo.AddressList[0]; | |||||
} | |||||
remote = new Socks5Proxy(); | remote = new Socks5Proxy(); | ||||
proxyEP = new IPEndPoint(ipAddress, _config.proxyPort); | |||||
proxyEP = SocketUtil.GetEndPoint(_config.proxyServer, _config.proxyPort); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
remote = new DirectConnect(); | remote = new DirectConnect(); | ||||
proxyEP = destEP; | |||||
proxyEP = null; | |||||
} | } | ||||
@@ -396,7 +379,9 @@ namespace Shadowsocks.Controller | |||||
proxyTimer.AutoReset = false; | proxyTimer.AutoReset = false; | ||||
proxyTimer.Elapsed += proxyConnectTimer_Elapsed; | proxyTimer.Elapsed += proxyConnectTimer_Elapsed; | ||||
proxyTimer.Enabled = true; | proxyTimer.Enabled = true; | ||||
proxyTimer.DestEndPoint = destEP; | |||||
proxyTimer.Proxy = remote; | |||||
proxyTimer.DestEndPoint = SocketUtil.GetEndPoint(server.server, server.server_port); | |||||
proxyTimer.Server = server; | proxyTimer.Server = server; | ||||
_proxyConnected = false; | _proxyConnected = false; | ||||
@@ -417,9 +402,9 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
return; | return; | ||||
} | } | ||||
var ep = ((ProxyTimer)sender).DestEndPoint; | |||||
var proxy = ((ProxyTimer)sender).Proxy; | |||||
Logging.Info($"Proxy {ep} timed out"); | |||||
Logging.Info($"Proxy {proxy.ProxyEndPoint} timed out"); | |||||
remote?.Close(); | remote?.Close(); | ||||
RetryConnect(); | RetryConnect(); | ||||
} | } | ||||
@@ -434,7 +419,7 @@ namespace Shadowsocks.Controller | |||||
try | try | ||||
{ | { | ||||
ProxyTimer timer = (ProxyTimer)ar.AsyncState; | ProxyTimer timer = (ProxyTimer)ar.AsyncState; | ||||
var destEP = timer.DestEndPoint; | |||||
var destEndPoint = timer.DestEndPoint; | |||||
server = timer.Server; | server = timer.Server; | ||||
timer.Elapsed -= proxyConnectTimer_Elapsed; | timer.Elapsed -= proxyConnectTimer_Elapsed; | ||||
timer.Enabled = false; | timer.Enabled = false; | ||||
@@ -462,7 +447,7 @@ namespace Shadowsocks.Controller | |||||
_destConnected = false; | _destConnected = false; | ||||
// Connect to the remote endpoint. | // Connect to the remote endpoint. | ||||
remote.BeginConnectDest(destEP, new AsyncCallback(ConnectCallback), connectTimer); | |||||
remote.BeginConnectDest(destEndPoint, new AsyncCallback(ConnectCallback), connectTimer); | |||||
} | } | ||||
catch (ArgumentException) | catch (ArgumentException) | ||||
{ | { | ||||
@@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; | |||||
using Shadowsocks.Controller.Strategy; | using Shadowsocks.Controller.Strategy; | ||||
using Shadowsocks.Encryption; | using Shadowsocks.Encryption; | ||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
using Shadowsocks.Util; | |||||
namespace Shadowsocks.Controller | namespace Shadowsocks.Controller | ||||
{ | { | ||||
@@ -56,7 +57,7 @@ namespace Shadowsocks.Controller | |||||
private byte[] _buffer = new byte[1500]; | private byte[] _buffer = new byte[1500]; | ||||
private IPEndPoint _localEndPoint; | private IPEndPoint _localEndPoint; | ||||
private IPEndPoint _remoteEndPoint; | |||||
private EndPoint _remoteEndPoint; | |||||
public UDPHandler(Socket local, Server server, IPEndPoint localEndPoint) | public UDPHandler(Socket local, Server server, IPEndPoint localEndPoint) | ||||
{ | { | ||||
@@ -64,16 +65,8 @@ namespace Shadowsocks.Controller | |||||
_server = server; | _server = server; | ||||
_localEndPoint = localEndPoint; | _localEndPoint = localEndPoint; | ||||
// TODO async resolving | |||||
IPAddress ipAddress; | |||||
bool parsed = IPAddress.TryParse(server.server, out ipAddress); | |||||
if (!parsed) | |||||
{ | |||||
IPHostEntry ipHostInfo = Dns.GetHostEntry(server.server); | |||||
ipAddress = ipHostInfo.AddressList[0]; | |||||
} | |||||
_remoteEndPoint = new IPEndPoint(ipAddress, server.server_port); | |||||
_remote = new Socket(_remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp); | |||||
_remoteEndPoint = SocketUtil.GetEndPoint(server.server, server.server_port); | |||||
_remote = SocketUtil.CreateSocket(_remoteEndPoint, ProtocolType.Udp); | |||||
} | } | ||||
public void Send(byte[] data, int length) | public void Send(byte[] data, int length) | ||||
@@ -113,4 +113,6 @@ Failed to update registry=无法修改注册表 | |||||
System Proxy On: =系统代理已启用: | System Proxy On: =系统代理已启用: | ||||
Running: Port {0}=正在运行:端口 {0} | Running: Port {0}=正在运行:端口 {0} | ||||
Unexpected error, shadowsocks will exit. Please report to=非预期错误,Shadowsocks将退出。请提交此错误到 | Unexpected error, shadowsocks will exit. Please report to=非预期错误,Shadowsocks将退出。请提交此错误到 | ||||
Unsupported operating system, use Windows Vista at least.=不支持的操作系统版本,最低需求为Windows Vista。 | |||||
Proxy request failed=代理请求失败 | |||||
Proxy handshake failed=代理握手失败 |
@@ -18,6 +18,14 @@ namespace Shadowsocks | |||||
[STAThread] | [STAThread] | ||||
static void Main() | static void Main() | ||||
{ | { | ||||
// Check OS since we are using dual-mode socket | |||||
if (!Utils.IsWinVistaOrHigher()) | |||||
{ | |||||
MessageBox.Show(I18N.GetString("Unsupported operating system, use Windows Vista at least."), | |||||
"Shadowsocks Error", MessageBoxButtons.OK, MessageBoxIcon.Error); | |||||
return; | |||||
} | |||||
Utils.ReleaseMemory(true); | Utils.ReleaseMemory(true); | ||||
using (Mutex mutex = new Mutex(false, "Global\\Shadowsocks_" + Application.StartupPath.GetHashCode())) | using (Mutex mutex = new Mutex(false, "Global\\Shadowsocks_" + Application.StartupPath.GetHashCode())) | ||||
{ | { | ||||
@@ -2,6 +2,7 @@ | |||||
using System.Net; | using System.Net; | ||||
using System.Net.Sockets; | using System.Net.Sockets; | ||||
using System.Threading; | using System.Threading; | ||||
using Shadowsocks.Util; | |||||
namespace Shadowsocks.Proxy | namespace Shadowsocks.Proxy | ||||
{ | { | ||||
@@ -20,19 +21,26 @@ namespace Shadowsocks.Proxy | |||||
public bool CompletedSynchronously { get; } = true; | public bool CompletedSynchronously { get; } = true; | ||||
} | } | ||||
private class FakeEndPoint : EndPoint | |||||
{ | |||||
public override AddressFamily AddressFamily { get; } = AddressFamily.Unspecified; | |||||
public override string ToString() | |||||
{ | |||||
return "null proxy"; | |||||
} | |||||
} | |||||
private Socket _remote; | private Socket _remote; | ||||
public EndPoint LocalEndPoint => _remote.LocalEndPoint; | public EndPoint LocalEndPoint => _remote.LocalEndPoint; | ||||
public EndPoint ProxyEndPoint { get; private set; } | |||||
public EndPoint ProxyEndPoint { get; } = new FakeEndPoint(); | |||||
public EndPoint DestEndPoint { get; private set; } | public EndPoint DestEndPoint { get; private set; } | ||||
public void BeginConnectProxy(EndPoint remoteEP, AsyncCallback callback, object state) | public void BeginConnectProxy(EndPoint remoteEP, AsyncCallback callback, object state) | ||||
{ | { | ||||
// do nothing | // do nothing | ||||
ProxyEndPoint = remoteEP; | |||||
var r = new FakeAsyncResult(state); | var r = new FakeAsyncResult(state); | ||||
callback?.Invoke(r); | callback?.Invoke(r); | ||||
@@ -43,17 +51,16 @@ namespace Shadowsocks.Proxy | |||||
// do nothing | // do nothing | ||||
} | } | ||||
public void BeginConnectDest(EndPoint remoteEP, AsyncCallback callback, object state) | |||||
public void BeginConnectDest(EndPoint destEndPoint, AsyncCallback callback, object state) | |||||
{ | { | ||||
DestEndPoint = destEndPoint; | |||||
if (_remote == null) | if (_remote == null) | ||||
{ | { | ||||
_remote = new Socket(remoteEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); | |||||
_remote = SocketUtil.CreateSocket(destEndPoint); | |||||
_remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | _remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | ||||
} | } | ||||
DestEndPoint = remoteEP; | |||||
_remote.BeginConnect(remoteEP, callback, state); | |||||
_remote.BeginConnect(destEndPoint, callback, state); | |||||
} | } | ||||
public void EndConnectDest(IAsyncResult asyncResult) | public void EndConnectDest(IAsyncResult asyncResult) | ||||
@@ -17,7 +17,7 @@ namespace Shadowsocks.Proxy | |||||
void EndConnectProxy(IAsyncResult asyncResult); | void EndConnectProxy(IAsyncResult asyncResult); | ||||
void BeginConnectDest(EndPoint remoteEP, AsyncCallback callback, object state); | |||||
void BeginConnectDest(EndPoint destEndPoint, AsyncCallback callback, object state); | |||||
void EndConnectDest(IAsyncResult asyncResult); | void EndConnectDest(IAsyncResult asyncResult); | ||||
@@ -6,6 +6,7 @@ using System.Net.Sockets; | |||||
using System.Text; | using System.Text; | ||||
using System.Threading; | using System.Threading; | ||||
using Shadowsocks.Controller; | using Shadowsocks.Controller; | ||||
using Shadowsocks.Util; | |||||
namespace Shadowsocks.Proxy | namespace Shadowsocks.Proxy | ||||
{ | { | ||||
@@ -51,7 +52,7 @@ namespace Shadowsocks.Proxy | |||||
public void BeginConnectProxy(EndPoint remoteEP, AsyncCallback callback, object state) | public void BeginConnectProxy(EndPoint remoteEP, AsyncCallback callback, object state) | ||||
{ | { | ||||
_remote = new Socket(remoteEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); | |||||
_remote = SocketUtil.CreateSocket(remoteEP); | |||||
_remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | _remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | ||||
var st = new Socks5State(); | var st = new Socks5State(); | ||||
@@ -73,50 +74,62 @@ namespace Shadowsocks.Proxy | |||||
} | } | ||||
} | } | ||||
public void BeginConnectDest(EndPoint remoteEP, AsyncCallback callback, object state) | |||||
public void BeginConnectDest(EndPoint destEndPoint, AsyncCallback callback, object state) | |||||
{ | { | ||||
var ep = remoteEP as IPEndPoint; | |||||
if (ep == null) | |||||
{ | |||||
throw new Exception(I18N.GetString("Proxy request faild")); | |||||
} | |||||
DestEndPoint = destEndPoint; | |||||
byte[] request = null; | byte[] request = null; | ||||
byte atyp = 0; | byte atyp = 0; | ||||
switch (ep.AddressFamily) | |||||
int port; | |||||
var dep = destEndPoint as DnsEndPoint; | |||||
if (dep != null) | |||||
{ | { | ||||
case AddressFamily.InterNetwork: | |||||
request = new byte[4 + 4 + 2]; | |||||
atyp = 1; | |||||
break; | |||||
case AddressFamily.InterNetworkV6: | |||||
request = new byte[4 + 16 + 2]; | |||||
atyp = 4; | |||||
break; | |||||
// is a domain name, we will leave it to server | |||||
atyp = 3; // DOMAINNAME | |||||
var enc = Encoding.UTF8; | |||||
var hostByteCount = enc.GetByteCount(dep.Host); | |||||
request = new byte[4 + 1/*length byte*/ + hostByteCount + 2]; | |||||
request[4] = (byte)hostByteCount; | |||||
enc.GetBytes(dep.Host, 0, dep.Host.Length, request, 5); | |||||
port = dep.Port; | |||||
} | } | ||||
if (request == null) | |||||
else | |||||
{ | { | ||||
throw new Exception(I18N.GetString("Proxy request faild")); | |||||
switch (DestEndPoint.AddressFamily) | |||||
{ | |||||
case AddressFamily.InterNetwork: | |||||
request = new byte[4 + 4 + 2]; | |||||
atyp = 1; // IP V4 address | |||||
break; | |||||
case AddressFamily.InterNetworkV6: | |||||
request = new byte[4 + 16 + 2]; | |||||
atyp = 4; // IP V6 address | |||||
break; | |||||
default: | |||||
throw new Exception(I18N.GetString("Proxy request failed")); | |||||
} | |||||
port = ((IPEndPoint) DestEndPoint).Port; | |||||
var addr = ((IPEndPoint)DestEndPoint).Address.GetAddressBytes(); | |||||
Array.Copy(addr, 0, request, 4, request.Length - 4 - 2); | |||||
} | } | ||||
// 构造request包 | |||||
var addr = ep.Address.GetAddressBytes(); | |||||
// 构造request包剩余部分 | |||||
request[0] = 5; | request[0] = 5; | ||||
request[1] = 1; | request[1] = 1; | ||||
request[2] = 0; | request[2] = 0; | ||||
request[3] = atyp; | request[3] = atyp; | ||||
Array.Copy(addr, 0, request, 4, request.Length - 4 - 2); | |||||
request[request.Length - 2] = (byte) ((ep.Port >> 8) & 0xff); | |||||
request[request.Length - 1] = (byte) (ep.Port & 0xff); | |||||
request[request.Length - 2] = (byte) ((port >> 8) & 0xff); | |||||
request[request.Length - 1] = (byte) (port & 0xff); | |||||
var st = new Socks5State(); | var st = new Socks5State(); | ||||
st.Callback = callback; | st.Callback = callback; | ||||
st.AsyncState = state; | st.AsyncState = state; | ||||
DestEndPoint = remoteEP; | |||||
_remote?.BeginSend(request, 0, request.Length, 0, Socks5RequestSendCallback, st); | _remote?.BeginSend(request, 0, request.Length, 0, Socks5RequestSendCallback, st); | ||||
} | } | ||||
public void EndConnectDest(IAsyncResult asyncResult) | public void EndConnectDest(IAsyncResult asyncResult) | ||||
@@ -206,12 +219,12 @@ namespace Shadowsocks.Proxy | |||||
{ | { | ||||
if (_receiveBuffer[0] != 5 || _receiveBuffer[1] != 0) | if (_receiveBuffer[0] != 5 || _receiveBuffer[1] != 0) | ||||
{ | { | ||||
ex = new Exception(I18N.GetString("Proxy handshake faild")); | |||||
ex = new Exception(I18N.GetString("Proxy handshake failed")); | |||||
} | } | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
ex = new Exception(I18N.GetString("Proxy handshake faild")); | |||||
ex = new Exception(I18N.GetString("Proxy handshake failed")); | |||||
} | } | ||||
} | } | ||||
catch (Exception ex2) | catch (Exception ex2) | ||||
@@ -261,20 +274,20 @@ namespace Shadowsocks.Proxy | |||||
_remote.BeginReceive(_receiveBuffer, 0, 16 + 2, 0, Socks5ReplyReceiveCallback2, state); | _remote.BeginReceive(_receiveBuffer, 0, 16 + 2, 0, Socks5ReplyReceiveCallback2, state); | ||||
break; | break; | ||||
default: | default: | ||||
state.ex = new Exception(I18N.GetString("Proxy request faild")); | |||||
state.ex = new Exception(I18N.GetString("Proxy request failed")); | |||||
state.Callback?.Invoke(new FakeAsyncResult(ar, state)); | state.Callback?.Invoke(new FakeAsyncResult(ar, state)); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
state.ex = new Exception(I18N.GetString("Proxy request faild")); | |||||
state.ex = new Exception(I18N.GetString("Proxy request failed")); | |||||
state.Callback?.Invoke(new FakeAsyncResult(ar, state)); | state.Callback?.Invoke(new FakeAsyncResult(ar, state)); | ||||
} | } | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
state.ex = new Exception(I18N.GetString("Proxy request faild")); | |||||
state.ex = new Exception(I18N.GetString("Proxy request failed")); | |||||
state.Callback?.Invoke(new FakeAsyncResult(ar, state)); | state.Callback?.Invoke(new FakeAsyncResult(ar, state)); | ||||
} | } | ||||
} | } | ||||
@@ -297,7 +310,7 @@ namespace Shadowsocks.Proxy | |||||
if (bytesRead < bytesNeedSkip) | if (bytesRead < bytesNeedSkip) | ||||
{ | { | ||||
ex = new Exception(I18N.GetString("Proxy request faild")); | |||||
ex = new Exception(I18N.GetString("Proxy request failed")); | |||||
} | } | ||||
} | } | ||||
catch (Exception ex2) | catch (Exception ex2) | ||||
@@ -0,0 +1,66 @@ | |||||
using System; | |||||
using System.Net; | |||||
using System.Net.Sockets; | |||||
namespace Shadowsocks.Util | |||||
{ | |||||
public static class SocketUtil | |||||
{ | |||||
private class DnsEndPoint2 : DnsEndPoint | |||||
{ | |||||
public DnsEndPoint2(string host, int port) : base(host, port) | |||||
{ | |||||
} | |||||
public DnsEndPoint2(string host, int port, AddressFamily addressFamily) : base(host, port, addressFamily) | |||||
{ | |||||
} | |||||
public override string ToString() | |||||
{ | |||||
return this.Host + ":" + this.Port; | |||||
} | |||||
} | |||||
public static EndPoint GetEndPoint(string host, int port) | |||||
{ | |||||
IPAddress ipAddress; | |||||
bool parsed = IPAddress.TryParse(host, out ipAddress); | |||||
if (parsed) | |||||
{ | |||||
return new IPEndPoint(ipAddress, port); | |||||
} | |||||
// maybe is a domain name | |||||
return new DnsEndPoint2(host, port); | |||||
} | |||||
public static Socket CreateSocket(EndPoint endPoint, ProtocolType protocolType = ProtocolType.Tcp) | |||||
{ | |||||
SocketType socketType; | |||||
switch (protocolType) | |||||
{ | |||||
case ProtocolType.Tcp: | |||||
socketType = SocketType.Stream; | |||||
break; | |||||
case ProtocolType.Udp: | |||||
socketType = SocketType.Dgram; | |||||
break; | |||||
default: | |||||
throw new NotSupportedException("Protocol " + protocolType + " doesn't supported!"); | |||||
} | |||||
if (endPoint is DnsEndPoint) | |||||
{ | |||||
var socket = new Socket(AddressFamily.InterNetworkV6, socketType, protocolType); | |||||
socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); | |||||
return socket; | |||||
} | |||||
else | |||||
{ | |||||
return new Socket(endPoint.AddressFamily, socketType, protocolType); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -151,12 +151,16 @@ namespace Shadowsocks.Util | |||||
// we are building x86 binary for both x86 and x64, which will | // we are building x86 binary for both x86 and x64, which will | ||||
// cause problem when opening registry key | // cause problem when opening registry key | ||||
// detect operating system instead of CPU | // detect operating system instead of CPU | ||||
RegistryKey userKey = RegistryKey.OpenBaseKey( RegistryHive.CurrentUser, | |||||
Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32 ); | |||||
userKey = userKey.OpenSubKey( name, writable ); | |||||
RegistryKey userKey = RegistryKey.OpenRemoteBaseKey( RegistryHive.CurrentUser, "", | |||||
Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32 ) | |||||
.OpenSubKey( name, writable ); | |||||
return userKey; | return userKey; | ||||
} | } | ||||
public static bool IsWinVistaOrHigher() { | |||||
return Environment.OSVersion.Version.Major > 5; | |||||
} | |||||
[DllImport("kernel32.dll")] | [DllImport("kernel32.dll")] | ||||
[return: MarshalAs(UnmanagedType.Bool)] | [return: MarshalAs(UnmanagedType.Bool)] | ||||
private static extern bool SetProcessWorkingSetSize(IntPtr process, | private static extern bool SetProcessWorkingSetSize(IntPtr process, | ||||
@@ -176,6 +176,7 @@ | |||||
<Compile Include="Controller\Strategy\IStrategy.cs" /> | <Compile Include="Controller\Strategy\IStrategy.cs" /> | ||||
<Compile Include="Proxy\Socks5Proxy.cs" /> | <Compile Include="Proxy\Socks5Proxy.cs" /> | ||||
<Compile Include="StringEx.cs" /> | <Compile Include="StringEx.cs" /> | ||||
<Compile Include="Util\SocketUtil.cs" /> | |||||
<Compile Include="Util\Util.cs" /> | <Compile Include="Util\Util.cs" /> | ||||
<Compile Include="View\ConfigForm.cs"> | <Compile Include="View\ConfigForm.cs"> | ||||
<SubType>Form</SubType> | <SubType>Form</SubType> | ||||