/// <summary> /// Update the config of transport at runtime. /// </summary> /// <param name="type">The type of transport stream.</param> internal void UpdateConfig(SecurityStreamType type) { lock (receivingStreams) { foreach (Socket sock in this.receivingStreams.Keys) { if (!(receivingStreams[sock].ReceiveStream is NetworkStream)) { //Skip the connections which already were updated to SSL or CredSSP. continue; } else { NetworkStream netStream = (NetworkStream)receivingStreams[sock].ReceiveStream; if (type == SecurityStreamType.Ssl) { SslStream sslStream = new SslStream(new ETWStream(netStream)); ((SslStream)sslStream).AuthenticateAsServer(this.cert); receivingStreams[sock].ReceiveStream = sslStream; } else if (type == SecurityStreamType.CredSsp) { string targetSPN = ConstValue.CREDSSP_SERVER_NAME_PREFIX + config.LocalIpAddress; var csspServer = new CsspServer(new ETWStream(netStream)); var credSspStream = csspServer.GetStream(); receivingStreams[sock].ReceiveStream = credSspStream; csspServer.Authenticate(cert, targetSPN); } } } } }
private void AcceptLoopInternal() { listenSock = new Socket(config.LocalIpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); var streamType = config.StreamType; var endPoint = new IPEndPoint(config.LocalIpAddress, config.LocalIpPort); listenSock.Bind(endPoint); listenSock.Listen(config.MaxConnections); UpdateSocketBlockingMode(listenSock, false); while (!acceptThreadCancellationTokenSource.IsCancellationRequested) { if (this.receivingStreams.Count >= config.MaxConnections) { // not listen untill the current connections are less than the max value. // the interval to query is 1 seconds: Thread.Sleep(1000); continue; } Socket socket = null; try { socket = this.listenSock.Accept(); UpdateSocketBlockingMode(socket, true); } catch (SocketException socketException) { if (socketException.SocketErrorCode == SocketError.WouldBlock) { continue; } throw; } TransportEvent connectEvent; Stream receiveStream = null; Stream baseStream = new NetworkStream(socket); switch (streamType) { case SecurityStreamType.None: receiveStream = baseStream; break; case SecurityStreamType.CredSsp: string targetSPN = ConstValue.CREDSSP_SERVER_NAME_PREFIX + config.LocalIpAddress; var csspServer = new CsspServer(new ETWStream(baseStream)); var credSspStream = csspServer.GetStream(); csspServer.Authenticate(cert, targetSPN); receiveStream = credSspStream; break; default: receiveStream = baseStream; break; } // Start receive thread with non-blocking mode. UpdateSocketBlockingMode(socket, false); RdpbcgrReceiveThread receiveThread = new RdpbcgrReceiveThread( socket.RemoteEndPoint, this.packetQueue, this.decoder, receiveStream, this.config.BufferSize ); connectEvent = new TransportEvent(EventType.Connected, socket.RemoteEndPoint, null); RdpbcgrServerSessionContext session = new RdpbcgrServerSessionContext(); session.Identity = connectEvent.EndPoint; session.Server = this.rdpbcgrServer; session.LocalIdentity = socket.LocalEndPoint; session.IsClientToServerEncrypted = this.rdpbcgrServer.IsClientToServerEncrypted; this.rdpbcgrServer.ServerContext.AddSession(session); this.packetQueue.AddObject(connectEvent); lock (this.receivingStreams) { this.receivingStreams.Add(socket, receiveThread); } receiveThread.Start(); } }
/// <summary> /// Creates a new Socket for a newly created connection and a new thread to receive packet in the loop. /// </summary> private void AcceptLoop() { while (!exitLoop) { if (this.receivingStreams.Count >= config.MaxConnections) { // not listen untill the current connections are less than the max value. // the interval to query is 1 seconds: Thread.Sleep(1000); continue; } Socket socket = null; try { socket = this.listenSock.Accept(); } catch (SocketException) { exitLoop = true; continue; } TransportEvent connectEvent; Stream receiveStream = null; Stream baseStream = new NetworkStream(socket); switch (streamType) { case SecurityStreamType.None: receiveStream = baseStream; break; case SecurityStreamType.Ssl: receiveStream = new SslStream( new ETWStream( baseStream), false ); ((SslStream)receiveStream).AuthenticateAsServer(cert); break; case SecurityStreamType.CredSsp: string targetSPN = ConstValue.CREDSSP_SERVER_NAME_PREFIX + config.LocalIpAddress; var csspServer = new CsspServer(new ETWStream(baseStream)); var credSspStream = csspServer.GetStream(); csspServer.Authenticate(cert, targetSPN); receiveStream = credSspStream; break; default: receiveStream = baseStream; break; } RdpbcgrReceiveThread receiveThread = new RdpbcgrReceiveThread( socket.RemoteEndPoint, this.packetQueue, this.decoder, receiveStream, this.config.BufferSize, this.rdpbcgrServer); connectEvent = new TransportEvent(EventType.Connected, socket.RemoteEndPoint, null); RdpbcgrServerSessionContext session = new RdpbcgrServerSessionContext(); session.Identity = connectEvent.EndPoint; session.Server = this.rdpbcgrServer; session.LocalIdentity = socket.LocalEndPoint; session.IsClientToServerEncrypted = this.rdpbcgrServer.IsClientToServerEncrypted; this.rdpbcgrServer.ServerContext.AddSession(session); this.packetQueue.AddObject(connectEvent); lock (this.receivingStreams) { this.receivingStreams.Add(socket, receiveThread); } receiveThread.Start(); } }