/// <summary> /// Constructor /// </summary> /// <param name="config">The config, contains information about transport type, tcp listening port and so on</param> public Smb2Server(Smb2ServerConfig config) { decoder = new Smb2Decoder(Smb2Role.Server); decoder.TransportType = config.TransportType; clientEndpoints = new List<Smb2Endpoint>(); context = new Smb2ServerContext(); context.transportType = config.TransportType; context.requireMessageSigning = config.RequireMessageSigning; context.isDfsCapable = config.IsDfsCapable; transportType = config.TransportType; if (transportType == Smb2TransportType.NetBios) { NetbiosTransportConfig netbiosConfig = new NetbiosTransportConfig(); netbiosConfig.BufferSize = Smb2Consts.MaxNetbiosBufferSize; netbiosConfig.LocalNetbiosName = config.LocalNetbiosName; netbiosConfig.MaxNames = Smb2Consts.MaxNames; netbiosConfig.MaxSessions = Smb2Consts.MaxSessions; netbiosConfig.Type = StackTransportType.Netbios; netbiosConfig.Role = Role.Server; transport = new TransportStack(netbiosConfig, decoder.Smb2DecodePacketCallback); } else if (transportType == Smb2TransportType.Tcp) { SocketTransportConfig socketConfig = new SocketTransportConfig(); socketConfig.BufferSize = Smb2Consts.MaxNetbiosBufferSize; socketConfig.MaxConnections = Smb2Consts.MaxConnectionNumer; socketConfig.LocalIpAddress = IPAddress.Any; socketConfig.LocalIpPort = config.ServerTcpListeningPort; socketConfig.Role = Role.Server; socketConfig.Type = StackTransportType.Tcp; transport = new TransportStack(socketConfig, decoder.Smb2DecodePacketCallback); } else { throw new ArgumentException("config contains invalid transport type", "config"); } }
/// <summary> /// to update the config of transport at runtime. /// </summary> /// <param name="config"> /// a TransportConfig object that contains the config to update /// </param> /// <exception cref="ArgumentException"> /// thrown when transportConfig is not SocketTransportConfig /// </exception> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when config is null. /// </exception> public void UpdateConfig(TransportConfig config) { if (disposed) { throw new ObjectDisposedException("TcpClientTransport"); } if (config == null) { throw new ArgumentNullException("config"); } SocketTransportConfig socketTransportConfig = config as SocketTransportConfig; if (socketTransportConfig == null) { throw new ArgumentException("transportConfig must be SocketTransportConfig", "config"); } this.socketConfig = socketTransportConfig; }
/// <summary> /// get the endpoint to listen by the port.<para/> /// retrieve the address from socket config. /// </summary> /// <param name="socketConfig"> /// a SocketTransportConfig object that contains the LocalAddress. /// </param> /// <param name="localEndPoint"> /// an int value that specifies the port to start at. /// </param> /// <returns> /// an IPEndPoint object that specifies the endpoint to listen at. /// </returns> public static IPEndPoint GetEndPointByPort(SocketTransportConfig socketConfig, object localEndPoint) { int port; try { port = Convert.ToInt32(localEndPoint, CultureInfo.InvariantCulture); } catch (Exception) { throw new ArgumentException("localEndPoint is not an IPEndPoint/port.", "localEndPoint"); } if (socketConfig.LocalIpAddress == null) { throw new InvalidOperationException( "localEndPoint is an int port, but the LocalIpAddress is not configured."); } return(new IPEndPoint(socketConfig.LocalIpAddress, port)); }
public void Start(ushort localPort, KileConnectionType transportType, KileIpType ipType, int transportSize) { SocketTransportConfig transportConfig = new SocketTransportConfig(); transportConfig.Role = Role.Server; transportConfig.MaxConnections = ConstValue.MAX_CONNECTIONS; transportConfig.BufferSize = transportSize; if (ipType == KileIpType.Ipv4) { transportConfig.LocalIpAddress = IPAddress.Any; } else { transportConfig.LocalIpAddress = IPAddress.IPv6Any; } transportConfig.LocalIpPort = localPort; if (transportType == KileConnectionType.TCP) { transportConfig.Type = StackTransportType.Tcp; } else if (transportType == KileConnectionType.UDP) { transportConfig.Type = StackTransportType.Udp; } else { throw new ArgumentException("ConnectionType can only be TCP or UDP."); } decoder = new KileDecoder(contextList, transportType); transport = new TransportStack(transportConfig, decoder.DecodePacketCallback); transport.Start(); }
/// <summary> /// to set up the tcp connection, and add the connection into context. Exception will be thrown if failed to /// set up connection with server. /// </summary> /// <param name = "serverName">the server name or server ip address to connect to </param> /// <param name = "serverPort">the port of server to connect to </param> /// <param name = "ipVersion">the ipversion to connect to server </param> /// <param name = "bufferSize">the buffer size of transport </param> /// <exception cref="InvalidOperationException"> /// Failed to get the IP address of SMB server in SmbClient(). /// </exception> public virtual void Connect(string serverName, int serverPort, IpVersion ipVersion, int bufferSize) { // initialize the config for transport SocketTransportConfig config = new SocketTransportConfig(); config.Role = Role.Client; config.Type = StackTransportType.Tcp; config.BufferSize = bufferSize; // init remote address of config #region Lookup the ip address from server name. IPHostEntry ipHostEntry = Dns.GetHostEntry(serverName); if (ipHostEntry != null) { foreach (IPAddress address in ipHostEntry.AddressList) { if (ipVersion != IpVersion.Ipv4 && address.AddressFamily == AddressFamily.InterNetworkV6) { config.LocalIpAddress = IPAddress.IPv6Any; config.RemoteIpAddress = address; break; } else if (ipVersion != IpVersion.Ipv6 && address.AddressFamily == AddressFamily.InterNetwork) { config.LocalIpAddress = IPAddress.Any; config.RemoteIpAddress = address; break; } else { continue; } } } if (config.RemoteIpAddress == null) { throw new InvalidOperationException("Failed to get the IP address of SMB server in SmbClient()."); } #endregion // init remote port config.RemoteIpPort = serverPort; // init local address of config config.LocalIpAddress = IPAddress.Any; config.LocalIpPort = 0; // init transport this.transport = new TransportStack(config, new SmbClientDecodePacket(this).DecodePacket); // connect to server. object endPointIdentity = this.transport.Connect(); // initialize the connection SmbClientConnection connection = new SmbClientConnection(); connection.ConnectionId = this.Context.GetConnectionID(endPointIdentity as IPEndPoint); connection.ConnectionState = StackTransportState.ConnectionEstablished; connection.MaxBufferSize = (uint)bufferSize; // update the context this.cifsClient.Context.AddOrUpdateConnection(connection); // update the connection id, to identity the connection instance. this.ConnectionId = connection.ConnectionId; // set the transport type this.capability.TransportType = TransportType.TCP; }
/// <summary> /// to start the smbserver, tcp transport. /// </summary> /// <param name="serverAddress">the address of server</param> /// <param name="localPort">the local port to bind for server</param> /// <param name="maxConnections">the max connections of server capability</param> /// <param name="bufferSize">the buffer size of transport </param> /// <param name="accountCredential">the credential to authenticate client, spn is always cifs/machine</param> public virtual void Start(IPAddress serverAddress, int localPort, int maxConnections, int bufferSize, AccountCredential accountCredential) { this.credential = accountCredential; SocketTransportConfig config = new SocketTransportConfig(); config.Type = StackTransportType.Tcp; config.Role = Role.Server; config.LocalIpAddress = serverAddress; config.LocalIpPort = localPort; config.MaxConnections = maxConnections; config.BufferSize = bufferSize; SmbServerDecodePacket decoder = new SmbServerDecodePacket(); decoder.Context = this.context; this.transport = new TransportStack(config, decoder.DecodePacket); this.transport.Start(); this.transportType = TransportType.TCP; }
/// <summary> /// to update the config of transport at runtime. /// </summary> /// <param name="config"> /// a TransportConfig object that contains the config to update /// </param> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="ArgumentException"> /// thrown when transportConfig is not SocketTransportConfig. /// </exception> public void UpdateConfig(TransportConfig config) { if (disposed) { throw new ObjectDisposedException("TcpServerTransport"); } SocketTransportConfig socketTransportConfig = config as SocketTransportConfig; if (socketTransportConfig == null) { throw new ArgumentException("transportConfig must be SocketTransportConfig", "config"); } this.socketConfig = socketTransportConfig; }
/// <summary> /// Starts the server to listen on specified port. /// </summary> public void Start() { if (transportStack == null) { SocketTransportConfig transportConfig = new SocketTransportConfig(); transportConfig.LocalIpAddress = IPAddress.Any; transportConfig.LocalIpPort = this.listenPort; transportConfig.Role = Role.Server; transportConfig.BufferSize = DefaultBufferSize; transportConfig.MaxConnections = int.MaxValue; transportConfig.Type = isTcp ? StackTransportType.Tcp : StackTransportType.Udp; this.transportStack = new TransportStack(transportConfig, decoder.DecodeLdapPacketCallBack); } this.transportStack.Start(); }
public virtual RpceServerContext StartTcp(ushort port) { lock (this.tcpThreadLocker) { RpceServerContext serverContext = this.serverContextManager.LookupServerContext( RpceUtility.RPC_OVER_TCPIP_PROTOCOL_SEQUENCE, port.ToString()); if (serverContext != null) { throw new InvalidOperationException("The server with the port has been started. Please try other port."); } serverContext = new RpceServerContext( RpceUtility.RPC_OVER_TCPIP_PROTOCOL_SEQUENCE, port.ToString()); this.serverContextManager.AddServerContext(serverContext); if (this.openedTcpPortList == null) { this.openedTcpPortList = new List<ushort>(); } this.openedTcpPortList.Add(port); bool ipv4Started = false; bool ipv6Started = false; Exception ex = null; try { if (this.tcpTransport == null) { SocketTransportConfig config = new SocketTransportConfig(); config.Type = StackTransportType.Tcp; config.Role = Role.Server; config.LocalIpAddress = IPAddress.Any; config.MaxConnections = RpceServerContext.DEFAULT_MAX_CONNECTIONS; config.BufferSize = Math.Max(serverContext.MaxReceiveFragmentSize, serverContext.MaxTransmitFragmentSize); this.tcpTransport = new TransportStack(config, RpceDecodePduCallback); } } catch (Exception e) { ex = e; this.tcpTransport = null; } try { //Start IPv4 IPEndPoint ipv4Endpoint = new IPEndPoint(IPAddress.Any, port); this.tcpTransport.Start(ipv4Endpoint); ipv4Started = true; } catch (Exception e) { ex = e; } //Start IPv6 try { IPEndPoint ipv6Endpoint = new IPEndPoint(IPAddress.IPv6Any, port); this.tcpTransport.Start(ipv6Endpoint); ipv6Started = true; } catch (Exception e) { ex = e; } if (!ipv4Started && !ipv6Started) { this.serverContextManager.RemoveServerContext(serverContext); this.openedTcpPortList.Remove(port); throw new InvalidOperationException("TCP server failed to start.", ex); } if (this.tcpReceiveThread == null) { this.tcpReceiveThread = new Thread(TcpReceiveLoop); this.tcpReceiveThread.Start(); } return serverContext; } }
/// <summary> /// Set up the TCP/UDP transport connection with KDC. /// </summary> /// <exception cref="System.ArgumentException">Thrown when the connection type is neither TCP nor UDP</exception> public virtual void Connect() { SocketTransportConfig transportConfig = new SocketTransportConfig(); transportConfig.Role = Role.Client; transportConfig.MaxConnections = 1; transportConfig.BufferSize = TransportBufferSize; transportConfig.RemoteIpPort = kdcPort; transportConfig.RemoteIpAddress = IPAddress.Parse(kdcAddress); // For UDP bind if (transportConfig.RemoteIpAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { transportConfig.LocalIpAddress = IPAddress.Any; } else if (transportConfig.RemoteIpAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { transportConfig.LocalIpAddress = IPAddress.IPv6Any; } if (transportType == TransportType.TCP) { transportConfig.Type = StackTransportType.Tcp; } else if (transportType == TransportType.UDP) { transportConfig.Type = StackTransportType.Udp; } else { throw new ArgumentException("ConnectionType can only be TCP or UDP."); } kdcTransport = new TransportStack(transportConfig, DecodePacketCallback); if (transportType == TransportType.TCP) { kdcTransport.Connect(); } else { kdcTransport.Start(); } }
public void Connect( string protocolSequence, string networkAddress, string endpoint, AccountCredential transportCredential, TimeSpan timeout, SecurityPackageType securityPackage) { if (protocolSequence == null) { throw new ArgumentNullException("protocolSequence"); } if (networkAddress == null) { throw new ArgumentNullException("networkAddress"); } if (endpoint == null) { throw new ArgumentNullException("endpoint"); } if (context.tcpTransport != null || context.fileServiceTransport != null) { throw new InvalidOperationException("RPCE is already connected."); } if (string.Compare(protocolSequence, RpceUtility.RPC_OVER_TCPIP_PROTOCOL_SEQUENCE, true) == 0) { IPAddress[] addresses = Dns.GetHostAddresses(networkAddress); if (addresses == null || addresses.Length == 0) { throw new ArgumentException( "Cannot resolve network address.", "networkAddress"); } IPAddress addr = addresses[0]; int port; if (!int.TryParse(endpoint, out port)) { throw new ArgumentException("Invalid endpoint.", "endpoint"); } SocketTransportConfig config = new SocketTransportConfig(); config.BufferSize = Math.Max(context.MaxTransmitFragmentSize, context.MaxReceiveFragmentSize); config.RemoteIpAddress = addr; config.RemoteIpPort = port; config.Role = Role.Client; config.Type = StackTransportType.Tcp; context.tcpTransport = new TransportStack(config, RpceDecodePduCallback); context.tcpTransport.Connect(); } else if (string.Compare(protocolSequence, RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, true) == 0) { if (!endpoint.StartsWith( RpceUtility.NAMED_PIPE_ENDPOINT_PREFIX, StringComparison.InvariantCultureIgnoreCase)) { throw new ArgumentException("endpoint format is incorrect.", "endpoint"); } if (transportCredential == null) { throw new ArgumentNullException("transportCredential"); } timeoutForFsTransport = timeout; pipeTransceiveResponseQueue = new Queue<byte[]>(); if (!RpceUtility.DisableSmb2) { try { context.fileServiceTransport = new Smb2ClientTransport(timeout); context.fileServiceTransport.ConnectShare( networkAddress, RpceUtility.NAMED_PIPE_PORT, IpVersion.Any, transportCredential.DomainName, transportCredential.AccountName, transportCredential.Password, RpceUtility.NAMED_PIPE_SHARENAME, securityPackage, false); } catch { context.fileServiceTransport.Dispose(); context.fileServiceTransport = null; } } if (context.fileServiceTransport == null) { // Remote doesn't support SMB2, use SMB. context.fileServiceTransport = new SmbClientTransport(); context.fileServiceTransport.ConnectShare( networkAddress, RpceUtility.NAMED_PIPE_PORT, IpVersion.Any, transportCredential.DomainName, transportCredential.AccountName, transportCredential.Password, RpceUtility.NAMED_PIPE_SHARENAME, securityPackage, false); } context.fileServiceTransport.Create( endpoint.Substring(RpceUtility.NAMED_PIPE_ENDPOINT_PREFIX.Length), FsFileDesiredAccess.FILE_READ_DATA | FsFileDesiredAccess.FILE_WRITE_DATA | FsFileDesiredAccess.FILE_APPEND_DATA | FsFileDesiredAccess.FILE_READ_EA | FsFileDesiredAccess.FILE_WRITE_EA | FsFileDesiredAccess.FILE_READ_ATTRIBUTES | FsFileDesiredAccess.FILE_WRITE_ATTRIBUTES | FsFileDesiredAccess.READ_CONTROL | FsFileDesiredAccess.SYNCHRONIZE, FsImpersonationLevel.Impersonation, FsFileAttribute.NONE, FsCreateDisposition.FILE_OPEN, FsCreateOption.FILE_NON_DIRECTORY_FILE | FsCreateOption.FILE_OPEN_NO_RECALL); } else { throw new NotSupportedException("Specified protocol sequence is not supported."); } context.ProtocolSequence = protocolSequence; context.NetworkAddress = networkAddress; context.Endpoint = endpoint; // Make handle always different. handle = new IntPtr(Environment.TickCount); }