Spec-Zone.ru › Tokio

Struct ServerOptions

pub struct ServerOptions { /* private fields */ }
Available on Windows and crate feature net only.

A builder structure for construct a named pipe with named pipe-specific options. This is required to use for named pipe servers who wants to modify pipe-related options.

See ServerOptions::create.

Implementations

impl ServerOptions

pub fn new() -> ServerOptions

Creates a new named pipe builder with the default settings.

use tokio::net::windows::named_pipe::ServerOptions;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-new";

let server = ServerOptions::new().create(PIPE_NAME)?;

pub fn pipe_mode(&mut self, pipe_mode: PipeMode) -> &mut Self

The pipe mode.

The default pipe mode is PipeMode::Byte. See PipeMode for documentation of what each mode means.

This corresponds to specifying PIPE_TYPE_ and PIPE_READMODE_ in dwPipeMode.

pub fn access_inbound(&mut self, allowed: bool) -> &mut Self

The flow of data in the pipe goes from client to server only.

This corresponds to setting PIPE_ACCESS_INBOUND.

Errors

Server side prevents connecting by denying inbound access, client errors with std::io::ErrorKind::PermissionDenied when attempting to create the connection.

use std::io;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-inbound-err1";

let _server = ServerOptions::new()
    .access_inbound(false)
    .create(PIPE_NAME)?;

let e = ClientOptions::new()
    .open(PIPE_NAME)
    .unwrap_err();

assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);

Disabling writing allows a client to connect, but errors with std::io::ErrorKind::PermissionDenied if a write is attempted.

use std::io;
use tokio::io::AsyncWriteExt;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-inbound-err2";

let server = ServerOptions::new()
    .access_inbound(false)
    .create(PIPE_NAME)?;

let mut client = ClientOptions::new()
    .write(false)
    .open(PIPE_NAME)?;

server.connect().await?;

let e = client.write(b"ping").await.unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
Examples

A unidirectional named pipe that only supports server-to-client communication.

use std::io;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-inbound";

let mut server = ServerOptions::new()
    .access_inbound(false)
    .create(PIPE_NAME)?;

let mut client = ClientOptions::new()
    .write(false)
    .open(PIPE_NAME)?;

server.connect().await?;

let write = server.write_all(b"ping");

let mut buf = [0u8; 4];
let read = client.read_exact(&mut buf);

let ((), read) = tokio::try_join!(write, read)?;

assert_eq!(read, 4);
assert_eq!(&buf[..], b"ping");

pub fn access_outbound(&mut self, allowed: bool) -> &mut Self

The flow of data in the pipe goes from server to client only.

This corresponds to setting PIPE_ACCESS_OUTBOUND.

Errors

Server side prevents connecting by denying outbound access, client errors with std::io::ErrorKind::PermissionDenied when attempting to create the connection.

use std::io;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-outbound-err1";

let server = ServerOptions::new()
    .access_outbound(false)
    .create(PIPE_NAME)?;

let e = ClientOptions::new()
    .open(PIPE_NAME)
    .unwrap_err();

assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);

Disabling reading allows a client to connect, but attempting to read will error with std::io::ErrorKind::PermissionDenied.

use std::io;
use tokio::io::AsyncReadExt;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-outbound-err2";

let server = ServerOptions::new()
    .access_outbound(false)
    .create(PIPE_NAME)?;

let mut client = ClientOptions::new()
    .read(false)
    .open(PIPE_NAME)?;

server.connect().await?;

let mut buf = [0u8; 4];
let e = client.read(&mut buf).await.unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
Examples

A unidirectional named pipe that only supports client-to-server communication.

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-outbound";

let mut server = ServerOptions::new()
    .access_outbound(false)
    .create(PIPE_NAME)?;

let mut client = ClientOptions::new()
    .read(false)
    .open(PIPE_NAME)?;

server.connect().await?;

let write = client.write_all(b"ping");

let mut buf = [0u8; 4];
let read = server.read_exact(&mut buf);

let ((), read) = tokio::try_join!(write, read)?;

println!("done reading and writing");

assert_eq!(read, 4);
assert_eq!(&buf[..], b"ping");

pub fn first_pipe_instance(&mut self, first: bool) -> &mut Self

If you attempt to create multiple instances of a pipe with this flag set, creation of the first server instance succeeds, but creation of any subsequent instances will fail with std::io::ErrorKind::PermissionDenied.

This option is intended to be used with servers that want to ensure that they are the only process listening for clients on a given named pipe. This is accomplished by enabling it for the first server instance created in a process.

This corresponds to setting FILE_FLAG_FIRST_PIPE_INSTANCE.

Errors

If this option is set and more than one instance of the server for a given named pipe exists, calling create will fail with std::io::ErrorKind::PermissionDenied.

use std::io;
use tokio::net::windows::named_pipe::ServerOptions;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-first-instance-error";

let server1 = ServerOptions::new()
    .first_pipe_instance(true)
    .create(PIPE_NAME)?;

// Second server errs, since it's not the first instance.
let e = ServerOptions::new()
    .first_pipe_instance(true)
    .create(PIPE_NAME)
    .unwrap_err();

assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
Examples
use std::io;
use tokio::net::windows::named_pipe::ServerOptions;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-first-instance";

let mut builder = ServerOptions::new();
builder.first_pipe_instance(true);

let server = builder.create(PIPE_NAME)?;
let e = builder.create(PIPE_NAME).unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
drop(server);

// OK: since, we've closed the other instance.
let _server2 = builder.create(PIPE_NAME)?;

pub fn write_dac(&mut self, requested: bool) -> &mut Self

Requests permission to modify the pipe’s discretionary access control list.

This corresponds to setting WRITE_DAC in dwOpenMode.

Examples
use std::{io, os::windows::prelude::AsRawHandle, ptr};

use tokio::net::windows::named_pipe::ServerOptions;
use windows_sys::{
    Win32::Foundation::ERROR_SUCCESS,
    Win32::Security::DACL_SECURITY_INFORMATION,
    Win32::Security::Authorization::{SetSecurityInfo, SE_KERNEL_OBJECT},
};

const PIPE_NAME: &str = r"\\.\pipe\write_dac_pipe";

let mut pipe_template = ServerOptions::new();
pipe_template.write_dac(true);
let pipe = pipe_template.create(PIPE_NAME)?;

unsafe {
    assert_eq!(
        ERROR_SUCCESS,
        SetSecurityInfo(
            pipe.as_raw_handle() as _,
            SE_KERNEL_OBJECT,
            DACL_SECURITY_INFORMATION,
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null_mut(),
        )
    );
}
use std::{io, os::windows::prelude::AsRawHandle, ptr};

use tokio::net::windows::named_pipe::ServerOptions;
use windows_sys::{
    Win32::Foundation::ERROR_ACCESS_DENIED,
    Win32::Security::DACL_SECURITY_INFORMATION,
    Win32::Security::Authorization::{SetSecurityInfo, SE_KERNEL_OBJECT},
};

const PIPE_NAME: &str = r"\\.\pipe\write_dac_pipe_fail";

let mut pipe_template = ServerOptions::new();
pipe_template.write_dac(false);
let pipe = pipe_template.create(PIPE_NAME)?;

unsafe {
    assert_eq!(
        ERROR_ACCESS_DENIED,
        SetSecurityInfo(
            pipe.as_raw_handle() as _,
            SE_KERNEL_OBJECT,
            DACL_SECURITY_INFORMATION,
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null_mut(),
        )
    );
}

pub fn write_owner(&mut self, requested: bool) -> &mut Self

Requests permission to modify the pipe’s owner.

This corresponds to setting WRITE_OWNER in dwOpenMode.

pub fn access_system_security(&mut self, requested: bool) -> &mut Self

Requests permission to modify the pipe’s system access control list.

This corresponds to setting ACCESS_SYSTEM_SECURITY in dwOpenMode.

pub fn reject_remote_clients(&mut self, reject: bool) -> &mut Self

Indicates whether this server can accept remote clients or not. Remote clients are disabled by default.

This corresponds to setting PIPE_REJECT_REMOTE_CLIENTS.

pub fn max_instances(&mut self, instances: usize) -> &mut Self

The maximum number of instances that can be created for this pipe. The first instance of the pipe can specify this value; the same number must be specified for other instances of the pipe. Acceptable values are in the range 1 through 254. The default value is unlimited.

This corresponds to specifying nMaxInstances.

Errors

The same numbers of max_instances have to be used by all servers. Any additional servers trying to be built which uses a mismatching value might error.

use std::io;
use tokio::net::windows::named_pipe::{ServerOptions, ClientOptions};
use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-max-instances";

let mut server = ServerOptions::new();
server.max_instances(2);

let s1 = server.create(PIPE_NAME)?;
let c1 = ClientOptions::new().open(PIPE_NAME);

let s2 = server.create(PIPE_NAME)?;
let c2 = ClientOptions::new().open(PIPE_NAME);

// Too many servers!
let e = server.create(PIPE_NAME).unwrap_err();
assert_eq!(e.raw_os_error(), Some(ERROR_PIPE_BUSY as i32));

// Still too many servers even if we specify a higher value!
let e = server.max_instances(100).create(PIPE_NAME).unwrap_err();
assert_eq!(e.raw_os_error(), Some(ERROR_PIPE_BUSY as i32));
Panics

This function will panic if more than 254 instances are specified. If you do not wish to set an instance limit, leave it unspecified.

ⓘ
use tokio::net::windows::named_pipe::ServerOptions;

let builder = ServerOptions::new().max_instances(255);

pub fn out_buffer_size(&mut self, buffer: u32) -> &mut Self

The number of bytes to reserve for the output buffer.

This corresponds to specifying nOutBufferSize.

pub fn in_buffer_size(&mut self, buffer: u32) -> &mut Self

The number of bytes to reserve for the input buffer.

This corresponds to specifying nInBufferSize.

pub fn create(&self, addr: impl AsRef<OsStr>) -> Result<NamedPipeServer>

Creates the named pipe identified by addr for use as a server.

This uses the CreateNamedPipe function.

Errors

This errors if called outside of a Tokio Runtime, or in a runtime that has not enabled I/O, or if any OS-specific I/O errors occur.

Examples
use tokio::net::windows::named_pipe::ServerOptions;

const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-create";

let server = ServerOptions::new().create(PIPE_NAME)?;

pub unsafe fn create_with_security_attributes_raw( &self, addr: impl AsRef<OsStr>, attrs: *mut c_void, ) -> Result<NamedPipeServer>

Creates the named pipe identified by addr for use as a server.

This is the same as create except that it supports providing the raw pointer to a structure of SECURITY_ATTRIBUTES which will be passed as the lpSecurityAttributes argument to CreateFile.

Errors

This errors if called outside of a Tokio Runtime, or in a runtime that has not enabled I/O, or if any OS-specific I/O errors occur.

Safety

The attrs argument must either be null or point at a valid instance of the SECURITY_ATTRIBUTES structure. If the argument is null, the behavior is identical to calling the create method.

Trait Implementations

impl Clone for ServerOptions

fn clone(&self) -> ServerOptions

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) ·

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

impl Debug for ServerOptions

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations

impl Freeze for ServerOptions

impl RefUnwindSafe for ServerOptions

impl Send for ServerOptions

impl Sync for ServerOptions

impl Unpin for ServerOptions

impl UnsafeUnpin for ServerOptions

impl UnwindSafe for ServerOptions

Blanket Implementations

impl<T> Any for T
where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more

impl<T> Borrow<T> for T
where T: ?Sized,

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more

impl<T> BorrowMut<T> for T
where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more

impl<T> CloneToUninit for T
where T: Clone,

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more

impl<T> From<T> for T

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> Instrument for T

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more

impl<T, U> Into<U> for T
where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

impl<T> ToOwned for T
where T: Clone,

type Owned = T

The resulting type after obtaining ownership.

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more

impl<T, U> TryFrom<U> for T
where U: Into<T>,

type Error = Infallible

The type returned in the event of a conversion error.

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.

impl<T> WithSubscriber for T

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more

MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/net/windows/named_pipe/struct.ServerOptions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API