OpenVPN 3 Core Library
Loading...
Searching...
No Matches
namedpipe.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#pragma once
13
17
18namespace openvpn::Acceptor {
19
20class NamedPipe : public Base
21{
22 public:
23 OPENVPN_EXCEPTION(named_pipe_acceptor_error);
24
26
27 NamedPipe(openvpn_io::io_context &io_context,
28 const std::string &name_arg,
29 const std::string &sddl_string)
30 : name(name_arg),
31 handle(io_context),
32 sa(sddl_string, false, "named pipe")
33 {
34 }
35
36 void async_accept(ListenerBase *listener,
37 const size_t acceptor_index,
38 openvpn_io::io_context &io_context) override
39 {
40 // create the named pipe
41 const HANDLE h = ::CreateNamedPipeA(
42 name.c_str(),
43 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
44 PIPE_REJECT_REMOTE_CLIENTS | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
45 PIPE_UNLIMITED_INSTANCES,
46 2048, // output buffer size
47 2048, // input buffer size
48 0,
49 &sa.sa);
51 {
52 const openvpn_io::error_code err(::GetLastError(), openvpn_io::error::get_system_category());
53 OPENVPN_THROW(named_pipe_acceptor_error, "failed to create named pipe: " << name << " : " << err.message());
54 }
55
56 // wait for connection (asynchronously)
57 {
58 handle.assign(h);
59 openvpn_io::windows::overlapped_ptr over(
60 io_context,
61 [self = Ptr(this),
62 listener = ListenerBase::Ptr(listener),
63 acceptor_index](const openvpn_io::error_code &ec, size_t bytes_transferred)
64 {
65 // accept client connection
66 listener->handle_accept(new AsioPolySock::NamedPipe(std::move(self->handle), acceptor_index),
67 ec.value() == ERROR_PIPE_CONNECTED // not an error
68 ? openvpn_io::error_code()
69 : ec);
70 });
71
72 const BOOL ok = ::ConnectNamedPipe(handle.native_handle(), over.get());
73 const DWORD err = ::GetLastError();
74 if (!ok && err != ERROR_IO_PENDING)
75 {
76 // The operation completed immediately,
77 // so a completion notification needs
78 // to be posted. When complete() is called,
79 // ownership of the OVERLAPPED-derived
80 // object passes to the io_service.
81 const openvpn_io::error_code ec(err, openvpn_io::error::get_system_category());
82 over.complete(ec, 0);
83 }
84 else // ok || err == ERROR_IO_PENDING
85 {
86 // The operation was successfully initiated,
87 // so ownership of the OVERLAPPED-derived object
88 // has passed to the io_service.
89 over.release();
90 }
91 }
92 }
93
94 void close() override
95 {
96 handle.close();
97 }
98
99 private:
100 std::string name;
101 openvpn_io::windows::stream_handle handle;
103};
104
105} // namespace openvpn::Acceptor
OPENVPN_EXCEPTION(named_pipe_acceptor_error)
NamedPipe(openvpn_io::io_context &io_context, const std::string &name_arg, const std::string &sddl_string)
Definition namedpipe.hpp:27
openvpn_io::windows::stream_handle handle
void async_accept(ListenerBase *listener, const size_t acceptor_index, openvpn_io::io_context &io_context) override
Definition namedpipe.hpp:36
Win::SecurityAttributes sa
RCPtr< NamedPipe > Ptr
Definition namedpipe.hpp:25
The smart pointer class.
Definition rc.hpp:119
#define OPENVPN_THROW(exc, stuff)
bool defined(HANDLE handle)
Definition handle.hpp:25
virtual void handle_accept(AsioPolySock::Base::Ptr sock, const openvpn_io::error_code &error)=0