/// <summary> /// the received loop for tcp connection. /// </summary> /// <param name="host"> /// an IVisitorTcpReceiveLoop interface that specifies the host of visitor. /// </param> /// <param name="server"> /// an ITransport object that provides AddEvent, it must be TcpClient or TcpServerConnection. /// </param> /// <param name="stream"> /// a Stream object that specifies the underlayer transport stream.<para/> /// if DirectTcp, it's the stream of TcpClient.GetStream().<para/> /// if Tcp over Ssl, it's SslStream. /// </param> /// <param name="thread"> /// a ThreadManager object that specifies the received thread. /// </param> /// <param name="bufferSize"> /// an int value that specifies the max buffer size. /// </param> public static void Visit( IVisitorTcpReceiveLoop host, ITransport server, Stream stream, ThreadManager thread, int bufferSize) { byte[] data = new byte[bufferSize]; while (!thread.ShouldExit) { int receivedLength = 0; try { // received data from server. receivedLength = stream.Read(data, 0, data.Length); // if the server close the socket, return. if (receivedLength == 0) { server.AddEvent(host.VisitorCreateTransportEvent(EventType.Disconnected, null)); break; } host.VisitorAddReceivedData(ArrayUtility.SubArray<byte>(data, 0, receivedLength)); } catch (IOException ex) { SocketException socketException = ex.InnerException as SocketException; // if the server disconnect the socket. if (socketException != null && (socketException.SocketErrorCode == SocketError.ConnectionReset || socketException.SocketErrorCode == SocketError.Interrupted || socketException.SocketErrorCode == SocketError.ConnectionAborted)) { // handle the disconnected event, return. server.AddEvent(host.VisitorCreateTransportEvent(EventType.Disconnected, ex)); } else { // handle exception event, return. server.AddEvent(host.VisitorCreateTransportEvent(EventType.Exception, ex)); } break; } } }
public static void Visit( IVisitorNetbiosReceiveLoop host, ITransport server, NetbiosTransport transport, int localEP, int remoteEP, ThreadManager thread) { byte[] data = null; while (!thread.ShouldExit) { try { // received data from server. data = transport.Receive(remoteEP); // if the server close the socket, return. if (data == null) { server.AddEvent(new TransportEvent(EventType.Disconnected, remoteEP, localEP, null)); break; } host.VisitorAddReceivedData(ArrayUtility.SubArray<byte>(data, 0)); } // the connection is disconnected. catch (InvalidOperationException ex) { server.AddEvent(new TransportEvent(EventType.Disconnected, remoteEP, localEP, ex)); break; } catch (Exception ex) { // handle exception event, return. server.AddEvent(new TransportEvent(EventType.Exception, remoteEP, localEP, ex)); break; } } }
/// <summary> /// constructor /// </summary> /// <param name="tcpListener"> /// a TcpListener that specifies the listener. /// </param> /// <param name="tcpServerTransport"> /// a TcpServerTransport that represents the owner of listener. /// </param> /// <param name="isLspHooked"> /// a bool value that indicates whether lsp hooked the transport. /// </param> /// <exception cref="ArgumentNullException"> /// thrown when tcpListener is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when tcpServerTransport is null. /// </exception> public TcpServerListener(TcpListener tcpListener, TcpServerTransport tcpServerTransport, bool isLspHooked) { if (tcpListener == null) { throw new ArgumentNullException("tcpListener"); } if (tcpServerTransport == null) { throw new ArgumentNullException("tcpServerTransport"); } this.lspHooked = isLspHooked; this.listener = tcpListener; this.server = tcpServerTransport; this.thread = new ThreadManager(AcceptLoop, Unblock); }
public static void Visit( IVisitorUdpReceiveLoop host, ITransport server, UdpClient udpClient, ThreadManager thread, bool isLspHooked) { byte[] data = null; // get the endpoint of tcp client. IPEndPoint localEP = host.LspHookedLocalEP; while (!thread.ShouldExit) { try { // received data from server. IPEndPoint remoteEP = null; data = udpClient.Receive(ref remoteEP); if (data == null) { break; } if (isLspHooked) { int numBytesReceived = data.Length; if (numBytesReceived < Marshal.SizeOf(typeof(LspUdpHeader))) { throw new FormatException("Invalid LSP udp packet received"); } //Get udp header byte[] udpHeaderBuffer = ArrayUtility.SubArray(data, 0, Marshal.SizeOf(typeof(LspUdpHeader))); IntPtr p = Marshal.AllocHGlobal(udpHeaderBuffer.Length); Marshal.Copy(udpHeaderBuffer, 0, p, udpHeaderBuffer.Length); LspUdpHeader udpHeader = (LspUdpHeader)Marshal.PtrToStructure(p, typeof(LspUdpHeader)); Marshal.FreeHGlobal(p); //get address byte[] srcAddressArray = ArrayUtility.SubArray <byte>(data, Marshal.SizeOf(typeof(LspUdpHeader)), udpHeader.HeaderLength - Marshal.SizeOf(typeof(LspUdpHeader))); string srcAddress = Encoding.ASCII.GetString(srcAddressArray); //replacement numBytesReceived = numBytesReceived - udpHeader.HeaderLength; byte[] msgBody = new byte[numBytesReceived]; Array.Copy(data, udpHeader.HeaderLength, msgBody, 0, numBytesReceived); //endPoint is real remote client endpoint, remoteEP is LspDll's endpoint IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(srcAddress), udpHeader.Port); //map from the real endpoint to the lsp dll endpoint //when sending response to the real endpoint, response will be sent to the lsp dll endpoint //and the lsp dll will relay it to the real endpoint LspConsole.Instance.SetMappedIPEndPoint( (IPEndPoint)udpClient.Client.LocalEndPoint, (IPEndPoint)endPoint, (IPEndPoint)remoteEP, StackTransportType.Udp); host.VisitorAddReceivedData(msgBody, localEP, (IPEndPoint)endPoint); } else { host.VisitorAddReceivedData(data, localEP, remoteEP); } } catch (Exception ex) { // handle exception event, return. server.AddEvent(new TransportEvent(EventType.Exception, localEP, ex)); break; } } }
/// <summary> /// Release resources. /// </summary> /// <param name = "disposing"> /// If disposing equals true, Managed and unmanaged resources are disposed. if false, Only unmanaged resources /// can be disposed. /// </param> protected virtual void Dispose(bool disposing) { if (!this.disposed) { // If disposing equals true, dispose all managed and unmanaged resources. if (disposing) { // Free managed resources & other reference types: if (this.thread != null) { this.thread.Dispose(); this.thread = null; } if (this.transport != null) { // the netbios transport may throw exception, donot arise exception. Utility.SafelyDisconnectNetbiosConnection(this.transport, this.remoteEndPoint); this.transport.Dispose(); this.transport = null; } if (this.eventQueue != null) { // the SyncFilterQueue may throw exception, donot arise exception. this.eventQueue.Dispose(); this.eventQueue = null; } if (this.packetCache != null) { this.packetCache.Dispose(); this.packetCache = null; } if (this.buffer != null) { this.buffer.Dispose(); this.buffer = null; } } // Call the appropriate methods to clean up unmanaged resources. // If disposing is false, only the following code is executed: this.disposed = true; } }
/// <summary> /// Release resources. /// </summary> /// <param name = "disposing"> /// If disposing equals true, managed and unmanaged resources are disposed. if false, Only unmanaged resources /// can be disposed. /// </param> protected virtual void Dispose(bool disposing) { if (!this.disposed) { // If disposing equals true, dispose all managed and unmanaged resources. if (disposing) { // Free managed resources & other reference types: if (this.thread != null) { this.thread.Dispose(); this.thread = null; } if (this.stream != null) { this.stream.Close(); this.stream = null; } if (this.buffer != null) { this.buffer.Dispose(); this.buffer = null; } if (associatedForwarderChannel != null) { this.associatedForwarderChannel.Dispose(); } } // Call the appropriate methods to clean up unmanaged resources. // If disposing is false, only the following code is executed: this.disposed = true; } }
/// <summary> /// Release resources. /// </summary> /// <param name = "disposing"> /// If disposing equals true, managed and unmanaged resources are disposed. if false, Only unmanaged resources /// can be disposed. /// </param> protected virtual void Dispose(bool disposing) { if (!this.disposed) { // If disposing equals true, dispose all managed and unmanaged resources. if (disposing) { // Free managed resources & other reference types: if (this.thread != null) { this.thread.Dispose(); this.thread = null; } if (this.transport != null) { this.transport.Dispose(); this.transport = null; } } // Call the appropriate methods to clean up unmanaged resources. // If disposing is false, only the following code is executed: this.disposed = true; } }
/// <summary> /// start the listener and then start a thread to accept connection from client. /// </summary> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the listener on the endpoint has been started. /// </exception> public void Start() { if (disposed) { throw new ObjectDisposedException("NetbiosServerListener"); } if (this.thread != null) { throw new InvalidOperationException("the listener on the endpoint has been started."); } if (this.transport == null) { this.transport = new NetbiosTransport( this.netbiosName, this.server.NetbiosConfig.AdapterIndex, (ushort)this.server.NetbiosConfig.BufferSize, (byte)this.server.NetbiosConfig.MaxSessions, (byte)this.server.NetbiosConfig.MaxNames); } this.localEndPoint = this.transport.NcbNum; this.thread = new ThreadManager(AcceptLoop, Unblock); this.thread.Start(); }
/// <summary> /// Release resources. /// </summary> /// <param name = "disposing"> /// If disposing equals true, managed and unmanaged resources are disposed. if false, Only unmanaged resources /// can be disposed. /// </param> protected virtual void Dispose(bool disposing) { if (!this.disposed) { // If disposing equals true, dispose all managed and unmanaged resources. if (disposing) { // Free managed resources & other reference types: if (this.thread != null) { this.thread.Dispose(); this.thread = null; } if (this.udpClient != null) { this.udpClient.Close(); this.udpClient = null; } if (this.eventQueue != null) { // the SyncFilterQueue may throw exception, donot arise exception. this.eventQueue.Dispose(); this.eventQueue = null; } if (this.packetCache != null) { this.packetCache.Dispose(); this.packetCache = null; } if (this.buffer != null) { // the SyncFilterQueue may throw exception, donot arise exception. this.buffer.Dispose(); this.buffer = null; } } // Call the appropriate methods to clean up unmanaged resources. // If disposing is false, only the following code is executed: this.disposed = true; } }
/// <summary> /// stop the specified listener.<para/> /// the underlayer transport must be TcpServer, UdpServer or NetbiosServer. /// </summary> /// <param name="localEndPoint"> /// an object that specifies the listener. /// </param> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when remoteEndPoint is null. /// </exception> /// <exception cref="ArgumentException"> /// thrown when the specified endpoint is not an IPEndPoint. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the udp client is not connected to server, must invoke Start() first. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when failed to stop the endpoint, it is not started. /// </exception> public void Stop(object localEndPoint) { if (disposed) { throw new ObjectDisposedException("UdpClientTransport"); } if (this.udpClient == null) { throw new InvalidOperationException( "udp client is not connected to server, must invoke Start() first."); } if (localEndPoint == null) { throw new ArgumentNullException("localEndPoint"); } IPEndPoint localEP = localEndPoint as IPEndPoint; if (localEP == null) { Utility.StopTransportByPort(this, null, this.socketConfig.LocalIpAddress, localEndPoint); return; } if (this.lspHooked) { localEP = this.udpClient.Client.LocalEndPoint as IPEndPoint; LspConsole.Instance.UnblockTraffic(localEP, this.socketConfig.Type); } if (!localEP.Equals(this.udpClient.Client.LocalEndPoint)) { throw new InvalidOperationException("failed to stop the endpoint, it is not started."); } this.thread.Stop(); this.thread = null; this.udpClient.Close(); this.udpClient = null; }
/// <summary> /// start at the specified endpoint<para/> /// the underlayer transport must be TcpServer, UdpServer or NetbiosServer. /// </summary> /// <param name="localEndPoint"> /// an object that specifies the listener. /// </param> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when localEndPoint is null. /// </exception> /// <exception cref="ArgumentException"> /// thrown when localEndPoint is not an IPEndPoint/port. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the udp client is started. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the received thread does not cleanup. /// </exception> public void Start(object localEndPoint) { if (disposed) { throw new ObjectDisposedException("UdpClientTransport"); } if (localEndPoint == null) { throw new ArgumentNullException("localEndPoint"); } if (this.udpClient != null) { throw new InvalidOperationException("udp client is started."); } if (this.thread != null) { throw new InvalidOperationException("the received thread does not cleanup."); } IPEndPoint requiredLocalEP = localEndPoint as IPEndPoint; if (requiredLocalEP == null) { if (this.socketConfig.LocalIpAddress == null) { this.socketConfig.LocalIpAddress = IPAddress.Any; } requiredLocalEP = Utility.GetEndPointByPort(this.socketConfig, localEndPoint); } this.socketConfig.LocalIpAddress = requiredLocalEP.Address; this.socketConfig.LocalIpPort = requiredLocalEP.Port; this.eventQueue.Clear(); this.packetCache.Clear(); this.buffer.Clear(); bool isLspHooked; bool isBlocking; StackTransportType type = this.socketConfig.Type; // get the replaced endpoint from LSP. IPEndPoint actualListenedLocalEP = LspConsole.Instance.GetReplacedEndPoint(type, requiredLocalEP, out isLspHooked, out isBlocking); // store the lsp state. this.lspHooked = isLspHooked; this.udpClient = new UdpClient(actualListenedLocalEP); if (socketConfig.LocalIpPort == 0) { //If set local Port to 0, a free port will be selected socketConfig.LocalIpPort = (udpClient.Client.LocalEndPoint as IPEndPoint).Port; } // if LSP is enabled, intercept the traffic if (isLspHooked) { LspConsole.Instance.InterceptTraffic(type, isBlocking, requiredLocalEP, (IPEndPoint)this.udpClient.Client.LocalEndPoint); } this.thread = new ThreadManager(this.UdpClientReceiveLoop, this.UnblockReceiveThread); this.thread.Start(); }
public static void Visit( IVisitorUdpReceiveLoop host, ITransport server, UdpClient udpClient, ThreadManager thread, bool isLspHooked) { byte[] data = null; // get the endpoint of tcp client. IPEndPoint localEP = host.LspHookedLocalEP; while (!thread.ShouldExit) { try { // received data from server. IPEndPoint remoteEP = null; data = udpClient.Receive(ref remoteEP); if (data == null) { break; } if(isLspHooked) { int numBytesReceived = data.Length; if (numBytesReceived < Marshal.SizeOf(typeof(LspUdpHeader))) { throw new FormatException("Invalid LSP udp packet received"); } //Get udp header byte[] udpHeaderBuffer = ArrayUtility.SubArray(data, 0, Marshal.SizeOf(typeof(LspUdpHeader))); IntPtr p = Marshal.AllocHGlobal(udpHeaderBuffer.Length); Marshal.Copy(udpHeaderBuffer, 0, p, udpHeaderBuffer.Length); LspUdpHeader udpHeader = (LspUdpHeader)Marshal.PtrToStructure(p, typeof(LspUdpHeader)); Marshal.FreeHGlobal(p); //get address byte[] srcAddressArray = ArrayUtility.SubArray<byte>(data, Marshal.SizeOf(typeof(LspUdpHeader)), udpHeader.HeaderLength - Marshal.SizeOf(typeof(LspUdpHeader))); string srcAddress = Encoding.ASCII.GetString(srcAddressArray); //replacement numBytesReceived = numBytesReceived - udpHeader.HeaderLength; byte[] msgBody = new byte[numBytesReceived]; Array.Copy(data, udpHeader.HeaderLength, msgBody, 0, numBytesReceived); //endPoint is real remote client endpoint, remoteEP is LspDll's endpoint IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(srcAddress), udpHeader.Port); //map from the real endpoint to the lsp dll endpoint //when sending response to the real endpoint, response will be sent to the lsp dll endpoint //and the lsp dll will relay it to the real endpoint LspConsole.Instance.SetMappedIPEndPoint( (IPEndPoint)udpClient.Client.LocalEndPoint, (IPEndPoint)endPoint, (IPEndPoint)remoteEP, StackTransportType.Udp); host.VisitorAddReceivedData(msgBody, localEP, (IPEndPoint)endPoint); } else { host.VisitorAddReceivedData(data, localEP, remoteEP); } } catch (Exception ex) { // handle exception event, return. server.AddEvent(new TransportEvent(EventType.Exception, localEP, ex)); break; } } }
/// <summary> /// disconnect from remote host.<para/> /// the underlayer transport must be TcpClient, NetbiosClient, TcpServer or NetbiosServer.<para/> /// client side will disconnect the connection to server.<para/> /// server side will disconnect all client connection. /// </summary> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when tcp client is not connected to server, must invoke Connect() first. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the received thread does not initialize. /// </exception> public void Disconnect() { if (disposed) { throw new ObjectDisposedException("TcpClientTransport"); } if (this.stream == null) { throw new InvalidOperationException( "tcp client is not connected to server, must invoke Connect() first."); } if (this.thread == null) { throw new InvalidOperationException("the received thread does not initialize."); } this.thread.Dispose(); this.thread = null; this.stream.Close(); this.stream = null; }
/// <summary> /// connect to remote endpoint.<para/> /// the underlayer transport must be TcpClient, UdpClient or NetbiosClient. /// </summary> /// <returns> /// the remote endpoint of the connection. /// </returns> /// <exception cref="InvalidOperationException"> /// thrown when tcp client is connected to server. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the received thread does not cleanup. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the remote ip address is null. /// </exception> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> public object Connect() { if (disposed) { throw new ObjectDisposedException("TcpClientTransport"); } if (this.stream != null) { throw new InvalidOperationException("tcp client is connected to server."); } if (this.thread != null) { throw new InvalidOperationException("the received thread does not cleanup."); } if (this.socketConfig.RemoteIpAddress == null) { throw new InvalidOperationException("the remote ip address is null."); } this.buffer = new BytesBuffer(); this.eventQueue.Clear(); this.packetCache.Clear(); TcpClient tcpClient; if (this.socketConfig.LocalIpAddress != null) { tcpClient = new TcpClient(new IPEndPoint(this.socketConfig.LocalIpAddress, 0)); } else { tcpClient = new TcpClient(this.socketConfig.RemoteIpAddress.AddressFamily); } // The Timeout be set to TimeSpan.Zero if it is not initialized. if (this.socketConfig.Timeout != TimeSpan.Zero) { IAsyncResult result = tcpClient.BeginConnect(this.socketConfig.RemoteIpAddress, this.socketConfig.RemoteIpPort, new AsyncCallback(TcpConnectCallback), tcpClient); result.AsyncWaitHandle.WaitOne(this.socketConfig.Timeout, true); if (!tcpClient.Connected) { throw new TimeoutException(string.Format(CultureInfo.InvariantCulture, "Failed to connect server {0}:{1} within {2} milliseconds.", this.socketConfig.RemoteIpAddress,this.socketConfig.RemoteIpPort, this.socketConfig.Timeout.TotalMilliseconds)); } } else { tcpClient.Connect(new IPEndPoint(this.socketConfig.RemoteIpAddress, this.socketConfig.RemoteIpPort)); } this.localEndPoint = tcpClient.Client.LocalEndPoint; this.remoteEndPoint = tcpClient.Client.RemoteEndPoint; this.stream = tcpClient.GetStream(); if (this.sslProvider != null) { SslStream sslStream = new SslStream(this.stream); if (this.sslProvider.Certificate == null) { sslStream.AuthenticateAsClient(this.sslProvider.TargetHost); } else { sslStream.AuthenticateAsClient(this.sslProvider.TargetHost, new X509CertificateCollection(new X509Certificate[] { this.sslProvider.Certificate }), this.sslProvider.EnabledSslProtocols, false); } this.stream = sslStream; } this.thread = new ThreadManager(TcpClientReceiveLoop, UnblockReceiveThread); this.thread.Start(); return this.localEndPoint; }
/// <summary> /// constructor /// </summary> /// <param name="localEndPoint"> /// an int value that specifies the session id of connection. /// </param> /// <param name="remoteEndPoint"> /// an int value that specifies the session id of connection. /// </param> /// <param name="server"> /// NetbiosServerTransport object that specifies the netbios server transport. /// </param> /// <param name="transport"> /// a NetbiosTransport object that specifies the owner of client. /// </param> /// <exception cref="ArgumentNullException"> /// thrown when the server is null! /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when the transport is null! /// </exception> public NetbiosServerConnection( int localEndPoint, int remoteEndPoint, NetbiosServerTransport server, NetbiosTransport transport) { if (server == null) { throw new ArgumentNullException("server"); } if (transport == null) { throw new ArgumentNullException("transport"); } this.localEndPoint = localEndPoint; this.remoteEndPoint = remoteEndPoint; this.server = server; this.transport = transport; this.thread = new ThreadManager(NetbiosServerConnectionReceiveLoop, Unblock); this.buffer = new BytesBuffer(); }
/// <summary> /// connect to remote endpoint.<para/> /// the underlayer transport must be TcpClient, UdpClient or NetbiosClient. /// </summary> /// <returns> /// the remote endpoint of the connection. /// </returns> /// <exception cref="InvalidOperationException"> /// thrown when tcp client is connected to server. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the received thread does not cleanup. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the remote ip address is null. /// </exception> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> public object Connect() { if (disposed) { throw new ObjectDisposedException("TcpClientTransport"); } if (this.stream != null) { throw new InvalidOperationException("tcp client is connected to server."); } if (this.thread != null) { throw new InvalidOperationException("the received thread does not cleanup."); } if (this.socketConfig.RemoteIpAddress == null) { throw new InvalidOperationException("the remote ip address is null."); } this.buffer = new BytesBuffer(); this.eventQueue.Clear(); this.packetCache.Clear(); TcpClient tcpClient; if (this.socketConfig.LocalIpAddress != null) { tcpClient = new TcpClient(new IPEndPoint(this.socketConfig.LocalIpAddress, 0)); } else { tcpClient = new TcpClient(this.socketConfig.RemoteIpAddress.AddressFamily); } // The Timeout be set to TimeSpan.Zero if it is not initialized. if (this.socketConfig.Timeout != TimeSpan.Zero) { IAsyncResult result = tcpClient.BeginConnect(this.socketConfig.RemoteIpAddress, this.socketConfig.RemoteIpPort, new AsyncCallback(TcpConnectCallback), tcpClient); result.AsyncWaitHandle.WaitOne(this.socketConfig.Timeout, true); if (!tcpClient.Connected) { throw new TimeoutException(string.Format(CultureInfo.InvariantCulture, "Failed to connect server {0}:{1} within {2} milliseconds.", this.socketConfig.RemoteIpAddress, this.socketConfig.RemoteIpPort, this.socketConfig.Timeout.TotalMilliseconds)); } } else { tcpClient.Connect(new IPEndPoint(this.socketConfig.RemoteIpAddress, this.socketConfig.RemoteIpPort)); } this.localEndPoint = tcpClient.Client.LocalEndPoint; this.remoteEndPoint = tcpClient.Client.RemoteEndPoint; this.stream = tcpClient.GetStream(); if (this.sslProvider != null) { SslStream sslStream = new SslStream(this.stream); if (this.sslProvider.Certificate == null) { sslStream.AuthenticateAsClient(this.sslProvider.TargetHost); } else { sslStream.AuthenticateAsClient(this.sslProvider.TargetHost, new X509CertificateCollection(new X509Certificate[] { this.sslProvider.Certificate }), this.sslProvider.EnabledSslProtocols, false); } this.stream = sslStream; } this.thread = new ThreadManager(TcpClientReceiveLoop, UnblockReceiveThread); this.thread.Start(); return(this.localEndPoint); }
/// <summary> /// constructor /// </summary> /// <param name="udpListener"> /// a UdpClient that specifies the listener. /// </param> /// <param name="udpServerTransport"> /// a UdpServerTransport that represents the owner of listener. /// </param> /// <param name="isLspHooked"> /// a bool value that indicates whether lsp hooked the transport. /// </param> /// <exception cref="ArgumentNullException"> /// thrown when tcpListener is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when tcpServerTransport is null. /// </exception> public UdpServerListener(UdpClient udpListener, UdpServerTransport udpServerTransport, bool isLspHooked) { if (udpListener == null) { throw new ArgumentNullException("udpListener"); } if (udpServerTransport == null) { throw new ArgumentNullException("udpServerTransport"); } this.lspHooked = isLspHooked; this.listener = udpListener; this.server = udpServerTransport; this.thread = new ThreadManager(UdpServerListenerReceiveLoop, Unblock); }
/// <summary> /// stop the listener: stop the listening thread. /// </summary> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> public void Stop() { if (disposed) { throw new ObjectDisposedException("NetbiosServerListener"); } if (this.thread == null) { return; } this.thread.Stop(); this.thread = null; }
/// <summary> /// connect to remote endpoint.<para/> /// the underlayer transport must be NetbiosTransport, UdpClient or NetbiosClient. /// </summary> /// <returns> /// the remote endpoint of the connection. /// </returns> /// <exception cref="InvalidOperationException"> /// thrown when netbios client is connected to server. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the received thread does not cleanup. /// </exception> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> public object Connect() { if (disposed) { throw new ObjectDisposedException("NetbiosClientTransport"); } if (this.transport != null) { throw new InvalidOperationException("netbios client is connected to server."); } if (this.thread != null) { throw new InvalidOperationException("the received thread does not cleanup."); } this.buffer = new BytesBuffer(); this.eventQueue.Clear(); this.packetCache.Clear(); this.transport = new NetbiosTransport( this.netbiosConfig.LocalNetbiosName, this.netbiosConfig.AdapterIndex, (ushort)this.netbiosConfig.BufferSize, (byte)this.netbiosConfig.MaxSessions, (byte)this.netbiosConfig.MaxNames); this.remoteEndPoint = this.transport.Connect(this.netbiosConfig.RemoteNetbiosName); this.localEndPoint = this.transport.NcbNum; this.thread = new ThreadManager(NetbiosClientReceiveLoop, UnblockReceiveThread); this.thread.Start(); return this.remoteEndPoint; }
/// <summary> /// disconnect from remote host.<para/> /// the underlayer transport must be NetbiosTransport, NetbiosClient, NetbiosServer or NetbiosServer.<para/> /// client side will disconnect the connection to server.<para/> /// server side will disconnect all client connection. /// </summary> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when netbios client is not connected to server, must invoke Connect() first. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when the received thread does not initialize. /// </exception> public void Disconnect() { if (disposed) { throw new ObjectDisposedException("NetbiosClientTransport"); } if (this.transport == null) { throw new InvalidOperationException( "netbios client is not connected to server, must invoke Connect() first."); } if (this.thread == null) { throw new InvalidOperationException("the received thread does not initialize."); } this.transport.Disconnect(this.remoteEndPoint); this.thread.Dispose(); this.thread = null; this.transport.Dispose(); this.transport = null; }
/// <summary> /// constructor /// </summary> /// <param name="tcpClient"> /// a TcpClient object that specifies the tcp client. /// </param> /// <param name="tcpServerTransport"> /// a TcpServerTransport that represents the owner of listener. /// </param> /// <param name="lspHookedLocalEP"> /// an IPEndPoint object that specifies the local endpoint.<para/> /// if LSP hooked, return the required local endpoint.<para/> /// otherwise, return the actual listened local endpoint. /// </param> /// <param name="isLspHooked"> /// a bool value that indicates whether lsp hooked the transport. /// </param> /// <exception cref="ArgumentNullException"> /// thrown when the tcpClient is null! /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when the tcpServerTransport is null! /// </exception> public TcpServerConnection( TcpClient tcpClient, TcpServerTransport tcpServerTransport, IPEndPoint lspHookedLocalEP, bool isLspHooked) { if (tcpClient == null) { throw new ArgumentNullException("tcpClient"); } if (tcpServerTransport == null) { throw new ArgumentNullException("tcpServerTransport"); } this.isAForwarderChannel = false; this.lspHooked = isLspHooked; this.stream = tcpClient.GetStream(); this.server = tcpServerTransport; this.thread = new ThreadManager(TcpServerConnectionReceiveLoop, Unblock); this.buffer = new BytesBuffer(); if (isLspHooked) { IPEndPoint destinationEndpoint; this.localEndPoint = lspHookedLocalEP; this.remoteEndPoint = LspConsole.Instance.RetrieveRemoteEndPoint(tcpClient.Client, out destinationEndpoint); //if equals, it means this is a forwarder channel. if (remoteEndPoint.Equals(destinationEndpoint)) { isAForwarderChannel = true; } } else { this.localEndPoint = tcpClient.Client.LocalEndPoint as IPEndPoint; this.remoteEndPoint = tcpClient.Client.RemoteEndPoint as IPEndPoint; } }