private void CreateRpcConnection(string server, RpcProtocol protocol, NetworkCredential credential = null) { EndpointBindingInfo binding; switch (protocol) { case RpcProtocol.TCP: binding = new EndpointBindingInfo(RpcProtseq.ncacn_ip_tcp, server, null); break; case RpcProtocol.SMB: binding = new EndpointBindingInfo(RpcProtseq.ncacn_np, server, DrsNamedPipeName); if (credential != null) { // Connect named pipe this.npConnection = new NamedPipeConnection(server, credential); } break; default: // TODO: Extract as string throw new NotImplementedException("The requested RPC protocol is not supported."); } this.rpcConnection = new NativeClient(binding); NetworkCredential rpcCredential = credential ?? Client.Self; string spn = String.Format(ServicePrincipalNameFormat, server); this.rpcConnection.AuthenticateAs(spn, rpcCredential, RPC_C_AUTHN_LEVEL.RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN.RPC_C_AUTHN_GSS_NEGOTIATE); }
private void CreateRpcConnection(string server, RpcProtocol protocol, NetworkCredential credential = null) { EndpointBindingInfo binding; switch (protocol) { case RpcProtocol.TCP: binding = new EndpointBindingInfo(RpcProtseq.ncacn_ip_tcp, server, null); break; case RpcProtocol.SMB: binding = new EndpointBindingInfo(RpcProtseq.ncacn_np, server, DrsNamedPipeName); if (credential != null) { // Connect named pipe this.npConnection = new NamedPipeConnection(server, credential); } break; default: // TODO: Custom exception type // TODO: Extract as string throw new Exception("Unsupported RPC protocol"); } NetworkCredential rpcCredential = credential ?? Client.Self; this.rpcConnection = new NativeClient(binding); this.rpcConnection.AuthenticateAs(rpcCredential); }
public DirectoryReplicationClient(string server, RpcProtocol protocol, NetworkCredential credential = null) { Validator.AssertNotNullOrWhiteSpace(server, nameof(server)); this.CreateRpcConnection(server, protocol, credential); this.drsConnection = new DrsConnection(this.rpcConnection.Binding, NtdsApiClientGuid); }
public DirectoryReplicationClient(string server, RpcProtocol protocol, NetworkCredential credential = null) { this.CreateRpcConnection(server, protocol, credential); this.drsConnection = new DrsConnection(this.rpcConnection.Binding, DcPromoGuid2k3); }
private void CreateRpcConnection(string server, RpcProtocol protocol, NetworkCredential credential = null) { EndpointBindingInfo binding; switch(protocol) { case RpcProtocol.TCP: binding = new EndpointBindingInfo(RpcProtseq.ncacn_ip_tcp, server, null); break; case RpcProtocol.SMB: binding = new EndpointBindingInfo(RpcProtseq.ncacn_np, server, DrsNamedPipeName); if(credential != null) { // Connect named pipe this.npConnection = new NamedPipeConnection(server, credential); } break; default: // TODO: Custom exception type // TODO: Extract as string throw new Exception("Unsupported RPC protocol"); } NetworkCredential rpcCredential = credential ?? Client.Self; this.rpcConnection = new NativeClient(binding); this.rpcConnection.AuthenticateAs(rpcCredential); }
/// <summary> /// Construct a new RpcBuffer /// </summary> /// <param name="name">The unique channel name. This is the name to be shared between the master/slave pair. Each pair must have a unique value.</param> /// <param name="bufferCapacity">Master only: Maximum buffer capacity. Messages will be split into packets that fit this capacity (including a packet header of 64-bytes). The slave will use the same size as defined by the master</param> /// <param name="protocolVersion">ProtocolVersion.V1 = 64-byte header for each packet</param> /// <param name="bufferNodeCount">Master only: The number of nodes in the underlying circular buffers, each with a size of <paramref name="bufferCapacity"/></param> public RpcBuffer(string name, int bufferCapacity = 50000, RpcProtocol protocolVersion = RpcProtocol.V1, int bufferNodeCount = 10) { if (bufferCapacity < 256) // min 256 bytes { throw new ArgumentOutOfRangeException(nameof(bufferCapacity), "cannot be less than 256 bytes"); } if (bufferCapacity > 1024 * 1024) // max 1MB { throw new ArgumentOutOfRangeException(nameof(bufferCapacity), "cannot be larger than 1MB"); } Statistics = new RpcStatistics(); masterMutex = new Mutex(true, name + "SharedMemory_MasterMutex", out bool createdNew); if (createdNew && masterMutex.WaitOne(500)) { instanceType = InstanceType.Master; } else { instanceType = InstanceType.Slave; if (masterMutex != null) { masterMutex.Close(); masterMutex.Dispose(); masterMutex = null; } } switch (protocolVersion) { case RpcProtocol.V1: this.protocolVersion = protocolVersion; protocolLength = FastStructure.SizeOf <RpcProtocolHeaderV1>(); Statistics.ProtocolOverheadPerPacket = protocolLength; break; } this.bufferCapacity = bufferCapacity; this.bufferNodeCount = bufferNodeCount; if (instanceType == InstanceType.Master) { WriteBuffer = new CircularBuffer(name + "_Slave_SharedMemory_MMF", bufferNodeCount, this.bufferCapacity); ReadBuffer = new CircularBuffer(name + "_Master_SharedMemory_MMF", bufferNodeCount, this.bufferCapacity); } else { ReadBuffer = new CircularBuffer(name + "_Slave_SharedMemory_MMF"); WriteBuffer = new CircularBuffer(name + "_Master_SharedMemory_MMF"); this.bufferCapacity = ReadBuffer.NodeBufferSize; this.bufferNodeCount = ReadBuffer.NodeCount; } this.msgBufferLength = Convert.ToInt32(this.bufferCapacity) - protocolLength; Task.Run(() => { switch (protocolVersion) { case RpcProtocol.V1: ReadThreadV1(); break; } }); }
/// <summary> /// Construct a new RpcBuffer /// </summary> /// <param name="name">The unique channel name. This is the name to be shared between the master/slave pair. Each pair must have a unique value.</param> /// <param name="asyncRemoteCallHandlerWithResult">Function to asynchronously handle requests with a response.</param> /// <param name="bufferCapacity">Master only: Maximum buffer capacity. Messages will be split into packets that fit this capacity (including a packet header of 64-bytes). The slave will use the same size as defined by the master</param> /// <param name="protocolVersion">ProtocolVersion.V1 = 64-byte header for each packet</param> /// <param name="bufferNodeCount">Master only: The number of nodes in the underlying circular buffers, each with a size of <paramref name="bufferCapacity"/></param> public RpcBuffer(string name, Func <ulong, byte[], Task <byte[]> > asyncRemoteCallHandlerWithResult, int bufferCapacity = 50000, RpcProtocol protocolVersion = RpcProtocol.V1, int bufferNodeCount = 10) : this(name, bufferCapacity, protocolVersion, bufferNodeCount) { AsyncRemoteCallHandlerWithResult = asyncRemoteCallHandlerWithResult; }
/// <summary> /// Construct a new RpcBuffer /// </summary> /// <param name="name">The channel name. This is the name to be shared between the master/slave pair. Each pair must have a unique value.</param> /// <param name="remoteCallHandler">Action to handle requests with no response.</param> /// <param name="bufferCapacity">Master only: Maximum buffer capacity. Messages will be split into packets that fit this capacity (including a packet header of 64-bytes). The slave will use the same size as defined by the master</param> /// <param name="protocolVersion">ProtocolVersion.V1 = 64-byte header for each packet</param> /// <param name="bufferNodeCount">Master only: The number of nodes in the underlying circular buffers, each with a size of <paramref name="bufferCapacity"/></param> public RpcBuffer(string name, Action <ulong, byte[]> remoteCallHandler, int bufferCapacity = 50000, RpcProtocol protocolVersion = RpcProtocol.V1, int bufferNodeCount = 10) : this(name, bufferCapacity, protocolVersion, bufferNodeCount) { RemoteCallHandler = remoteCallHandler; }