From 04acd2c2791adc9a7d003950a7fbc9de9539fa9b Mon Sep 17 00:00:00 2001 From: Jorropo Date: Fri, 28 Feb 2020 01:24:08 +0100 Subject: [PATCH 1/6] Adding QTransport interfaces. There is also more additional new interface. --- transport/transport.go | 76 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/transport/transport.go b/transport/transport.go index 39a8fd38..0371c726 100644 --- a/transport/transport.go +++ b/transport/transport.go @@ -28,6 +28,9 @@ var AcceptTimeout = 60 * time.Second // capabilities required by libp2p: stream multiplexing, encryption and // peer authentication. // +// DEPREACATED try to use QCapableConn instead, using this will result in +// wrong transport choice when trying to pick a good one. +// // These capabilities may be natively provided by the transport, or they // may be shimmed via the "connection upgrade" process, which converts a // "raw" network connection into one that supports such capabilities by @@ -44,6 +47,55 @@ type CapableConn interface { Transport() Transport } +// Quality is an estimation of how bad the connection will be. +// It must be short and fast to run. +// Lower is the returned score, better we expect the connection to be. +// Don't implement a pinging/monitoring algorithm quality must be deterministic. +// +// To see where to place your transport on the scale take a look at this (note: +// a proto with a Quality twice bigger is not twice slower or twice worst, it is +// just worst, like the place on a leaderboard): +// - TCP, 2^31, multiplexed stated continuous protocol (stream have fight for a +// place in the underlying protocol) +// - QUIC, 2^30, async stated discontinuous protocol (stream doesn't have to +// fight but there is time taken to open the connection and stream) +// - Circuit, router underlying connection quality + the number of hops * 8 +// (that consider that all router are equal but there is really no better than +// pinging/monitoring to know that) + 2^16 (base circuit value). +// +// Its also not needed to follow that closely, thing can be added if a proto add +// some overhead : +// - WS tcp score + 50 +// - WSS ws score + 150 +// +// If conn is on a private network Quality() must divide score by 2^8 (shift +// right by 8). +// If conn is on the loopback Quality() must divide score by 2^16 (shift right +// by 16). +// +// QCapableConn embed CapableConn but with `Quality() uint32` support. +type QCapableConn interface { + CapableConn + + // Quality returns the Quality we can expect from the connection to this peer. + // That must be deterministic and fast. + Quality() uint32 +} + +// Score is used by transport to returns expectation about connection +type Score struct { + // Score of the future connection, must not change once the connection is + // actualy created + Quality uint32 + // True if quality was actualy calculable (it may only be calculable with an + // open connection). + // Note: if IsQuality == true swarm will be able to cancel the dial if a + // better transport is found. + IsQuality bool + // Number of file descriptor expected to be open. + Fd uint8 +} + // Transport represents any device by which you can connect to and accept // connections from other peers. // @@ -55,11 +107,30 @@ type CapableConn interface { // stream multiplexing and connection security (encryption and authentication). // // For a conceptual overview, see https://docs.libp2p.io/concepts/transport/ +// +// DEPREACATED try to use QTransport instead, using this will result in +// wrong transport choice when trying to pick a good one. type Transport interface { + BaseTransport + // Dial dials a remote peer. It should try to reuse local listener // addresses if possible but it may choose not to. Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (CapableConn, error) +} + +type QTransport interface { + BaseTransport + + // Dial dials a remote peer. It should try to reuse local listener + // addresses if possible but it may choose not to. + Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (QCapableConn, error) + // Score returns the Quality we can expect from the connection to this peer. + // That must be deterministic and fast. + Score(raddr ma.Multiaddr, p peer.ID) (Score, error) +} + +type BaseTransport interface { // CanDial returns true if this transport knows how to dial the given // multiaddr. // @@ -109,5 +180,8 @@ type TransportNetwork interface { // local multiaddr and pick the *last* protocol registered with a proxy // transport, if any. Otherwise, it'll pick the transport registered to // handle the last protocol in the multiaddr. - AddTransport(t Transport) error + // + // Even if BaseTransport are accepted its needed to be able to cast to + // Transport or QTransport. + AddTransport(t BaseTransport) error } From 2d4fee4a16be87e322e555002a40ffad35592331 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Sat, 29 Feb 2020 10:48:15 +0100 Subject: [PATCH 2/6] Changing QCapableConn.Transport() to return QTransport. --- transport/transport.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/transport/transport.go b/transport/transport.go index 0371c726..6ae8942d 100644 --- a/transport/transport.go +++ b/transport/transport.go @@ -39,9 +39,7 @@ var AcceptTimeout = 60 * time.Second // CapableConn provides accessors for the local and remote multiaddrs used to // establish the connection and an accessor for the underlying Transport. type CapableConn interface { - mux.MuxedConn - network.ConnSecurity - network.ConnMultiaddrs + BaseCapableConn // Transport returns the transport to which this connection belongs. Transport() Transport @@ -75,11 +73,21 @@ type CapableConn interface { // // QCapableConn embed CapableConn but with `Quality() uint32` support. type QCapableConn interface { - CapableConn + BaseCapableConn // Quality returns the Quality we can expect from the connection to this peer. // That must be deterministic and fast. Quality() uint32 + + // Transport returns the transport to which this connection belongs. + Transport() QTransport +} + +// CapableConnBase is used to build `CapableConn` and `QCapableConn` +type BaseCapableConn interface { + mux.MuxedConn + network.ConnSecurity + network.ConnMultiaddrs } // Score is used by transport to returns expectation about connection From b1a91b671f5187c0e7157cce781101e531a27d19 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Sat, 29 Feb 2020 11:00:26 +0100 Subject: [PATCH 3/6] Adding transport.QListener --- transport/transport.go | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/transport/transport.go b/transport/transport.go index 6ae8942d..0c9de98e 100644 --- a/transport/transport.go +++ b/transport/transport.go @@ -73,11 +73,17 @@ type CapableConn interface { // // QCapableConn embed CapableConn but with `Quality() uint32` support. type QCapableConn interface { - BaseCapableConn + ListenedQCapableConn // Quality returns the Quality we can expect from the connection to this peer. // That must be deterministic and fast. Quality() uint32 +} + +// ListenedQCapableConn is like QCapableConn but is used by listener, quality is +// managed on client side. +type ListenedQCapableConn interface { + BaseCapableConn // Transport returns the transport to which this connection belongs. Transport() QTransport @@ -124,6 +130,9 @@ type Transport interface { // Dial dials a remote peer. It should try to reuse local listener // addresses if possible but it may choose not to. Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (CapableConn, error) + + // Listen listens on the passed multiaddr. + Listen(laddr ma.Multiaddr) (Listener, error) } type QTransport interface { @@ -133,6 +142,9 @@ type QTransport interface { // addresses if possible but it may choose not to. Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (QCapableConn, error) + // Listen listens on the passed multiaddr. + Listen(laddr ma.Multiaddr) (QListener, error) + // Score returns the Quality we can expect from the connection to this peer. // That must be deterministic and fast. Score(raddr ma.Multiaddr, p peer.ID) (Score, error) @@ -147,9 +159,6 @@ type BaseTransport interface { // out addresses that we can't dial. CanDial(addr ma.Multiaddr) bool - // Listen listens on the passed multiaddr. - Listen(laddr ma.Multiaddr) (Listener, error) - // Protocol returns the set of protocols handled by this transport. // // See the Network interface for an explanation of how this is used. @@ -167,7 +176,20 @@ type BaseTransport interface { // package, and also exposes a Multiaddr method as opposed to a regular Addr // method type Listener interface { + BaseListener + Accept() (CapableConn, error) +} + +// QListener is like listener but produce QCapableConn instead of CapableConn. +type QListener interface { + BaseListener + + Accept() (ListenedQCapableConn, error) +} + +// BaseListener is used to build `Lister` and `QListener` +type BaseListener interface { Close() error Addr() net.Addr Multiaddr() ma.Multiaddr From 85534fa14c5522c603c1a5817099001c99111d59 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 3 Mar 2020 20:09:32 +0100 Subject: [PATCH 4/6] Adding `network.Conn.OnBetter`. --- network/conn.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/network/conn.go b/network/conn.go index e7844a0e..086d2e84 100644 --- a/network/conn.go +++ b/network/conn.go @@ -2,6 +2,7 @@ package network import ( "io" + "time" ic "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" @@ -27,8 +28,17 @@ type Conn interface { // Stat stores metadata pertaining to this conn. Stat() Stat + + // OnBetter is an callback when a better connection is found. + // OnBetter is threadsafe, it can be called even once the event raised and the + // callback we be yield. + OnBetter(OnBetterHandler) } +// OnBetterHandler are args to pass to Conn.OnBetter The time is the deadline +// before a hard close (fixed time not duration). +type OnBetterHandler func(time.Time) + // ConnSecurity is the interface that one can mix into a connection interface to // give it the security methods. type ConnSecurity interface { From 7e1329f48604f857f433af2c6f33d66769912b69 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 3 Mar 2020 21:10:32 +0100 Subject: [PATCH 5/6] Removing `transport.Score.IsQuality` to avoid excessive redial. We don't want to dial the same peer again and again, allowing transport to not return an expected quality means we must try to dial each time. --- go.mod | 116 +++++++++++++++++++++++++++++++++++++++++ go.sum | 1 + transport/transport.go | 12 ++--- 3 files changed, 121 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 7022bc16..786926a0 100644 --- a/go.mod +++ b/go.mod @@ -19,3 +19,119 @@ require ( ) go 1.13 + +replace github.com/libp2p/go-addr-util => ../go-addr-util + +replace github.com/libp2p/go-buffer-pool => ../go-buffer-pool + +replace github.com/libp2p/go-conn-security-multistream => ../go-conn-security-multistream + +replace github.com/libp2p/go-eventbus => ../go-eventbus + +replace github.com/libp2p/go-flow-metrics => ../go-flow-metrics + +replace github.com/libp2p/go-libp2p => ../go-libp2p + +replace github.com/libp2p/go-libp2p-autonat => ../go-libp2p-autonat + +replace github.com/libp2p/go-libp2p-autonat-svc => ../go-libp2p-autonat-svc + +replace github.com/libp2p/go-libp2p-blankhost => ../go-libp2p-blankhost + +replace github.com/libp2p/go-libp2p-circuit => ../go-libp2p-circuit + +replace github.com/libp2p/go-libp2p-connmgr => ../go-libp2p-connmgr + +replace github.com/libp2p/go-libp2p-consensus => ../go-libp2p-consensus + +replace github.com/libp2p/go-libp2p-daemon => ../go-libp2p-daemon + +replace github.com/libp2p/go-libp2p-discovery => ../go-libp2p-discovery + +replace github.com/libp2p/go-libp2p-examples => ../go-libp2p-examples + +replace github.com/libp2p/go-libp2p-gorpc => ../go-libp2p-gorpc + +replace github.com/libp2p/go-libp2p-introspection => ../go-libp2p-introspection + +replace github.com/libp2p/go-libp2p-kad-dht => ../go-libp2p-kad-dht + +replace github.com/libp2p/go-libp2p-kbucket => ../go-libp2p-kbucket + +replace github.com/libp2p/go-libp2p-loggables => ../go-libp2p-loggables + +replace github.com/libp2p/go-libp2p-mplex => ../go-libp2p-mplex + +replace github.com/libp2p/go-libp2p-nat => ../go-libp2p-nat + +replace github.com/libp2p/go-libp2p-netutil => ../go-libp2p-netutil + +replace github.com/libp2p/go-libp2p-noise => ../go-libp2p-noise + +replace github.com/libp2p/go-libp2p-peerstore => ../go-libp2p-peerstore + +replace github.com/libp2p/go-libp2p-pnet => ../go-libp2p-pnet + +replace github.com/libp2p/go-libp2p-pubsub => ../go-libp2p-pubsub + +replace github.com/libp2p/go-libp2p-pubsub-router => ../go-libp2p-pubsub-router + +replace github.com/libp2p/go-libp2p-pubsub-tracer => ../go-libp2p-pubsub-tracer + +replace github.com/libp2p/go-libp2p-quic-transport => ../go-libp2p-quic-transport + +replace github.com/libp2p/go-libp2p-raft => ../go-libp2p-raft + +replace github.com/libp2p/go-libp2p-record => ../go-libp2p-record + +replace github.com/libp2p/go-libp2p-routing-helpers => ../go-libp2p-routing-helpers + +replace github.com/libp2p/go-libp2p-secio => ../go-libp2p-secio + +replace github.com/libp2p/go-libp2p-swarm => ../go-libp2p-swarm + +replace github.com/libp2p/go-libp2p-testing => ../go-libp2p-testing + +replace github.com/libp2p/go-libp2p-tls => ../go-libp2p-tls + +replace github.com/libp2p/go-libp2p-transport-upgrader => ../go-libp2p-transport-upgrader + +replace github.com/libp2p/go-libp2p-webrtc-direct => ../go-libp2p-webrtc-direct + +replace github.com/libp2p/go-libp2p-yamux => ../go-libp2p-yamux + +replace github.com/libp2p/go-maddr-filter => ../go-maddr-filter + +replace github.com/libp2p/go-mplex => ../go-mplex + +replace github.com/libp2p/go-msgio => ../go-msgio + +replace github.com/multiformats/go-multiaddr => ../go-multiaddr + +replace github.com/multiformats/go-multiaddr-dns => ../go-multiaddr-dns + +replace github.com/multiformats/go-multiaddr-fmt => ../go-multiaddr-fmt + +replace github.com/multiformats/go-multiaddr-net => ../go-multiaddr-net + +replace github.com/multiformats/go-multistream => ../go-multistream + +replace github.com/libp2p/go-nat => ../go-nat + +replace github.com/libp2p/go-reuseport => ../go-reuseport + +replace github.com/libp2p/go-reuseport-transport => ../go-reuseport-transport + +replace github.com/libp2p/go-sockaddr => ../go-sockaddr + +replace github.com/libp2p/go-stream-muxer-multistream => ../go-stream-muxer-multistream + +replace github.com/libp2p/go-tcp-transport => ../go-tcp-transport + +replace github.com/libp2p/go-utp-transport => ../go-utp-transport + +replace github.com/Jorropo/go-webrtc-aside-transport => ../go-webrtc-aside-transport + +replace github.com/libp2p/go-ws-transport => ../go-ws-transport + +replace github.com/libp2p/go-yamux => ../go-yamux diff --git a/go.sum b/go.sum index 034ee22c..8348504a 100644 --- a/go.sum +++ b/go.sum @@ -89,6 +89,7 @@ github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/B github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-varint v0.0.1 h1:TR/0rdQtnNxuN2IhiB639xC3tWM4IUi7DkTBVTdGW/M= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= diff --git a/transport/transport.go b/transport/transport.go index 0c9de98e..49773ad6 100644 --- a/transport/transport.go +++ b/transport/transport.go @@ -96,16 +96,12 @@ type BaseCapableConn interface { network.ConnMultiaddrs } -// Score is used by transport to returns expectation about connection +// Score is used by transport to returns expectation about connection, might be +// different than what the connection actualy return but that DEPREACATED. +// (that will cause weird cancel issue) type Score struct { - // Score of the future connection, must not change once the connection is - // actualy created + // Score of the future connection. Quality uint32 - // True if quality was actualy calculable (it may only be calculable with an - // open connection). - // Note: if IsQuality == true swarm will be able to cancel the dial if a - // better transport is found. - IsQuality bool // Number of file descriptor expected to be open. Fd uint8 } From f7acec3051f5c08ebfada69facf05b98314e9d69 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 5 Mar 2020 01:06:16 +0100 Subject: [PATCH 6/6] Last change of Quality Transport. Except if some errors sneeked in that should be the last version of Quality Transport interfaces. --- go.mod | 116 ----------------------------------------- transport/transport.go | 10 +--- 2 files changed, 2 insertions(+), 124 deletions(-) diff --git a/go.mod b/go.mod index 786926a0..7022bc16 100644 --- a/go.mod +++ b/go.mod @@ -19,119 +19,3 @@ require ( ) go 1.13 - -replace github.com/libp2p/go-addr-util => ../go-addr-util - -replace github.com/libp2p/go-buffer-pool => ../go-buffer-pool - -replace github.com/libp2p/go-conn-security-multistream => ../go-conn-security-multistream - -replace github.com/libp2p/go-eventbus => ../go-eventbus - -replace github.com/libp2p/go-flow-metrics => ../go-flow-metrics - -replace github.com/libp2p/go-libp2p => ../go-libp2p - -replace github.com/libp2p/go-libp2p-autonat => ../go-libp2p-autonat - -replace github.com/libp2p/go-libp2p-autonat-svc => ../go-libp2p-autonat-svc - -replace github.com/libp2p/go-libp2p-blankhost => ../go-libp2p-blankhost - -replace github.com/libp2p/go-libp2p-circuit => ../go-libp2p-circuit - -replace github.com/libp2p/go-libp2p-connmgr => ../go-libp2p-connmgr - -replace github.com/libp2p/go-libp2p-consensus => ../go-libp2p-consensus - -replace github.com/libp2p/go-libp2p-daemon => ../go-libp2p-daemon - -replace github.com/libp2p/go-libp2p-discovery => ../go-libp2p-discovery - -replace github.com/libp2p/go-libp2p-examples => ../go-libp2p-examples - -replace github.com/libp2p/go-libp2p-gorpc => ../go-libp2p-gorpc - -replace github.com/libp2p/go-libp2p-introspection => ../go-libp2p-introspection - -replace github.com/libp2p/go-libp2p-kad-dht => ../go-libp2p-kad-dht - -replace github.com/libp2p/go-libp2p-kbucket => ../go-libp2p-kbucket - -replace github.com/libp2p/go-libp2p-loggables => ../go-libp2p-loggables - -replace github.com/libp2p/go-libp2p-mplex => ../go-libp2p-mplex - -replace github.com/libp2p/go-libp2p-nat => ../go-libp2p-nat - -replace github.com/libp2p/go-libp2p-netutil => ../go-libp2p-netutil - -replace github.com/libp2p/go-libp2p-noise => ../go-libp2p-noise - -replace github.com/libp2p/go-libp2p-peerstore => ../go-libp2p-peerstore - -replace github.com/libp2p/go-libp2p-pnet => ../go-libp2p-pnet - -replace github.com/libp2p/go-libp2p-pubsub => ../go-libp2p-pubsub - -replace github.com/libp2p/go-libp2p-pubsub-router => ../go-libp2p-pubsub-router - -replace github.com/libp2p/go-libp2p-pubsub-tracer => ../go-libp2p-pubsub-tracer - -replace github.com/libp2p/go-libp2p-quic-transport => ../go-libp2p-quic-transport - -replace github.com/libp2p/go-libp2p-raft => ../go-libp2p-raft - -replace github.com/libp2p/go-libp2p-record => ../go-libp2p-record - -replace github.com/libp2p/go-libp2p-routing-helpers => ../go-libp2p-routing-helpers - -replace github.com/libp2p/go-libp2p-secio => ../go-libp2p-secio - -replace github.com/libp2p/go-libp2p-swarm => ../go-libp2p-swarm - -replace github.com/libp2p/go-libp2p-testing => ../go-libp2p-testing - -replace github.com/libp2p/go-libp2p-tls => ../go-libp2p-tls - -replace github.com/libp2p/go-libp2p-transport-upgrader => ../go-libp2p-transport-upgrader - -replace github.com/libp2p/go-libp2p-webrtc-direct => ../go-libp2p-webrtc-direct - -replace github.com/libp2p/go-libp2p-yamux => ../go-libp2p-yamux - -replace github.com/libp2p/go-maddr-filter => ../go-maddr-filter - -replace github.com/libp2p/go-mplex => ../go-mplex - -replace github.com/libp2p/go-msgio => ../go-msgio - -replace github.com/multiformats/go-multiaddr => ../go-multiaddr - -replace github.com/multiformats/go-multiaddr-dns => ../go-multiaddr-dns - -replace github.com/multiformats/go-multiaddr-fmt => ../go-multiaddr-fmt - -replace github.com/multiformats/go-multiaddr-net => ../go-multiaddr-net - -replace github.com/multiformats/go-multistream => ../go-multistream - -replace github.com/libp2p/go-nat => ../go-nat - -replace github.com/libp2p/go-reuseport => ../go-reuseport - -replace github.com/libp2p/go-reuseport-transport => ../go-reuseport-transport - -replace github.com/libp2p/go-sockaddr => ../go-sockaddr - -replace github.com/libp2p/go-stream-muxer-multistream => ../go-stream-muxer-multistream - -replace github.com/libp2p/go-tcp-transport => ../go-tcp-transport - -replace github.com/libp2p/go-utp-transport => ../go-utp-transport - -replace github.com/Jorropo/go-webrtc-aside-transport => ../go-webrtc-aside-transport - -replace github.com/libp2p/go-ws-transport => ../go-ws-transport - -replace github.com/libp2p/go-yamux => ../go-yamux diff --git a/transport/transport.go b/transport/transport.go index 49773ad6..a5dd1739 100644 --- a/transport/transport.go +++ b/transport/transport.go @@ -73,17 +73,11 @@ type CapableConn interface { // // QCapableConn embed CapableConn but with `Quality() uint32` support. type QCapableConn interface { - ListenedQCapableConn + BaseCapableConn // Quality returns the Quality we can expect from the connection to this peer. // That must be deterministic and fast. Quality() uint32 -} - -// ListenedQCapableConn is like QCapableConn but is used by listener, quality is -// managed on client side. -type ListenedQCapableConn interface { - BaseCapableConn // Transport returns the transport to which this connection belongs. Transport() QTransport @@ -181,7 +175,7 @@ type Listener interface { type QListener interface { BaseListener - Accept() (ListenedQCapableConn, error) + Accept() (QCapableConn, error) } // BaseListener is used to build `Lister` and `QListener`