private NamedPipeServerStream(String pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability) : base(direction, transmissionMode, outBufferSize) { if (pipeName == null) { throw new ArgumentNullException("pipeName"); } if (pipeName.Length == 0) { throw new ArgumentException(SR.Argument_NeedNonemptyPipeName); } if ((options & ~(PipeOptions.WriteThrough | PipeOptions.Asynchronous)) != 0) { throw new ArgumentOutOfRangeException("options", SR.ArgumentOutOfRange_OptionsInvalid); } if (inBufferSize < 0) { throw new ArgumentOutOfRangeException("inBufferSize", SR.ArgumentOutOfRange_NeedNonNegNum); } ValidateMaxNumberOfServerInstances(maxNumberOfServerInstances); // inheritability will always be None since this private constructor is only called from other constructors from which // inheritability is always set to None. Desktop has a public constructor to allow setting it to something else, but Core // doesnt. if (inheritability < HandleInheritability.None || inheritability > HandleInheritability.Inheritable) { throw new ArgumentOutOfRangeException("inheritability", SR.ArgumentOutOfRange_HandleInheritabilityNoneOrInheritable); } Create(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, inheritability); }
private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability) { Debug.Assert(pipeName != null && pipeName.Length != 0, "fullPipeName is null or empty"); Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction"); Debug.Assert(inBufferSize >= 0, "inBufferSize is negative"); Debug.Assert(outBufferSize >= 0, "outBufferSize is negative"); Debug.Assert((maxNumberOfServerInstances >= 1) || (maxNumberOfServerInstances == MaxAllowedServerInstances), "maxNumberOfServerInstances is invalid"); Debug.Assert(transmissionMode >= PipeTransmissionMode.Byte && transmissionMode <= PipeTransmissionMode.Message, "transmissionMode is out of range"); if (transmissionMode == PipeTransmissionMode.Message) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_MessageTransmissionMode); } // NOTE: We don't have a good way to enforce maxNumberOfServerInstances, and don't currently try. // It's a Windows-specific concept. _path = GetPipePath(".", pipeName); _direction = direction; _options = options; _inBufferSize = inBufferSize; _outBufferSize = outBufferSize; _inheritability = inheritability; }
private NamedPipeServerStream(String pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability) : base(direction, transmissionMode, outBufferSize) { if (pipeName == null) { throw new ArgumentNullException("pipeName"); } if (pipeName.Length == 0) { throw new ArgumentException(SR.Argument_NeedNonemptyPipeName); } if ((options & ~(PipeOptions.WriteThrough | PipeOptions.Asynchronous)) != 0) { throw new ArgumentOutOfRangeException("options", SR.ArgumentOutOfRange_OptionsInvalid); } if (inBufferSize < 0) { throw new ArgumentOutOfRangeException("inBufferSize", SR.ArgumentOutOfRange_NeedNonNegNum); } // win32 allows fixed values of 1-254 or 255 to mean max allowed by system. We expose 255 as -1 (unlimited) // through the MaxAllowedServerInstances constant. This is consistent e.g. with -1 as infinite timeout, etc if ((maxNumberOfServerInstances < 1 || maxNumberOfServerInstances > 254) && (maxNumberOfServerInstances != MaxAllowedServerInstances)) { throw new ArgumentOutOfRangeException("maxNumberOfServerInstances", SR.ArgumentOutOfRange_MaxNumServerInstances); } if (inheritability < HandleInheritability.None || inheritability > HandleInheritability.Inheritable) { throw new ArgumentOutOfRangeException("inheritability", SR.ArgumentOutOfRange_HandleInheritabilityNoneOrInheritable); } Create(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, inheritability); }
private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability) { Debug.Assert(pipeName != null && pipeName.Length != 0, "fullPipeName is null or empty"); Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction"); Debug.Assert(inBufferSize >= 0, "inBufferSize is negative"); Debug.Assert(outBufferSize >= 0, "outBufferSize is negative"); Debug.Assert((maxNumberOfServerInstances >= 1) || (maxNumberOfServerInstances == MaxAllowedServerInstances), "maxNumberOfServerInstances is invalid"); Debug.Assert(transmissionMode >= PipeTransmissionMode.Byte && transmissionMode <= PipeTransmissionMode.Message, "transmissionMode is out of range"); if (transmissionMode == PipeTransmissionMode.Message) { throw new PlatformNotSupportedException(); } // NOTE: We don't have a good way to enforce maxNumberOfServerInstances, and don't currently try. // It's a Windows-specific concept. // Make sure the FIFO exists, but don't open it until WaitForConnection is called. _path = GetPipePath(".", pipeName); while (true) { int result = Interop.libc.mkfifo(_path, (int)Interop.libc.Permissions.S_IRWXU); if (result == 0) { // The FIFO was successfully created - note that although we create the FIFO here, we don't // ever delete it. If we remove the FIFO we could invalidate other servers that also use it. // See #2764 for further discussion. break; } Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo(); if (errorInfo.Error == Interop.Error.EINTR) { // interrupted; try again continue; } else if (errorInfo.Error == Interop.Error.EEXIST) { // FIFO already exists; nothing more to do break; } else { // something else; fail throw Interop.GetExceptionForIoErrno(errorInfo, _path); } } // Store the rest of the creation arguments. They'll be used when we open the connection // in WaitForConnection. _direction = direction; _options = options; _inBufferSize = inBufferSize; _outBufferSize = outBufferSize; _inheritability = inheritability; }
private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability) { Debug.Assert(pipeName != null && pipeName.Length != 0, "fullPipeName is null or empty"); Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction"); Debug.Assert(inBufferSize >= 0, "inBufferSize is negative"); Debug.Assert(outBufferSize >= 0, "outBufferSize is negative"); Debug.Assert((maxNumberOfServerInstances >= 1 && maxNumberOfServerInstances <= 254) || (maxNumberOfServerInstances == MaxAllowedServerInstances), "maxNumberOfServerInstances is invalid"); Debug.Assert(transmissionMode >= PipeTransmissionMode.Byte && transmissionMode <= PipeTransmissionMode.Message, "transmissionMode is out of range"); throw NotImplemented.ByDesign; // TODO: Implement this }
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights) : base (direction, transmissionMode, outBufferSize) { if (pipeSecurity != null) throw ThrowACLException (); var rights = ToAccessRights (direction) | additionalAccessRights; // FIXME: reject some rights declarations (for ACL). if (IsWindows) impl = new Win32NamedPipeServer (this, pipeName, maxNumberOfServerInstances, transmissionMode, rights, options, inBufferSize, outBufferSize, inheritability); else impl = new UnixNamedPipeServer (this, pipeName, maxNumberOfServerInstances, transmissionMode, rights, options, inBufferSize, outBufferSize, inheritability); InitializeHandle (impl.Handle, false, (options & PipeOptions.Asynchronous) != PipeOptions.None); }
private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability) { Debug.Assert(pipeName != null && pipeName.Length != 0, "fullPipeName is null or empty"); Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction"); Debug.Assert(inBufferSize >= 0, "inBufferSize is negative"); Debug.Assert(outBufferSize >= 0, "outBufferSize is negative"); Debug.Assert((maxNumberOfServerInstances >= 1 && maxNumberOfServerInstances <= 254) || (maxNumberOfServerInstances == MaxAllowedServerInstances), "maxNumberOfServerInstances is invalid"); Debug.Assert(transmissionMode >= PipeTransmissionMode.Byte && transmissionMode <= PipeTransmissionMode.Message, "transmissionMode is out of range"); string fullPipeName = Path.GetFullPath(@"\\.\pipe\" + pipeName); // Make sure the pipe name isn't one of our reserved names for anonymous pipes. if (String.Equals(fullPipeName, @"\\.\pipe\anonymous", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentOutOfRangeException("pipeName", SR.ArgumentOutOfRange_AnonymousReserved); } int openMode = ((int)direction) | (maxNumberOfServerInstances == 1 ? Interop.mincore.FileOperations.FILE_FLAG_FIRST_PIPE_INSTANCE : 0) | (int)options; // We automatically set the ReadMode to match the TransmissionMode. int pipeModes = (int)transmissionMode << 2 | (int)transmissionMode << 1; // Convert -1 to 255 to match win32 (we asserted that it is between -1 and 254). if (maxNumberOfServerInstances == MaxAllowedServerInstances) { maxNumberOfServerInstances = 255; } Interop.mincore.SECURITY_ATTRIBUTES secAttrs = PipeStream.GetSecAttrs(inheritability); SafePipeHandle handle = Interop.mincore.CreateNamedPipe(fullPipeName, openMode, pipeModes, maxNumberOfServerInstances, outBufferSize, inBufferSize, 0, ref secAttrs); if (handle.IsInvalid) { throw Win32Marshal.GetExceptionForLastWin32Error(); } InitializeHandle(handle, false, (options & PipeOptions.Asynchronous) != 0); }
public NamedPipeClientStream(string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability) : base(DirectionFromRights(desiredAccessRights), 0) { if (pipeName == null) { throw new ArgumentNullException("pipeName"); } if (serverName == null) { throw new ArgumentNullException("serverName", System.SR.GetString("ArgumentNull_ServerName")); } if (pipeName.Length == 0) { throw new ArgumentException(System.SR.GetString("Argument_NeedNonemptyPipeName")); } if (serverName.Length == 0) { throw new ArgumentException(System.SR.GetString("Argument_EmptyServerName")); } if ((options & ~(PipeOptions.Asynchronous | PipeOptions.WriteThrough)) != PipeOptions.None) { throw new ArgumentOutOfRangeException("options", System.SR.GetString("ArgumentOutOfRange_OptionsInvalid")); } if ((impersonationLevel < TokenImpersonationLevel.None) || (impersonationLevel > TokenImpersonationLevel.Delegation)) { throw new ArgumentOutOfRangeException("impersonationLevel", System.SR.GetString("ArgumentOutOfRange_ImpersonationInvalid")); } if ((inheritability < HandleInheritability.None) || (inheritability > HandleInheritability.Inheritable)) { throw new ArgumentOutOfRangeException("inheritability", System.SR.GetString("ArgumentOutOfRange_HandleInheritabilityNoneOrInheritable")); } if ((desiredAccessRights & ~(PipeAccessRights.AccessSystemSecurity | PipeAccessRights.FullControl)) != 0) { throw new ArgumentOutOfRangeException("desiredAccessRights", System.SR.GetString("ArgumentOutOfRange_InvalidPipeAccessRights")); } this.m_normalizedPipePath = Path.GetFullPath(@"\\" + serverName + @"\pipe\" + pipeName); if (string.Compare(this.m_normalizedPipePath, @"\\.\pipe\anonymous", StringComparison.OrdinalIgnoreCase) == 0) { throw new ArgumentOutOfRangeException("pipeName", System.SR.GetString("ArgumentOutOfRange_AnonymousReserved")); } this.m_inheritability = inheritability; this.m_impersonationLevel = impersonationLevel; this.m_pipeOptions = options; this.m_access = (int) desiredAccessRights; }
private NamedPipeServerStream(String pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability) : base(direction, transmissionMode, outBufferSize) { if (pipeName == null) { throw new ArgumentNullException(nameof(pipeName)); } if (pipeName.Length == 0) { throw new ArgumentException(SR.Argument_NeedNonemptyPipeName); } if ((options & ~(PipeOptions.WriteThrough | PipeOptions.Asynchronous)) != 0) { throw new ArgumentOutOfRangeException(nameof(options), SR.ArgumentOutOfRange_OptionsInvalid); } if (inBufferSize < 0) { throw new ArgumentOutOfRangeException(nameof(inBufferSize), SR.ArgumentOutOfRange_NeedNonNegNum); } if ((maxNumberOfServerInstances < 1 || maxNumberOfServerInstances > 254) && (maxNumberOfServerInstances != MaxAllowedServerInstances)) { // win32 allows fixed values of 1-254 or 255 to mean max allowed by system. We expose 255 as -1 (unlimited) // through the MaxAllowedServerInstances constant. This is consistent e.g. with -1 as infinite timeout, etc. // We do this check for consistency on Unix, even though maxNumberOfServerInstances is otherwise ignored. throw new ArgumentOutOfRangeException(nameof(maxNumberOfServerInstances), SR.ArgumentOutOfRange_MaxNumServerInstances); } // inheritability will always be None since this private constructor is only called from other constructors from which // inheritability is always set to None. Desktop has a public constructor to allow setting it to something else, but Core // doesn't. if (inheritability < HandleInheritability.None || inheritability > HandleInheritability.Inheritable) { throw new ArgumentOutOfRangeException(nameof(inheritability), SR.ArgumentOutOfRange_HandleInheritabilityNoneOrInheritable); } Create(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, inheritability); }
internal NamedPipeClientStream(String serverName, String pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability) : base(direction, 0) { if (pipeName == null) { throw new ArgumentNullException("pipeName"); } if (serverName == null) { throw new ArgumentNullException("serverName", SR.ArgumentNull_ServerName); } if (pipeName.Length == 0) { throw new ArgumentException(SR.Argument_NeedNonemptyPipeName); } if (serverName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyServerName); } if ((options & ~(PipeOptions.WriteThrough | PipeOptions.Asynchronous)) != 0) { throw new ArgumentOutOfRangeException("options", SR.ArgumentOutOfRange_OptionsInvalid); } if (impersonationLevel < TokenImpersonationLevel.None || impersonationLevel > TokenImpersonationLevel.Delegation) { throw new ArgumentOutOfRangeException("impersonationLevel", SR.ArgumentOutOfRange_ImpersonationInvalid); } if (inheritability < HandleInheritability.None || inheritability > HandleInheritability.Inheritable) { throw new ArgumentOutOfRangeException("inheritability", SR.ArgumentOutOfRange_HandleInheritabilityNoneOrInheritable); } _normalizedPipePath = GetPipePath(serverName, pipeName); _direction = direction; _inheritability = inheritability; _impersonationLevel = impersonationLevel; _pipeOptions = options; }
/// <summary> /// Enables efficiently reading a <see cref="WebSocket"/> using <see cref="PipeReader"/>. /// </summary> /// <param name="webSocket">The web socket to read from using a pipe.</param> /// <param name="sizeHint">A hint at the size of messages that are commonly transferred. Use 0 for a commonly reasonable default.</param> /// <param name="pipeOptions">Optional pipe options to use.</param> /// <param name="cancellationToken">A cancellation token that aborts reading from the <paramref name="webSocket"/>.</param> /// <returns>A <see cref="PipeReader"/>.</returns> public static PipeReader UsePipeReader(this WebSocket webSocket, int sizeHint = 0, PipeOptions pipeOptions = null, CancellationToken cancellationToken = default) { Requires.NotNull(webSocket, nameof(webSocket)); var pipe = new Pipe(pipeOptions ?? PipeOptions.Default); Task.Run(async delegate { while (!cancellationToken.IsCancellationRequested) { Memory <byte> memory = pipe.Writer.GetMemory(sizeHint); try { var readResult = await webSocket.ReceiveAsync(memory, cancellationToken); if (readResult.Count == 0) { break; } pipe.Writer.Advance(readResult.Count); } catch (Exception ex) { pipe.Writer.Complete(ex); throw; } FlushResult result = await pipe.Writer.FlushAsync(); if (result.IsCompleted) { break; } } // Tell the PipeReader that there's no more data coming pipe.Writer.Complete(); }).Forget(); return(pipe.Reader); }
private void Create(String fullPipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeAccessRights rights, UnsafeNativeMethods.SECURITY_ATTRIBUTES secAttrs) { Debug.Assert(fullPipeName != null && fullPipeName.Length != 0, "fullPipeName is null or empty"); Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction"); Debug.Assert(inBufferSize >= 0, "inBufferSize is negative"); Debug.Assert(outBufferSize >= 0, "outBufferSize is negative"); Debug.Assert((maxNumberOfServerInstances >= 1 && maxNumberOfServerInstances <= 254) || (maxNumberOfServerInstances == MaxAllowedServerInstances), "maxNumberOfServerInstances is invalid"); Debug.Assert(transmissionMode >= PipeTransmissionMode.Byte && transmissionMode <= PipeTransmissionMode.Message, "transmissionMode is out of range"); int openMode = ((int)direction) | (maxNumberOfServerInstances == 1 ? UnsafeNativeMethods.FILE_FLAG_FIRST_PIPE_INSTANCE : 0) | (int)options | (int)rights; // We automatically set the ReadMode to match the TransmissionMode. int pipeModes = (int)transmissionMode << 2 | (int)transmissionMode << 1; // Convert -1 to 255 to match win32 (we asserted that it is between -1 and 254). if (maxNumberOfServerInstances == MaxAllowedServerInstances) { maxNumberOfServerInstances = 255; } SafePipeHandle handle = UnsafeNativeMethods.CreateNamedPipe(fullPipeName, openMode, pipeModes, maxNumberOfServerInstances, outBufferSize, inBufferSize, 0, secAttrs); if (handle.IsInvalid) { __Error.WinIOError(Marshal.GetLastWin32Error(), String.Empty); } InitializeHandle(handle, false, (options & PipeOptions.Asynchronous) != 0); }
public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options) : this (serverName, pipeName, direction, options, TokenImpersonationLevel.None) { }
// .ctor without handle - create new public UnixNamedPipeServer (NamedPipeServerStream owner, string pipeName, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeAccessRights rights, PipeOptions options, int inBufferSize, int outBufferSize, HandleInheritability inheritability) { string name = Path.Combine ("/var/tmp/", pipeName); EnsureTargetFile (name); RightsToAccess (rights); ValidateOptions (options, owner.TransmissionMode); // FIXME: maxNumberOfServerInstances, modes, sizes, handle inheritability var fs = new FileStream (name, FileMode.Open, RightsToFileAccess (rights), FileShare.ReadWrite); handle = new SafePipeHandle (fs.Handle, false); owner.Stream = fs; should_close_handle = true; }
[PlatformSpecific(TestPlatforms.Windows)] // Unix currently doesn't support message mode public void Windows_MessagePipeTransmissionMode(PipeOptions serverOptions) { byte[] msg1 = new byte[] { 5, 7, 9, 10 }; byte[] msg2 = new byte[] { 2, 4 }; byte[] received1 = new byte[] { 0, 0, 0, 0 }; byte[] received2 = new byte[] { 0, 0 }; byte[] received3 = new byte[] { 0, 0, 0, 0 }; byte[] received4 = new byte[] { 0, 0, 0, 0 }; byte[] received5 = new byte[] { 0, 0 }; byte[] received6 = new byte[] { 0, 0, 0, 0 }; string pipeName = GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Message, serverOptions)) { using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { server.ReadMode = PipeTransmissionMode.Message; Assert.Equal(PipeTransmissionMode.Message, server.ReadMode); client.Connect(); Task clientTask = Task.Run(() => { client.Write(msg1, 0, msg1.Length); client.Write(msg2, 0, msg2.Length); client.Write(msg1, 0, msg1.Length); client.Write(msg1, 0, msg1.Length); client.Write(msg2, 0, msg2.Length); client.Write(msg1, 0, msg1.Length); int serverCount = client.NumberOfServerInstances; Assert.Equal(1, serverCount); }); Task serverTask = Task.Run(async() => { server.WaitForConnection(); int len1 = server.Read(received1, 0, msg1.Length); Assert.True(server.IsMessageComplete); Assert.Equal(msg1.Length, len1); Assert.Equal(msg1, received1); int len2 = server.Read(received2, 0, msg2.Length); Assert.True(server.IsMessageComplete); Assert.Equal(msg2.Length, len2); Assert.Equal(msg2, received2); int expectedRead = msg1.Length - 1; int len3 = server.Read(received3, 0, expectedRead); // read one less than message Assert.False(server.IsMessageComplete); Assert.Equal(expectedRead, len3); for (int i = 0; i < expectedRead; ++i) { Assert.Equal(msg1[i], received3[i]); } expectedRead = msg1.Length - expectedRead; Assert.Equal(expectedRead, server.Read(received3, len3, expectedRead)); Assert.True(server.IsMessageComplete); Assert.Equal(msg1, received3); Assert.Equal(msg1.Length, await server.ReadAsync(received4, 0, msg1.Length)); Assert.True(server.IsMessageComplete); Assert.Equal(msg1, received4); Assert.Equal(msg2.Length, await server.ReadAsync(received5, 0, msg2.Length)); Assert.True(server.IsMessageComplete); Assert.Equal(msg2, received5); expectedRead = msg1.Length - 1; Assert.Equal(expectedRead, await server.ReadAsync(received6, 0, expectedRead)); // read one less than message Assert.False(server.IsMessageComplete); for (int i = 0; i < expectedRead; ++i) { Assert.Equal(msg1[i], received6[i]); } expectedRead = msg1.Length - expectedRead; Assert.Equal(expectedRead, await server.ReadAsync(received6, msg1.Length - expectedRead, expectedRead)); Assert.True(server.IsMessageComplete); Assert.Equal(msg1, received6); }); Assert.True(Task.WaitAll(new[] { clientTask, serverTask }, TimeSpan.FromSeconds(15))); } } }
private async Task ProcessEventStream(IDuplexPipe application, HttpResponseMessage response, CancellationToken cancellationToken) { Log.StartReceive(_logger); using (response) using (var stream = await response.Content.ReadAsStreamAsync()) { var options = new PipeOptions(pauseWriterThreshold: 0, resumeWriterThreshold: 0); var reader = PipeReaderFactory.CreateFromStream(options, stream, cancellationToken); try { while (true) { var result = await reader.ReadAsync(); var buffer = result.Buffer; var consumed = buffer.Start; var examined = buffer.End; try { if (result.IsCanceled) { Log.ReceiveCanceled(_logger); break; } if (!buffer.IsEmpty) { Log.ParsingSSE(_logger, buffer.Length); var parseResult = _parser.ParseMessage(buffer, out consumed, out examined, out var message); FlushResult flushResult = default; switch (parseResult) { case ServerSentEventsMessageParser.ParseResult.Completed: Log.MessageToApplication(_logger, message.Length); flushResult = await _application.Output.WriteAsync(message); _parser.Reset(); break; case ServerSentEventsMessageParser.ParseResult.Incomplete: if (result.IsCompleted) { throw new FormatException("Incomplete message."); } break; } // We canceled in the middle of applying back pressure // or if the consumer is done if (flushResult.IsCanceled || flushResult.IsCompleted) { Log.EventStreamEnded(_logger); break; } } else if (result.IsCompleted) { break; } } finally { reader.AdvanceTo(consumed, examined); } } } catch (Exception ex) { _error = ex; } finally { _application.Output.Complete(_error); Log.ReceiveStopped(_logger); reader.Complete(); } } }
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options) : base (default(PipeDirection), default(int)) { Contract.Ensures(1 <= pipeName.Length); }
public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights) : base (default(PipeDirection), default(int)) { Contract.Ensures(1 <= pipeName.Length); }
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize) #if MOBILE : base (direction, inBufferSize) { throw new NotImplementedException (); }
public ServiceConnectionProxy(IClientConnectionManager clientConnectionManager, ILoggerFactory loggerFactory, ConnectionDelegate callback = null, PipeOptions clientPipeOptions = null) : base( Guid.NewGuid().ToString("N"), Guid.NewGuid().ToString("N"), SharedServiceProtocol, new TestConnectionFactory(), clientConnectionManager, loggerFactory.CreateLogger <ServiceConnectionProxy>()) { }
public NamedPipeClientStream (string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability) : base (ToDirection (desiredAccessRights), DefaultBufferSize) { if (impersonationLevel != TokenImpersonationLevel.None || inheritability != HandleInheritability.None) throw ThrowACLException (); if (IsWindows) impl = new Win32NamedPipeClient (this, serverName, pipeName, desiredAccessRights, options, inheritability); else impl = new UnixNamedPipeClient (this, serverName, pipeName, desiredAccessRights, options, inheritability); }
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize) : this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, null) { }
protected void ValidateOptions (PipeOptions options, PipeTransmissionMode mode) { if ((options & PipeOptions.WriteThrough) != 0) throw new NotImplementedException ("WriteThrough is not supported"); if ((mode & PipeTransmissionMode.Message) != 0) throw new NotImplementedException ("Message transmission mode is not supported"); if ((options & PipeOptions.Asynchronous) != 0) // FIXME: use O_NONBLOCK? throw new NotImplementedException ("Asynchronous pipe mode is not supported"); }
private static SafePipeHandle CreateNamedPipe(string fullPipeName, PipeDirection direction, uint maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, uint inBufferSize, uint outBufferSize, PipeAccessRights rights, SECURITY_ATTRIBUTES secAttrs) { uint openMode = (uint)direction | (uint)options; uint pipeMode = 0; if (maxNumberOfServerInstances == -1) { maxNumberOfServerInstances = 0xff; } SafePipeHandle handle = CreateNamedPipe(fullPipeName, openMode, pipeMode, maxNumberOfServerInstances, outBufferSize, inBufferSize, 0, ref secAttrs); if (handle.IsInvalid) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(handle); }
public async Task WritesDontCompleteImmediatelyWhenTooManyBytesIncludingNonImmediateAreAlreadyBuffered(int maxResponseBufferSize) { await Task.Run(async() => { var completeQueue = new ConcurrentQueue <Action <int> >(); // Arrange _mockLibuv.OnWrite = (socket, buffers, triggerCompleted) => { completeQueue.Enqueue(triggerCompleted); return(0); }; var pipeOptions = new PipeOptions ( pool: _memoryPool, readerScheduler: _libuvThread, writerScheduler: PipeScheduler.Inline, pauseWriterThreshold: maxResponseBufferSize, resumeWriterThreshold: maxResponseBufferSize, useSynchronizationContext: false ); using (var outputProducer = CreateOutputProducer(pipeOptions)) { var bufferSize = maxResponseBufferSize / 2; var data = new byte[bufferSize]; var halfWriteBehindBuffer = new ArraySegment <byte>(data, 0, bufferSize); // Act var writeTask1 = outputProducer.WriteDataAsync(halfWriteBehindBuffer); // Assert // The first write should pre-complete since it is <= _maxBytesPreCompleted. Assert.Equal(TaskStatus.RanToCompletion, writeTask1.Status); await _mockLibuv.OnPostTask; Assert.NotEmpty(completeQueue); // Add more bytes to the write-behind buffer to prevent the next write from outputProducer.Write((writableBuffer, state) => { writableBuffer.Write(state); return(state.Count); }, halfWriteBehindBuffer); // Act var writeTask2 = outputProducer.WriteDataAsync(halfWriteBehindBuffer); Assert.False(writeTask2.IsCompleted); var writeTask3 = outputProducer.WriteDataAsync(halfWriteBehindBuffer); Assert.False(writeTask3.IsCompleted); // Drain the write queue while (completeQueue.TryDequeue(out var triggerNextCompleted)) { await _libuvThread.PostAsync(cb => cb(0), triggerNextCompleted); } var timeout = TestConstants.DefaultTimeout; await writeTask2.TimeoutAfter(timeout); await writeTask3.TimeoutAfter(timeout); Assert.Empty(completeQueue); } }); }
public PipeOptionsPair(PipeOptions sendOpts, PipeOptions receiveOpts) { SendOpts = sendOpts; ReceiveOpts = receiveOpts; }
public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability) #if MOBILE : base (direction, DefaultBufferSize) { throw new NotImplementedException (); }
public static async Task ClientServerOneWayOperations( string pipeName, PipeDirection serverDirection, bool asyncServerPipe, bool asyncClientPipe, bool asyncServerOps, bool asyncClientOps) { PipeDirection clientDirection = serverDirection == PipeDirection.Out ? PipeDirection.In : PipeDirection.Out; PipeOptions serverOptions = asyncServerPipe ? PipeOptions.Asynchronous : PipeOptions.None; PipeOptions clientOptions = asyncClientPipe ? PipeOptions.Asynchronous : PipeOptions.None; using (NamedPipeServerStream server = new NamedPipeServerStream(pipeName, serverDirection, 1, PipeTransmissionMode.Byte, serverOptions)) { byte[] received = new byte[] { 0 }; Task clientTask = Task.Run(async() => { using (NamedPipeClientStream client = new NamedPipeClientStream(".", pipeName, clientDirection, clientOptions)) { if (asyncClientOps) { await client.ConnectAsync(); if (clientDirection == PipeDirection.In) { received = await ReadBytesAsync(client, sendBytes.Length); } else { await WriteBytesAsync(client, sendBytes); } } else { client.Connect(); if (clientDirection == PipeDirection.In) { received = ReadBytes(client, sendBytes.Length); } else { WriteBytes(client, sendBytes); } } } }); if (asyncServerOps) { await server.WaitForConnectionAsync(); if (serverDirection == PipeDirection.Out) { await WriteBytesAsync(server, sendBytes); } else { received = await ReadBytesAsync(server, sendBytes.Length); } } else { server.WaitForConnection(); if (serverDirection == PipeDirection.Out) { WriteBytes(server, sendBytes); } else { received = ReadBytes(server, sendBytes.Length); } } await clientTask; Assert.Equal(sendBytes, received); server.Disconnect(); Assert.False(server.IsConnected); } }
protected override NamedPipePair CreateNamedPipePair(PipeOptions serverOptions, PipeOptions clientOptions) { NamedPipePair ret = new NamedPipePair(); string pipeName = GetUniquePipeName(); ret.serverStream = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, serverOptions); ret.clientStream = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, clientOptions); ret.writeToServer = false; return ret; }
public NamedPipeClientStream(string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel) : this(serverName, pipeName, direction, options, impersonationLevel, HandleInheritability.None) { }
public NamedPipeServerStream(String pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights) : base(direction, transmissionMode, outBufferSize) { if (pipeName == null) { throw new ArgumentNullException("pipeName"); } if (pipeName.Length == 0) { throw new ArgumentException(SR.GetString(SR.Argument_NeedNonemptyPipeName)); } if ((options & ~(PipeOptions.WriteThrough | PipeOptions.Asynchronous)) != 0) { throw new ArgumentOutOfRangeException("options", SR.GetString(SR.ArgumentOutOfRange_OptionsInvalid)); } if (inBufferSize < 0) { throw new ArgumentOutOfRangeException("inBufferSize", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNum)); } // win32 allows fixed values of 1-254 or 255 to mean max allowed by system. We expose 255 as -1 (unlimited) // through the MaxAllowedServerInstances constant. This is consistent e.g. with -1 as infinite timeout, etc if ((maxNumberOfServerInstances < 1 || maxNumberOfServerInstances > 254) && (maxNumberOfServerInstances != MaxAllowedServerInstances)) { throw new ArgumentOutOfRangeException("maxNumberOfServerInstances", SR.GetString(SR.ArgumentOutOfRange_MaxNumServerInstances)); } if (inheritability < HandleInheritability.None || inheritability > HandleInheritability.Inheritable) { throw new ArgumentOutOfRangeException("inheritability", SR.GetString(SR.ArgumentOutOfRange_HandleInheritabilityNoneOrInheritable)); } // ChangePermissions, TakeOwnership, and AccessSystemSecurity are only legal values user may provide; // internally this is set to 0 if not provided. This handles both cases. if ((additionalAccessRights & ~(PipeAccessRights.ChangePermissions | PipeAccessRights.TakeOwnership | PipeAccessRights.AccessSystemSecurity)) != 0) { throw new ArgumentOutOfRangeException("additionalAccessRights", SR.GetString(SR.ArgumentOutOfRange_AdditionalAccessLimited)); } // Named Pipe Servers require Windows NT if (Environment.OSVersion.Platform == PlatformID.Win32Windows) { throw new PlatformNotSupportedException(SR.GetString(SR.PlatformNotSupported_NamedPipeServers)); } string normalizedPipePath = Path.GetFullPath(@"\\.\pipe\" + pipeName); // Make sure the pipe name isn't one of our reserved names for anonymous pipes. if (String.Compare(normalizedPipePath, @"\\.\pipe\anonymous", StringComparison.OrdinalIgnoreCase) == 0) { throw new ArgumentOutOfRangeException("pipeName", SR.GetString(SR.ArgumentOutOfRange_AnonymousReserved)); } Object pinningHandle = null; UnsafeNativeMethods.SECURITY_ATTRIBUTES secAttrs = PipeStream.GetSecAttrs(inheritability, pipeSecurity, out pinningHandle); try { Create(normalizedPipePath, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, additionalAccessRights, secAttrs); } finally { if (pinningHandle != null) { GCHandle pinHandle = (GCHandle)pinningHandle; pinHandle.Free(); } } }
public async Task WriteAsyncWithTokenAfterCallWithoutIsCancelled(int maxResponseBufferSize) { await Task.Run(async() => { var completeQueue = new ConcurrentQueue <Action <int> >(); // Arrange _mockLibuv.OnWrite = (socket, buffers, triggerCompleted) => { completeQueue.Enqueue(triggerCompleted); return(0); }; var abortedSource = new CancellationTokenSource(); var pipeOptions = new PipeOptions ( pool: _memoryPool, readerScheduler: _libuvThread, writerScheduler: PipeScheduler.Inline, pauseWriterThreshold: maxResponseBufferSize, resumeWriterThreshold: maxResponseBufferSize, useSynchronizationContext: false ); await using (var processor = CreateOutputProducer(pipeOptions)) { var outputProducer = processor.OutputProducer; var bufferSize = maxResponseBufferSize; var data = new byte[bufferSize]; var fullBuffer = new ArraySegment <byte>(data, 0, bufferSize); // Act var task1Waits = outputProducer.WriteDataAsync(fullBuffer); // First task is not completed Assert.False(task1Waits.IsCompleted); Assert.False(task1Waits.IsCanceled); Assert.False(task1Waits.IsFaulted); // following tasks should wait. var task2Canceled = outputProducer.WriteDataAsync(fullBuffer, cancellationToken: abortedSource.Token); // Give time for tasks to percolate await _mockLibuv.OnPostTask; // Second task is not completed Assert.False(task2Canceled.IsCompleted); Assert.False(task2Canceled.IsCanceled); Assert.False(task2Canceled.IsFaulted); abortedSource.Cancel(); // Complete writes while (completeQueue.TryDequeue(out var triggerNextCompleted)) { await _libuvThread.PostAsync(cb => cb(0), triggerNextCompleted); } await task1Waits.DefaultTimeout(); // First task is completed Assert.True(task1Waits.IsCompleted); Assert.False(task1Waits.IsCanceled); Assert.False(task1Waits.IsFaulted); // Second task is now canceled await Assert.ThrowsAsync <OperationCanceledException>(() => task2Canceled); Assert.True(task2Canceled.IsCanceled); // A final write can still succeed. var task3Success = outputProducer.WriteDataAsync(fullBuffer); await _mockLibuv.OnPostTask; // Complete the 3rd write while (completeQueue.TryDequeue(out var triggerNextCompleted)) { await _libuvThread.PostAsync(cb => cb(0), triggerNextCompleted); } await task3Success.DefaultTimeout(); Assert.True(task3Success.IsCompleted); Assert.False(task3Success.IsCanceled); Assert.False(task3Success.IsFaulted); } }); }
/// <summary> /// Enables reading and writing to a <see cref="Stream"/> using <see cref="PipeWriter"/> and <see cref="PipeReader"/>. /// </summary> /// <param name="stream">The stream to access using a pipe.</param> /// <param name="sizeHint">A hint at the size of messages that are commonly transferred. Use 0 for a commonly reasonable default.</param> /// <param name="pipeOptions">Optional pipe options to use.</param> /// <param name="cancellationToken">A token that may cancel async processes to read from and write to the <paramref name="stream"/>.</param> /// <returns>An <see cref="IDuplexPipe"/> instance.</returns> public static IDuplexPipe UsePipe(this Stream stream, int sizeHint = 0, PipeOptions pipeOptions = null, CancellationToken cancellationToken = default) { return(new DuplexPipe(stream.UsePipeReader(sizeHint, pipeOptions, cancellationToken), stream.UsePipeWriter(pipeOptions, cancellationToken))); }
public async Task OneWayReadWrites(PipeOptions serverOptions, PipeOptions clientOptions, bool asyncServerOps, bool asyncClientOps) { using (NamedPipePair pair = CreateNamedPipePair(serverOptions, clientOptions)) { NamedPipeClientStream client = pair.clientStream; NamedPipeServerStream server = pair.serverStream; byte[] received = new byte[] { 0 }; Task clientTask = Task.Run(async() => { if (asyncClientOps) { await client.ConnectAsync(); if (pair.writeToServer) { received = await ReadBytesAsync(client, sendBytes.Length); } else { await WriteBytesAsync(client, sendBytes); } } else { client.Connect(); if (pair.writeToServer) { received = ReadBytes(client, sendBytes.Length); } else { WriteBytes(client, sendBytes); } } }); if (asyncServerOps) { await server.WaitForConnectionAsync(); if (pair.writeToServer) { await WriteBytesAsync(server, sendBytes); } else { received = await ReadBytesAsync(server, sendBytes.Length); } } else { server.WaitForConnection(); if (pair.writeToServer) { WriteBytes(server, sendBytes); } else { received = ReadBytes(server, sendBytes.Length); } } await clientTask; Assert.Equal(sendBytes, received); server.Disconnect(); Assert.False(server.IsConnected); } }
/// <summary> /// Enables reading and writing to a <see cref="WebSocket"/> using <see cref="PipeWriter"/> and <see cref="PipeReader"/>. /// </summary> /// <param name="webSocket">The <see cref="WebSocket"/> to access using a pipe.</param> /// <param name="sizeHint">A hint at the size of messages that may be transferred. Use 0 for a commonly reasonable default.</param> /// <param name="pipeOptions">Optional pipe options to use.</param> /// <param name="cancellationToken">A token that may cancel async processes to read from and write to the <paramref name="webSocket"/>.</param> /// <returns>An <see cref="IDuplexPipe"/> instance.</returns> public static IDuplexPipe UsePipe(this WebSocket webSocket, int sizeHint = 0, PipeOptions pipeOptions = null, CancellationToken cancellationToken = default) { return(new DuplexPipe(webSocket.UsePipeReader(sizeHint, pipeOptions, cancellationToken), webSocket.UsePipeWriter(pipeOptions, cancellationToken))); }
internal static NamedPipeClientStream CreateNamedPipeClient(string serverName, string pipeName, PipeDirection direction, PipeOptions options) => new NamedPipeClientStream(serverName, pipeName, direction, options);
public static DuplexPipePair CreateConnectionPair(PipeOptions inputOptions, PipeOptions outputOptions) { var input = new Pipe(inputOptions); var output = new Pipe(outputOptions); var transportToApplication = new DuplexPipe(output.Reader, input.Writer); var applicationToTransport = new DuplexPipe(input.Reader, output.Writer); return(new DuplexPipePair(applicationToTransport, transportToApplication)); }
/// <summary> /// Initializes a new instance of the <see cref="PipeClientWithCallback"/> class. /// </summary> /// <param name="pipeName">The name of the pipe.</param> /// <param name="handlerFactoryFunc">A factory function to provide the handler implementation.</param> /// <param name="options">One of the enumeration values that determines how to open or create the pipe.</param> /// <param name="impersonationLevel">One of the enumeration values that determines the security impersonation level.</param> /// <param name="inheritability">One of the enumeration values that determines whether the underlying handle will be inheritable by child processes.</param> public PipeClientWithCallback(string pipeName, Func <THandling> handlerFactoryFunc, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability) : this(".", pipeName, handlerFactoryFunc, options, impersonationLevel, inheritability) { if (string.IsNullOrEmpty(_uniqueId)) { _uniqueId = Guid.NewGuid().ToString(); int index = _uniqueId.LastIndexOf('-'); _uniqueId = _uniqueId.Substring(index + 1, _uniqueId.Length - index - 1); } //Console.WriteLine($"uniqueId: [{_uniqueId}] - 5"); }
protected override NamedPipePair CreateNamedPipePair(PipeOptions serverOptions, PipeOptions clientOptions) { NamedPipePair ret = new NamedPipePair(); string pipeName = GetUniquePipeName(); ret.serverStream = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, serverOptions); ret.clientStream = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, clientOptions); ret.writeToServer = false; return(ret); }
public async Task WriteAsyncWithTokenAfterCallWithoutIsCancelled(int maxResponseBufferSize) { await Task.Run(async() => { var completeQueue = new ConcurrentQueue <Action <int> >(); // Arrange _mockLibuv.OnWrite = (socket, buffers, triggerCompleted) => { completeQueue.Enqueue(triggerCompleted); return(0); }; var abortedSource = new CancellationTokenSource(); var pipeOptions = new PipeOptions { ReaderScheduler = _libuvThread, MaximumSizeHigh = maxResponseBufferSize, MaximumSizeLow = maxResponseBufferSize, }; using (var outputProducer = CreateOutputProducer(pipeOptions)) { var bufferSize = maxResponseBufferSize; var data = new byte[bufferSize]; var fullBuffer = new ArraySegment <byte>(data, 0, bufferSize); // Act var task1Waits = outputProducer.WriteAsync(fullBuffer); // First task is not completed Assert.False(task1Waits.IsCompleted); Assert.False(task1Waits.IsCanceled); Assert.False(task1Waits.IsFaulted); // following tasks should wait. var task3Canceled = outputProducer.WriteAsync(fullBuffer, cancellationToken: abortedSource.Token); // Give time for tasks to percolate await _mockLibuv.OnPostTask; // Third task is not completed Assert.False(task3Canceled.IsCompleted); Assert.False(task3Canceled.IsCanceled); Assert.False(task3Canceled.IsFaulted); abortedSource.Cancel(); // Complete writes while (completeQueue.TryDequeue(out var triggerNextCompleted)) { await _libuvThread.PostAsync(cb => cb(0), triggerNextCompleted); } // First task is completed Assert.True(task1Waits.IsCompleted); Assert.False(task1Waits.IsCanceled); Assert.False(task1Waits.IsFaulted); // A final write guarantees that the error is observed by OutputProducer, // but doesn't return a canceled/faulted task. var task4Success = outputProducer.WriteAsync(fullBuffer); Assert.True(task4Success.IsCompleted); Assert.False(task4Success.IsCanceled); Assert.False(task4Success.IsFaulted); // Third task is now canceled await Assert.ThrowsAsync <OperationCanceledException>(() => task3Canceled); Assert.True(task3Canceled.IsCanceled); await _mockLibuv.OnPostTask; // Complete the 4th write while (completeQueue.TryDequeue(out var triggerNextCompleted)) { await _libuvThread.PostAsync(cb => cb(0), triggerNextCompleted); } } }); }
public ServiceConnectionProxy(ConnectionDelegate callback = null, PipeOptions clientPipeOptions = null, TestConnectionFactory connectionFactory = null) { ConnectionFactory = connectionFactory ?? new TestConnectionFactory(); ClientConnectionManager = new ClientConnectionManager(); _clientPipeOptions = clientPipeOptions; ServiceConnection = new ServiceConnection( ServiceProtocol, this, ConnectionFactory, NullLoggerFactory.Instance, callback ?? OnConnectionAsync, this, Guid.NewGuid().ToString("N")); }
public PipeConnection(PipeOptions pipeOptions) { Input = new Pipe(pipeOptions); Output = new Pipe(pipeOptions); }
/// <summary> /// Initializes a new instance of the <see cref="PipeClientWithCallback"/> class. /// </summary> /// <param name="serverName">The name of the server to connect to.</param> /// <param name="pipeName">The name of the pipe.</param> /// <param name="handlerFactoryFunc">A factory function to provide the handler implementation.</param> /// <param name="options">One of the enumeration values that determines how to open or create the pipe.</param> /// <param name="impersonationLevel">One of the enumeration values that determines the security impersonation level.</param> /// <param name="inheritability">One of the enumeration values that determines whether the underlying handle will be inheritable by child processes.</param> public PipeClientWithCallback(string serverName, string pipeName, Func <THandling> handlerFactoryFunc, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability) { this.pipeName = pipeName; this.serverName = serverName; this.handlerFactoryFunc = handlerFactoryFunc; this.options = options; this.impersonationLevel = impersonationLevel; this.inheritability = inheritability; if (string.IsNullOrEmpty(_uniqueId)) { _uniqueId = Guid.NewGuid().ToString(); int index = _uniqueId.LastIndexOf('-'); _uniqueId = _uniqueId.Substring(index + 1, _uniqueId.Length - index - 1); } //Console.WriteLine($"PipeClientWithCallback(6) _uniqueId: [{_uniqueId}]"); }
// ----------------------------- // ---- PAL layer ends here ---- // ----------------------------- internal static Interop.libc.OpenFlags TranslateFlags(PipeDirection direction, PipeOptions options, HandleInheritability inheritability) { // Translate direction Interop.libc.OpenFlags flags = direction == PipeDirection.InOut ? Interop.libc.OpenFlags.O_RDWR : direction == PipeDirection.Out ? Interop.libc.OpenFlags.O_WRONLY : Interop.libc.OpenFlags.O_RDONLY; // Translate options if ((options & PipeOptions.WriteThrough) != 0) { flags |= Interop.libc.OpenFlags.O_SYNC; } // Translate inheritability. if ((inheritability & HandleInheritability.Inheritable) == 0) { flags |= Interop.libc.OpenFlags.O_CLOEXEC; } // PipeOptions.Asynchronous is ignored, at least for now. Asynchronous processing // is handling just by queueing a work item to do the work synchronously on a pool thread. return(flags); }
public NamedPipeServerStream(String pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize) : this(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, HandleInheritability.None) { }
// This overload is used in Mono to implement public constructors. private void Create(string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity?pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights) { Debug.Assert(pipeName != null && pipeName.Length != 0, "fullPipeName is null or empty"); Debug.Assert(direction >= PipeDirection.In && direction <= PipeDirection.InOut, "invalid pipe direction"); Debug.Assert(inBufferSize >= 0, "inBufferSize is negative"); Debug.Assert(outBufferSize >= 0, "outBufferSize is negative"); Debug.Assert((maxNumberOfServerInstances >= 1 && maxNumberOfServerInstances <= 254) || (maxNumberOfServerInstances == MaxAllowedServerInstances), "maxNumberOfServerInstances is invalid"); Debug.Assert(transmissionMode >= PipeTransmissionMode.Byte && transmissionMode <= PipeTransmissionMode.Message, "transmissionMode is out of range"); string fullPipeName = Path.GetFullPath(@"\\.\pipe\" + pipeName); // Make sure the pipe name isn't one of our reserved names for anonymous pipes. if (string.Equals(fullPipeName, @"\\.\pipe\anonymous", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentOutOfRangeException(nameof(pipeName), SR.ArgumentOutOfRange_AnonymousReserved); } if (IsCurrentUserOnly) { Debug.Assert(pipeSecurity == null); using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent()) { SecurityIdentifier identifier = currentIdentity.Owner !; // Grant full control to the owner so multiple servers can be opened. // Full control is the default per MSDN docs for CreateNamedPipe. PipeAccessRule rule = new PipeAccessRule(identifier, PipeAccessRights.FullControl, AccessControlType.Allow); pipeSecurity = new PipeSecurity(); pipeSecurity.AddAccessRule(rule); pipeSecurity.SetOwner(identifier); } // PipeOptions.CurrentUserOnly is special since it doesn't match directly to a corresponding Win32 valid flag. // Remove it, while keeping others untouched since historically this has been used as a way to pass flags to CreateNamedPipe // that were not defined in the enumeration. options &= ~PipeOptions.CurrentUserOnly; } int openMode = ((int)direction) | (maxNumberOfServerInstances == 1 ? Interop.Kernel32.FileOperations.FILE_FLAG_FIRST_PIPE_INSTANCE : 0) | (int)options | (int)additionalAccessRights; // We automatically set the ReadMode to match the TransmissionMode. int pipeModes = (int)transmissionMode << 2 | (int)transmissionMode << 1; // Convert -1 to 255 to match win32 (we asserted that it is between -1 and 254). if (maxNumberOfServerInstances == MaxAllowedServerInstances) { maxNumberOfServerInstances = 255; } GCHandle pinningHandle = default; try { Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability, pipeSecurity, ref pinningHandle); SafePipeHandle handle = Interop.Kernel32.CreateNamedPipe(fullPipeName, openMode, pipeModes, maxNumberOfServerInstances, outBufferSize, inBufferSize, 0, ref secAttrs); if (handle.IsInvalid) { throw Win32Marshal.GetExceptionForLastWin32Error(); } InitializeHandle(handle, false, (options & PipeOptions.Asynchronous) != 0); } finally { if (pinningHandle.IsAllocated) { pinningHandle.Free(); } } }
// .ctor without handle - create new public UnixNamedPipeClient (NamedPipeClientStream owner, string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, HandleInheritability inheritability) { this.owner = owner; if (serverName != "." && !Dns.GetHostEntry (serverName).AddressList.Contains (IPAddress.Loopback)) throw new NotImplementedException ("Unix fifo does not support remote server connection"); var name = Path.Combine ("/var/tmp/", pipeName); EnsureTargetFile (name); RightsToAccess (desiredAccessRights); ValidateOptions (options, owner.TransmissionMode); // FIXME: handle inheritability opener = delegate { var fs = new FileStream (name, FileMode.Open, RightsToFileAccess (desiredAccessRights), FileShare.ReadWrite); owner.Stream = fs; handle = new SafePipeHandle (fs.Handle, false); }; }
/// <summary> /// Provides a stable client loop controlled by data of the TransmissionLine. /// </summary> /// <param name="line">A line that will be handled by the loop.</param> /// <param name="pipeDirection">Direction of the pipe. Defines the loop's behavior model.</param> /// <param name="pipeOptions">Options that will be applied to a pipe client established for the line.</param> public static void ClientLoop( TransmissionLine line, PipeDirection pipeDirection, PipeOptions pipeOptions) { // Loop will work until this proceesor line not closed. while (!line.Closed) { // In case if line in out transmission mode. // If queries not placed then wait. while (line.Direction == TransmissionLine.TransmissionDirection.Out && (!line.HasQueries || !line.TryDequeQuery(out _))) { // Drop if closed. if (line.Closed) { return; } Thread.Sleep(50); continue; } // Skip connection in line interrupted before connecting. if (line.Interrupted) { continue; } // Open pipe. using (NamedPipeClientStream pipeClient = new NamedPipeClientStream( line.ServerName, line.ServerPipeName, pipeDirection, pipeOptions, TokenImpersonationLevel.Impersonation, HandleInheritability.None)) { // Update meta data. line.pipeClient = pipeClient; // Log. Console.WriteLine("{0}/{1} (CL0): Connection to server.", line.ServerName, line.ServerPipeName); // Wait until named pipe server would become exit. while (!NativeMethods.DoesNamedPipeExist( line.ServerName, line.ServerPipeName)) { // Drop if not relevant. if (line.Closed) { return; } // Suspend thread if server not exist. Thread.Sleep(50); } // Skip connection in line interrupted before connecting. if (line.Interrupted) { continue; } // Connect to server. Would suspend moving forward until connect establishing. ConnectToServer(pipeClient); // Log about establishing. Console.WriteLine("{0}/{1}: Connection established.", line.ServerName, line.ServerPipeName); try { // Execute target query. line.queryHandler?.Invoke(line); // Wait until processing finish. Console.WriteLine("{0}/{1}: WAIT UNITL QUERY PROCESSOR FINISH HANDLER.", line.ServerName, line.ServerPipeName); while (line.Processing) { if (line.Interrupted) { break; } Thread.Sleep(50); } Console.WriteLine("{0}/{1}: QUERY PROCESSOR HANDLER FINISHED.", line.ServerName, line.ServerPipeName); } catch (Exception ex) { Console.WriteLine("{0}/{1}: EXECUTION TIME ERROR. {2}", line.ServerName, line.ServerPipeName, ex.Message); } // Log about establishing. Console.WriteLine("{0}/{1}: Transmission finished at {2}.", line.ServerName, line.ServerPipeName, DateTime.Now.ToString("HH:mm:ss.fff")); // Remove not relevant meta data. line.pipeClient.Dispose(); line.DropMeta(); Console.WriteLine(); } // Let other threads time for processing before next query. Thread.Sleep(50); } }
public async Task WritesDontCompleteImmediatelyWhenTooManyBytesAreAlreadyBuffered(int maxResponseBufferSize) { var completeQueue = new ConcurrentQueue <Action <int> >(); // Arrange _mockLibuv.OnWrite = (socket, buffers, triggerCompleted) => { completeQueue.Enqueue(triggerCompleted); return(0); }; var pipeOptions = new PipeOptions ( pool: _memoryPool, readerScheduler: _libuvThread, writerScheduler: PipeScheduler.Inline, pauseWriterThreshold: maxResponseBufferSize, resumeWriterThreshold: maxResponseBufferSize, useSynchronizationContext: false ); using (var outputProducer = CreateOutputProducer(pipeOptions)) { var bufferSize = maxResponseBufferSize - 1; var buffer = new ArraySegment <byte>(new byte[bufferSize], 0, bufferSize); // Act var writeTask1 = outputProducer.WriteDataAsync(buffer); // Assert // The first write should pre-complete since it is <= _maxBytesPreCompleted. Assert.Equal(TaskStatus.RanToCompletion, writeTask1.Status); // Act var writeTask2 = outputProducer.WriteDataAsync(buffer); await _mockLibuv.OnPostTask; // Assert // Too many bytes are already pre-completed for the second write to pre-complete. Assert.False(writeTask2.IsCompleted); // Act Assert.True(completeQueue.TryDequeue(out var triggerNextCompleted)); await _libuvThread.PostAsync(cb => cb(0), triggerNextCompleted); // Finishing the first write should allow the second write to pre-complete. await writeTask2.DefaultTimeout(); // Cleanup outputProducer.Dispose(); // Wait for all writes to complete so the completeQueue isn't modified during enumeration. await _mockLibuv.OnPostTask; // Drain the write queue while (completeQueue.TryDequeue(out triggerNextCompleted)) { await _libuvThread.PostAsync(cb => cb(0), triggerNextCompleted); } } }
public static void Connection_UnderSameUser_SingleSide_CurrentUserOnly_Works(PipeOptions serverPipeOptions, PipeOptions clientPipeOptions) { string name = GetUniquePipeName(); using (var server = new NamedPipeServerStream(name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, serverPipeOptions)) using (var client = new NamedPipeClientStream(".", name, PipeDirection.InOut, clientPipeOptions)) { Task[] tasks = new[] { Task.Run(() => server.WaitForConnection()), Task.Run(() => client.Connect()) }; Assert.True(Task.WaitAll(tasks, 20_000)); } }
public async Task FailedWriteCompletesOrCancelsAllPendingTasks(int maxResponseBufferSize) { await Task.Run(async() => { var completeQueue = new ConcurrentQueue <Action <int> >(); // Arrange _mockLibuv.OnWrite = (socket, buffers, triggerCompleted) => { completeQueue.Enqueue(triggerCompleted); return(0); }; var abortedSource = new CancellationTokenSource(); var pipeOptions = new PipeOptions ( pool: _memoryPool, readerScheduler: _libuvThread, writerScheduler: PipeScheduler.Inline, pauseWriterThreshold: maxResponseBufferSize, resumeWriterThreshold: maxResponseBufferSize, useSynchronizationContext: false ); using (var outputProducer = CreateOutputProducer(pipeOptions, abortedSource)) { var bufferSize = maxResponseBufferSize - 1; var data = new byte[bufferSize]; var fullBuffer = new ArraySegment <byte>(data, 0, bufferSize); // Act var task1Success = outputProducer.WriteDataAsync(fullBuffer, cancellationToken: abortedSource.Token); // task1 should complete successfully as < _maxBytesPreCompleted // First task is completed and successful Assert.True(task1Success.IsCompleted); Assert.False(task1Success.IsCanceled); Assert.False(task1Success.IsFaulted); // following tasks should wait. var task2Success = outputProducer.WriteDataAsync(fullBuffer); var task3Canceled = outputProducer.WriteDataAsync(fullBuffer, cancellationToken: abortedSource.Token); // Give time for tasks to percolate await _mockLibuv.OnPostTask; // Second task is not completed Assert.False(task2Success.IsCompleted); Assert.False(task2Success.IsCanceled); Assert.False(task2Success.IsFaulted); // Third task is not completed Assert.False(task3Canceled.IsCompleted); Assert.False(task3Canceled.IsCanceled); Assert.False(task3Canceled.IsFaulted); // Cause all writes to fail while (completeQueue.TryDequeue(out var triggerNextCompleted)) { await _libuvThread.PostAsync(cb => cb(-1), triggerNextCompleted); } // Second task is now completed Assert.True(task2Success.IsCompleted); Assert.False(task2Success.IsCanceled); Assert.False(task2Success.IsFaulted); // A final write guarantees that the error is observed by OutputProducer, // but doesn't return a canceled/faulted task. var task4Success = outputProducer.WriteDataAsync(fullBuffer, cancellationToken: default(CancellationToken)); Assert.True(task4Success.IsCompleted); Assert.False(task4Success.IsCanceled); Assert.False(task4Success.IsFaulted); // Third task is now canceled await Assert.ThrowsAsync <OperationCanceledException>(() => task3Canceled); Assert.True(task3Canceled.IsCanceled); Assert.True(abortedSource.IsCancellationRequested); await _mockLibuv.OnPostTask; // Complete the 4th write while (completeQueue.TryDequeue(out var triggerNextCompleted)) { await _libuvThread.PostAsync(cb => cb(0), triggerNextCompleted); } } }); }
public DefaultConnectionContext CreateConnection(PipeOptions transportPipeOptions, PipeOptions appPipeOptions) { var id = MakeNewConnectionId(); _logger.CreatedNewConnection(id); var connectionTimer = SocketEventSource.Log.ConnectionStart(id); var pair = DuplexPipe.CreateConnectionPair(transportPipeOptions, appPipeOptions); var connection = new DefaultConnectionContext(id, pair.Application, pair.Transport); connection.ConnectionTimer = connectionTimer; _connections.TryAdd(id, connection); return(connection); }
public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel) : this (serverName, pipeName, direction, options, impersonationLevel, HandleInheritability.None) { }
protected virtual void SetPipeReaderOptions(MemoryPool <byte>?pool = null, int bufferSize = -1) { PipeOptions options = new PipeOptions(pool, readerScheduler: PipeScheduler.Inline, useSynchronizationContext: false, minimumSegmentSize: bufferSize); Pipe = new Pipe(options); }
public NamedPipeClientStream(String serverName, String pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability) : base(direction, 0) { if (pipeName == null) { throw new ArgumentNullException("pipeName"); } if (serverName == null) { throw new ArgumentNullException("serverName", SR.GetString(SR.ArgumentNull_ServerName)); } if (pipeName.Length == 0) { throw new ArgumentException(SR.GetString(SR.Argument_NeedNonemptyPipeName)); } if (serverName.Length == 0) { throw new ArgumentException(SR.GetString(SR.Argument_EmptyServerName)); } if ((options & ~(PipeOptions.WriteThrough | PipeOptions.Asynchronous)) != 0) { throw new ArgumentOutOfRangeException("options", SR.GetString(SR.ArgumentOutOfRange_OptionsInvalid)); } if (impersonationLevel < TokenImpersonationLevel.None || impersonationLevel > TokenImpersonationLevel.Delegation) { throw new ArgumentOutOfRangeException("impersonationLevel", SR.GetString(SR.ArgumentOutOfRange_ImpersonationInvalid)); } if (inheritability < HandleInheritability.None || inheritability > HandleInheritability.Inheritable) { throw new ArgumentOutOfRangeException("inheritability", SR.GetString(SR.ArgumentOutOfRange_HandleInheritabilityNoneOrInheritable)); } m_normalizedPipePath = Path.GetFullPath(@"\\" + serverName + @"\pipe\" + pipeName); if (String.Compare(m_normalizedPipePath, @"\\.\pipe\anonymous", StringComparison.OrdinalIgnoreCase) == 0) { throw new ArgumentOutOfRangeException("pipeName", SR.GetString(SR.ArgumentOutOfRange_AnonymousReserved)); } m_inheritability = inheritability; m_impersonationLevel = impersonationLevel; m_pipeOptions = options; if ((PipeDirection.In & direction) != 0) { m_access |= UnsafeNativeMethods.GENERIC_READ; } if ((PipeDirection.Out & direction) != 0) { m_access |= UnsafeNativeMethods.GENERIC_WRITE; } }
public async Task OneWayReadWrites(PipeOptions serverOptions, PipeOptions clientOptions, bool asyncServerOps, bool asyncClientOps) { using (NamedPipePair pair = CreateNamedPipePair(serverOptions, clientOptions)) { NamedPipeClientStream client = pair.clientStream; NamedPipeServerStream server = pair.serverStream; byte[] received = new byte[] { 0 }; Task clientTask = Task.Run(async () => { if (asyncClientOps) { await client.ConnectAsync(); if (pair.writeToServer) { received = await ReadBytesAsync(client, sendBytes.Length); } else { await WriteBytesAsync(client, sendBytes); } } else { client.Connect(); if (pair.writeToServer) { received = ReadBytes(client, sendBytes.Length); } else { WriteBytes(client, sendBytes); } } }); if (asyncServerOps) { await server.WaitForConnectionAsync(); if (pair.writeToServer) { await WriteBytesAsync(server, sendBytes); } else { received = await ReadBytesAsync(server, sendBytes.Length); } } else { server.WaitForConnection(); if (pair.writeToServer) { WriteBytes(server, sendBytes); } else { received = ReadBytes(server, sendBytes.Length); } } await clientTask; Assert.Equal(sendBytes, received); server.Disconnect(); Assert.False(server.IsConnected); } }
public NamedPipeServerStream(String pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options) : this(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, 0, 0, null, HandleInheritability.None, (PipeAccessRights)0) { }
// ----------------------------- // ---- PAL layer ends here ---- // ----------------------------- internal static Interop.libc.OpenFlags TranslateFlags(PipeDirection direction, PipeOptions options, HandleInheritability inheritability) { // Translate direction Interop.libc.OpenFlags flags = direction == PipeDirection.InOut ? Interop.libc.OpenFlags.O_RDWR : direction == PipeDirection.Out ? Interop.libc.OpenFlags.O_WRONLY : Interop.libc.OpenFlags.O_RDONLY; // Translate options if ((options & PipeOptions.WriteThrough) != 0) { flags |= Interop.libc.OpenFlags.O_SYNC; } // Translate inheritability. if ((inheritability & HandleInheritability.Inheritable) == 0) { flags |= Interop.libc.OpenFlags.O_CLOEXEC; } // PipeOptions.Asynchronous is ignored, at least for now. Asynchronous processing // is handling just by queueing a work item to do the work synchronously on a pool thread. return flags; }
public NamedPipeServerStream(String pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity, HandleInheritability inheritability) : this(pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, inheritability, (PipeAccessRights)0) { }