As noted in the Asio documentation, an AsioTimer handler can be
called with a non-error status after timer cancellation.
Unfortunately, this can lead to race conditions, so I'm moving over
all AsioTimer users to AsioTimerSafe when I don't see the handler
clearly checking for late cancellation.
Signed-off-by: James Yonan <james@openvpn.net>
Sometimes when machine wakes from sleep,
it takes too long for agent service to start. This causes
an error which core treats as fatal and stops connection.
Fix by detecting timeout and throw non-fatal error, which
makes core reconnect.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
* HostRetry, which is essentially a string vector, now
inherits directly from std::vector<std::string>
* WS::ClientSet doesn't need a crypto-grade RNG, so rename
rng to prng.
* WS::ClientSet almost always contains a single client
object, so use std::map instead of std::unordered_map
to contain it so as to reduce overhead.
Signed-off-by: James Yonan <james@openvpn.net>
A common AsioTimer usage pattern is:
expires_at(Time::now() + duration)
This is more succinctly and efficiently stated as:
expires_after(duration).
Signed-off-by: James Yonan <james@openvpn.net>
Created a lightweight abstraction layer so that another i/o
reactor can be dropped in place of asio.
This commit includes:
* Added ASIO=1 to many "go" scripts that require asio
* Renamed "asio::" to "openvpn_io::".
Signed-off-by: James Yonan <james@openvpn.net>
The Cleanup code could potentially execute after io_context
is released, causing undefined behavior. The fix is to move
the io_context declaration to the outermost scope (i.e. top
of the method) so that it is still in scope when Cleanup code
is called.
* Added optional Stop object to new_request_synchronous()
method to allow for asynchronous request abort that is
triggered from another thread.
* In new_request_synchronous(), allow exceptions to
break out of method and reach caller.
* In new_request_synchronous(), don't automatically call
ts->hsc.reset() before method exit, since that is better
controlled by preserve_http_state.
Added get_socket() method to WS::Client to return the
underlying HTTP AsioPolySock::Base object.
Added unix_fd() method to WS::ClientSet which depends on
get_socket() above and will return the fd of HTTP socket
if it's a unix domain socket.
The fix is twofold:
1. HTTPStateContainer should reset the HTTPDelegate by calling
stop() in the delegate instead of reset() on the shared
pointer to avoid triggering HTTPDelegate destructor.
2. http_done() method should not call next_request() directly but
should instead call it through an asio::post() to ensure a
fresh stack.
* Added new_request_synchronous() static method
to synchronously execute a TransactionSet
in a worker thread.
* Added TransactionSet::preserve_http_state bool
(default=false) to determine whether or not to
preserve HTTP session across multiple completions.
* TransactionSet::completion() callback is now optional.
* Simplify Transaction and TransactionSet class
declarations by eliminating constructors in favor
of C++11 member initialization.
* Added content_only flag to dump().
* In title header, show full format_status() line.
* format_status() no longer adds a newline to end of
returned string.
In testing, I found an s3fetch regression apparently caused by
AsyncResolvableTCP.
When WS::Client is built with AsyncResolvableTCP, s3fetch will
segfault when large numbers of query threads (> 256) are used.
Signed-off-by: James Yonan <james@openvpn.net>
As noted in the Asio documentation, an AsioTimer handler can be
called with a non-error status after timer cancellation.
Unfortunately, this can lead to race conditions, so I'm moving over
all AsioTimer users to AsioTimerSafe when I don't see the handler
clearly checking for late cancellation.
Signed-off-by: James Yonan <james@openvpn.net>
Fixed a bug where exceptions thrown by done() method would
endlessly retry, ignoring the max_retries value.
Signed-off-by: James Yonan <james@openvpn.net>
Alt Routing allows services on meshed PG nodes to communicate
with services on other nodes via the secure mesh, and without
requiring SSL.
Signed-off-by: James Yonan <james@openvpn.net>
A common AsioTimer usage pattern is:
expires_at(Time::now() + duration)
This is more succinctly and efficiently stated as:
expires_after(duration).
Signed-off-by: James Yonan <james@openvpn.net>
Created a lightweight abstraction layer so that another i/o
reactor can be dropped in place of asio.
This commit includes:
* Added ASIO=1 to many "go" scripts that require asio
* Renamed "asio::" to "openvpn_io::".
Signed-off-by: James Yonan <james@openvpn.net>
Could benefit from some minor modifications to
python client backend and tray app:
* Client backend and ovpn3 both implement connection timeout.
Client backend should defer to the ovpn3 implementation.
* Client backend and ovpn3 both implement DNS server config
and SystemConfiguration event sent to
'Setup:/Network/Global/IPv4' for 'VPN up'.
Client backend should defer to the ovpn3 implementation.
* Ensure that system state changes (sleep, wakeup, network
roam, fast user switching, etc.) don't cause conflicts
between client backend and ovpn3 core both trying to
implement similar functionality.
* Tray app should render error detail in >FATAL: messages.
Right now tray raises a Disconnected notification but
loses any error detail.
Added get_socket() method to WS::Client to return the
underlying HTTP AsioPolySock::Base object.
Added unix_fd() method to WS::ClientSet which depends on
get_socket() above and will return the fd of HTTP socket
if it's a unix domain socket.
* Where unicode/ansi versions of a method exist, always
explicitly call one of unicode or ansi methods by
appending a 'W' or 'A' to the end of the method name.
Never omit the 'W' or 'A' because that will cause the
default method to be used which may vary according to
build flags.
* Prepend all Windows API method references with "::" to
indicate that the method names should be resolved from
the top-level namespace.
* Added Request::set_creds() method.
* In HTTPCore, added a virtual destructor that calls stop().
* Added is_alive() method.
* In HTTPDelegate class template, detach() method now accepts
a keepalive parameter.
* Added HTTPDelegate::attach() method.
This is to prevent attacks where a large number of very
small messages (such as 1 byte each) are sent to the
server to force it to consume more memory than the
max_content_bytes limit would normally allow.
Both Client/Server side:
1. Support asynchronous sending of content via
set_async_out() and http_content_out_finish()
methods and http_content_out_needed() callback.
2. Added ContentInfo::extra_headers for caller-defined
extra HTTP headers.
3. Made ContentInfo::CHUNKED into a constexpr
type to match ContentInfo::length member var.
4. Set FD_CLOEXEC on socket.
5. Added remote_ip_port() method to allow remote IP
address and port of socket to be obtained.
Client side:
1. In Host, added hint string to override transport host
when a specific IP address should be used for host
instead of resolving host via DNS.
2. Added Host::host_port_str() method.
3. Make general_timeout work like a true timeout, where
traffic resets the timer (this is how server-side
already works).
4. Added new method remote_endpoint_str() to match
the same method on server-side.
5. Added new method host_hint() to return the current Host
object, but set the hint/port fields to the live
remote IP address/port of the connection.
6. Added new callback http_mutate_resolver_results() to
allow user to modify the order of endpoint list returned
by resolver.
Server side:
1. Make content_len_t into a 64-bit signed int since one
of its possible values is -1 for CHUNKED.
2. Added ContentInfo::no_cache member var to trigger headers
telling clients to not cache the content.
3. Added Factory::stop() virtual method for users to
optionally override.
4. Made get_client_id() method public.
5. Fixed issue where code that allocates a client_id
wasn't actually calling new_client_id().
* Check for empty DNS resolve results.
* Fix some debugging names passed to asio_error_handler,
after functions were renamed for tcp vs. unix domain
sockets.
* HTTP client and server now support unix domain sockets
via AsioPolySock abstraction.
* HTTP server now supports Basic auth credentials.
* HTTP server now supports peercred authentication
over unix domain sockets.
* HTTP server now supports file creation permission
bits on unix domain socket.
* Added udstest tool to test HTTP client over unix domain
sockets.
* Fixed issue where HTTP server did not detect
mid-session client disconnect.
* Implement parent_handoff (for proxies).
* Improved handling of residual content, allowing
HTTP 1.1 pipelining to be supported.