示例#1
0
 void DataChannelClose()
 {
     foreach (MultiplexedTcpConnection connection in new List <MultiplexedTcpConnection>(connections.Values))
     {
         try
         {
             lock (connectionLock)
             {
                 connections.Remove(connection.Id);
             }
             connection.Dispose();
         }
         catch (Exception ex)
         {
             Trace.TraceError("Error shutting down multiplex connection: {0}", ex.Message);
         }
     }
     if (dataChannel != null)
     {
         dataChannel.Close();
         dataChannel = null;
     }
 }
示例#2
0
        void StreamAccepted(HybridConnectionStream hybridConnectionStream)
        {
            try
            {
                if (hybridConnectionStream != null)
                {
                    relayListener.AcceptConnectionAsync().ContinueWith(t => StreamAccepted(t.Result));
                    var preambleReader = new BinaryReader(hybridConnectionStream);
                    var connectionInfo = preambleReader.ReadString();
                    if (connectionInfo.StartsWith("tcp:", StringComparison.OrdinalIgnoreCase))
                    {
                        int port;

                        if (!int.TryParse(connectionInfo.Substring(4), out port))
                        {
                            try
                            {
                                hybridConnectionStream.Close();
                            }
                            catch (Exception ex)
                            {
                                Trace.TraceError("Error closing stream: {0}", ex.Message);
                            }
                            return;
                        }
                        bool portAllowed = noPortConstraints;
                        Trace.TraceInformation("Incoming connection for port {0}", port);
                        if (!portAllowed)
                        {
                            for (int i = 0; i < allowedPorts.Count; i++)
                            {
                                if (port == allowedPorts[i])
                                {
                                    portAllowed = true;
                                    break;
                                }
                            }
                        }
                        if (!portAllowed)
                        {
                            Trace.TraceWarning("Incoming connection for port {0} not permitted", port);
                            try
                            {
                                hybridConnectionStream.Close();
                            }
                            catch (Exception ex)
                            {
                                Trace.TraceError("Error closing stream: {0}", ex.Message);
                            }
                            return;
                        }
                    }
                    else if (connectionInfo.StartsWith("np:", StringComparison.OrdinalIgnoreCase))
                    {
                        string pipeName = connectionInfo.Substring(3);
                        Trace.TraceInformation("Incoming connection for pipe {0}", pipeName);

                        bool pipeAllowed = noPipeConstraints;
                        if (!pipeAllowed)
                        {
                            for (int i = 0; i < allowedPipes.Count; i++)
                            {
                                if (pipeName.Equals(allowedPipes[i], StringComparison.OrdinalIgnoreCase))
                                {
                                    pipeAllowed = true;
                                    break;
                                }
                            }
                        }
                        if (!pipeAllowed)
                        {
                            Trace.TraceWarning("Incoming connection for pipe {0} not permitted", pipeName);
                            try
                            {
                                hybridConnectionStream.Close();
                            }
                            catch (Exception ex)
                            {
                                Trace.TraceError("Error closing stream: {0}", ex.Message);
                            }
                            return;
                        }
                    }
                    else
                    {
                        Trace.TraceError("Unable to handle connection for {0}", connectionInfo);
                        hybridConnectionStream.Close();
                        return;
                    }

                    MultiplexConnectionInputPump connectionPump =
                        new MultiplexConnectionInputPump(
                            hybridConnectionStream.Read,
                            OnCreateConnection,
                            new StreamConnection(hybridConnectionStream, connectionInfo));
                    connectionPump.Run(false);
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError("Error accepting connection: {0}", ex.Message);
            }
        }
        private Task OnNewClient(Guid streamId, HybridConnectionStream stream, CancellationToken token)
        {
            return(Task.Factory.StartNew(async() =>
            {
                var buffer = new byte[65536];

                while (true)
                {
                    var id = Guid.Empty;
                    int remotePort = 0;
                    var count = 0;
                    Int32 controlCommand = ControlCommands.Forward;
                    Int32 frameSize = 0;
                    Int32 bytesRead = 0;
                    var memStream = new MemoryStream();

                    // read control command
                    count = await stream.ReadAsync(buffer, 0, sizeof(Int32));
                    if (0 == count || token.IsCancellationRequested)
                    {
                        break;
                    }

                    controlCommand = BitConverter.ToInt32(new ArraySegment <byte>(buffer, 0, sizeof(Int32)).ToArray(), 0);

                    if (ControlCommands.Forward == controlCommand)
                    {
                        // read forwarding preamble
                        count = await stream.ReadAsync(buffer, 0, 16 + sizeof(Int32) + sizeof(Int32));

                        if (0 == count || token.IsCancellationRequested)
                        {
                            break;
                        }

                        id = new Guid(new ArraySegment <byte>(buffer, 0, 16).ToArray());
                        remotePort = BitConverter.ToInt32(new ArraySegment <byte>(buffer, 16, sizeof(Int32)).ToArray(), 0);
                        frameSize = BitConverter.ToInt32(new ArraySegment <byte>(buffer, 16 + sizeof(Int32), sizeof(Int32)).ToArray(), 0);

                        if (!_validPorts.Contains(remotePort))
                        {
                            _logger.LogError($"Connection on port {remotePort} not allowed for hybrid connectio  {_connectionName}.");

                            stream.Close();
                        }

                        while (true)
                        {
                            var length = frameSize - bytesRead > buffer.Length ? buffer.Length : frameSize - bytesRead;
                            count = await stream.ReadAsync(buffer, 0, length);

                            if (0 == count || token.IsCancellationRequested)
                            {
                                break;
                            }

                            bytesRead += count;
                            await memStream.WriteAsync(buffer, 0, count);

                            if (bytesRead == frameSize)
                            {
                                await _demultiplexer.Demultiplex(streamId, id, remotePort, memStream.ToArray());
                                break;
                            }
                        }

                        if (0 == count || token.IsCancellationRequested)
                        {
                            break;
                        }
                    }
                    else
                    {
                        count = await stream.ReadAsync(buffer, 0, 16);
                        if (0 == count || token.IsCancellationRequested)
                        {
                            break;
                        }

                        id = new Guid(new ArraySegment <byte>(buffer, 0, 16).ToArray());

                        await _demultiplexer.ClientConnectionClosed(streamId, id);
                    }
                }

                lock (_syncRoot)
                {
                    _hybridConnectionStreams.Remove(streamId);
                }

                await stream.ShutdownAsync(_cts.Token);
            }));
        }