-
dcaf370 fix: Add missing re-export for TransportErrorCode
This is in the public interface, as a field of Close::Transport
. Sadly this isn't detected by the unreachable_pub
lint.
-
33ca793 chore!: Remove unused Config::max_msg_size_allowed
BREAKING CHANGE: Config::max_msg_size_allowed
has been removed.
-
10397e1 refactor: Sort error
items in order of appearance
This should help to keep this module navigable.
-
958f09a refactor: Use a different struct for config internally
The InternalConfig
struct is a trimmed down version of Config
, which ditches extraneous keys (that are used elsewhere) and removes Option
s (when there are default values).
This does not affect on the public API.
-
b8461a6 refactor!: Remove random port fallback
This is a bit 'too clever' for this library, and it's unlikely that this fallback was really being used (it would usually be left unspecified, so always be random).
BREAKING CHANGE: This is a breaking behavioural change. It is now up to the caller if they want to retry with a different port.
-
e5fc09c refactor!: Move local address from config to QuicP2p::bootstrap
Keeping the local address in config involved quite a lot of shenanigans to obtain a default value, and it doesn't provide much value. Typically users would look at Endpoint::local_addr
, which is read from the underlying socket (by quinn).
This does mean passing a local address when constructing an endpoint, but it's expected that users will have their own configuration structures, such that this won't be too disruptive.
BREAKING CHANGE: Config::local_ip
and Config::local_port
have been removed. QuicP2p::bootstrap
and QuicP2p::new_endpoint
now require a local address to bind to. The Error::UnspecifiedLocalIp
variant has been removed.
-
ad71740 refactor!: Remove BootstrapCache
and hard-coded contacts
This is another change intended to shed some cleverness from this library. It's likely that users will already be storing and maintaining a list of contacts, so rather than having to synchronise that with this library, we now just accept a list of contacts when bootstrap
is called.
BREAKING CHANGE: Config::hard_coded_contacts
and Config::bootstrap_cache_dir
have been removed. Additionally, QuicP2p::with_config
no longer takes bootstrap_nodes
β these should instead be passed to QuicP2p::bootstrap
. Finally, the Error::InvalidPath
and Error::UserHomeDir
variants have been removed.
-
9fc3eb0 refactor!: Make Config
in QuicP2p::from_config
non-optional
Now that there are no shenanigans needed when setting up default Config
, callers can just use Config::default()
.
BREAKING CHANGE: QuicP2p::from_config
now takes a Config
argument, rather than Option<Config>
. Config::default()
(or Option::unwrap_or_default
) should be used instead.
-
34e2ed1 feat: Add Endpoint::connect_to_any
This implements the 'bootstrap' process of contacting a set of nodes and returning the first one to which we successfully connect. QuicP2p::bootstrap
is now implemented in terms of this function.
-
c837e9f doc: Update README
The library has diverged somewhat from what was in the README. The new text tries to articulate the features you get over just using a QUIC library like quinn
directly.
-
b36f31d chore: Remove redundant structopt
annotation
structopt
uses kebab-ase by default.
-
c6fd90e refactor!: Use Duration
in config and centralise defaults
Rather than using names and documentation to specify the units for durations, we can use the Duration
type which lets callers choose whatever works best for them. It also means we no longer have to convert to Duration
internally, simplifying some code.
Additionally, the default values for duration constants have been centralised under config
, which has been made public so users can see them in documentation.
BREAKING CHANGE: The duration fields in config have all changed:
idle_timeout_msec
is renamed idle_timeout
and is now an Option<Duration>
.
keep_alive_interval_msec
is renamed keep_alive_interval
and is now an Option<Duration>
.
upnp_lease_duration
is now an Option<Duration>
.
retry_duration_msec
is renamed min_retry_duration
and is now an Option<Duration>
.
-
a2cc68c refactor: Move quinn config into InternalConfig
This moves some responsbilities from QuicP2p
to config
.
-
cf29520 refactor: Move InternalConfig
construction into config
mod
This further reduces the responsibilities of QuicP2p
, and also reduces the 'spread' of config concerns.
-
44ced5f refactor: Make SerialisableCertificate
mod private
This was only being used in tests::quinn
, which can get what it needs from InternalConfig
.
-
5dea879 refactor: Merge peer_config
into InternalConfig
The peer_config
mod contained helper functions for constructing the various bits of quinn
configuration we need. Being config related, they fit just as well in the config
module, further reducing the spread of 'config' concerns.
-
af418be refactor!: Delete SerializableCertificate
This was not exposed, so the whole things can be replaced by a single function on InternalConfig
.
BREAKING CHANGE: The Error::Base64Decode
variant has been removed.
-
a805a11 refactor!: Separate ConfigError
from Error
Currently, the only configuration-time errors are related to certificate generation. Since we currently generate self-signed certificates, the only failures that could happen would be due to bugs. As such, the ConfigError::CertificateGeneration
variant doesn't attempt to capture all the info, rather just an opaque Error
(though the backtrace and source chain will be preserved).
This removes a number of variants from Error
.
BREAKING CHANGE: There are several breaking changes:
QuicP2p::from_config
now returns Result<Self, ConfigError>
.
- The
Error::CertificateParse
variant has been removed.
- The
Error::CertificatePkParse
variant has been removed.
- The
Error::CertificateGen
variant has been removed.
- The
Error::Tls
variant has been removed.
-
237d23b chore!: Remove unused Error
variants
BREAKING CHANGE: The Error::DisconnectionNotification
and Error::Configuration
variants have been removed.
-
8356d1e refactor!: Refactor WireMsg::read_from_stream
to avoid logic error
Previously we used TryFrom
which we know will succeed thanks to our assertions, however we don't want to allow for the possibility of unexpected panics by using unwrap
here.
Since we have asserted the pointer size though, we can reasonably perform a lossy conversion with as
, knowing that in fact nothing will be lost.
BREAKING CHANGE: The Error::UnexpectedError
variant has been removed.
-
7c0dba6 refactor!: Rename Endpoint::socket_addr
to public_addr
This is a more appropriate name for the method.
BREAKING CHANGE: Endpoint::socket_addr
has been renamed to public_addr
.
-
9ea04db refactor!: Make ConnId::generate
infallible
This trait method originally allowed for an arbitrary Box<dyn Error>
, likely to account for the possible serialization failure when using bincode::serialize
in the impl for XorName
. Whilst this allows for more exotic connection ID strategies, having to account for this error in all APIs that touch connection IDs is a bit of a pain.
By rewriting the XorName
impl to 'manually' extract the IP and port bytes, we can avoid any possibility of error and make the method infallible.
BREAKING CHANGE: The ConnId::generate
method now returns Self
, and doesn't allow for errors. The Error::ConnectionIdGeneration
variant has been removed.
-
aec6334 refactor!: Return Option
from Endpoint::connect_to_any
The Result
returned by connect_to_any
could only fail for two reasons:
- An empty list of nodes was provided. Callers could know if that's the case and do their own validation, otherwise
None
is a perfectly reasonable result and consistent with other list operations (first
, last
, etc.).
- Every peer failed to connect. In this case we would print the error, but only return a marker to the caller (
Error::BootstrapFailed
). This gives no extra information vs. None
(especially since, as noted above, the caller can already distinguish this from an empty list of peers).
QuicP2p::bootstrap
still converts None
to the corresponding error, so as to not break that API (though it should be removed soon).
BREAKING CHANGE: Endpoint::connect_to_any
now returns Option<SocketAddr>
instead of Result<SocketAddr>
.
-
6bc1fb1 feat: Add Endpoint::new_client
constructor
This creates an Endpoint
that can work as a client only (all the machinery for incoming transactions are dropped).
Another difference from Endpoint::new
is that this does none of the reachability checking, since this should not be necessary for client- only endpoints (though, the API for bidirectional streams is currently unusable). This massively reduces the possible errors, which have their own ClientError
enum.
-
9619472 refactor: Remove connection_deduplicator::Error
This introduces a new (crate private) enum ConnectFailure
which covers the three possible reasons a connect attempt might fail:
- The connect parameters were invalid (
quinn::ConnectError
).
- An I/O or protocol error occurred during connect (
quinn::ConnectionError
), which we expose as two variants in our API:
Error::ConnectionClosed
indicating the connection was closed gracefully by ourselves, the application, or the protocol.
Error::ConnectionError
for other possibilities (resets, timeouts, and transport errors).
Ultimately, this allows us to ditch connection_deduplicator::Error
in favour of ConnectFailure
which can be used for other things in future.
The separation of quinn::ConnectionError
to Close
and ConnectionError
has also be factored into a private ConnectionCloseOrError
enum.
-
60dc1cd refactor: Remove Endpoint::create_new_connection
This wasn't doing anything more than attempt_connection
, so it can be removed.
-
0d18404 refactor!: Merge 'connect' and 'close' errors with ConnectionError
This introduces new variants to the ConnectionError
enum to cover failures that may be encountered before establishing a connection (quinn::ConnectError
) as well as closures (Close
).
This is useful for a couple of reasons:
- Many of our APIs will transparently try to create connections before using them. Even when reducing the possible variants from these APIs, we would still need to account for these three possibilities (pre-connect error, connection error, and connection close).
- It removes
quinn::ConnectError
from our public API, and better represents errors that should be impossible as bugs.
- It replaces the crate-private
ConnectFailure
and simplifies some of the error conversion logic.
BREAKING CHANGE: The Error::Connect
and Error::ConnectionClosed
variants have been removed. Several additional variants have been added to ConnectionError
.
-
a80ba51 refactor!: Remove Error::UnknownStream
variant
This variant existed to handle errors returned by quinn when trying to set or get the stream's priority. The errors can occur because the stream objects are essentially indices into a map of underlying streams. Calling methods on the stream translates to a lookup into this map. Undelrying streams may close for various reasons independent of our handles for them (e.g. if the stream or connection closes).
However, handling this situation as errors is not very useful. If we fail to set the priority of a stream because it doesn't exist, the effect of the priority would be unobservable. Any attempt to observe the effect (e.g. reading/writing to the stream) would lead to an error at that point, which is a far more convenient place to handle them.
By ignoring errors when setting stream priority (and dropping the getter for priority, since there's no downstream use-case), we can remove the UnknownStream
variant and reduce the range of possible errors from all functions that establish connections (which is many!).
BREAKING CHANGE:
- The
Error::UnknownStream
variant has been removed.
SendStream::set_priority
is now infallible and returns ()
.
SendStream::priority
has been removed.
-
f771972 refactor!: Make Endpoint::disconnect_from
infallible
This function can never return an error.
BREAKING CHANGE: Endpoint::disconnect_from
now returns ()
.
-
95f59c0 fix: Make connection deduplicator handle cancellations
When a connection attempt is made, ConnectionDeduplicator::query
would return None
for the first attempt, and any future attempts will await on the broadcast channel until the first caller calls ConnectionDeduplicator::complete
. As such, subsequent callers would await forever if the first caller never called complete
, e.g. because the enclosing task was cancelled, or due to a logic bug.
This commit refactors ConnectionDeduplicator
to store Weak
references to the broadcast sender in the map, and query
now returns the only strong reference. This way, if the caller that gets the strong reference is cancelled, the sender will drop and any queued callers will notice.
This has the nice side effect of having to properly correlate the query
and 'complete's, since the result of query
is needed to complete.
-
df73eb3 refactor: Centralise connection pool interactions
Endpoint
had a few different methods for connecting, some of which would use the connection pool + deduplicator and some would not. It's not really clear when we wouldn't want to retry connection attempts, so this commit introduces a (private) get_or_connect_to
function which always uses the pool and always retries. All functions that need a connection now use this.
This has the nice side-effect of removing (most of) the need for Error::MissingConnection
, since get_or_connect_to
returns the established connection.
-
98e98a6 refactor!: Use ConnectionError
when possible
This changes the public Endpoint
methods connect_to
and open_bidirectional_stream
to use ConnectionError
for errors. This reduces the scope of errors for callers to handle, and sets us up for further reductions with other methods.
BREAKING CHANGE: Endpoint::connect_to
and Endpoint::open_bidirectional_stream
now use ConnectionError
, rather than Error
, for error results.
-
4ea22d3 fix!: Fix WireMsg
visibility
This was marked pub
and appeared in some APIs (SendStream::send
, Error::UnexpectedMessageType
) even though the type itself is unreachable (wire_msg
mod is private and WireMsg
is not re-exported).
The type itself has been marked pub(crate)
, along with its associated functions, and functions that use it. The Error::UnexpectedMessageType
variant has been changed to include a public newtype, which for users would behave like an opaque error. This assumes the intention was for the type not to be exposed.
BREAKING CHANGE: SendStream::send
is no longer public. Error::UnexpectedMessageType
now contains a simple error struct.
-
bdf8dac feat!: Add SendError
for send-specific errors
The SendError
covers only the error possibilities when sending a message, which makes it easier to handle by users. All APIs that simply connect and send messages (or just send messages) have been changed to return SendError
.
One method that could not easily be changed is try_send_message
, since it returns a particular error variant when there is no matching connection in the pool. This may be changed separately.
BREAKING CHANGE: The following APIs had their error type changed from Error
to SendError
:
SendStream::send_user_msg
SendStream::send
SendStream::finish
Endpoint::send_message
Additionally, the StreamWrite
and MaxLengthExceeded
variants have been removed from Error
, and a Send
variant has been added.
-
fffa96f feat!: Add RecvNextError
for receive-specific errors
The RecvNextError
(and RecvError
) model the possible errors that can occur when receiving a message. RecvNextError
is returned from RecvStream::next
, and covers the additional possibility (over RecvError
) of the received message not being a user message.
This allowed the removal of several Error
variants.
BREAKING CHANGE: RecvStream::next
now returns RecvNextError
as the error type. The following Error
variants have been removed:
Error::Serialisation
(this is now fully covered by SendError
and RecvError
).
Error::InvalidMsgFlag
(this case is now covered by RecvError::Serialization
).
Error::StreamRead
(this is now covered by RecvError
).
Error::EmptyResponse
(this case is now covered by RecvError::Serialization
).
Error::UnexpectedMessageType
(this case is now covered by `ReadNextError::UnexpectedMessageType).
Finally, a Recv
variant has been added to Error
.
-
6d2b523 refactor: Rename Endpoint::new
to _new
This is in preparation for adding a public new
constructor.
-
de416c4 refactor: Switch test errors from anyhow
to eyre
We now use eyre
, via color_eyre
, for errors in tests. This should give us nicer output, and is consistent with the approach taken in other MaidSafe repositories.
-
6e16a09 refactor!: Use SerializationError
for too long messages
This will allow merging the SendError
and RecvError
types.
BREAKING CHANGE: The SendError::TooLong
variant has been removed. The same condition (attempting to send a message longer than u32::MAX
bytes) will now return SendError::Serialization
.
-
779afc0 refactor!: Treat unexpected messages as serialization errors
The semantics of this are a bit questionable, but it allows us to remove the RecvNextError
and UnexpectedMessageType
types. Essentially, we treat the problem of receiving an unexpected message as if we've tried to deserialize the expected message, and found something else. This doesn't quite match the logic (we in fact do deserialize a message successfully), but is suitable for the API.
BREAKING CHANGE: The RecvNextError
and UnexpectedMessageType
types have been removed. RecvError
is used where RecvNextError
was used previously.
-
efc4b56 refactor: Simplify igd::port_forward
The new signature requires the caller to specify the external port separately from the local address, which is a better match for the actual port mapping functionality. This removes some unnecessary 'plumbing' for the return value.
-
f2ec696 refactor!: Use a separate type for IGD errors
This removes all the Igd*
variants from the Error
enum. These would in fact never be exposed to users, since IGD errors are always caught and logged. As such, the new IgdError
enum is crate-private.
BREAKING CHANGE: The IgdAddPort
, IgdRenewPort
, IgdSearch
, and IgdNotSupported
variants have been removed from Error
. These variants would never have been returned, but may be referenced in matches against Error
values.
-
86bc285 feat: Add public Endpoint::new
constructor
This can be used to construct new peer endpoints, which is positioned as the 'default' by naming the method simply new
.
This roughly follows the logic of the crate private new
that it replaces (renamed to _new
, to be removed in future), with some differences:
-
Errors that occur when establishing the public address or port forwarding are returned to the user. As a library, it's been deemed preferable that callers handle this and retry, with the relevant configuration altered, if desired.
-
Configured external IP/port are now combined with the steps to query our public address from a peer. This is intended to simplify the logic around public address handling β there's now a single sequence of steps:
- Start with
public_addr = local_addr
.
- If we bootstrapped to a peer, get our
visible_addr
from them.
- If we configured a specific
external_ip
, override that in public_addr
.
- Otherwise, if we have a
visible_addr
, override the IP in public_addr
.
- If we configured a specific
external_port
, override that in public_addr
.
- Otherwise, if we have a
visible_addr
, override the port in public_addr
.
Still not exactly "simple", but easier to follow.
-
If we bootstrapped to a peer, we always test reachability of our determined public_addr
. There's no reason not to do this β even if the endpoint is local-only, it verifies the expectation of the caller that the given contacts can reach us (which will work if they are also local).
-
6a379c9 refactor!: Remove QuicP2p
Now that Endpoint
has public constructors, there's no need for the QuicP2p
interface. This also removes a decent chunk of code from Endpoint
itself.
This leaves behind some redundant Error
variants, but the intention is to remove that whole type soon.
BREAKING CHANGE: The QuicP2p
type has been removed. Use Endpoint::new
or Endpoint::new_client
instead. The BootstrapFailure
, EmptyBootstrapNodesList
, Io
, Endpoint
, NoEchoServerEndpointDefined
, EchoServiceFailure
, CannotAssignPort
, IncorrectPublicAddress
, and UnresolvedPublicIp
Error
variants have been removed.
-
7102f59 refactor!: Remove Result
alias
Now that there are several public error types, a single Result
alias doesn't really make sense. This also makes it easier to find and remove Error
references.
BREAKING CHANGE: The Result
alias has been removed. It can be replaced by std::result::Result<T, qp2p::Error>
.
-
0f603c8 refactor!: Return RpcError
from Endpoint::is_reachable
The is_reachable
method performs an endpoint echo operation against a given peer address. RpcError
covers all the possible errors that can occur during this operation, and no more.
BREAKING CHANGE: Endpoint::is_reachable
now returns Result<(), RpcError>
, rather than Result<(), Error>
.
-
08a38ed refactor!: Return SendError
in Endpoint::try_send_message
Rather than returning an Error::MissingConnection
if the connection is not in the pool, this now returns Err(None)
. If the connection is in the pool, but there's an error sending the message, this will return Err(Some(error))
. It remains to be seen how usable this will be for callers, but it avoid introducing another type for this single case and is a reasonable model.
BREAKING CHANGE: Endpoint::try_send_message
now returns Result<(), Option<SendError>>
rather than Result<(), Error>
. The Error::MissingConnection
variant has been removed.
-
22f5259 refactor!: Remove Error
This was no longer used in any public APIs. The one internal use was to unify error when reading from streams in connections
. This has been replaced by a private enum for that specific purpose.
BREAKING CHANGE: The Error
type has been removed.
-
5492287 refactor!: Remove Endpoint::bootstrap_nodes
This is no longer used.
BREAKING CHANGE: The Endpoint::bootstrap_nodes
method has been removed since it is no longer set.
-
9f6cbbd fix: Don't use connection pool in Endpoint::is_reachable
The point of this function is to test if a given address can be connected to. If we use the connection pool, we may use a connection that they established, giving us a false positive.
-
7bd640f refactor: Deduplicate endpoint building logic
This is an internal-only refactor to deduplicate the code for building an endpoint, between the new
and new_client
constructors.