コード例 #1
0
ファイル: RelayServer.cs プロジェクト: gfody/WebRelay
        private async Task HandleWebsocketRequest(WebSocketContext context)
        {
            string key = null;

            try
            {
                var    timeout  = new CancellationTokenSource(new TimeSpan(0, 0, 3));
                string filename = await context.WebSocket.ReceiveString(timeout.Token);

                long?filesize = null; if (long.TryParse(await context.WebSocket.ReceiveString(timeout.Token), out long size))
                {
                    filesize = size;
                }
                string mimetype = await context.WebSocket.ReceiveString(timeout.Token);

                SocketRelay relay = new SocketRelay(context.WebSocket, filename, filesize, mimetype);
                key = AddRelay(relay);
                await context.WebSocket.SendString($"code={key}", timeout.Token);

                OnSocketRelay?.Invoke(filename, filesize, key, relay);

                await relay.HandleUpload();
            }
            catch (TaskCanceledException)
            {
                await context.WebSocket.CloseOutputAsync(WebSocketCloseStatus.Empty, null, CancellationToken.None);
            }
            // client disconnects without closing
            catch (WebSocketException) { }
            catch (Exception e) when(e.InnerException is WebSocketException)
            {
            }
            finally
            {
                if (key != null)
                {
                    activeRelays.TryRemove(key, out IRelay x);
                }
            }
        }
コード例 #2
0
        private async void ProcessLocalConnection(object state)
        {
            var connection = (ConnectionInfo)state;
            var buffer     = new byte[BufferSize];

            try
            {
                var bytesRead = connection.LocalSocket.Receive(buffer);
                if (bytesRead < 1 || buffer[0] != Protocol.Socks4.Version)
                {
                    connection.Terminate();
                    return;
                }

                OnLogMessage?.Invoke(this, $"Got {bytesRead} bytes from ");
            }
            catch (SocketException ex)
            {
                OnLogMessage?.Invoke(this, $"Caught SocketException in ProcessLocalConnection with error code {ex.SocketErrorCode}");
            }

            try
            {
                switch (buffer[1])
                {
                case Protocol.Socks4.CommandStreamConnection:
                {
                    var portBuffer = new[] { buffer[2], buffer[3] };
                    var port       = (ushort)(portBuffer[0] << 8 | portBuffer[1]);

                    var address           = new[] { buffer[4], buffer[5], buffer[6], buffer[7] };
                    var destAddress       = new IPAddress(address).ToString();
                    var destAddressFamily = AddressFamily.InterNetwork;

                    if (IsSocks4AProtocol(address))
                    {
                        var hostBuffer = new byte[256];
                        Buffer.BlockCopy(buffer, 9, hostBuffer, 0, 100);

                        // Resolve hostname, fallback to remote proxy dns resolution
                        var hostname = Encoding.ASCII.GetString(hostBuffer).TrimEnd((char)0);
                        if (!ResolveHostnamesRemotely)
                        {
                            var resolvedHostname = await DnsResolver.TryResolve(hostname);

                            if (resolvedHostname == null)
                            {
                                OnLogMessage?.Invoke(this, $"DNS resolution failed for {hostname}");
                                SendSocks4Reply(connection.LocalSocket, Protocol.Socks4.StatusRequestGranted, address, portBuffer);
                                connection.Terminate();
                                break;
                            }

                            destAddress       = resolvedHostname.ToString();
                            destAddressFamily = resolvedHostname.AddressFamily;
                        }
                        else
                        {
                            destAddress       = hostname;
                            destAddressFamily = AddressFamily.Unspecified;
                        }
                    }

                    connection.RemoteSocket = Socks5Client.Connect(
                        RemotEndPoint.Address.ToString(),
                        RemotEndPoint.Port,
                        destAddress,
                        port,
                        Username,
                        Password,
                        SendTimeout,
                        ReceiveTimeout);

                    OnRemoteConnect?.Invoke(this, new DnsEndPoint(destAddress, port, destAddressFamily));

                    if (connection.RemoteSocket.Connected)
                    {
                        OnLogMessage?.Invoke(this, "RelayBiDirectionally between server and client started");
                        SendSocks4Reply(connection.LocalSocket, Protocol.Socks4.StatusRequestGranted, address, portBuffer);
                        SocketRelay.RelayBiDirectionally(connection.RemoteSocket, connection.LocalSocket);
                    }
                    else
                    {
                        OnLogMessage?.Invoke(this, "RemoteSocket connection failed");
                        SendSocks4Reply(connection.LocalSocket, Protocol.Socks4.StatusRequestFailed, address, portBuffer);
                        connection.Terminate();
                    }

                    break;
                }

                case Protocol.Socks4.CommandBindingConnection:
                {
                    var portBuffer = new[] { buffer[2], buffer[3] };
                    var address    = new[] { buffer[4], buffer[5], buffer[6], buffer[7] };

                    // TCP/IP port binding not supported
                    SendSocks4Reply(connection.LocalSocket, Protocol.Socks4.StatusRequestFailed, address, portBuffer);
                    connection.Terminate();
                    break;
                }

                default:
                    OnLogMessage?.Invoke(this, "Unknown protocol on LocalSocket");
                    connection.Terminate();
                    break;
                }
            }
            catch (SocketException ex)
            {
                OnLogMessage?.Invoke(this, $"Caught SocketException in ProcessLocalConnection with error code {ex.SocketErrorCode.ToString()}");
            }
            catch (Socks5Exception ex)
            {
                var portBuffer = new[] { buffer[2], buffer[3] };
                var address    = new[] { buffer[4], buffer[5], buffer[6], buffer[7] };

                SendSocks4Reply(connection.LocalSocket, Protocol.Socks4.StatusRequestFailed, address, portBuffer);
                connection.Terminate();

                OnLogMessage?.Invoke(this, $"Caught Socks5Exception in ProcessLocalConnection with message {ex.Message}");
            }
        }
コード例 #3
0
        private void AcceptCallback(IAsyncResult ar)
        {
            Socket sktActive = null;
            try
            {
                var state = (Tuple<Socket, EventWaitHandle>)ar.AsyncState;
                state.Item2.Set();
                sktActive = state.Item1.EndAccept(ar);
            }
            catch (ObjectDisposedException)
            {
                // Accept has been cancelled.
                return;
            }

            try
            {
                // 安全验证
                //if (!m_confirm.Confirm(sktActive))
                //{
                //	sktActive.Close();
                //	return;
                //}

                Socket sktPassive = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sktPassive.Connect(m_epDest);

                SocketRelay relay = new SocketRelay(sktActive, sktPassive);
                relay.OnFinished += OnSocketRelayFinished;
                relay.Run();
                lock (m_listSR) m_listSR.Add(relay);
            }
            catch (SocketException ex)
            {
                string strbuf = String.Format("{0}({1})", ex.Message, ex.ErrorCode);
                byte[] buf = Encoding.Default.GetBytes(strbuf);
                sktActive.Send(buf);

                sktActive.Shutdown(SocketShutdown.Both);
                sktActive.Close();
            }
        }
コード例 #4
0
 private void OnSocketRelayFinished(SocketRelay item)
 {
     lock (m_listSR)
     {
         if (m_listSR.Contains(item))
             m_listSR.Remove(item);
     }
 }