From 995786888a336a9572b726926e5e004bb30146fc Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 4 Feb 2021 19:44:34 +0200 Subject: [PATCH 01/66] v2 client scaffolding --- v2/client/client.go | 36 ++++++++++++++ v2/client/conn.go | 103 +++++++++++++++++++++++++++++++++++++++++ v2/client/dial.go | 14 ++++++ v2/client/listen.go | 37 +++++++++++++++ v2/client/transport.go | 80 ++++++++++++++++++++++++++++++++ 5 files changed, 270 insertions(+) create mode 100644 v2/client/client.go create mode 100644 v2/client/conn.go create mode 100644 v2/client/dial.go create mode 100644 v2/client/listen.go create mode 100644 v2/client/transport.go diff --git a/v2/client/client.go b/v2/client/client.go new file mode 100644 index 0000000..5481081 --- /dev/null +++ b/v2/client/client.go @@ -0,0 +1,36 @@ +package client + +import ( + "context" + + "github.com/libp2p/go-libp2p-core/host" + + logging "github.com/ipfs/go-log" + tptu "github.com/libp2p/go-libp2p-transport-upgrader" +) + +const ( + ProtoIDv1 = "/libp2p/circuit/relay/0.1.0" + ProtoIDv2Hop = "/libp2p/circuit/relay/0.2.0/hop" + ProtoIDv2Stop = "/libp2p/circuit/relay/0.2.0/stop" +) + +var log = logging.Logger("p2p-circuit") + +type Client struct { + ctx context.Context + host host.Host + upgrader *tptu.Upgrader +} + +// New constructs a new p2p-circuit/v2 client, attached to the given host and using the given +// upgrader to perform connection upgrades. +func New(ctx context.Context, h host.Host, upgrader *tptu.Upgrader) (*Client, error) { + // TODO + return nil, nil +} + +// Start registers the circuit (client) protocol stream handlers and starts background goroutines +func (c *Client) Start() { + // TODO +} diff --git a/v2/client/conn.go b/v2/client/conn.go new file mode 100644 index 0000000..ca8c151 --- /dev/null +++ b/v2/client/conn.go @@ -0,0 +1,103 @@ +package client + +import ( + "fmt" + "net" + "time" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" +) + +type Conn struct { + stream network.Stream + remote peer.AddrInfo +} + +type NetAddr struct { + Relay string + Remote string +} + +var _ net.Addr = (*NetAddr)(nil) + +func (n *NetAddr) Network() string { + return "libp2p-circuit-relay" +} + +func (n *NetAddr) String() string { + return fmt.Sprintf("relay[%s-%s]", n.Remote, n.Relay) +} + +// Conn interface +var _ manet.Conn = (*Conn)(nil) + +func (c *Conn) Close() error { + c.untagHop() + return c.stream.Reset() +} + +func (c *Conn) Read(buf []byte) (int, error) { + return c.stream.Read(buf) +} + +func (c *Conn) Write(buf []byte) (int, error) { + return c.stream.Write(buf) +} + +func (c *Conn) SetDeadline(t time.Time) error { + return c.stream.SetDeadline(t) +} + +func (c *Conn) SetReadDeadline(t time.Time) error { + return c.stream.SetReadDeadline(t) +} + +func (c *Conn) SetWriteDeadline(t time.Time) error { + return c.stream.SetWriteDeadline(t) +} + +// TODO: is it okay to cast c.Conn().RemotePeer() into a multiaddr? might be "user input" +func (c *Conn) RemoteMultiaddr() ma.Multiaddr { + // TODO: We should be able to do this directly without converting to/from a string. + relayAddr, err := ma.NewComponent( + ma.ProtocolWithCode(ma.P_P2P).Name, + c.stream.Conn().RemotePeer().Pretty(), + ) + if err != nil { + panic(err) + } + return ma.Join(c.stream.Conn().RemoteMultiaddr(), relayAddr, circuitAddr) +} + +func (c *Conn) LocalMultiaddr() ma.Multiaddr { + return c.stream.Conn().LocalMultiaddr() +} + +func (c *Conn) LocalAddr() net.Addr { + na, err := manet.ToNetAddr(c.stream.Conn().LocalMultiaddr()) + if err != nil { + log.Error("failed to convert local multiaddr to net addr:", err) + return nil + } + return na +} + +func (c *Conn) RemoteAddr() net.Addr { + return &NetAddr{ + Relay: c.stream.Conn().RemotePeer().Pretty(), + Remote: c.remote.ID.Pretty(), + } +} + +// conn manager hop tagging +func (c *Conn) tagHop() { + // TODO +} + +func (c *Conn) untagHop() { + // TODO +} diff --git a/v2/client/dial.go b/v2/client/dial.go new file mode 100644 index 0000000..a4c150c --- /dev/null +++ b/v2/client/dial.go @@ -0,0 +1,14 @@ +package client + +import ( + "context" + + "github.com/libp2p/go-libp2p-core/peer" + + ma "github.com/multiformats/go-multiaddr" +) + +func (c *Client) dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (*Conn, error) { + // TODO + return nil, nil +} diff --git a/v2/client/listen.go b/v2/client/listen.go new file mode 100644 index 0000000..52a4b31 --- /dev/null +++ b/v2/client/listen.go @@ -0,0 +1,37 @@ +package client + +import ( + "net" + + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" +) + +var _ manet.Listener = (*Listener)(nil) + +type Listener Client + +func (c *Client) Listener() *Listener { + return (*Listener)(c) +} + +func (l *Listener) Accept() (manet.Conn, error) { + // TODO + return nil, nil +} + +func (l *Listener) Addr() net.Addr { + return &NetAddr{ + Relay: "any", + Remote: "any", + } +} + +func (l *Listener) Multiaddr() ma.Multiaddr { + return circuitAddr +} + +func (l *Listener) Close() error { + // noop for now + return nil +} diff --git a/v2/client/transport.go b/v2/client/transport.go new file mode 100644 index 0000000..406188c --- /dev/null +++ b/v2/client/transport.go @@ -0,0 +1,80 @@ +package client + +import ( + "context" + "fmt" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/transport" + + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + ma "github.com/multiformats/go-multiaddr" +) + +var circuitProtocol = ma.ProtocolWithCode(ma.P_CIRCUIT) +var circuitAddr = ma.Cast(circuitProtocol.VCode) + +// AddTransport constructs a new p2p-circuit/v2 client and adds it as a transport to the +// host network +func AddTransport(ctx context.Context, h host.Host, upgrader *tptu.Upgrader) error { + n, ok := h.Network().(transport.TransportNetwork) + if !ok { + return fmt.Errorf("%v is not a transport network", h.Network()) + } + + c, err := New(ctx, h, upgrader) + if err != nil { + return fmt.Errorf("error constructing circuit client: %w", err) + } + + err = n.AddTransport(c) + if err != nil { + return fmt.Errorf("error adding circuit transport: %w", err) + } + + err = n.Listen(circuitAddr) + if err != nil { + return fmt.Errorf("error listening to circuit addr: %w", err) + } + + c.Start() + + return nil +} + +// Transport interface +var _ transport.Transport = (*Client)(nil) + +func (c *Client) Dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (transport.CapableConn, error) { + conn, err := c.dial(ctx, a, p) + if err != nil { + return nil, err + } + + conn.tagHop() + + return c.upgrader.UpgradeOutbound(ctx, c, conn, p) +} + +func (c *Client) CanDial(addr ma.Multiaddr) bool { + _, err := addr.ValueForProtocol(ma.P_CIRCUIT) + return err == nil +} + +func (c *Client) Listen(addr ma.Multiaddr) (transport.Listener, error) { + // TODO connect to the relay and reserve slot if specified + if _, err := addr.ValueForProtocol(ma.P_CIRCUIT); err != nil { + return nil, err + } + + return c.upgrader.UpgradeListener(c, c.Listener()), nil +} + +func (c *Client) Protocols() []int { + return []int{ma.P_CIRCUIT} +} + +func (c *Client) Proxy() bool { + return true +} From 07c94b2bfe579b69b38326f58b38ff84f63ed035 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 4 Feb 2021 19:53:54 +0200 Subject: [PATCH 02/66] gomod: go-libp2p-core and go-libp2p-transport-upgrader feature dependencies --- go.mod | 4 ++-- go.sum | 29 +++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index fff8d7f..7805331 100644 --- a/go.mod +++ b/go.mod @@ -7,9 +7,9 @@ require ( github.com/ipfs/go-log v1.0.4 github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-libp2p-blankhost v0.2.0 - github.com/libp2p/go-libp2p-core v0.7.0 + github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee github.com/libp2p/go-libp2p-swarm v0.3.0 - github.com/libp2p/go-libp2p-transport-upgrader v0.3.0 + github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309 github.com/libp2p/go-msgio v0.0.6 github.com/multiformats/go-multiaddr v0.3.1 github.com/multiformats/go-varint v0.0.6 diff --git a/go.sum b/go.sum index 54976bd..91e9a9d 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= @@ -86,8 +87,9 @@ github.com/ipfs/go-log v1.0.4 h1:6nLQdX4W8P9yZZFH7mO+X/PzjN8Laozm/lMJ6esdgzY= github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= -github.com/ipfs/go-log/v2 v2.0.5 h1:fL4YI+1g5V/b1Yxr1qAiXTMg1H8z9vx/VmJxBuQMHvU= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= +github.com/ipfs/go-log/v2 v2.1.1 h1:G4TtqN+V9y9HY9TA6BwbCVyyBZ2B9MbCjR2MtGx8FR0= +github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= @@ -127,6 +129,7 @@ github.com/libp2p/go-libp2p-blankhost v0.2.0 h1:3EsGAi0CBGcZ33GwRuXEYJLLPoVWyXJ1 github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= +github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= @@ -134,13 +137,16 @@ github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.7.0 h1:4a0TMjrWNTZlNvcqxZmrMRDi/NQWrhwO2pkTuLSQ/IQ= github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee h1:M3DUy4DHSFAlYAftWF/vosJM3lnyTQM9UXA9pe0N5RU= +github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= -github.com/libp2p/go-libp2p-mplex v0.2.3 h1:2zijwaJvpdesST2MXpI5w9wWFRgYtMcpRX7rrw0jmOo= github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= +github.com/libp2p/go-libp2p-mplex v0.4.0 h1:ukojv97fEBM3ffCqXuuve2WSHu1HsA4/omMk1h2KFgc= +github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes9v7In4+Qq3U= github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= @@ -149,18 +155,22 @@ github.com/libp2p/go-libp2p-swarm v0.3.0 h1:w18ZLMccbvwgyR+dODEeA3r1zbFZj+YVq6PC github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= -github.com/libp2p/go-libp2p-testing v0.3.0 h1:ZiBYstPamsi7y6NJZebRudUzsYmVkt998hltyLqf8+g= +github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= +github.com/libp2p/go-libp2p-testing v0.4.0 h1:PrwHRi0IGqOwVQWR3xzgigSlhlLfxgfXgkHxr77EghQ= +github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= -github.com/libp2p/go-libp2p-transport-upgrader v0.3.0 h1:q3ULhsknEQ34eVDhv4YwKS8iet69ffs9+Fir6a7weN4= github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309 h1:XxFG5lVqdn/o0/7F51XiT6xnvCltayYagaANzNPg/jw= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309/go.mod h1:wFqIXZJ8k08YwnioC9twyokMXpewf2LKRQYtm34Y/T8= github.com/libp2p/go-libp2p-yamux v0.4.0 h1:qunEZzWwwmfSBYTtSyd81PlD1TjB5uuWcGYHWVXLbUg= github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= -github.com/libp2p/go-mplex v0.1.2 h1:qOg1s+WdGLlpkrczDqmhYzyk3vCfsQ8+RxRTQjOZWwI= github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= +github.com/libp2p/go-mplex v0.2.0 h1:Ov/D+8oBlbRkjBs1R1Iua8hJ8cUfbdiW8EOdZuxcgaI= +github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.6 h1:lQ7Uc0kS1wb1EfRxO2Eir/RJoHkHn7t6o+EiwsYIKJA= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= @@ -251,8 +261,9 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -308,8 +319,9 @@ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKY go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -385,6 +397,7 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 00f66ac8365dd062fbd3b5bca091a217694db787 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 4 Feb 2021 19:54:13 +0200 Subject: [PATCH 03/66] Conn implements network.ConnStat --- v2/client/conn.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/v2/client/conn.go b/v2/client/conn.go index ca8c151..1c9bab9 100644 --- a/v2/client/conn.go +++ b/v2/client/conn.go @@ -15,6 +15,7 @@ import ( type Conn struct { stream network.Stream remote peer.AddrInfo + stat network.Stat } type NetAddr struct { @@ -93,6 +94,13 @@ func (c *Conn) RemoteAddr() net.Addr { } } +// ConnStat interface +var _ network.ConnStat = (*Conn)(nil) + +func (c *Conn) Stat() network.Stat { + return c.stat +} + // conn manager hop tagging func (c *Conn) tagHop() { // TODO From 2a4f0fe2d800ca328d56839d525f3d2038f25ccf Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 4 Feb 2021 21:09:06 +0200 Subject: [PATCH 04/66] add reservation stub --- v2/client/reservation.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 v2/client/reservation.go diff --git a/v2/client/reservation.go b/v2/client/reservation.go new file mode 100644 index 0000000..5538312 --- /dev/null +++ b/v2/client/reservation.go @@ -0,0 +1,16 @@ +package client + +import ( + "context" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" +) + +type Reservation struct { +} + +func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation, error) { + // TODO + return nil, nil +} From d65387befc91232a3aa8e49c49c2934905bb24ac Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 4 Feb 2021 22:03:01 +0200 Subject: [PATCH 05/66] utilities --- v2/util/io.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++ v2/util/pbconv.go | 45 +++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 v2/util/io.go create mode 100644 v2/util/pbconv.go diff --git a/v2/util/io.go b/v2/util/io.go new file mode 100644 index 0000000..4f154e4 --- /dev/null +++ b/v2/util/io.go @@ -0,0 +1,67 @@ +package util + +import ( + "errors" + "io" + + pool "github.com/libp2p/go-buffer-pool" + "github.com/libp2p/go-msgio/protoio" + + "github.com/gogo/protobuf/proto" + "github.com/multiformats/go-varint" +) + +type DelimitedReader struct { + r io.Reader + buf []byte +} + +// The gogo protobuf NewDelimitedReader is buffered, which may eat up stream data. +// So we need to implement a compatible delimited reader that reads unbuffered. +// There is a slowdown from unbuffered reading: when reading the message +// it can take multiple single byte Reads to read the length and another Read +// to read the message payload. +// However, this is not critical performance degradation as +// - the reader is utilized to read one (dialer, stop) or two messages (hop) during +// the handshake, so it's a drop in the water for the connection lifetime. +// - messages are small (max 4k) and the length fits in a couple of bytes, +// so overall we have at most three reads per message. +func NewDelimitedReader(r io.Reader, maxSize int) *DelimitedReader { + return &DelimitedReader{r: r, buf: pool.Get(maxSize)} +} + +func (d *DelimitedReader) Close() { + if d.buf != nil { + pool.Put(d.buf) + d.buf = nil + } +} + +func (d *DelimitedReader) ReadByte() (byte, error) { + buf := d.buf[:1] + _, err := d.r.Read(buf) + return buf[0], err +} + +func (d *DelimitedReader) ReadMsg(msg proto.Message) error { + mlen, err := varint.ReadUvarint(d) + if err != nil { + return err + } + + if uint64(len(d.buf)) < mlen { + return errors.New("Message too large") + } + + buf := d.buf[:mlen] + _, err = io.ReadFull(d.r, buf) + if err != nil { + return err + } + + return proto.Unmarshal(buf, msg) +} + +func NewDelimitedWriter(w io.Writer) protoio.WriteCloser { + return protoio.NewDelimitedWriter(w) +} diff --git a/v2/util/pbconv.go b/v2/util/pbconv.go new file mode 100644 index 0000000..73cedcc --- /dev/null +++ b/v2/util/pbconv.go @@ -0,0 +1,45 @@ +package util + +import ( + "errors" + + pbv1 "github.com/libp2p/go-libp2p-circuit/pb" + + "github.com/libp2p/go-libp2p-core/peer" + + ma "github.com/multiformats/go-multiaddr" +) + +func PeerToPeerInfoV1(p *pbv1.CircuitRelay_Peer) (peer.AddrInfo, error) { + if p == nil { + return peer.AddrInfo{}, errors.New("nil peer") + } + + id, err := peer.IDFromBytes(p.Id) + if err != nil { + return peer.AddrInfo{}, err + } + + addrs := make([]ma.Multiaddr, 0, len(p.Addrs)) + for _, addrBytes := range p.Addrs { + a, err := ma.NewMultiaddrBytes(addrBytes) + if err == nil { + addrs = append(addrs, a) + } + } + + return peer.AddrInfo{ID: id, Addrs: addrs}, nil +} + +func PeerInfoToPeerV1(pi peer.AddrInfo) *pbv1.CircuitRelay_Peer { + addrs := make([][]byte, len(pi.Addrs)) + for i, addr := range pi.Addrs { + addrs[i] = addr.Bytes() + } + + p := new(pbv1.CircuitRelay_Peer) + p.Id = []byte(pi.ID) + p.Addrs = addrs + + return p +} From 2158d4e00e18055fc0d0461dd5a4af025dfba380 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 4 Feb 2021 22:05:56 +0200 Subject: [PATCH 06/66] dial scaffolding and v1 compat dialing --- v2/client/conn.go | 2 + v2/client/dial.go | 97 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/v2/client/conn.go b/v2/client/conn.go index 1c9bab9..953d272 100644 --- a/v2/client/conn.go +++ b/v2/client/conn.go @@ -16,6 +16,8 @@ type Conn struct { stream network.Stream remote peer.AddrInfo stat network.Stat + + client *Client } type NetAddr struct { diff --git a/v2/client/dial.go b/v2/client/dial.go index a4c150c..f913496 100644 --- a/v2/client/dial.go +++ b/v2/client/dial.go @@ -2,13 +2,110 @@ package client import ( "context" + "fmt" + pbv1 "github.com/libp2p/go-libp2p-circuit/pb" + //pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + "github.com/libp2p/go-libp2p-circuit/v2/util" + + "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" ma "github.com/multiformats/go-multiaddr" ) +const maxMessageSize = 4096 + func (c *Client) dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (*Conn, error) { + // split /a/p2p-circuit/b into (/a, /p2p-circuit/b) + relayaddr, destaddr := ma.SplitFunc(a, func(c ma.Component) bool { + return c.Protocol().Code == ma.P_CIRCUIT + }) + + // If the address contained no /p2p-circuit part, the second part is nil. + if destaddr == nil { + return nil, fmt.Errorf("%s is not a relay address", a) + } + + if relayaddr == nil { + return nil, fmt.Errorf("can't dial a p2p-circuit without specifying a relay: %s", a) + } + + dinfo := peer.AddrInfo{ID: p} + + // Strip the /p2p-circuit prefix from the destaddr so that we can pass the destination address + // (if present) for active relays + _, destaddr = ma.SplitFirst(destaddr) + if destaddr != nil { + dinfo.Addrs = append(dinfo.Addrs, destaddr) + } + + rinfo, err := peer.AddrInfoFromP2pAddr(relayaddr) + if err != nil { + return nil, fmt.Errorf("error parsing relay multiaddr '%s': %w", relayaddr, err) + } + + return c.dialPeer(ctx, *rinfo, dinfo) +} + +func (c *Client) dialPeer(ctx context.Context, relay, dest peer.AddrInfo) (*Conn, error) { + log.Debugf("dialing peer %s through relay %s", dest.ID, relay.ID) + + if len(relay.Addrs) > 0 { + c.host.Peerstore().AddAddrs(relay.ID, relay.Addrs, peerstore.TempAddrTTL) + } + + s, err := c.host.NewStream(ctx, relay.ID, ProtoIDv2Hop, ProtoIDv1) + if err != nil { + return nil, fmt.Errorf("error opening hop stream to relay: %w", err) + } + + switch s.Protocol() { + case ProtoIDv2Hop: + return c.connectV2(s, dest) + + case ProtoIDv1: + return c.connectV1(s, dest) + + default: + s.Reset() + return nil, fmt.Errorf("unexpected stream protocol: %s", s.Protocol()) + } +} + +func (c *Client) connectV2(s network.Stream, dest peer.AddrInfo) (*Conn, error) { // TODO return nil, nil } + +func (c *Client) connectV1(s network.Stream, dest peer.AddrInfo) (*Conn, error) { + rd := util.NewDelimitedReader(s, maxMessageSize) + wr := util.NewDelimitedWriter(s) + defer rd.Close() + + var msg pbv1.CircuitRelay + + msg.Type = pbv1.CircuitRelay_HOP.Enum() + msg.SrcPeer = util.PeerInfoToPeerV1(c.host.Peerstore().PeerInfo(c.host.ID())) + msg.DstPeer = util.PeerInfoToPeerV1(dest) + + err := wr.WriteMsg(&msg) + if err != nil { + s.Reset() + return nil, err + } + + if msg.GetType() != pbv1.CircuitRelay_STATUS { + s.Reset() + return nil, fmt.Errorf("unexpected relay response; not a status message (%d)", msg.GetType()) + } + + status := msg.GetCode() + if status != pbv1.CircuitRelay_SUCCESS { + s.Reset() + return nil, fmt.Errorf("error opening relay circuit: %s (%d)", pbv1.CircuitRelay_Status_name[int32(status)], status) + } + + return &Conn{stream: s, remote: dest, client: c}, nil +} From 4cf0099dc72213a8a73006549003c2cbd85a8f49 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 4 Feb 2021 22:37:12 +0200 Subject: [PATCH 07/66] stream handling scaffolding and v1 incoming connection handling --- v2/client/client.go | 12 ++++- v2/client/handlers.go | 102 ++++++++++++++++++++++++++++++++++++++++++ v2/client/listen.go | 22 ++++++++- 3 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 v2/client/handlers.go diff --git a/v2/client/client.go b/v2/client/client.go index 5481081..48b6c5e 100644 --- a/v2/client/client.go +++ b/v2/client/client.go @@ -21,6 +21,13 @@ type Client struct { ctx context.Context host host.Host upgrader *tptu.Upgrader + + incoming chan accept +} + +type accept struct { + conn *Conn + writeResponse func() error } // New constructs a new p2p-circuit/v2 client, attached to the given host and using the given @@ -30,7 +37,8 @@ func New(ctx context.Context, h host.Host, upgrader *tptu.Upgrader) (*Client, er return nil, nil } -// Start registers the circuit (client) protocol stream handlers and starts background goroutines +// Start registers the circuit (client) protocol stream handlers func (c *Client) Start() { - // TODO + c.host.SetStreamHandler(ProtoIDv1, c.handleStreamV1) + c.host.SetStreamHandler(ProtoIDv2Stop, c.handleStreamV2) } diff --git a/v2/client/handlers.go b/v2/client/handlers.go new file mode 100644 index 0000000..9ae3c54 --- /dev/null +++ b/v2/client/handlers.go @@ -0,0 +1,102 @@ +package client + +import ( + "time" + + pbv1 "github.com/libp2p/go-libp2p-circuit/pb" + //pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + "github.com/libp2p/go-libp2p-circuit/v2/util" + + "github.com/libp2p/go-libp2p-core/network" +) + +var ( + streamTimeout = 1 * time.Minute + acceptTimeout = 10 * time.Second +) + +func (c *Client) handleStreamV2(s network.Stream) { + // TODO +} + +func (c *Client) handleStreamV1(s network.Stream) { + log.Debugf("new relay stream from: %s", s.Conn().RemotePeer()) + + s.SetReadDeadline(time.Now().Add(streamTimeout)) + + rd := util.NewDelimitedReader(s, maxMessageSize) + defer rd.Close() + + writeResponse := func(status pbv1.CircuitRelay_Status) error { + wr := util.NewDelimitedWriter(s) + + var msg pbv1.CircuitRelay + msg.Type = pbv1.CircuitRelay_STATUS.Enum() + msg.Code = status.Enum() + + return wr.WriteMsg(&msg) + } + + handleError := func(status pbv1.CircuitRelay_Status) { + log.Debugf("protocol error: %s (%d)", pbv1.CircuitRelay_Status_name[int32(status)], status) + err := writeResponse(status) + if err != nil { + s.Reset() + log.Debugf("error writing circuit response: %s", err.Error()) + } else { + s.Close() + } + } + + var msg pbv1.CircuitRelay + + err := rd.ReadMsg(&msg) + if err != nil { + handleError(pbv1.CircuitRelay_MALFORMED_MESSAGE) + return + } + // reset stream deadline as message has been read + s.SetReadDeadline(time.Time{}) + + switch msg.GetType() { + case pbv1.CircuitRelay_STOP: + + case pbv1.CircuitRelay_HOP: + handleError(pbv1.CircuitRelay_HOP_CANT_SPEAK_RELAY) + return + + case pbv1.CircuitRelay_CAN_HOP: + handleError(pbv1.CircuitRelay_HOP_CANT_SPEAK_RELAY) + return + + default: + log.Debugf("unexpected relay handshake: %d", msg.GetType()) + handleError(pbv1.CircuitRelay_MALFORMED_MESSAGE) + return + } + + src, err := util.PeerToPeerInfoV1(msg.GetSrcPeer()) + if err != nil { + handleError(pbv1.CircuitRelay_STOP_SRC_MULTIADDR_INVALID) + return + } + + dst, err := util.PeerToPeerInfoV1(msg.GetDstPeer()) + if err != nil || dst.ID != c.host.ID() { + handleError(pbv1.CircuitRelay_STOP_DST_MULTIADDR_INVALID) + return + } + + log.Infof("incoming relay connection from: %s", src.ID) + + select { + case c.incoming <- accept{ + conn: &Conn{stream: s, remote: src, client: c}, + writeResponse: func() error { + return writeResponse(pbv1.CircuitRelay_SUCCESS) + }, + }: + case <-time.After(acceptTimeout): + handleError(pbv1.CircuitRelay_STOP_RELAY_REFUSED) + } +} diff --git a/v2/client/listen.go b/v2/client/listen.go index 52a4b31..056689a 100644 --- a/v2/client/listen.go +++ b/v2/client/listen.go @@ -16,8 +16,26 @@ func (c *Client) Listener() *Listener { } func (l *Listener) Accept() (manet.Conn, error) { - // TODO - return nil, nil + for { + select { + case evt := <-l.incoming: + err := evt.writeResponse() + if err != nil { + log.Debugf("error writing relay response: %s", err.Error()) + evt.conn.stream.Reset() + continue + } + + // TODO: Pretty print. + log.Debugf("accepted relay connection: %q", evt.conn) + + evt.conn.tagHop() + return evt.conn, nil + + case <-l.ctx.Done(): + return nil, l.ctx.Err() + } + } } func (l *Listener) Addr() net.Addr { From 08e8616bfb5162aaf6ba1ad3db0c44312adac402 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 4 Feb 2021 22:40:37 +0200 Subject: [PATCH 08/66] implement hop tagging --- v2/client/client.go | 5 +++++ v2/client/conn.go | 22 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/v2/client/client.go b/v2/client/client.go index 48b6c5e..41e89dd 100644 --- a/v2/client/client.go +++ b/v2/client/client.go @@ -2,8 +2,10 @@ package client import ( "context" + "sync" "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" logging "github.com/ipfs/go-log" tptu "github.com/libp2p/go-libp2p-transport-upgrader" @@ -23,6 +25,9 @@ type Client struct { upgrader *tptu.Upgrader incoming chan accept + + mx sync.Mutex + hopCount map[peer.ID]int } type accept struct { diff --git a/v2/client/conn.go b/v2/client/conn.go index 953d272..65c3666 100644 --- a/v2/client/conn.go +++ b/v2/client/conn.go @@ -12,6 +12,9 @@ import ( manet "github.com/multiformats/go-multiaddr/net" ) +// HopTagWeight is the connection manager weight for connections carrying relay hop streams +var HopTagWeight = 5 + type Conn struct { stream network.Stream remote peer.AddrInfo @@ -105,9 +108,24 @@ func (c *Conn) Stat() network.Stat { // conn manager hop tagging func (c *Conn) tagHop() { - // TODO + c.client.mx.Lock() + defer c.client.mx.Unlock() + + p := c.stream.Conn().RemotePeer() + c.client.hopCount[p]++ + if c.client.hopCount[p] == 1 { + c.client.host.ConnManager().TagPeer(p, "relay-hop-stream", HopTagWeight) + } } func (c *Conn) untagHop() { - // TODO + c.client.mx.Lock() + defer c.client.mx.Unlock() + + p := c.stream.Conn().RemotePeer() + c.client.hopCount[p]-- + if c.client.hopCount[p] == 0 { + c.client.host.ConnManager().UntagPeer(p, "relay-hop-stream") + delete(c.client.hopCount, p) + } } From 5775e43790d4df931142d6a934352ff853958b38 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 4 Feb 2021 22:45:59 +0200 Subject: [PATCH 09/66] export timeout variables --- v2/client/handlers.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/v2/client/handlers.go b/v2/client/handlers.go index 9ae3c54..8735ae6 100644 --- a/v2/client/handlers.go +++ b/v2/client/handlers.go @@ -11,8 +11,8 @@ import ( ) var ( - streamTimeout = 1 * time.Minute - acceptTimeout = 10 * time.Second + StreamTimeout = 1 * time.Minute + AcceptTimeout = 10 * time.Second ) func (c *Client) handleStreamV2(s network.Stream) { @@ -22,7 +22,7 @@ func (c *Client) handleStreamV2(s network.Stream) { func (c *Client) handleStreamV1(s network.Stream) { log.Debugf("new relay stream from: %s", s.Conn().RemotePeer()) - s.SetReadDeadline(time.Now().Add(streamTimeout)) + s.SetReadDeadline(time.Now().Add(StreamTimeout)) rd := util.NewDelimitedReader(s, maxMessageSize) defer rd.Close() @@ -96,7 +96,7 @@ func (c *Client) handleStreamV1(s network.Stream) { return writeResponse(pbv1.CircuitRelay_SUCCESS) }, }: - case <-time.After(acceptTimeout): + case <-time.After(AcceptTimeout): handleError(pbv1.CircuitRelay_STOP_RELAY_REFUSED) } } From 3a20a7de056b9100c534982a01986763f8f953f3 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 00:39:19 +0200 Subject: [PATCH 10/66] v2 protobuf --- v2/pb/Makefile | 11 + v2/pb/circuit.pb.go | 1709 +++++++++++++++++++++++++++++++++++++++++++ v2/pb/circuit.proto | 59 ++ 3 files changed, 1779 insertions(+) create mode 100644 v2/pb/Makefile create mode 100644 v2/pb/circuit.pb.go create mode 100644 v2/pb/circuit.proto diff --git a/v2/pb/Makefile b/v2/pb/Makefile new file mode 100644 index 0000000..c360a6f --- /dev/null +++ b/v2/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --gogofast_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/v2/pb/circuit.pb.go b/v2/pb/circuit.pb.go new file mode 100644 index 0000000..7f73050 --- /dev/null +++ b/v2/pb/circuit.pb.go @@ -0,0 +1,1709 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: circuit.proto + +package circuit_pb + +import ( + fmt "fmt" + github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type Status int32 + +const ( + Status_OK Status = 100 + Status_NO_RESERVATION Status = 200 + Status_RESERVATION_REFUSED Status = 201 + Status_RESOURCE_LIMIT_EXCEEDED Status = 202 + Status_CONNECTION_FAILED Status = 300 + Status_MALFORMED_MESSAGE Status = 400 +) + +var Status_name = map[int32]string{ + 100: "OK", + 200: "NO_RESERVATION", + 201: "RESERVATION_REFUSED", + 202: "RESOURCE_LIMIT_EXCEEDED", + 300: "CONNECTION_FAILED", + 400: "MALFORMED_MESSAGE", +} + +var Status_value = map[string]int32{ + "OK": 100, + "NO_RESERVATION": 200, + "RESERVATION_REFUSED": 201, + "RESOURCE_LIMIT_EXCEEDED": 202, + "CONNECTION_FAILED": 300, + "MALFORMED_MESSAGE": 400, +} + +func (x Status) Enum() *Status { + p := new(Status) + *p = x + return p +} + +func (x Status) String() string { + return proto.EnumName(Status_name, int32(x)) +} + +func (x *Status) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Status_value, data, "Status") + if err != nil { + return err + } + *x = Status(value) + return nil +} + +func (Status) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_ed01bbc211f15e47, []int{0} +} + +type HopMessage_Type int32 + +const ( + HopMessage_RESERVE HopMessage_Type = 0 + HopMessage_CONNECT HopMessage_Type = 1 + HopMessage_STATUS HopMessage_Type = 2 +) + +var HopMessage_Type_name = map[int32]string{ + 0: "RESERVE", + 1: "CONNECT", + 2: "STATUS", +} + +var HopMessage_Type_value = map[string]int32{ + "RESERVE": 0, + "CONNECT": 1, + "STATUS": 2, +} + +func (x HopMessage_Type) Enum() *HopMessage_Type { + p := new(HopMessage_Type) + *p = x + return p +} + +func (x HopMessage_Type) String() string { + return proto.EnumName(HopMessage_Type_name, int32(x)) +} + +func (x *HopMessage_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(HopMessage_Type_value, data, "HopMessage_Type") + if err != nil { + return err + } + *x = HopMessage_Type(value) + return nil +} + +func (HopMessage_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_ed01bbc211f15e47, []int{0, 0} +} + +type StopMessage_Type int32 + +const ( + StopMessage_CONNECT StopMessage_Type = 0 + StopMessage_STATUS StopMessage_Type = 1 +) + +var StopMessage_Type_name = map[int32]string{ + 0: "CONNECT", + 1: "STATUS", +} + +var StopMessage_Type_value = map[string]int32{ + "CONNECT": 0, + "STATUS": 1, +} + +func (x StopMessage_Type) Enum() *StopMessage_Type { + p := new(StopMessage_Type) + *p = x + return p +} + +func (x StopMessage_Type) String() string { + return proto.EnumName(StopMessage_Type_name, int32(x)) +} + +func (x *StopMessage_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(StopMessage_Type_value, data, "StopMessage_Type") + if err != nil { + return err + } + *x = StopMessage_Type(value) + return nil +} + +func (StopMessage_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_ed01bbc211f15e47, []int{1, 0} +} + +type HopMessage struct { + Type *HopMessage_Type `protobuf:"varint,1,req,name=type,enum=circuit.pb.HopMessage_Type" json:"type,omitempty"` + Peer *Peer `protobuf:"bytes,2,opt,name=peer" json:"peer,omitempty"` + Reservation *Reservation `protobuf:"bytes,3,opt,name=reservation" json:"reservation,omitempty"` + Limit *Limit `protobuf:"bytes,4,opt,name=limit" json:"limit,omitempty"` + Status *Status `protobuf:"varint,5,opt,name=status,enum=circuit.pb.Status" json:"status,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HopMessage) Reset() { *m = HopMessage{} } +func (m *HopMessage) String() string { return proto.CompactTextString(m) } +func (*HopMessage) ProtoMessage() {} +func (*HopMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_ed01bbc211f15e47, []int{0} +} +func (m *HopMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HopMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HopMessage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HopMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_HopMessage.Merge(m, src) +} +func (m *HopMessage) XXX_Size() int { + return m.Size() +} +func (m *HopMessage) XXX_DiscardUnknown() { + xxx_messageInfo_HopMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_HopMessage proto.InternalMessageInfo + +func (m *HopMessage) GetType() HopMessage_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return HopMessage_RESERVE +} + +func (m *HopMessage) GetPeer() *Peer { + if m != nil { + return m.Peer + } + return nil +} + +func (m *HopMessage) GetReservation() *Reservation { + if m != nil { + return m.Reservation + } + return nil +} + +func (m *HopMessage) GetLimit() *Limit { + if m != nil { + return m.Limit + } + return nil +} + +func (m *HopMessage) GetStatus() Status { + if m != nil && m.Status != nil { + return *m.Status + } + return Status_OK +} + +type StopMessage struct { + Type *StopMessage_Type `protobuf:"varint,1,req,name=type,enum=circuit.pb.StopMessage_Type" json:"type,omitempty"` + Peer *Peer `protobuf:"bytes,2,opt,name=peer" json:"peer,omitempty"` + Limit *Limit `protobuf:"bytes,3,opt,name=limit" json:"limit,omitempty"` + Status *Status `protobuf:"varint,4,opt,name=status,enum=circuit.pb.Status" json:"status,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StopMessage) Reset() { *m = StopMessage{} } +func (m *StopMessage) String() string { return proto.CompactTextString(m) } +func (*StopMessage) ProtoMessage() {} +func (*StopMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_ed01bbc211f15e47, []int{1} +} +func (m *StopMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StopMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StopMessage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StopMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopMessage.Merge(m, src) +} +func (m *StopMessage) XXX_Size() int { + return m.Size() +} +func (m *StopMessage) XXX_DiscardUnknown() { + xxx_messageInfo_StopMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_StopMessage proto.InternalMessageInfo + +func (m *StopMessage) GetType() StopMessage_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return StopMessage_CONNECT +} + +func (m *StopMessage) GetPeer() *Peer { + if m != nil { + return m.Peer + } + return nil +} + +func (m *StopMessage) GetLimit() *Limit { + if m != nil { + return m.Limit + } + return nil +} + +func (m *StopMessage) GetStatus() Status { + if m != nil && m.Status != nil { + return *m.Status + } + return Status_OK +} + +type Peer struct { + Id []byte `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + Addrs [][]byte `protobuf:"bytes,2,rep,name=addrs" json:"addrs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Peer) Reset() { *m = Peer{} } +func (m *Peer) String() string { return proto.CompactTextString(m) } +func (*Peer) ProtoMessage() {} +func (*Peer) Descriptor() ([]byte, []int) { + return fileDescriptor_ed01bbc211f15e47, []int{2} +} +func (m *Peer) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Peer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Peer.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Peer) XXX_Merge(src proto.Message) { + xxx_messageInfo_Peer.Merge(m, src) +} +func (m *Peer) XXX_Size() int { + return m.Size() +} +func (m *Peer) XXX_DiscardUnknown() { + xxx_messageInfo_Peer.DiscardUnknown(m) +} + +var xxx_messageInfo_Peer proto.InternalMessageInfo + +func (m *Peer) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *Peer) GetAddrs() [][]byte { + if m != nil { + return m.Addrs + } + return nil +} + +type Reservation struct { + Ttl *int32 `protobuf:"varint,1,opt,name=ttl" json:"ttl,omitempty"` + Relay *Peer `protobuf:"bytes,2,opt,name=relay" json:"relay,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Reservation) Reset() { *m = Reservation{} } +func (m *Reservation) String() string { return proto.CompactTextString(m) } +func (*Reservation) ProtoMessage() {} +func (*Reservation) Descriptor() ([]byte, []int) { + return fileDescriptor_ed01bbc211f15e47, []int{3} +} +func (m *Reservation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Reservation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Reservation.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Reservation) XXX_Merge(src proto.Message) { + xxx_messageInfo_Reservation.Merge(m, src) +} +func (m *Reservation) XXX_Size() int { + return m.Size() +} +func (m *Reservation) XXX_DiscardUnknown() { + xxx_messageInfo_Reservation.DiscardUnknown(m) +} + +var xxx_messageInfo_Reservation proto.InternalMessageInfo + +func (m *Reservation) GetTtl() int32 { + if m != nil && m.Ttl != nil { + return *m.Ttl + } + return 0 +} + +func (m *Reservation) GetRelay() *Peer { + if m != nil { + return m.Relay + } + return nil +} + +type Limit struct { + Duration *int32 `protobuf:"varint,1,opt,name=duration" json:"duration,omitempty"` + Data *int64 `protobuf:"varint,2,opt,name=data" json:"data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Limit) Reset() { *m = Limit{} } +func (m *Limit) String() string { return proto.CompactTextString(m) } +func (*Limit) ProtoMessage() {} +func (*Limit) Descriptor() ([]byte, []int) { + return fileDescriptor_ed01bbc211f15e47, []int{4} +} +func (m *Limit) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Limit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Limit.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Limit) XXX_Merge(src proto.Message) { + xxx_messageInfo_Limit.Merge(m, src) +} +func (m *Limit) XXX_Size() int { + return m.Size() +} +func (m *Limit) XXX_DiscardUnknown() { + xxx_messageInfo_Limit.DiscardUnknown(m) +} + +var xxx_messageInfo_Limit proto.InternalMessageInfo + +func (m *Limit) GetDuration() int32 { + if m != nil && m.Duration != nil { + return *m.Duration + } + return 0 +} + +func (m *Limit) GetData() int64 { + if m != nil && m.Data != nil { + return *m.Data + } + return 0 +} + +func init() { + proto.RegisterEnum("circuit.pb.Status", Status_name, Status_value) + proto.RegisterEnum("circuit.pb.HopMessage_Type", HopMessage_Type_name, HopMessage_Type_value) + proto.RegisterEnum("circuit.pb.StopMessage_Type", StopMessage_Type_name, StopMessage_Type_value) + proto.RegisterType((*HopMessage)(nil), "circuit.pb.HopMessage") + proto.RegisterType((*StopMessage)(nil), "circuit.pb.StopMessage") + proto.RegisterType((*Peer)(nil), "circuit.pb.Peer") + proto.RegisterType((*Reservation)(nil), "circuit.pb.Reservation") + proto.RegisterType((*Limit)(nil), "circuit.pb.Limit") +} + +func init() { proto.RegisterFile("circuit.proto", fileDescriptor_ed01bbc211f15e47) } + +var fileDescriptor_ed01bbc211f15e47 = []byte{ + // 478 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0x4f, 0x8b, 0xd3, 0x40, + 0x18, 0xc6, 0x77, 0xf2, 0xa7, 0xca, 0x9b, 0x5a, 0x66, 0xdf, 0x15, 0x37, 0xe8, 0x52, 0x43, 0x10, + 0x0d, 0x8b, 0x54, 0xe9, 0x45, 0x3c, 0xc6, 0x66, 0xba, 0x16, 0x9b, 0x46, 0x26, 0xa9, 0x78, 0x0b, + 0x71, 0x33, 0x48, 0xa0, 0xda, 0x90, 0x4c, 0x85, 0x7e, 0x08, 0xc1, 0xaf, 0xe0, 0xdd, 0x0f, 0xb2, + 0x7a, 0xf2, 0xee, 0x45, 0xfa, 0x49, 0x24, 0xc9, 0xda, 0x64, 0x0f, 0xa2, 0xe0, 0x6d, 0xde, 0x79, + 0x9e, 0x67, 0x92, 0xdf, 0x33, 0x03, 0x37, 0xce, 0xb3, 0xe2, 0x7c, 0x93, 0xc9, 0x51, 0x5e, 0xac, + 0xe5, 0x1a, 0x61, 0x3f, 0xbe, 0xb1, 0x3f, 0x2b, 0x00, 0xcf, 0xd7, 0xb9, 0x2f, 0xca, 0x32, 0x79, + 0x2b, 0xf0, 0x11, 0x68, 0x72, 0x9b, 0x0b, 0x93, 0x58, 0x8a, 0x33, 0x18, 0xdf, 0x19, 0xb5, 0xce, + 0x51, 0xeb, 0x1a, 0x45, 0xdb, 0x5c, 0xf0, 0xda, 0x88, 0xf7, 0x40, 0xcb, 0x85, 0x28, 0x4c, 0xc5, + 0x22, 0x8e, 0x31, 0xa6, 0xdd, 0xc0, 0x4b, 0x21, 0x0a, 0x5e, 0xab, 0xf8, 0x14, 0x8c, 0x42, 0x94, + 0xa2, 0xf8, 0x90, 0xc8, 0x6c, 0xfd, 0xde, 0x54, 0x6b, 0xf3, 0x71, 0xd7, 0xcc, 0x5b, 0x99, 0x77, + 0xbd, 0xf8, 0x00, 0xf4, 0x55, 0xf6, 0x2e, 0x93, 0xa6, 0x56, 0x87, 0x0e, 0xbb, 0xa1, 0x79, 0x25, + 0xf0, 0x46, 0xc7, 0x53, 0xe8, 0x95, 0x32, 0x91, 0x9b, 0xd2, 0xd4, 0x2d, 0xe2, 0x0c, 0xc6, 0xd8, + 0x75, 0x86, 0xb5, 0xc2, 0x2f, 0x1d, 0xf6, 0x43, 0xd0, 0x2a, 0x06, 0x34, 0xe0, 0x1a, 0x67, 0x21, + 0xe3, 0xaf, 0x18, 0x3d, 0xa8, 0x86, 0x49, 0xb0, 0x58, 0xb0, 0x49, 0x44, 0x09, 0x02, 0xf4, 0xc2, + 0xc8, 0x8d, 0x96, 0x21, 0x55, 0xec, 0x1f, 0x04, 0x8c, 0x50, 0xb6, 0x25, 0x3d, 0xbe, 0x52, 0xd2, + 0xc9, 0xd5, 0xef, 0xfc, 0x47, 0x4b, 0x7b, 0x54, 0xf5, 0x9f, 0x51, 0xb5, 0xbf, 0xa2, 0xde, 0x6d, + 0x51, 0x7f, 0xd3, 0x1d, 0x74, 0xe8, 0x48, 0xd5, 0x45, 0xf5, 0x0f, 0x38, 0x00, 0x25, 0x4b, 0x6b, + 0xa6, 0x3e, 0x57, 0xb2, 0x14, 0x6f, 0x82, 0x9e, 0xa4, 0x69, 0x51, 0x9a, 0x8a, 0xa5, 0x3a, 0x7d, + 0xde, 0x0c, 0xf6, 0x19, 0x18, 0x9d, 0xab, 0x42, 0x0a, 0xaa, 0x94, 0x2b, 0x93, 0x58, 0xc4, 0xd1, + 0x79, 0xb5, 0xc4, 0xfb, 0xa0, 0x17, 0x62, 0x95, 0x6c, 0xff, 0xc8, 0xda, 0xc8, 0xf6, 0x13, 0xd0, + 0x6b, 0x26, 0xbc, 0x0d, 0xd7, 0xd3, 0x4d, 0xd1, 0x3c, 0x8c, 0xe6, 0x9c, 0xfd, 0x8c, 0x08, 0x5a, + 0x9a, 0xc8, 0xa4, 0x3e, 0x4b, 0xe5, 0xf5, 0xfa, 0xf4, 0x23, 0x81, 0x5e, 0xc3, 0x88, 0x3d, 0x50, + 0x82, 0x17, 0x34, 0xc5, 0x23, 0x18, 0x2c, 0x82, 0xb8, 0xb9, 0x49, 0x37, 0x9a, 0x05, 0x0b, 0x7a, + 0x41, 0xd0, 0x84, 0xa3, 0xce, 0x4e, 0xcc, 0xd9, 0x74, 0x19, 0x32, 0x8f, 0x7e, 0x25, 0x78, 0x02, + 0xc7, 0x9c, 0x85, 0xc1, 0x92, 0x4f, 0x58, 0x3c, 0x9f, 0xf9, 0xb3, 0x28, 0x66, 0xaf, 0x27, 0x8c, + 0x79, 0xcc, 0xa3, 0xdf, 0x08, 0xde, 0x82, 0xc3, 0xcb, 0xa2, 0xaa, 0xd8, 0xd4, 0x9d, 0xcd, 0x99, + 0x47, 0xbf, 0x28, 0xd5, 0xbe, 0xef, 0xce, 0xa7, 0x01, 0xf7, 0x99, 0x17, 0xfb, 0x2c, 0x0c, 0xdd, + 0x33, 0x46, 0x3f, 0xa9, 0xcf, 0xfa, 0x17, 0xbb, 0x21, 0xf9, 0xbe, 0x1b, 0x92, 0x9f, 0xbb, 0x21, + 0xf9, 0x15, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x23, 0x17, 0x15, 0x6b, 0x03, 0x00, 0x00, +} + +func (m *HopMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HopMessage) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HopMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Status != nil { + i = encodeVarintCircuit(dAtA, i, uint64(*m.Status)) + i-- + dAtA[i] = 0x28 + } + if m.Limit != nil { + { + size, err := m.Limit.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCircuit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.Reservation != nil { + { + size, err := m.Reservation.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCircuit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Peer != nil { + { + size, err := m.Peer.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCircuit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { + i = encodeVarintCircuit(dAtA, i, uint64(*m.Type)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *StopMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StopMessage) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StopMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Status != nil { + i = encodeVarintCircuit(dAtA, i, uint64(*m.Status)) + i-- + dAtA[i] = 0x20 + } + if m.Limit != nil { + { + size, err := m.Limit.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCircuit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Peer != nil { + { + size, err := m.Peer.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCircuit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Type == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } else { + i = encodeVarintCircuit(dAtA, i, uint64(*m.Type)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Peer) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Peer) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Peer) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Addrs) > 0 { + for iNdEx := len(m.Addrs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Addrs[iNdEx]) + copy(dAtA[i:], m.Addrs[iNdEx]) + i = encodeVarintCircuit(dAtA, i, uint64(len(m.Addrs[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if m.Id == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") + } else { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintCircuit(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Reservation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Reservation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Reservation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Relay != nil { + { + size, err := m.Relay.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCircuit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Ttl != nil { + i = encodeVarintCircuit(dAtA, i, uint64(*m.Ttl)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Limit) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Limit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Limit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Data != nil { + i = encodeVarintCircuit(dAtA, i, uint64(*m.Data)) + i-- + dAtA[i] = 0x10 + } + if m.Duration != nil { + i = encodeVarintCircuit(dAtA, i, uint64(*m.Duration)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintCircuit(dAtA []byte, offset int, v uint64) int { + offset -= sovCircuit(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *HopMessage) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Type != nil { + n += 1 + sovCircuit(uint64(*m.Type)) + } + if m.Peer != nil { + l = m.Peer.Size() + n += 1 + l + sovCircuit(uint64(l)) + } + if m.Reservation != nil { + l = m.Reservation.Size() + n += 1 + l + sovCircuit(uint64(l)) + } + if m.Limit != nil { + l = m.Limit.Size() + n += 1 + l + sovCircuit(uint64(l)) + } + if m.Status != nil { + n += 1 + sovCircuit(uint64(*m.Status)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *StopMessage) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Type != nil { + n += 1 + sovCircuit(uint64(*m.Type)) + } + if m.Peer != nil { + l = m.Peer.Size() + n += 1 + l + sovCircuit(uint64(l)) + } + if m.Limit != nil { + l = m.Limit.Size() + n += 1 + l + sovCircuit(uint64(l)) + } + if m.Status != nil { + n += 1 + sovCircuit(uint64(*m.Status)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Peer) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != nil { + l = len(m.Id) + n += 1 + l + sovCircuit(uint64(l)) + } + if len(m.Addrs) > 0 { + for _, b := range m.Addrs { + l = len(b) + n += 1 + l + sovCircuit(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Reservation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Ttl != nil { + n += 1 + sovCircuit(uint64(*m.Ttl)) + } + if m.Relay != nil { + l = m.Relay.Size() + n += 1 + l + sovCircuit(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Limit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Duration != nil { + n += 1 + sovCircuit(uint64(*m.Duration)) + } + if m.Data != nil { + n += 1 + sovCircuit(uint64(*m.Data)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovCircuit(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozCircuit(x uint64) (n int) { + return sovCircuit(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *HopMessage) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HopMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HopMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v HopMessage_Type + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= HopMessage_Type(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Peer", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCircuit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCircuit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Peer == nil { + m.Peer = &Peer{} + } + if err := m.Peer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reservation", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCircuit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCircuit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Reservation == nil { + m.Reservation = &Reservation{} + } + if err := m.Reservation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCircuit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCircuit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Limit == nil { + m.Limit = &Limit{} + } + if err := m.Limit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var v Status + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= Status(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Status = &v + default: + iNdEx = preIndex + skippy, err := skipCircuit(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StopMessage) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StopMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StopMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var v StopMessage_Type + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= StopMessage_Type(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Type = &v + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Peer", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCircuit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCircuit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Peer == nil { + m.Peer = &Peer{} + } + if err := m.Peer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCircuit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCircuit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Limit == nil { + m.Limit = &Limit{} + } + if err := m.Limit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var v Status + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= Status(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Status = &v + default: + iNdEx = preIndex + skippy, err := skipCircuit(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("type") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Peer) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Peer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Peer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCircuit + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCircuit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Addrs", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCircuit + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCircuit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Addrs = append(m.Addrs, make([]byte, postIndex-iNdEx)) + copy(m.Addrs[len(m.Addrs)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCircuit(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("id") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Reservation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Reservation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Reservation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Ttl = &v + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Relay", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCircuit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCircuit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Relay == nil { + m.Relay = &Peer{} + } + if err := m.Relay.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCircuit(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Limit) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Limit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Limit: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Duration = &v + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Data = &v + default: + iNdEx = preIndex + skippy, err := skipCircuit(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthCircuit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipCircuit(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCircuit + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCircuit + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCircuit + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthCircuit + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupCircuit + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthCircuit + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthCircuit = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowCircuit = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupCircuit = fmt.Errorf("proto: unexpected end of group") +) diff --git a/v2/pb/circuit.proto b/v2/pb/circuit.proto new file mode 100644 index 0000000..a602a5e --- /dev/null +++ b/v2/pb/circuit.proto @@ -0,0 +1,59 @@ +syntax = "proto2"; + +package circuit.pb; + +message HopMessage { + enum Type { + RESERVE = 0; + CONNECT = 1; + STATUS = 2; + } + + required Type type = 1; + + optional Peer peer = 2; + optional Reservation reservation = 3; + optional Limit limit = 4; + + optional Status status = 5; +} + +message StopMessage { + enum Type { + CONNECT = 0; + STATUS = 1; + } + + required Type type = 1; + + optional Peer peer = 2; + optional Limit limit = 3; + + optional Status status = 4; +} + +message Peer { + required bytes id = 1; + repeated bytes addrs = 2; +} + +message Reservation { + optional int32 ttl = 1; // seconds + optional Peer relay = 2; + + // TODO: voucher +} + +message Limit { + optional int32 duration = 1; // seconds + optional int64 data = 2; // bytes +} + +enum Status { + OK = 100; + NO_RESERVATION = 200; + RESERVATION_REFUSED = 201; + RESOURCE_LIMIT_EXCEEDED = 202; + CONNECTION_FAILED = 300; + MALFORMED_MESSAGE = 400; +} From 67cdceef015ae4bf51b2eaa012ef715fb16fb840 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 00:40:13 +0200 Subject: [PATCH 11/66] v2 client protocol implementation --- v2/client/conn.go | 8 +++++ v2/client/dial.go | 56 +++++++++++++++++++++++++++++-- v2/client/handlers.go | 76 ++++++++++++++++++++++++++++++++++++++++--- v2/util/pbconv.go | 39 ++++++++++++++++++++-- 4 files changed, 170 insertions(+), 9 deletions(-) diff --git a/v2/client/conn.go b/v2/client/conn.go index 65c3666..51fa0f8 100644 --- a/v2/client/conn.go +++ b/v2/client/conn.go @@ -15,6 +15,14 @@ import ( // HopTagWeight is the connection manager weight for connections carrying relay hop streams var HopTagWeight = 5 +type statLimitDuration struct{} +type statLimitData struct{} + +var ( + StatLimitDuration = statLimitDuration{} + StatLimitData = statLimitData{} +) + type Conn struct { stream network.Stream remote peer.AddrInfo diff --git a/v2/client/dial.go b/v2/client/dial.go index f913496..980e818 100644 --- a/v2/client/dial.go +++ b/v2/client/dial.go @@ -3,9 +3,10 @@ package client import ( "context" "fmt" + "time" pbv1 "github.com/libp2p/go-libp2p-circuit/pb" - //pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" "github.com/libp2p/go-libp2p-circuit/v2/util" "github.com/libp2p/go-libp2p-core/network" @@ -75,8 +76,49 @@ func (c *Client) dialPeer(ctx context.Context, relay, dest peer.AddrInfo) (*Conn } func (c *Client) connectV2(s network.Stream, dest peer.AddrInfo) (*Conn, error) { - // TODO - return nil, nil + rd := util.NewDelimitedReader(s, maxMessageSize) + wr := util.NewDelimitedWriter(s) + defer rd.Close() + + var msg pbv2.HopMessage + + msg.Type = pbv2.HopMessage_CONNECT.Enum() + msg.Peer = util.PeerInfoToPeerV2(dest) + + err := wr.WriteMsg(&msg) + if err != nil { + s.Reset() + return nil, err + } + + msg.Reset() + + err = rd.ReadMsg(&msg) + if err != nil { + s.Reset() + return nil, err + } + + if msg.GetType() != pbv2.HopMessage_STATUS { + s.Reset() + return nil, fmt.Errorf("unexpected relay response; not a status message (%d)", msg.GetType()) + } + + status := msg.GetStatus() + if status != pbv2.Status_OK { + s.Reset() + return nil, fmt.Errorf("error opening relay circuit: %s (%d)", pbv2.Status_name[int32(status)], status) + } + + var stat network.Stat + if limit := msg.GetLimit(); limit != nil { + stat.Transient = true + stat.Extra = make(map[interface{}]interface{}) + stat.Extra[StatLimitDuration] = time.Duration(limit.GetDuration()) * time.Second + stat.Extra[StatLimitData] = limit.GetData() + } + + return &Conn{stream: s, remote: dest, stat: stat, client: c}, nil } func (c *Client) connectV1(s network.Stream, dest peer.AddrInfo) (*Conn, error) { @@ -96,6 +138,14 @@ func (c *Client) connectV1(s network.Stream, dest peer.AddrInfo) (*Conn, error) return nil, err } + msg.Reset() + + err = rd.ReadMsg(&msg) + if err != nil { + s.Reset() + return nil, err + } + if msg.GetType() != pbv1.CircuitRelay_STATUS { s.Reset() return nil, fmt.Errorf("unexpected relay response; not a status message (%d)", msg.GetType()) diff --git a/v2/client/handlers.go b/v2/client/handlers.go index 8735ae6..2a103e0 100644 --- a/v2/client/handlers.go +++ b/v2/client/handlers.go @@ -4,7 +4,7 @@ import ( "time" pbv1 "github.com/libp2p/go-libp2p-circuit/pb" - //pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" "github.com/libp2p/go-libp2p-circuit/v2/util" "github.com/libp2p/go-libp2p-core/network" @@ -16,11 +16,79 @@ var ( ) func (c *Client) handleStreamV2(s network.Stream) { - // TODO + log.Debugf("new relay/v2 stream from: %s", s.Conn().RemotePeer()) + + s.SetReadDeadline(time.Now().Add(StreamTimeout)) + + rd := util.NewDelimitedReader(s, maxMessageSize) + defer rd.Close() + + writeResponse := func(status pbv2.Status) error { + wr := util.NewDelimitedWriter(s) + + var msg pbv2.StopMessage + msg.Type = pbv2.StopMessage_STATUS.Enum() + msg.Status = status.Enum() + + return wr.WriteMsg(&msg) + } + + handleError := func(status pbv2.Status) { + log.Debugf("protocol error: %s (%d)", pbv2.Status_name[int32(status)], status) + err := writeResponse(status) + if err != nil { + s.Reset() + log.Debugf("error writing circuit response: %s", err.Error()) + } else { + s.Close() + } + } + + var msg pbv2.StopMessage + + err := rd.ReadMsg(&msg) + if err != nil { + handleError(pbv2.Status_MALFORMED_MESSAGE) + return + } + // reset stream deadline as message has been read + s.SetReadDeadline(time.Time{}) + + if msg.GetType() != pbv2.StopMessage_CONNECT { + handleError(pbv2.Status_MALFORMED_MESSAGE) + return + } + + src, err := util.PeerToPeerInfoV2(msg.GetPeer()) + if err != nil { + handleError(pbv2.Status_MALFORMED_MESSAGE) + return + } + + var stat network.Stat + if limit := msg.GetLimit(); limit != nil { + stat.Transient = true + stat.Extra = make(map[interface{}]interface{}) + stat.Extra[StatLimitDuration] = time.Duration(limit.GetDuration()) * time.Second + stat.Extra[StatLimitData] = limit.GetData() + } + + log.Debugf("incoming relay connection from: %s", src.ID) + + select { + case c.incoming <- accept{ + conn: &Conn{stream: s, remote: src, stat: stat, client: c}, + writeResponse: func() error { + return writeResponse(pbv2.Status_OK) + }, + }: + case <-time.After(AcceptTimeout): + handleError(pbv2.Status_CONNECTION_FAILED) + } } func (c *Client) handleStreamV1(s network.Stream) { - log.Debugf("new relay stream from: %s", s.Conn().RemotePeer()) + log.Debugf("new relay/v1 stream from: %s", s.Conn().RemotePeer()) s.SetReadDeadline(time.Now().Add(StreamTimeout)) @@ -87,7 +155,7 @@ func (c *Client) handleStreamV1(s network.Stream) { return } - log.Infof("incoming relay connection from: %s", src.ID) + log.Debugf("incoming relay connection from: %s", src.ID) select { case c.incoming <- accept{ diff --git a/v2/util/pbconv.go b/v2/util/pbconv.go index 73cedcc..0a176c4 100644 --- a/v2/util/pbconv.go +++ b/v2/util/pbconv.go @@ -4,6 +4,7 @@ import ( "errors" pbv1 "github.com/libp2p/go-libp2p-circuit/pb" + pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" "github.com/libp2p/go-libp2p-core/peer" @@ -20,7 +21,7 @@ func PeerToPeerInfoV1(p *pbv1.CircuitRelay_Peer) (peer.AddrInfo, error) { return peer.AddrInfo{}, err } - addrs := make([]ma.Multiaddr, 0, len(p.Addrs)) + var addrs []ma.Multiaddr for _, addrBytes := range p.Addrs { a, err := ma.NewMultiaddrBytes(addrBytes) if err == nil { @@ -32,7 +33,7 @@ func PeerToPeerInfoV1(p *pbv1.CircuitRelay_Peer) (peer.AddrInfo, error) { } func PeerInfoToPeerV1(pi peer.AddrInfo) *pbv1.CircuitRelay_Peer { - addrs := make([][]byte, len(pi.Addrs)) + var addrs [][]byte for i, addr := range pi.Addrs { addrs[i] = addr.Bytes() } @@ -43,3 +44,37 @@ func PeerInfoToPeerV1(pi peer.AddrInfo) *pbv1.CircuitRelay_Peer { return p } + +func PeerToPeerInfoV2(p *pbv2.Peer) (peer.AddrInfo, error) { + if p == nil { + return peer.AddrInfo{}, errors.New("nil peer") + } + + id, err := peer.IDFromBytes(p.Id) + if err != nil { + return peer.AddrInfo{}, err + } + + var addrs []ma.Multiaddr + for _, addrBytes := range p.Addrs { + a, err := ma.NewMultiaddrBytes(addrBytes) + if err == nil { + addrs = append(addrs, a) + } + } + + return peer.AddrInfo{ID: id, Addrs: addrs}, nil +} + +func PeerInfoToPeerV2(pi peer.AddrInfo) *pbv2.Peer { + var addrs [][]byte + for i, addr := range pi.Addrs { + addrs[i] = addr.Bytes() + } + + p := new(pbv2.Peer) + p.Id = []byte(pi.ID) + p.Addrs = addrs + + return p +} From 8abf64d68dfff6be117c708d447031aca7aeeed3 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 01:04:38 +0200 Subject: [PATCH 12/66] implement Reserve --- v2/client/reservation.go | 72 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/v2/client/reservation.go b/v2/client/reservation.go index 5538312..8c65bf5 100644 --- a/v2/client/reservation.go +++ b/v2/client/reservation.go @@ -2,15 +2,83 @@ package client import ( "context" + "fmt" + "time" + + pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + "github.com/libp2p/go-libp2p-circuit/v2/util" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peerstore" ) type Reservation struct { + Expiration time.Time + Relay peer.AddrInfo + + LimitDuration time.Duration + LimitData int64 } +// Reserve reserves a slot in a relay and returns the reservation information func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation, error) { - // TODO - return nil, nil + if len(ai.Addrs) > 0 { + h.Peerstore().AddAddrs(ai.ID, ai.Addrs, peerstore.TempAddrTTL) + } + + s, err := h.NewStream(ctx, ai.ID, ProtoIDv2Hop) + if err != nil { + return nil, err + } + defer s.Close() + + rd := util.NewDelimitedReader(s, maxMessageSize) + wr := util.NewDelimitedWriter(s) + defer rd.Close() + + var msg pbv2.HopMessage + msg.Type = pbv2.HopMessage_RESERVE.Enum() + + if err := wr.WriteMsg(&msg); err != nil { + s.Reset() + return nil, fmt.Errorf("error writing reservation message: %w", err) + } + + msg.Reset() + + if err := rd.ReadMsg(&msg); err != nil { + s.Reset() + return nil, fmt.Errorf("error reading reservation response message: %w", err) + } + + if msg.GetType() != pbv2.HopMessage_STATUS { + return nil, fmt.Errorf("unexpected relay response: not a status message (%d)", msg.GetType()) + } + + if status := msg.GetStatus(); status != pbv2.Status_OK { + return nil, fmt.Errorf("reservation failed: %s (%d)", pbv2.Status_name[int32(status)], status) + } + + rsvp := msg.GetReservation() + if rsvp == nil { + return nil, fmt.Errorf("missing reservation info") + } + + result := &Reservation{} + result.Expiration = time.Now().Add(time.Duration(rsvp.GetTtl()) * time.Second) + + rinfo, err := util.PeerToPeerInfoV2(rsvp.GetRelay()) + if err != nil { + return nil, fmt.Errorf("missing relay info") + } + result.Relay = rinfo + + limit := msg.GetLimit() + if limit != nil { + result.LimitDuration = time.Duration(limit.GetDuration()) * time.Second + result.LimitData = limit.GetData() + } + + return result, nil } From 5fa453e7da1dc6b001ed6ee92ce96d38f5a9fdb6 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 01:16:52 +0200 Subject: [PATCH 13/66] go get go-libp2p-swarm@feat/transient-conns --- go.mod | 2 +- go.sum | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 192 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index 7805331..e2c3de4 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-libp2p-blankhost v0.2.0 github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee - github.com/libp2p/go-libp2p-swarm v0.3.0 + github.com/libp2p/go-libp2p-swarm v0.4.1-0.20210204114217-94302e6b940c github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309 github.com/libp2p/go-msgio v0.0.6 github.com/multiformats/go-multiaddr v0.3.1 diff --git a/go.sum b/go.sum index 91e9a9d..08c4298 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,21 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= @@ -17,14 +28,18 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -39,28 +54,61 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= +github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -98,9 +146,12 @@ github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsj github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -111,6 +162,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/libp2p/go-addr-util v0.0.2 h1:7cWK5cdA5x72jX0g8iLrQWm5TRJZ6CzGdPEhWj7plWU= @@ -134,10 +186,8 @@ github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUh github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee h1:M3DUy4DHSFAlYAftWF/vosJM3lnyTQM9UXA9pe0N5RU= github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= @@ -151,20 +201,23 @@ github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= -github.com/libp2p/go-libp2p-swarm v0.3.0 h1:w18ZLMccbvwgyR+dODEeA3r1zbFZj+YVq6PClXo77lY= -github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= +github.com/libp2p/go-libp2p-quic-transport v0.10.0 h1:koDCbWD9CCHwcHZL3/WEvP2A+e/o5/W5L3QS/2SPMA0= +github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= +github.com/libp2p/go-libp2p-swarm v0.4.1-0.20210204114217-94302e6b940c h1:nOWDDMDP1wvzC94+t5TXk33wDAns7LQWjaiGclaYt64= +github.com/libp2p/go-libp2p-swarm v0.4.1-0.20210204114217-94302e6b940c/go.mod h1:IFaCw0U+is7U1+9ysFWBAalLeYMRhMqO6ttuIawJZB4= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= -github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= github.com/libp2p/go-libp2p-testing v0.4.0 h1:PrwHRi0IGqOwVQWR3xzgigSlhlLfxgfXgkHxr77EghQ= github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= +github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= +github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= -github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.0/go.mod h1:J4ko0ObtZSmgn5BX5AmegP+dK3CSnU2lMCKsSq/EY0s= github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309 h1:XxFG5lVqdn/o0/7F51XiT6xnvCltayYagaANzNPg/jw= github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309/go.mod h1:wFqIXZJ8k08YwnioC9twyokMXpewf2LKRQYtm34Y/T8= -github.com/libp2p/go-libp2p-yamux v0.4.0 h1:qunEZzWwwmfSBYTtSyd81PlD1TjB5uuWcGYHWVXLbUg= -github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= +github.com/libp2p/go-libp2p-yamux v0.5.0 h1:ZzmUhbQE+X7NuYUT2naxN31JyebZfRmpZVhKtRP13ys= +github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= @@ -174,8 +227,9 @@ github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.6 h1:lQ7Uc0kS1wb1EfRxO2Eir/RJoHkHn7t6o+EiwsYIKJA= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-netroute v0.1.2 h1:UHhB35chwgvcRI392znJA3RCBtZ3MpE3ahNCN5MR4Xg= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.3 h1:1ngWRx61us/EpaKkdqkMjKk/ufr/JlIFYQAxV2XX8Ig= +github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw= @@ -190,15 +244,26 @@ github.com/libp2p/go-stream-muxer-multistream v0.3.0 h1:TqnSHPJEIqDEO7h1wZZ0p3DX github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= github.com/libp2p/go-tcp-transport v0.2.0 h1:YoThc549fzmNJIh7XjHVtMIFaEDRtIrtWciG5LyYAPo= github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= -github.com/libp2p/go-yamux v1.4.0 h1:7nqe0T95T2CWh40IdJ/tp8RMor4ubc9/wYZpB2a/Hx0= -github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= +github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= +github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= +github.com/marten-seemann/qtls v0.10.0 h1:ECsuYUKalRL240rRD4Ri33ISb7kAQ3qGDlrrl55b2pc= +github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= +github.com/marten-seemann/qtls-go1-15 v0.1.1 h1:LIH6K34bPVttyXnUWixk0bzH6/N07VxbSabxn5A5gZQ= +github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= @@ -209,6 +274,8 @@ github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKU github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -234,7 +301,6 @@ github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDu github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= github.com/multiformats/go-multiaddr-net v0.2.0 h1:MSXRGN0mFymt6B1yo/6BPnIRpLPEnKgQNvVfCX5VDJk= github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= @@ -254,27 +320,66 @@ github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= @@ -296,13 +401,17 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -322,18 +431,26 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443 h1:IcSOAf4PyMp3U3XbIEj1/xJ2BjNN2jWv7JoyOsMxXUU= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -343,41 +460,69 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -387,12 +532,24 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -400,21 +557,39 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= From 7ebd713d12aacb8d6d3c37a4a6c9252fddb0474c Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 01:37:45 +0200 Subject: [PATCH 14/66] implement client.New --- v2/client/client.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/v2/client/client.go b/v2/client/client.go index 41e89dd..a8fddf9 100644 --- a/v2/client/client.go +++ b/v2/client/client.go @@ -38,8 +38,13 @@ type accept struct { // New constructs a new p2p-circuit/v2 client, attached to the given host and using the given // upgrader to perform connection upgrades. func New(ctx context.Context, h host.Host, upgrader *tptu.Upgrader) (*Client, error) { - // TODO - return nil, nil + return &Client{ + ctx: ctx, + host: h, + upgrader: upgrader, + incoming: make(chan accept), + hopCount: make(map[peer.ID]int), + }, nil } // Start registers the circuit (client) protocol stream handlers From 7cd275aa36403f073ee3a49b6b36a706a290e103 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 14:46:51 +0200 Subject: [PATCH 15/66] rework pb status codes --- v2/pb/circuit.pb.go | 94 ++++++++++++++++++++++++--------------------- v2/pb/circuit.proto | 14 ++++--- 2 files changed, 59 insertions(+), 49 deletions(-) diff --git a/v2/pb/circuit.pb.go b/v2/pb/circuit.pb.go index 7f73050..9d95ec7 100644 --- a/v2/pb/circuit.pb.go +++ b/v2/pb/circuit.pb.go @@ -27,29 +27,35 @@ type Status int32 const ( Status_OK Status = 100 - Status_NO_RESERVATION Status = 200 - Status_RESERVATION_REFUSED Status = 201 - Status_RESOURCE_LIMIT_EXCEEDED Status = 202 - Status_CONNECTION_FAILED Status = 300 + Status_RESERVATION_REFUSED Status = 200 + Status_RESOURCE_LIMIT_EXCEEDED Status = 201 + Status_PERMISSION_DENIED Status = 202 + Status_CONNECTION_FAILED Status = 203 + Status_NO_RESERVATION Status = 204 Status_MALFORMED_MESSAGE Status = 400 + Status_UNEXPECTED_MESSAGE Status = 401 ) var Status_name = map[int32]string{ 100: "OK", - 200: "NO_RESERVATION", - 201: "RESERVATION_REFUSED", - 202: "RESOURCE_LIMIT_EXCEEDED", - 300: "CONNECTION_FAILED", + 200: "RESERVATION_REFUSED", + 201: "RESOURCE_LIMIT_EXCEEDED", + 202: "PERMISSION_DENIED", + 203: "CONNECTION_FAILED", + 204: "NO_RESERVATION", 400: "MALFORMED_MESSAGE", + 401: "UNEXPECTED_MESSAGE", } var Status_value = map[string]int32{ "OK": 100, - "NO_RESERVATION": 200, - "RESERVATION_REFUSED": 201, - "RESOURCE_LIMIT_EXCEEDED": 202, - "CONNECTION_FAILED": 300, + "RESERVATION_REFUSED": 200, + "RESOURCE_LIMIT_EXCEEDED": 201, + "PERMISSION_DENIED": 202, + "CONNECTION_FAILED": 203, + "NO_RESERVATION": 204, "MALFORMED_MESSAGE": 400, + "UNEXPECTED_MESSAGE": 401, } func (x Status) Enum() *Status { @@ -487,37 +493,39 @@ func init() { func init() { proto.RegisterFile("circuit.proto", fileDescriptor_ed01bbc211f15e47) } var fileDescriptor_ed01bbc211f15e47 = []byte{ - // 478 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0x4f, 0x8b, 0xd3, 0x40, - 0x18, 0xc6, 0x77, 0xf2, 0xa7, 0xca, 0x9b, 0x5a, 0x66, 0xdf, 0x15, 0x37, 0xe8, 0x52, 0x43, 0x10, - 0x0d, 0x8b, 0x54, 0xe9, 0x45, 0x3c, 0xc6, 0x66, 0xba, 0x16, 0x9b, 0x46, 0x26, 0xa9, 0x78, 0x0b, - 0x71, 0x33, 0x48, 0xa0, 0xda, 0x90, 0x4c, 0x85, 0x7e, 0x08, 0xc1, 0xaf, 0xe0, 0xdd, 0x0f, 0xb2, - 0x7a, 0xf2, 0xee, 0x45, 0xfa, 0x49, 0x24, 0xc9, 0xda, 0x64, 0x0f, 0xa2, 0xe0, 0x6d, 0xde, 0x79, - 0x9e, 0x67, 0x92, 0xdf, 0x33, 0x03, 0x37, 0xce, 0xb3, 0xe2, 0x7c, 0x93, 0xc9, 0x51, 0x5e, 0xac, - 0xe5, 0x1a, 0x61, 0x3f, 0xbe, 0xb1, 0x3f, 0x2b, 0x00, 0xcf, 0xd7, 0xb9, 0x2f, 0xca, 0x32, 0x79, - 0x2b, 0xf0, 0x11, 0x68, 0x72, 0x9b, 0x0b, 0x93, 0x58, 0x8a, 0x33, 0x18, 0xdf, 0x19, 0xb5, 0xce, - 0x51, 0xeb, 0x1a, 0x45, 0xdb, 0x5c, 0xf0, 0xda, 0x88, 0xf7, 0x40, 0xcb, 0x85, 0x28, 0x4c, 0xc5, - 0x22, 0x8e, 0x31, 0xa6, 0xdd, 0xc0, 0x4b, 0x21, 0x0a, 0x5e, 0xab, 0xf8, 0x14, 0x8c, 0x42, 0x94, - 0xa2, 0xf8, 0x90, 0xc8, 0x6c, 0xfd, 0xde, 0x54, 0x6b, 0xf3, 0x71, 0xd7, 0xcc, 0x5b, 0x99, 0x77, - 0xbd, 0xf8, 0x00, 0xf4, 0x55, 0xf6, 0x2e, 0x93, 0xa6, 0x56, 0x87, 0x0e, 0xbb, 0xa1, 0x79, 0x25, - 0xf0, 0x46, 0xc7, 0x53, 0xe8, 0x95, 0x32, 0x91, 0x9b, 0xd2, 0xd4, 0x2d, 0xe2, 0x0c, 0xc6, 0xd8, - 0x75, 0x86, 0xb5, 0xc2, 0x2f, 0x1d, 0xf6, 0x43, 0xd0, 0x2a, 0x06, 0x34, 0xe0, 0x1a, 0x67, 0x21, - 0xe3, 0xaf, 0x18, 0x3d, 0xa8, 0x86, 0x49, 0xb0, 0x58, 0xb0, 0x49, 0x44, 0x09, 0x02, 0xf4, 0xc2, - 0xc8, 0x8d, 0x96, 0x21, 0x55, 0xec, 0x1f, 0x04, 0x8c, 0x50, 0xb6, 0x25, 0x3d, 0xbe, 0x52, 0xd2, - 0xc9, 0xd5, 0xef, 0xfc, 0x47, 0x4b, 0x7b, 0x54, 0xf5, 0x9f, 0x51, 0xb5, 0xbf, 0xa2, 0xde, 0x6d, - 0x51, 0x7f, 0xd3, 0x1d, 0x74, 0xe8, 0x48, 0xd5, 0x45, 0xf5, 0x0f, 0x38, 0x00, 0x25, 0x4b, 0x6b, - 0xa6, 0x3e, 0x57, 0xb2, 0x14, 0x6f, 0x82, 0x9e, 0xa4, 0x69, 0x51, 0x9a, 0x8a, 0xa5, 0x3a, 0x7d, - 0xde, 0x0c, 0xf6, 0x19, 0x18, 0x9d, 0xab, 0x42, 0x0a, 0xaa, 0x94, 0x2b, 0x93, 0x58, 0xc4, 0xd1, - 0x79, 0xb5, 0xc4, 0xfb, 0xa0, 0x17, 0x62, 0x95, 0x6c, 0xff, 0xc8, 0xda, 0xc8, 0xf6, 0x13, 0xd0, - 0x6b, 0x26, 0xbc, 0x0d, 0xd7, 0xd3, 0x4d, 0xd1, 0x3c, 0x8c, 0xe6, 0x9c, 0xfd, 0x8c, 0x08, 0x5a, - 0x9a, 0xc8, 0xa4, 0x3e, 0x4b, 0xe5, 0xf5, 0xfa, 0xf4, 0x23, 0x81, 0x5e, 0xc3, 0x88, 0x3d, 0x50, - 0x82, 0x17, 0x34, 0xc5, 0x23, 0x18, 0x2c, 0x82, 0xb8, 0xb9, 0x49, 0x37, 0x9a, 0x05, 0x0b, 0x7a, - 0x41, 0xd0, 0x84, 0xa3, 0xce, 0x4e, 0xcc, 0xd9, 0x74, 0x19, 0x32, 0x8f, 0x7e, 0x25, 0x78, 0x02, - 0xc7, 0x9c, 0x85, 0xc1, 0x92, 0x4f, 0x58, 0x3c, 0x9f, 0xf9, 0xb3, 0x28, 0x66, 0xaf, 0x27, 0x8c, - 0x79, 0xcc, 0xa3, 0xdf, 0x08, 0xde, 0x82, 0xc3, 0xcb, 0xa2, 0xaa, 0xd8, 0xd4, 0x9d, 0xcd, 0x99, - 0x47, 0xbf, 0x28, 0xd5, 0xbe, 0xef, 0xce, 0xa7, 0x01, 0xf7, 0x99, 0x17, 0xfb, 0x2c, 0x0c, 0xdd, - 0x33, 0x46, 0x3f, 0xa9, 0xcf, 0xfa, 0x17, 0xbb, 0x21, 0xf9, 0xbe, 0x1b, 0x92, 0x9f, 0xbb, 0x21, - 0xf9, 0x15, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x23, 0x17, 0x15, 0x6b, 0x03, 0x00, 0x00, + // 506 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0x4d, 0x8b, 0xd3, 0x40, + 0x18, 0xc7, 0x77, 0xf2, 0x52, 0xe5, 0x69, 0x2d, 0xb3, 0xcf, 0x8a, 0x0d, 0xba, 0xd4, 0x52, 0x44, + 0xcb, 0x22, 0x55, 0x7a, 0x11, 0x8f, 0xb5, 0x99, 0xae, 0xc1, 0x26, 0x29, 0x33, 0xa9, 0xec, 0xad, + 0xc4, 0xcd, 0x20, 0x81, 0x6a, 0x4b, 0x32, 0x15, 0xfa, 0x2d, 0xf4, 0x23, 0xf8, 0x45, 0x3c, 0xaf, + 0x2f, 0x07, 0xef, 0x5e, 0xa4, 0x9f, 0x44, 0x32, 0x59, 0xdb, 0xec, 0x41, 0x14, 0xbc, 0xcd, 0x33, + 0xff, 0xdf, 0x33, 0x93, 0xdf, 0x33, 0x81, 0x1b, 0xe7, 0x69, 0x76, 0xbe, 0x4e, 0x55, 0x7f, 0x95, + 0x2d, 0xd5, 0x12, 0x61, 0x57, 0xbe, 0xea, 0x7e, 0x34, 0x00, 0x9e, 0x2f, 0x57, 0xbe, 0xcc, 0xf3, + 0xf8, 0xb5, 0xc4, 0x47, 0x60, 0xa9, 0xcd, 0x4a, 0x3a, 0xa4, 0x63, 0xf4, 0x9a, 0x83, 0x3b, 0xfd, + 0x3d, 0xd9, 0xdf, 0x53, 0xfd, 0x68, 0xb3, 0x92, 0x5c, 0x83, 0x78, 0x0f, 0xac, 0x95, 0x94, 0x99, + 0x63, 0x74, 0x48, 0xaf, 0x3e, 0xa0, 0xd5, 0x86, 0xa9, 0x94, 0x19, 0xd7, 0x29, 0x3e, 0x85, 0x7a, + 0x26, 0x73, 0x99, 0xbd, 0x8b, 0x55, 0xba, 0x7c, 0xeb, 0x98, 0x1a, 0x6e, 0x55, 0x61, 0xbe, 0x8f, + 0x79, 0x95, 0xc5, 0x07, 0x60, 0x2f, 0xd2, 0x37, 0xa9, 0x72, 0x2c, 0xdd, 0x74, 0x58, 0x6d, 0x9a, + 0x14, 0x01, 0x2f, 0x73, 0x3c, 0x81, 0x5a, 0xae, 0x62, 0xb5, 0xce, 0x1d, 0xbb, 0x43, 0x7a, 0xcd, + 0x01, 0x56, 0x49, 0xa1, 0x13, 0x7e, 0x49, 0x74, 0x1f, 0x82, 0x55, 0x38, 0x60, 0x1d, 0xae, 0x71, + 0x26, 0x18, 0x7f, 0xc9, 0xe8, 0x41, 0x51, 0x8c, 0xc2, 0x20, 0x60, 0xa3, 0x88, 0x12, 0x04, 0xa8, + 0x89, 0x68, 0x18, 0xcd, 0x04, 0x35, 0xba, 0x3f, 0x08, 0xd4, 0x85, 0xda, 0x0f, 0xe9, 0xf1, 0x95, + 0x21, 0x1d, 0x5f, 0xbd, 0xe7, 0x3f, 0xa6, 0xb4, 0x53, 0x35, 0xff, 0x59, 0xd5, 0xfa, 0xab, 0xea, + 0xdd, 0xbd, 0xea, 0x6f, 0xbb, 0x83, 0x8a, 0x1d, 0x29, 0x66, 0x51, 0x7c, 0x03, 0x36, 0xc1, 0x48, + 0x13, 0xed, 0xd4, 0xe0, 0x46, 0x9a, 0xe0, 0x4d, 0xb0, 0xe3, 0x24, 0xc9, 0x72, 0xc7, 0xe8, 0x98, + 0xbd, 0x06, 0x2f, 0x8b, 0xee, 0x29, 0xd4, 0x2b, 0x4f, 0x85, 0x14, 0x4c, 0xa5, 0x16, 0x0e, 0xe9, + 0x90, 0x9e, 0xcd, 0x8b, 0x25, 0xde, 0x07, 0x3b, 0x93, 0x8b, 0x78, 0xf3, 0x47, 0xd7, 0x32, 0xee, + 0x3e, 0x01, 0x5b, 0x3b, 0xe1, 0x6d, 0xb8, 0x9e, 0xac, 0xb3, 0xf2, 0xc7, 0x28, 0xcf, 0xd9, 0xd5, + 0x88, 0x60, 0x25, 0xb1, 0x8a, 0xf5, 0x59, 0x26, 0xd7, 0xeb, 0x93, 0x4f, 0x04, 0x6a, 0xa5, 0x23, + 0xd6, 0xc0, 0x08, 0x5f, 0xd0, 0x04, 0x1d, 0x38, 0x2a, 0x9f, 0x71, 0x18, 0x79, 0x61, 0x30, 0xe7, + 0x6c, 0x3c, 0x13, 0xcc, 0xa5, 0x17, 0x04, 0x8f, 0xa1, 0xc5, 0x99, 0x08, 0x67, 0x7c, 0xc4, 0xe6, + 0x13, 0xcf, 0xf7, 0xa2, 0x39, 0x3b, 0x1b, 0x31, 0xe6, 0x32, 0x97, 0x7e, 0x26, 0x78, 0x0b, 0x0e, + 0xa7, 0x8c, 0xfb, 0x9e, 0x10, 0x45, 0x9b, 0xcb, 0x02, 0x8f, 0xb9, 0xf4, 0x8b, 0xde, 0xbf, 0x9c, + 0x55, 0xb1, 0x3f, 0x1e, 0x7a, 0x13, 0xe6, 0xd2, 0xaf, 0x04, 0x8f, 0xa0, 0x19, 0x84, 0xf3, 0xca, + 0x55, 0xf4, 0x9b, 0x86, 0xfd, 0xe1, 0x64, 0x1c, 0x72, 0x9f, 0xb9, 0x73, 0x9f, 0x09, 0x31, 0x3c, + 0x65, 0xf4, 0xbd, 0x89, 0x2d, 0xc0, 0x59, 0xc0, 0xce, 0xa6, 0x6c, 0x14, 0x55, 0x82, 0x0f, 0xe6, + 0xb3, 0xc6, 0xc5, 0xb6, 0x4d, 0xbe, 0x6f, 0xdb, 0xe4, 0xe7, 0xb6, 0x4d, 0x7e, 0x05, 0x00, 0x00, + 0xff, 0xff, 0x9d, 0xd3, 0x7c, 0x1f, 0x9c, 0x03, 0x00, 0x00, } func (m *HopMessage) Marshal() (dAtA []byte, err error) { diff --git a/v2/pb/circuit.proto b/v2/pb/circuit.proto index a602a5e..5d7e88b 100644 --- a/v2/pb/circuit.proto +++ b/v2/pb/circuit.proto @@ -50,10 +50,12 @@ message Limit { } enum Status { - OK = 100; - NO_RESERVATION = 200; - RESERVATION_REFUSED = 201; - RESOURCE_LIMIT_EXCEEDED = 202; - CONNECTION_FAILED = 300; - MALFORMED_MESSAGE = 400; + OK = 100; + RESERVATION_REFUSED = 200; + RESOURCE_LIMIT_EXCEEDED = 201; + PERMISSION_DENIED = 202; + CONNECTION_FAILED = 203; + NO_RESERVATION = 204; + MALFORMED_MESSAGE = 400; + UNEXPECTED_MESSAGE = 401; } From 780516715f42376f0c32006be791a059f5d8faf3 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 14:47:26 +0200 Subject: [PATCH 16/66] client responds with UNEXPECTED_MESSAGE when it's actually an unexpected message --- v2/client/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2/client/handlers.go b/v2/client/handlers.go index 2a103e0..7ace6ac 100644 --- a/v2/client/handlers.go +++ b/v2/client/handlers.go @@ -55,7 +55,7 @@ func (c *Client) handleStreamV2(s network.Stream) { s.SetReadDeadline(time.Time{}) if msg.GetType() != pbv2.StopMessage_CONNECT { - handleError(pbv2.Status_MALFORMED_MESSAGE) + handleError(pbv2.Status_UNEXPECTED_MESSAGE) return } From e4a463f49fe5aa2386483b78971f7144c989add7 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 15:43:58 +0200 Subject: [PATCH 17/66] relay scaffolding, reservation implementation --- v2/relay/acl.go | 11 +++ v2/relay/options.go | 3 + v2/relay/relay.go | 199 ++++++++++++++++++++++++++++++++++++++++++ v2/relay/resources.go | 18 ++++ 4 files changed, 231 insertions(+) create mode 100644 v2/relay/acl.go create mode 100644 v2/relay/options.go create mode 100644 v2/relay/relay.go create mode 100644 v2/relay/resources.go diff --git a/v2/relay/acl.go b/v2/relay/acl.go new file mode 100644 index 0000000..07e2c7d --- /dev/null +++ b/v2/relay/acl.go @@ -0,0 +1,11 @@ +package relay + +import ( + "github.com/libp2p/go-libp2p-core/peer" + + ma "github.com/multiformats/go-multiaddr" +) + +type ACLFilter interface { + AllowReserve(p peer.ID, a ma.Multiaddr) bool +} diff --git a/v2/relay/options.go b/v2/relay/options.go new file mode 100644 index 0000000..3dccc7f --- /dev/null +++ b/v2/relay/options.go @@ -0,0 +1,3 @@ +package relay + +type Option func(*Relay) error diff --git a/v2/relay/relay.go b/v2/relay/relay.go new file mode 100644 index 0000000..cbfebe2 --- /dev/null +++ b/v2/relay/relay.go @@ -0,0 +1,199 @@ +package relay + +import ( + "fmt" + "sync" + "time" + + pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + "github.com/libp2p/go-libp2p-circuit/v2/util" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + logging "github.com/ipfs/go-log" +) + +const ( + ProtoIDv2Hop = "/libp2p/circuit/relay/0.2.0/hop" + ProtoIDv2Stop = "/libp2p/circuit/relay/0.2.0/stop" + + ReservationTagWeight = 10 + + maxMessageSize = 4096 + streamTimeout = time.Minute +) + +var log = logging.Logger("relay") + +type Relay struct { + host host.Host + rc Resources + acl ACLFilter + + mx sync.Mutex + rsvp map[peer.ID]time.Time + refresh map[peer.ID]time.Time +} + +func New(h host.Host, opts ...Option) (*Relay, error) { + r := &Relay{ + host: h, + // TODO + } + + for _, opt := range opts { + err := opt(r) + if err != nil { + return nil, fmt.Errorf("error applying relay option: %w", err) + } + } + + h.SetStreamHandler(ProtoIDv2Hop, r.handleStream) + + // TODO network notifee for handling peer disconns and removing from rsvp table + // TODO start background goroutine for cleaning up reservations + + return r, nil +} + +func (r *Relay) Close() error { + // TODO + return nil +} + +func (r *Relay) handleStream(s network.Stream) { + s.SetReadDeadline(time.Now().Add(streamTimeout)) + + log.Infof("new relay stream from: %s", s.Conn().RemotePeer()) + + rd := util.NewDelimitedReader(s, maxMessageSize) + defer rd.Close() + + var msg pbv2.HopMessage + + err := rd.ReadMsg(&msg) + if err != nil { + r.handleError(s, pbv2.Status_MALFORMED_MESSAGE) + return + } + // reset stream deadline as message has been read + s.SetReadDeadline(time.Time{}) + + switch msg.GetType() { + case pbv2.HopMessage_RESERVE: + r.handleReserve(s, &msg) + + case pbv2.HopMessage_CONNECT: + r.handleConnect(s, &msg) + + default: + r.handleError(s, pbv2.Status_MALFORMED_MESSAGE) + } +} + +func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { + defer s.Close() + + p := s.Conn().RemotePeer() + a := s.Conn().RemoteMultiaddr() + + if r.acl != nil && !r.acl.AllowReserve(p, a) { + log.Debugf("refusing relay reservation for %s; permission denied", p) + r.handleError(s, pbv2.Status_PERMISSION_DENIED) + return + } + + r.mx.Lock() + now := time.Now() + + refresh, exists := r.refresh[p] + if exists && refresh.After(now) { + // extend refresh time, peer is trying too fast + r.refresh[p] = refresh.Add(r.rc.ReservationTTL / 2) + r.mx.Unlock() + log.Debugf("refusing relay reservation for %s; refreshing too fast", p) + r.handleError(s, pbv2.Status_RESERVATION_REFUSED) + return + } + + active := len(r.rsvp) + if active >= r.rc.MaxReservations { + r.mx.Unlock() + log.Debugf("refusing relay reservation for %s; too many reservations", p) + r.handleError(s, pbv2.Status_RESOURCE_LIMIT_EXCEEDED) + return + } + + r.rsvp[p] = now.Add(r.rc.ReservationTTL) + r.refresh[p] = now.Add(r.rc.ReservationTTL / 2) + r.host.ConnManager().TagPeer(p, "relay-reservation", ReservationTagWeight) + r.mx.Unlock() + + log.Debugf("reserving relay slot for %s", p) + + err := r.writeResponse(s, pbv2.Status_OK, r.makeReservationMsg(p), r.makeLimitMsg(p)) + if err != nil { + s.Reset() + log.Debugf("error writing reservation response; retracting reservation for %s", p) + r.mx.Lock() + delete(r.rsvp, p) + r.host.ConnManager().UntagPeer(p, "relay-reservation") + r.mx.Unlock() + } +} + +func (r *Relay) handleConnect(s network.Stream, msg *pbv2.HopMessage) { + // TODO +} + +func (r *Relay) handleError(s network.Stream, status pbv2.Status) { + log.Warnf("relay error: %s (%d)", pbv2.Status_name[int32(status)], status) + err := r.writeResponse(s, status, nil, nil) + if err != nil { + s.Reset() + log.Debugf("error writing relay response: %s", err.Error()) + } else { + s.Close() + } +} + +func (r *Relay) writeResponse(s network.Stream, status pbv2.Status, rsvp *pbv2.Reservation, limit *pbv2.Limit) error { + wr := util.NewDelimitedWriter(s) + + var msg pbv2.HopMessage + msg.Type = pbv2.HopMessage_STATUS.Enum() + msg.Status = status.Enum() + msg.Reservation = rsvp + msg.Limit = limit + + return wr.WriteMsg(&msg) +} + +func (r *Relay) makeReservationMsg(p peer.ID) *pbv2.Reservation { + // TODO signed reservation vouchers + + ttl := int32(r.rc.ReservationTTL / time.Second) + // TODO cache this + ai := peer.AddrInfo{r.host.ID(), r.host.Addrs()} + + return &pbv2.Reservation{ + Ttl: &ttl, + Relay: util.PeerInfoToPeerV2(ai), + } +} + +func (r *Relay) makeLimitMsg(p peer.ID) *pbv2.Limit { + if r.rc.Limit == nil { + return nil + } + + duration := int32(r.rc.Limit.Duration / time.Second) + data := int64(r.rc.Limit.Data) + + return &pbv2.Limit{ + Duration: &duration, + Data: &data, + } +} diff --git a/v2/relay/resources.go b/v2/relay/resources.go new file mode 100644 index 0000000..7079963 --- /dev/null +++ b/v2/relay/resources.go @@ -0,0 +1,18 @@ +package relay + +import ( + "time" +) + +type Resources struct { + Limit *RelayLimit + + ReservationTTL time.Duration + MaxReservations int + MaxCircuits int +} + +type RelayLimit struct { + Duration time.Duration + Data int +} From 66e3654b25678394c53db1f3824cd8162c42b52d Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 17:18:45 +0200 Subject: [PATCH 18/66] implement relaying --- v2/relay/acl.go | 1 + v2/relay/relay.go | 221 +++++++++++++++++++++++++++++++++++++++++- v2/relay/resources.go | 3 +- 3 files changed, 219 insertions(+), 6 deletions(-) diff --git a/v2/relay/acl.go b/v2/relay/acl.go index 07e2c7d..202addc 100644 --- a/v2/relay/acl.go +++ b/v2/relay/acl.go @@ -8,4 +8,5 @@ import ( type ACLFilter interface { AllowReserve(p peer.ID, a ma.Multiaddr) bool + AllowConnect(src peer.ID, srcAddr ma.Multiaddr, dest peer.ID) bool } diff --git a/v2/relay/relay.go b/v2/relay/relay.go index cbfebe2..d4572d8 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -1,8 +1,11 @@ package relay import ( + "context" "fmt" + "io" "sync" + "sync/atomic" "time" pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" @@ -12,6 +15,8 @@ import ( "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" + pool "github.com/libp2p/go-buffer-pool" + logging "github.com/ipfs/go-log" ) @@ -21,13 +26,19 @@ const ( ReservationTagWeight = 10 + StreamTimeout = time.Minute + ConnectTimeout = 30 * time.Second + HandshakeTimeout = time.Minute + maxMessageSize = 4096 - streamTimeout = time.Minute ) var log = logging.Logger("relay") type Relay struct { + ctx context.Context + cancel func() + host host.Host rc Resources acl ACLFilter @@ -35,11 +46,16 @@ type Relay struct { mx sync.Mutex rsvp map[peer.ID]time.Time refresh map[peer.ID]time.Time + conns map[peer.ID]int } func New(h host.Host, opts ...Option) (*Relay, error) { + ctx, cancel := context.WithCancel(context.Background()) + r := &Relay{ - host: h, + ctx: ctx, + cancel: cancel, + host: h, // TODO } @@ -64,7 +80,7 @@ func (r *Relay) Close() error { } func (r *Relay) handleStream(s network.Stream) { - s.SetReadDeadline(time.Now().Add(streamTimeout)) + s.SetReadDeadline(time.Now().Add(StreamTimeout)) log.Infof("new relay stream from: %s", s.Conn().RemotePeer()) @@ -145,11 +161,206 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { } func (r *Relay) handleConnect(s network.Stream, msg *pbv2.HopMessage) { - // TODO + src := s.Conn().RemotePeer() + dest, err := util.PeerToPeerInfoV2(msg.GetPeer()) + if err != nil { + r.handleError(s, pbv2.Status_MALFORMED_MESSAGE) + return + } + + if r.acl != nil && !r.acl.AllowConnect(src, s.Conn().RemoteMultiaddr(), dest.ID) { + log.Debugf("refusing connection from %s to %s; permission denied", src, dest.ID) + r.handleError(s, pbv2.Status_PERMISSION_DENIED) + return + } + + r.mx.Lock() + _, rsvp := r.rsvp[dest.ID] + if !rsvp { + r.mx.Unlock() + log.Debugf("refusing connection from %s to %s; no reservation", src, dest.ID) + r.handleError(s, pbv2.Status_NO_RESERVATION) + return + } + + srcConns := r.conns[src] + if srcConns >= r.rc.MaxCircuits { + r.mx.Unlock() + log.Debugf("refusing connection from %s to %s; too many connections from %s", src, dest.ID, src) + r.handleError(s, pbv2.Status_RESOURCE_LIMIT_EXCEEDED) + return + } + r.conns[src]++ + + destConns := r.conns[dest.ID] + if destConns >= r.rc.MaxCircuits { + r.conns[src]-- + r.mx.Unlock() + log.Debugf("refusing connection from %s to %s; too many connecitons to %s", src, dest.ID, dest.ID) + r.handleError(s, pbv2.Status_RESOURCE_LIMIT_EXCEEDED) + return + } + r.conns[dest.ID]++ + r.mx.Unlock() + + cleanup := func() { + r.mx.Lock() + r.conns[src]-- + r.conns[dest.ID]-- + r.mx.Unlock() + } + + ctx, cancel := context.WithTimeout(r.ctx, ConnectTimeout) + defer cancel() + + ctx = network.WithNoDial(ctx, "relay connect") + + bs, err := r.host.NewStream(ctx, dest.ID, ProtoIDv2Stop) + if err != nil { + log.Debugf("error opening relay stream to %s: %s", dest.ID, err) + cleanup() + r.handleError(s, pbv2.Status_CONNECTION_FAILED) + return + } + + // handshake + rd := util.NewDelimitedReader(bs, maxMessageSize) + wr := util.NewDelimitedWriter(bs) + defer rd.Close() + + var stopmsg pbv2.StopMessage + stopmsg.Type = pbv2.StopMessage_CONNECT.Enum() + stopmsg.Peer = util.PeerInfoToPeerV2(peer.AddrInfo{ID: src}) + stopmsg.Limit = r.makeLimitMsg(dest.ID) + + bs.SetDeadline(time.Now().Add(HandshakeTimeout)) + + err = wr.WriteMsg(&stopmsg) + if err != nil { + log.Debugf("error writing stop handshake") + bs.Reset() + cleanup() + r.handleError(s, pbv2.Status_CONNECTION_FAILED) + return + } + + stopmsg.Reset() + + err = rd.ReadMsg(&stopmsg) + if err != nil { + log.Debugf("error reading stop response: %s", err.Error()) + bs.Reset() + cleanup() + r.handleError(s, pbv2.Status_CONNECTION_FAILED) + return + } + + if t := stopmsg.GetType(); t != pbv2.StopMessage_STATUS { + log.Debugf("unexpected stop response; not a status message (%d)", t) + bs.Reset() + cleanup() + r.handleError(s, pbv2.Status_CONNECTION_FAILED) + return + } + + if status := stopmsg.GetStatus(); status != pbv2.Status_OK { + log.Debugf("relay stop failure: %d", status) + bs.Reset() + cleanup() + r.handleError(s, pbv2.Status_CONNECTION_FAILED) + return + } + + var response pbv2.HopMessage + response.Status = pbv2.Status_OK.Enum() + response.Limit = r.makeLimitMsg(dest.ID) + + wr = util.NewDelimitedWriter(s) + err = wr.WriteMsg(&response) + if err != nil { + log.Debugf("error writing relay response: %s", err) + bs.Reset() + s.Reset() + cleanup() + return + } + + // reset deadline + bs.SetDeadline(time.Time{}) + + log.Infof("relaying connection from %s to %s", src, dest.ID) + + goroutines := new(int32) + *goroutines = 2 + + done := func() { + if atomic.AddInt32(goroutines, -1) == 0 { + s.Close() + bs.Close() + cleanup() + } + } + + if r.rc.Limit != nil { + deadline := time.Now().Add(r.rc.Limit.Duration) + s.SetDeadline(deadline) + bs.SetDeadline(deadline) + go r.relayLimited(s, bs, src, dest.ID, r.rc.Limit.Data, done) + go r.relayLimited(bs, s, dest.ID, src, r.rc.Limit.Data, done) + } else { + go r.relayUnlimited(s, bs, src, dest.ID, done) + go r.relayUnlimited(bs, s, dest.ID, src, done) + } +} + +func (r *Relay) relayLimited(src, dest network.Stream, srcID, destID peer.ID, limit int64, done func()) { + defer done() + + buf := pool.Get(r.rc.BufferSize) + defer pool.Put(buf) + + limitedSrc := io.LimitReader(src, limit) + + count, err := io.CopyBuffer(dest, limitedSrc, buf) + if err != nil { + log.Debugf("relay copy error: %s", err) + // Reset both. + src.Reset() + dest.Reset() + } else { + // propagate the close + dest.CloseWrite() + if count == limit { + // we've reached the limit, discard further input + src.CloseRead() + } + } + + log.Debugf("relayed %d bytes from %s to %s", count, srcID, destID) +} + +func (r *Relay) relayUnlimited(src, dest network.Stream, srcID, destID peer.ID, done func()) { + defer done() + + buf := pool.Get(r.rc.BufferSize) + defer pool.Put(buf) + + count, err := io.CopyBuffer(dest, src, buf) + if err != nil { + log.Debugf("relay copy error: %s", err) + // Reset both. + src.Reset() + dest.Reset() + } else { + // propagate the close + dest.CloseWrite() + } + + log.Debugf("relayed %d bytes from %s to %s", count, srcID, destID) } func (r *Relay) handleError(s network.Stream, status pbv2.Status) { - log.Warnf("relay error: %s (%d)", pbv2.Status_name[int32(status)], status) + log.Debugf("relay error: %s (%d)", pbv2.Status_name[int32(status)], status) err := r.writeResponse(s, status, nil, nil) if err != nil { s.Reset() diff --git a/v2/relay/resources.go b/v2/relay/resources.go index 7079963..54a0fb5 100644 --- a/v2/relay/resources.go +++ b/v2/relay/resources.go @@ -10,9 +10,10 @@ type Resources struct { ReservationTTL time.Duration MaxReservations int MaxCircuits int + BufferSize int } type RelayLimit struct { Duration time.Duration - Data int + Data int64 } From 5e1217a5a09dcc7fbe056d28d48d28fcfb40008d Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 17:36:12 +0200 Subject: [PATCH 19/66] implement missing details --- v2/relay/relay.go | 82 +++++++++++++++++++++++++++++++++++++------ v2/relay/resources.go | 24 ++++++++++++- 2 files changed, 95 insertions(+), 11 deletions(-) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index d4572d8..215c46c 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -53,10 +53,14 @@ func New(h host.Host, opts ...Option) (*Relay, error) { ctx, cancel := context.WithCancel(context.Background()) r := &Relay{ - ctx: ctx, - cancel: cancel, - host: h, - // TODO + ctx: ctx, + cancel: cancel, + host: h, + rc: DefaultResources(), + acl: nil, + rsvp: make(map[peer.ID]time.Time), + refresh: make(map[peer.ID]time.Time), + conns: make(map[peer.ID]int), } for _, opt := range opts { @@ -67,19 +71,31 @@ func New(h host.Host, opts ...Option) (*Relay, error) { } h.SetStreamHandler(ProtoIDv2Hop, r.handleStream) - - // TODO network notifee for handling peer disconns and removing from rsvp table - // TODO start background goroutine for cleaning up reservations + h.Network().Notify( + &network.NotifyBundle{ + DisconnectedF: r.disconnected, + }) + go r.background() return r, nil } func (r *Relay) Close() error { - // TODO + select { + case <-r.ctx.Done(): + default: + r.cancel() + } return nil } func (r *Relay) handleStream(s network.Stream) { + select { + case <-r.ctx.Done(): + s.Reset() + return + } + s.SetReadDeadline(time.Now().Add(StreamTimeout)) log.Infof("new relay stream from: %s", s.Conn().RemotePeer()) @@ -127,7 +143,7 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { refresh, exists := r.refresh[p] if exists && refresh.After(now) { // extend refresh time, peer is trying too fast - r.refresh[p] = refresh.Add(r.rc.ReservationTTL / 2) + r.refresh[p] = refresh.Add(r.rc.ReservationRefreshTTL) r.mx.Unlock() log.Debugf("refusing relay reservation for %s; refreshing too fast", p) r.handleError(s, pbv2.Status_RESERVATION_REFUSED) @@ -143,7 +159,7 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { } r.rsvp[p] = now.Add(r.rc.ReservationTTL) - r.refresh[p] = now.Add(r.rc.ReservationTTL / 2) + r.refresh[p] = now.Add(r.rc.ReservationRefreshTTL) r.host.ConnManager().TagPeer(p, "relay-reservation", ReservationTagWeight) r.mx.Unlock() @@ -408,3 +424,49 @@ func (r *Relay) makeLimitMsg(p peer.ID) *pbv2.Limit { Data: &data, } } + +func (r *Relay) background() { + ticker := time.NewTicker(time.Minute) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + r.gc() + case <-r.ctx.Done(): + return + } + } +} + +func (r *Relay) gc() { + r.mx.Lock() + defer r.mx.Unlock() + + now := time.Now() + + for p, expire := range r.rsvp { + if expire.Before(now) { + delete(r.rsvp, p) + } + } + + for p, expire := range r.refresh { + _, rsvp := r.rsvp[p] + if !rsvp && expire.Before(now) { + delete(r.refresh, p) + } + } +} + +func (r *Relay) disconnected(n network.Network, c network.Conn) { + p := c.RemotePeer() + if n.Connectedness(p) == network.Connected { + return + } + + r.mx.Lock() + defer r.mx.Unlock() + + delete(r.rsvp, p) +} diff --git a/v2/relay/resources.go b/v2/relay/resources.go index 54a0fb5..053f8d6 100644 --- a/v2/relay/resources.go +++ b/v2/relay/resources.go @@ -7,7 +7,9 @@ import ( type Resources struct { Limit *RelayLimit - ReservationTTL time.Duration + ReservationTTL time.Duration + ReservationRefreshTTL time.Duration + MaxReservations int MaxCircuits int BufferSize int @@ -17,3 +19,23 @@ type RelayLimit struct { Duration time.Duration Data int64 } + +func DefaultResources() Resources { + return Resources{ + Limit: DefaultLimit(), + + ReservationTTL: time.Hour, + ReservationRefreshTTL: 15 * time.Minute, + + MaxReservations: 1024, + MaxCircuits: 16, + BufferSize: 2048, + } +} + +func DefaultLimit() *RelayLimit { + return &RelayLimit{ + Duration: time.Minute, + Data: 65536, + } +} From ff9fdfc721482fd2a5da7a46106aa1876a08618c Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 5 Feb 2021 17:38:33 +0200 Subject: [PATCH 20/66] add options for resources/limit --- v2/relay/options.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/v2/relay/options.go b/v2/relay/options.go index 3dccc7f..7cb8f01 100644 --- a/v2/relay/options.go +++ b/v2/relay/options.go @@ -1,3 +1,17 @@ package relay type Option func(*Relay) error + +func WithResources(rc Resources) Option { + return func(r *Relay) error { + r.rc = rc + return nil + } +} + +func WithLimit(limit *RelayLimit) Option { + return func(r *Relay) error { + r.rc.Limit = limit + return nil + } +} From cbe4fcbcb0d964f72cd1c809977dac2b895a6762 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sat, 6 Feb 2021 17:53:33 +0200 Subject: [PATCH 21/66] gc idle conn counts --- v2/relay/relay.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 215c46c..387d0e4 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -457,6 +457,12 @@ func (r *Relay) gc() { delete(r.refresh, p) } } + + for p, count := range r.conns { + if count == 0 { + delete(r.conns, p) + } + } } func (r *Relay) disconnected(n network.Network, c network.Conn) { From e36365e053b26baa34ccea6c142a359d9a13c7ec Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 7 Feb 2021 08:47:00 +0200 Subject: [PATCH 22/66] fix clown shoes in cancellation check --- v2/relay/relay.go | 1 + 1 file changed, 1 insertion(+) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 387d0e4..63757a3 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -94,6 +94,7 @@ func (r *Relay) handleStream(s network.Stream) { case <-r.ctx.Done(): s.Reset() return + default: } s.SetReadDeadline(time.Now().Add(StreamTimeout)) From 1fbd2d4de03cc16e6f84c45416e67959be115afe Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 11 Feb 2021 15:02:47 +0200 Subject: [PATCH 23/66] end to end relay test --- go.mod | 3 + go.sum | 3 + v2/relay/relay.go | 5 +- v2/test/e2e_test.go | 173 ++++++++++++++++++++++++++++++++++++++++++++ v2/util/pbconv.go | 4 +- 5 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 v2/test/e2e_test.go diff --git a/go.mod b/go.mod index e2c3de4..cebe62a 100644 --- a/go.mod +++ b/go.mod @@ -8,9 +8,12 @@ require ( github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-libp2p-blankhost v0.2.0 github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee + github.com/libp2p/go-libp2p-metrics v0.1.0 + github.com/libp2p/go-libp2p-peerstore v0.2.6 github.com/libp2p/go-libp2p-swarm v0.4.1-0.20210204114217-94302e6b940c github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309 github.com/libp2p/go-msgio v0.0.6 + github.com/libp2p/go-tcp-transport v0.2.0 github.com/multiformats/go-multiaddr v0.3.1 github.com/multiformats/go-varint v0.0.6 ) diff --git a/go.sum b/go.sum index 08c4298..3053b46 100644 --- a/go.sum +++ b/go.sum @@ -193,6 +193,8 @@ github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee h1:M3DUy4D github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-metrics v0.1.0 h1:v7YMUTHNobFaQeqaMfJJMbnK3EPlZeb6/KFm4gE9dks= +github.com/libp2p/go-libp2p-metrics v0.1.0/go.mod h1:rpoJmXWFxnj7qs5sJ02sxSzrhaZvpqBn8GCG6Sx6E1k= github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= github.com/libp2p/go-libp2p-mplex v0.4.0 h1:ukojv97fEBM3ffCqXuuve2WSHu1HsA4/omMk1h2KFgc= @@ -439,6 +441,7 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 63757a3..143ab30 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -49,8 +49,8 @@ type Relay struct { conns map[peer.ID]int } -func New(h host.Host, opts ...Option) (*Relay, error) { - ctx, cancel := context.WithCancel(context.Background()) +func New(ctx context.Context, h host.Host, opts ...Option) (*Relay, error) { + ctx, cancel := context.WithCancel(ctx) r := &Relay{ ctx: ctx, @@ -289,6 +289,7 @@ func (r *Relay) handleConnect(s network.Stream, msg *pbv2.HopMessage) { } var response pbv2.HopMessage + response.Type = pbv2.HopMessage_STATUS.Enum() response.Status = pbv2.Status_OK.Enum() response.Limit = r.makeLimitMsg(dest.ID) diff --git a/v2/test/e2e_test.go b/v2/test/e2e_test.go new file mode 100644 index 0000000..3248d75 --- /dev/null +++ b/v2/test/e2e_test.go @@ -0,0 +1,173 @@ +package test + +import ( + "bytes" + "context" + "fmt" + "io" + "testing" + + "github.com/libp2p/go-libp2p-circuit/v2/client" + "github.com/libp2p/go-libp2p-circuit/v2/relay" + + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + logging "github.com/ipfs/go-log" + bhost "github.com/libp2p/go-libp2p-blankhost" + metrics "github.com/libp2p/go-libp2p-metrics" + pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem" + swarm "github.com/libp2p/go-libp2p-swarm" + swarmt "github.com/libp2p/go-libp2p-swarm/testing" + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + tcp "github.com/libp2p/go-tcp-transport" + ma "github.com/multiformats/go-multiaddr" +) + +func init() { + // TODO temporary for debugging purposes; to be removed for merge. + logging.SetLogLevel("relay", "DEBUG") + logging.SetLogLevel("p2p-circuit", "DEBUG") +} + +func getNetHosts(t *testing.T, ctx context.Context, n int) (hosts []host.Host, upgraders []*tptu.Upgrader) { + for i := 0; i < n; i++ { + privk, pubk, err := crypto.GenerateKeyPair(crypto.Ed25519, 0) + if err != nil { + t.Fatal(err) + } + + p, err := peer.IDFromPublicKey(pubk) + if err != nil { + t.Fatal(err) + } + + ps := pstoremem.NewPeerstore() + err = ps.AddPrivKey(p, privk) + if err != nil { + t.Fatal(err) + } + + bwr := metrics.NewBandwidthCounter() + netw := swarm.NewSwarm(ctx, p, ps, bwr) + + upgrader := swarmt.GenUpgrader(netw) + upgraders = append(upgraders, upgrader) + + err = netw.AddTransport(tcp.NewTCPTransport(upgrader)) + if err != nil { + t.Fatal(err) + } + + err = netw.Listen(ma.StringCast("/ip4/127.0.0.1/tcp/0")) + if err != nil { + t.Fatal(err) + } + + h := bhost.NewBlankHost(netw) + + hosts = append(hosts, h) + } + + return hosts, upgraders +} + +func connect(t *testing.T, a, b host.Host) { + pi := peer.AddrInfo{ID: a.ID(), Addrs: a.Addrs()} + err := b.Connect(context.Background(), pi) + if err != nil { + t.Fatal(err) + } +} + +func addTransport(t *testing.T, ctx context.Context, h host.Host, upgrader *tptu.Upgrader) { + err := client.AddTransport(ctx, h, upgrader) + if err != nil { + t.Fatal(err) + } +} + +func TestBasicRelay(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + hosts, upgraders := getNetHosts(t, ctx, 3) + addTransport(t, ctx, hosts[0], upgraders[0]) + addTransport(t, ctx, hosts[2], upgraders[2]) + + rch := make(chan []byte, 1) + hosts[0].SetStreamHandler("test", func(s network.Stream) { + defer s.Close() + defer close(rch) + + buf := make([]byte, 1024) + nread := 0 + for nread < len(buf) { + n, err := s.Read(buf[nread:]) + + fmt.Printf("got %d bytes", n) + + nread += n + if err != nil { + if err == io.EOF { + break + } + t.Fatal(err) + } + } + + rch <- buf[:nread] + }) + + r, err := relay.New(ctx, hosts[1]) + if err != nil { + t.Fatal(err) + } + defer r.Close() + + connect(t, hosts[0], hosts[1]) + connect(t, hosts[1], hosts[2]) + + rinfo := hosts[1].Peerstore().PeerInfo(hosts[1].ID()) + _, err = client.Reserve(ctx, hosts[0], rinfo) + if err != nil { + t.Fatal(err) + } + + raddr, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s/p2p-circuit/p2p/%s", hosts[1].ID(), hosts[0].ID())) + if err != nil { + t.Fatal(err) + } + + err = hosts[2].Connect(ctx, peer.AddrInfo{ID: hosts[0].ID(), Addrs: []ma.Multiaddr{raddr}}) + if err != nil { + t.Fatal(err) + } + + conns := hosts[2].Network().ConnsToPeer(hosts[0].ID()) + if len(conns) != 1 { + t.Fatalf("expected 1 connection, but got %d", len(conns)) + } + if !conns[0].Stat().Transient { + t.Fatal("expected transient connection") + } + + s, err := hosts[2].NewStream(network.WithUseTransient(ctx), hosts[0].ID(), "test") + if err != nil { + t.Fatal(err) + } + + msg := []byte("relay works!") + nwritten, err := s.Write(msg) + if nwritten != len(msg) { + t.Fatalf("expected to write %d bytes, but wrote %d instead", len(msg), nwritten) + } + s.CloseWrite() + + got := <-rch + if !bytes.Equal(msg, got) { + t.Fatalf("Wrong echo; expected %s but got %s", string(msg), string(got)) + } +} diff --git a/v2/util/pbconv.go b/v2/util/pbconv.go index 0a176c4..7caccc5 100644 --- a/v2/util/pbconv.go +++ b/v2/util/pbconv.go @@ -68,8 +68,8 @@ func PeerToPeerInfoV2(p *pbv2.Peer) (peer.AddrInfo, error) { func PeerInfoToPeerV2(pi peer.AddrInfo) *pbv2.Peer { var addrs [][]byte - for i, addr := range pi.Addrs { - addrs[i] = addr.Bytes() + for _, addr := range pi.Addrs { + addrs = append(addrs, addr.Bytes()) } p := new(pbv2.Peer) From 71d18fdcdf54a506afc7dfd21cbc9ad796ec407a Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 11 Feb 2021 23:19:24 +0200 Subject: [PATCH 24/66] untag peers with expired reservations --- v2/relay/relay.go | 1 + 1 file changed, 1 insertion(+) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 143ab30..c125180 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -450,6 +450,7 @@ func (r *Relay) gc() { for p, expire := range r.rsvp { if expire.Before(now) { delete(r.rsvp, p) + r.host.ConnManager().UntagPeer(p, "relay-reservation") } } From c6793869aac75190e6418c25c7088895b8509778 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 12 Feb 2021 11:13:28 +0200 Subject: [PATCH 25/66] add time limit test --- v2/test/e2e_test.go | 76 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/v2/test/e2e_test.go b/v2/test/e2e_test.go index 3248d75..0b2e767 100644 --- a/v2/test/e2e_test.go +++ b/v2/test/e2e_test.go @@ -6,12 +6,14 @@ import ( "fmt" "io" "testing" + "time" "github.com/libp2p/go-libp2p-circuit/v2/client" "github.com/libp2p/go-libp2p-circuit/v2/relay" "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/mux" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" @@ -171,3 +173,77 @@ func TestBasicRelay(t *testing.T) { t.Fatalf("Wrong echo; expected %s but got %s", string(msg), string(got)) } } + +func TestRelayLimitTime(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + hosts, upgraders := getNetHosts(t, ctx, 3) + addTransport(t, ctx, hosts[0], upgraders[0]) + addTransport(t, ctx, hosts[2], upgraders[2]) + + rch := make(chan error, 1) + hosts[0].SetStreamHandler("test", func(s network.Stream) { + defer s.Close() + defer close(rch) + + buf := make([]byte, 1024) + _, err := s.Read(buf) + rch <- err + }) + + rc := relay.DefaultResources() + rc.Limit.Duration = time.Second + + r, err := relay.New(ctx, hosts[1], relay.WithResources(rc)) + if err != nil { + t.Fatal(err) + } + defer r.Close() + + connect(t, hosts[0], hosts[1]) + connect(t, hosts[1], hosts[2]) + + rinfo := hosts[1].Peerstore().PeerInfo(hosts[1].ID()) + _, err = client.Reserve(ctx, hosts[0], rinfo) + if err != nil { + t.Fatal(err) + } + + raddr, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s/p2p-circuit/p2p/%s", hosts[1].ID(), hosts[0].ID())) + if err != nil { + t.Fatal(err) + } + + err = hosts[2].Connect(ctx, peer.AddrInfo{ID: hosts[0].ID(), Addrs: []ma.Multiaddr{raddr}}) + if err != nil { + t.Fatal(err) + } + + conns := hosts[2].Network().ConnsToPeer(hosts[0].ID()) + if len(conns) != 1 { + t.Fatalf("expected 1 connection, but got %d", len(conns)) + } + if !conns[0].Stat().Transient { + t.Fatal("expected transient connection") + } + + s, err := hosts[2].NewStream(network.WithUseTransient(ctx), hosts[0].ID(), "test") + if err != nil { + t.Fatal(err) + } + + time.Sleep(2 * time.Second) + n, err := s.Write([]byte("should be closed")) + if n > 0 { + t.Fatalf("expected to write 0 bytes, wrote %d", n) + } + if err != mux.ErrReset { + t.Fatalf("expected reset, but got %s", err) + } + + err = <-rch + if err != mux.ErrReset { + t.Fatalf("expected reset, but got %s", err) + } +} From 20bdb29a6c2ef44d3b406907a7ec6ddca2975951 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 12 Feb 2021 11:17:53 +0200 Subject: [PATCH 26/66] better debug log for accepted conns --- v2/client/listen.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/v2/client/listen.go b/v2/client/listen.go index 056689a..fcfb9fa 100644 --- a/v2/client/listen.go +++ b/v2/client/listen.go @@ -26,8 +26,7 @@ func (l *Listener) Accept() (manet.Conn, error) { continue } - // TODO: Pretty print. - log.Debugf("accepted relay connection: %q", evt.conn) + log.Debugf("accepted relay connection from %s through %s", evt.conn.remote.ID, evt.conn.RemoteMultiaddr()) evt.conn.tagHop() return evt.conn, nil From d9dd2e8143343f1314ecee95ef05172bcb80e26e Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 12 Feb 2021 11:44:09 +0200 Subject: [PATCH 27/66] add data limit test --- v2/test/e2e_test.go | 104 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/v2/test/e2e_test.go b/v2/test/e2e_test.go index 0b2e767..9a3d702 100644 --- a/v2/test/e2e_test.go +++ b/v2/test/e2e_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "io" + "math/rand" "testing" "time" @@ -247,3 +248,106 @@ func TestRelayLimitTime(t *testing.T) { t.Fatalf("expected reset, but got %s", err) } } + +func TestRelayLimitData(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + hosts, upgraders := getNetHosts(t, ctx, 3) + addTransport(t, ctx, hosts[0], upgraders[0]) + addTransport(t, ctx, hosts[2], upgraders[2]) + + rch := make(chan int, 1) + hosts[0].SetStreamHandler("test", func(s network.Stream) { + defer s.Close() + defer close(rch) + + buf := make([]byte, 4096) + n, err := s.Read(buf) + if err != nil { + t.Fatal(err) + } + rch <- n + + n, err = s.Read(buf) + if err != mux.ErrReset { + t.Fatalf("expected reset but got %s", err) + } + rch <- n + }) + + rc := relay.DefaultResources() + rc.Limit.Duration = time.Second + rc.Limit.Data = 4096 + + r, err := relay.New(ctx, hosts[1], relay.WithResources(rc)) + if err != nil { + t.Fatal(err) + } + defer r.Close() + + connect(t, hosts[0], hosts[1]) + connect(t, hosts[1], hosts[2]) + + rinfo := hosts[1].Peerstore().PeerInfo(hosts[1].ID()) + _, err = client.Reserve(ctx, hosts[0], rinfo) + if err != nil { + t.Fatal(err) + } + + raddr, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s/p2p-circuit/p2p/%s", hosts[1].ID(), hosts[0].ID())) + if err != nil { + t.Fatal(err) + } + + err = hosts[2].Connect(ctx, peer.AddrInfo{ID: hosts[0].ID(), Addrs: []ma.Multiaddr{raddr}}) + if err != nil { + t.Fatal(err) + } + + conns := hosts[2].Network().ConnsToPeer(hosts[0].ID()) + if len(conns) != 1 { + t.Fatalf("expected 1 connection, but got %d", len(conns)) + } + if !conns[0].Stat().Transient { + t.Fatal("expected transient connection") + } + + s, err := hosts[2].NewStream(network.WithUseTransient(ctx), hosts[0].ID(), "test") + if err != nil { + t.Fatal(err) + } + + buf := make([]byte, 1024) + _, err = rand.Read(buf) + if err != nil { + t.Fatal(err) + } + + n, err := s.Write(buf) + if err != nil { + t.Fatal(err) + } + if n != len(buf) { + t.Fatalf("expected to write %d bytes but wrote %d", len(buf), n) + } + + n = <-rch + if n != len(buf) { + t.Fatalf("expected to read %d bytes but read %d", len(buf), n) + } + + buf = make([]byte, 4096) + _, err = rand.Read(buf) + if err != nil { + t.Fatal(err) + } + + s.Write(buf) + + n = <-rch + if n != 0 { + t.Fatalf("expected to read 0 bytes but read %d", n) + } + +} From 529b09fe400e4b74694e4dfe0fe20afdb7c6bf8f Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 12 Feb 2021 19:19:28 +0200 Subject: [PATCH 28/66] add v2-v1 compatibility tests --- v2/test/compat_test.go | 171 +++++++++++++++++++++++++++++++++++++++++ v2/test/e2e_test.go | 3 - v2/util/pbconv.go | 4 +- 3 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 v2/test/compat_test.go diff --git a/v2/test/compat_test.go b/v2/test/compat_test.go new file mode 100644 index 0000000..5fe10e4 --- /dev/null +++ b/v2/test/compat_test.go @@ -0,0 +1,171 @@ +package test + +import ( + "bytes" + "context" + "fmt" + "io" + "testing" + + v1 "github.com/libp2p/go-libp2p-circuit" + + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + + tptu "github.com/libp2p/go-libp2p-transport-upgrader" + ma "github.com/multiformats/go-multiaddr" +) + +func addTransportV1(t *testing.T, ctx context.Context, h host.Host, upgrader *tptu.Upgrader) { + err := v1.AddRelayTransport(ctx, h, upgrader) + if err != nil { + t.Fatal(err) + } +} + +func TestRelayCompatV2DialV1(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + hosts, upgraders := getNetHosts(t, ctx, 3) + addTransportV1(t, ctx, hosts[0], upgraders[0]) + addTransport(t, ctx, hosts[2], upgraders[2]) + + rch := make(chan []byte, 1) + hosts[0].SetStreamHandler("test", func(s network.Stream) { + defer s.Close() + defer close(rch) + + buf := make([]byte, 1024) + nread := 0 + for nread < len(buf) { + n, err := s.Read(buf[nread:]) + nread += n + if err != nil { + if err == io.EOF { + break + } + t.Fatal(err) + } + } + + rch <- buf[:nread] + }) + + _, err := v1.NewRelay(ctx, hosts[1], upgraders[1], v1.OptHop) + if err != nil { + t.Fatal(err) + } + + connect(t, hosts[0], hosts[1]) + connect(t, hosts[1], hosts[2]) + + raddr, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s/p2p-circuit/p2p/%s", hosts[1].ID(), hosts[0].ID())) + if err != nil { + t.Fatal(err) + } + + err = hosts[2].Connect(ctx, peer.AddrInfo{ID: hosts[0].ID(), Addrs: []ma.Multiaddr{raddr}}) + if err != nil { + t.Fatal(err) + } + + conns := hosts[2].Network().ConnsToPeer(hosts[0].ID()) + if len(conns) != 1 { + t.Fatalf("expected 1 connection, but got %d", len(conns)) + } + if conns[0].Stat().Transient { + t.Fatal("expected non transient connection") + } + + s, err := hosts[2].NewStream(ctx, hosts[0].ID(), "test") + if err != nil { + t.Fatal(err) + } + + msg := []byte("relay works!") + nwritten, err := s.Write(msg) + if nwritten != len(msg) { + t.Fatalf("expected to write %d bytes, but wrote %d instead", len(msg), nwritten) + } + s.CloseWrite() + + got := <-rch + if !bytes.Equal(msg, got) { + t.Fatalf("Wrong echo; expected %s but got %s", string(msg), string(got)) + } +} + +func TestRelayCompatV1DialV2(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + hosts, upgraders := getNetHosts(t, ctx, 3) + addTransport(t, ctx, hosts[0], upgraders[0]) + addTransportV1(t, ctx, hosts[2], upgraders[2]) + + rch := make(chan []byte, 1) + hosts[0].SetStreamHandler("test", func(s network.Stream) { + defer s.Close() + defer close(rch) + + buf := make([]byte, 1024) + nread := 0 + for nread < len(buf) { + n, err := s.Read(buf[nread:]) + nread += n + if err != nil { + if err == io.EOF { + break + } + t.Fatal(err) + } + } + + rch <- buf[:nread] + }) + + _, err := v1.NewRelay(ctx, hosts[1], upgraders[1], v1.OptHop) + if err != nil { + t.Fatal(err) + } + + connect(t, hosts[0], hosts[1]) + connect(t, hosts[1], hosts[2]) + + raddr, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s/p2p-circuit/p2p/%s", hosts[1].ID(), hosts[0].ID())) + if err != nil { + t.Fatal(err) + } + + err = hosts[2].Connect(ctx, peer.AddrInfo{ID: hosts[0].ID(), Addrs: []ma.Multiaddr{raddr}}) + if err != nil { + t.Fatal(err) + } + + conns := hosts[2].Network().ConnsToPeer(hosts[0].ID()) + if len(conns) != 1 { + t.Fatalf("expected 1 connection, but got %d", len(conns)) + } + if conns[0].Stat().Transient { + t.Fatal("expected non transient connection") + } + + s, err := hosts[2].NewStream(ctx, hosts[0].ID(), "test") + if err != nil { + t.Fatal(err) + } + + msg := []byte("relay works!") + nwritten, err := s.Write(msg) + if nwritten != len(msg) { + t.Fatalf("expected to write %d bytes, but wrote %d instead", len(msg), nwritten) + } + s.CloseWrite() + + got := <-rch + if !bytes.Equal(msg, got) { + t.Fatalf("Wrong echo; expected %s but got %s", string(msg), string(got)) + } +} diff --git a/v2/test/e2e_test.go b/v2/test/e2e_test.go index 9a3d702..856637e 100644 --- a/v2/test/e2e_test.go +++ b/v2/test/e2e_test.go @@ -109,9 +109,6 @@ func TestBasicRelay(t *testing.T) { nread := 0 for nread < len(buf) { n, err := s.Read(buf[nread:]) - - fmt.Printf("got %d bytes", n) - nread += n if err != nil { if err == io.EOF { diff --git a/v2/util/pbconv.go b/v2/util/pbconv.go index 7caccc5..5a2df0a 100644 --- a/v2/util/pbconv.go +++ b/v2/util/pbconv.go @@ -34,8 +34,8 @@ func PeerToPeerInfoV1(p *pbv1.CircuitRelay_Peer) (peer.AddrInfo, error) { func PeerInfoToPeerV1(pi peer.AddrInfo) *pbv1.CircuitRelay_Peer { var addrs [][]byte - for i, addr := range pi.Addrs { - addrs[i] = addr.Bytes() + for _, addr := range pi.Addrs { + addrs = append(addrs, addr.Bytes()) } p := new(pbv1.CircuitRelay_Peer) From c278b2c13191e49db0ada73a03008bbc549a3a39 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 12 Feb 2021 19:34:23 +0200 Subject: [PATCH 29/66] godocs --- v2/client/reservation.go | 17 ++++++++++++++--- v2/relay/acl.go | 5 +++++ v2/relay/options.go | 2 ++ v2/relay/relay.go | 2 ++ v2/relay/resources.go | 27 ++++++++++++++++++++++----- 5 files changed, 45 insertions(+), 8 deletions(-) diff --git a/v2/client/reservation.go b/v2/client/reservation.go index 8c65bf5..c730203 100644 --- a/v2/client/reservation.go +++ b/v2/client/reservation.go @@ -13,15 +13,26 @@ import ( "github.com/libp2p/go-libp2p-core/peerstore" ) +// Reservation is a struct carrying information about a relay/v2 slot reservation. type Reservation struct { + // Expiration is the expiration time of the reservation Expiration time.Time - Relay peer.AddrInfo + // Relay is the public addresses of the relay, which can be used for constructing + // and advertising relay specific addresses. + Relay peer.AddrInfo + // LimitDuration is the time limit for which the relay will keep a relayed connection + // open. If 0, there is no limit. LimitDuration time.Duration - LimitData int64 + // LimitData is the number of bytes that the relay will relay in each direction before + // resetting a relayed connection. + LimitData int64 + + // TODO reservation voucher } -// Reserve reserves a slot in a relay and returns the reservation information +// Reserve reserves a slot in a relay and returns the reservation information. +// Clients must reserve slots in order for the relay to relay connections to them. func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation, error) { if len(ai.Addrs) > 0 { h.Peerstore().AddAddrs(ai.ID, ai.Addrs, peerstore.TempAddrTTL) diff --git a/v2/relay/acl.go b/v2/relay/acl.go index 202addc..8a6d79c 100644 --- a/v2/relay/acl.go +++ b/v2/relay/acl.go @@ -6,7 +6,12 @@ import ( ma "github.com/multiformats/go-multiaddr" ) +// ACLFilter is an Access Control mechanism for relayed connect. type ACLFilter interface { + // AllowReserve returns true if a reservation from peer a given peer with a given multiaddr + // is allowed. AllowReserve(p peer.ID, a ma.Multiaddr) bool + // AllowConnect returns true if a source peer, with a given multiaddr is allowed to connect + // to a destination peer. AllowConnect(src peer.ID, srcAddr ma.Multiaddr, dest peer.ID) bool } diff --git a/v2/relay/options.go b/v2/relay/options.go index 7cb8f01..49f5acd 100644 --- a/v2/relay/options.go +++ b/v2/relay/options.go @@ -2,6 +2,7 @@ package relay type Option func(*Relay) error +// WithResources is a Relay option that sets specific relay resources for the relay. func WithResources(rc Resources) Option { return func(r *Relay) error { r.rc = rc @@ -9,6 +10,7 @@ func WithResources(rc Resources) Option { } } +// WithLimit is a Relay option that sets only the relayed connection limits for the relay. func WithLimit(limit *RelayLimit) Option { return func(r *Relay) error { r.rc.Limit = limit diff --git a/v2/relay/relay.go b/v2/relay/relay.go index c125180..2382dd0 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -35,6 +35,7 @@ const ( var log = logging.Logger("relay") +// Relay is the (limited) relay service object. type Relay struct { ctx context.Context cancel func() @@ -49,6 +50,7 @@ type Relay struct { conns map[peer.ID]int } +// New constructs a new limited relay that can provide relay services in the given host. func New(ctx context.Context, h host.Host, opts ...Option) (*Relay, error) { ctx, cancel := context.WithCancel(ctx) diff --git a/v2/relay/resources.go b/v2/relay/resources.go index 053f8d6..832e44a 100644 --- a/v2/relay/resources.go +++ b/v2/relay/resources.go @@ -4,22 +4,38 @@ import ( "time" ) +// Resources are the resource limits associated with the relay service. type Resources struct { + // Limit is the (optional) relayed connection limits. Limit *RelayLimit - ReservationTTL time.Duration + // ReservationTTL is the duration of a new (or refreshed reservation). + // Defaults to 1hr. + ReservationTTL time.Duration + // ReservationRefreshTTL is the time that must have ellapsed since the last reservation + // in order to accept a new reservation. If a client attempts to refresh a reservation + // sooner than that, then the refresh will be refused. + // Defaults to 15min. ReservationRefreshTTL time.Duration + // MaxReservations is the maximum number of active relay slots; defaults to 128. MaxReservations int - MaxCircuits int - BufferSize int + // MaxCircuits is the maximum number of open relay connections for each peer; defaults to 16. + MaxCircuits int + // BufferSize is the size of the relayed connection buffers; defaults to 2048. + BufferSize int } +// RelayLimit are the per relayed connection resource limits. type RelayLimit struct { + // Duration is the time limit before resetting a relayed connection; defaults to 1min. Duration time.Duration - Data int64 + // Data is the limit of data relayed (on each direction) before resetting the connection. + // Defaults to 64KB + Data int64 } +// DefaultResources returns a Resources object with the default filled in. func DefaultResources() Resources { return Resources{ Limit: DefaultLimit(), @@ -27,12 +43,13 @@ func DefaultResources() Resources { ReservationTTL: time.Hour, ReservationRefreshTTL: 15 * time.Minute, - MaxReservations: 1024, + MaxReservations: 128, MaxCircuits: 16, BufferSize: 2048, } } +// DefaultLimit returns a RelayLimit object with the defaults filled in. func DefaultLimit() *RelayLimit { return &RelayLimit{ Duration: time.Minute, From 017982ae1a656a4972ba90322d218bbae0ca43cd Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 12 Feb 2021 22:24:33 +0200 Subject: [PATCH 30/66] add WithACL relay option --- v2/relay/options.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/v2/relay/options.go b/v2/relay/options.go index 49f5acd..3464115 100644 --- a/v2/relay/options.go +++ b/v2/relay/options.go @@ -17,3 +17,11 @@ func WithLimit(limit *RelayLimit) Option { return nil } } + +// WithACL is a Relay option that supplies an ACLFilter for access control. +func WithACL(acl ACLFilter) Option { + return func(r *Relay) error { + r.acl = acl + return nil + } +} From 2dda59850d58608db6135f458210f2a6008e8ba1 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sat, 13 Feb 2021 12:01:34 +0200 Subject: [PATCH 31/66] only return public relay addrs in reservation record --- v2/relay/relay.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 2382dd0..7508d8a 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -15,9 +15,9 @@ import ( "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" - pool "github.com/libp2p/go-buffer-pool" - logging "github.com/ipfs/go-log" + pool "github.com/libp2p/go-buffer-pool" + manet "github.com/multiformats/go-multiaddr/net" ) const ( @@ -407,7 +407,12 @@ func (r *Relay) makeReservationMsg(p peer.ID) *pbv2.Reservation { ttl := int32(r.rc.ReservationTTL / time.Second) // TODO cache this - ai := peer.AddrInfo{r.host.ID(), r.host.Addrs()} + ai := peer.AddrInfo{ID: r.host.ID()} + for _, addr := range r.host.Addrs() { + if manet.IsPublicAddr(addr) { + ai.Addrs = append(ai.Addrs, addr) + } + } return &pbv2.Reservation{ Ttl: &ttl, From 96e502e012ae00d1d1cf3c4c254e5e84d2016ec5 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 15 Feb 2021 09:42:52 +0200 Subject: [PATCH 32/66] remove the refresh restriction madness --- v2/relay/relay.go | 43 ++++++++++++------------------------------- v2/relay/resources.go | 8 +------- 2 files changed, 13 insertions(+), 38 deletions(-) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 7508d8a..f6c3080 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -44,10 +44,9 @@ type Relay struct { rc Resources acl ACLFilter - mx sync.Mutex - rsvp map[peer.ID]time.Time - refresh map[peer.ID]time.Time - conns map[peer.ID]int + mx sync.Mutex + rsvp map[peer.ID]time.Time + conns map[peer.ID]int } // New constructs a new limited relay that can provide relay services in the given host. @@ -55,14 +54,13 @@ func New(ctx context.Context, h host.Host, opts ...Option) (*Relay, error) { ctx, cancel := context.WithCancel(ctx) r := &Relay{ - ctx: ctx, - cancel: cancel, - host: h, - rc: DefaultResources(), - acl: nil, - rsvp: make(map[peer.ID]time.Time), - refresh: make(map[peer.ID]time.Time), - conns: make(map[peer.ID]int), + ctx: ctx, + cancel: cancel, + host: h, + rc: DefaultResources(), + acl: nil, + rsvp: make(map[peer.ID]time.Time), + conns: make(map[peer.ID]int), } for _, opt := range opts { @@ -143,18 +141,9 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { r.mx.Lock() now := time.Now() - refresh, exists := r.refresh[p] - if exists && refresh.After(now) { - // extend refresh time, peer is trying too fast - r.refresh[p] = refresh.Add(r.rc.ReservationRefreshTTL) - r.mx.Unlock() - log.Debugf("refusing relay reservation for %s; refreshing too fast", p) - r.handleError(s, pbv2.Status_RESERVATION_REFUSED) - return - } - + _, exists := r.rsvp[p] active := len(r.rsvp) - if active >= r.rc.MaxReservations { + if !exists && active >= r.rc.MaxReservations { r.mx.Unlock() log.Debugf("refusing relay reservation for %s; too many reservations", p) r.handleError(s, pbv2.Status_RESOURCE_LIMIT_EXCEEDED) @@ -162,7 +151,6 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { } r.rsvp[p] = now.Add(r.rc.ReservationTTL) - r.refresh[p] = now.Add(r.rc.ReservationRefreshTTL) r.host.ConnManager().TagPeer(p, "relay-reservation", ReservationTagWeight) r.mx.Unlock() @@ -461,13 +449,6 @@ func (r *Relay) gc() { } } - for p, expire := range r.refresh { - _, rsvp := r.rsvp[p] - if !rsvp && expire.Before(now) { - delete(r.refresh, p) - } - } - for p, count := range r.conns { if count == 0 { delete(r.conns, p) diff --git a/v2/relay/resources.go b/v2/relay/resources.go index 832e44a..5ce468a 100644 --- a/v2/relay/resources.go +++ b/v2/relay/resources.go @@ -12,11 +12,6 @@ type Resources struct { // ReservationTTL is the duration of a new (or refreshed reservation). // Defaults to 1hr. ReservationTTL time.Duration - // ReservationRefreshTTL is the time that must have ellapsed since the last reservation - // in order to accept a new reservation. If a client attempts to refresh a reservation - // sooner than that, then the refresh will be refused. - // Defaults to 15min. - ReservationRefreshTTL time.Duration // MaxReservations is the maximum number of active relay slots; defaults to 128. MaxReservations int @@ -40,8 +35,7 @@ func DefaultResources() Resources { return Resources{ Limit: DefaultLimit(), - ReservationTTL: time.Hour, - ReservationRefreshTTL: 15 * time.Minute, + ReservationTTL: time.Hour, MaxReservations: 128, MaxCircuits: 16, From 6eaf6e19ac13057ff05bf6b0da412d8495237672 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 15 Feb 2021 10:11:48 +0200 Subject: [PATCH 33/66] set default limit Data to 128K --- v2/relay/resources.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2/relay/resources.go b/v2/relay/resources.go index 5ce468a..98c0313 100644 --- a/v2/relay/resources.go +++ b/v2/relay/resources.go @@ -47,6 +47,6 @@ func DefaultResources() Resources { func DefaultLimit() *RelayLimit { return &RelayLimit{ Duration: time.Minute, - Data: 65536, + Data: 1 << 17, // 128K } } From 92c0e0bdebca5d05122590ad425c407790da2da4 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 15 Feb 2021 10:12:01 +0200 Subject: [PATCH 34/66] fix typo in AllowReserve godoc --- v2/relay/acl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2/relay/acl.go b/v2/relay/acl.go index 8a6d79c..1d14e9a 100644 --- a/v2/relay/acl.go +++ b/v2/relay/acl.go @@ -8,7 +8,7 @@ import ( // ACLFilter is an Access Control mechanism for relayed connect. type ACLFilter interface { - // AllowReserve returns true if a reservation from peer a given peer with a given multiaddr + // AllowReserve returns true if a reservation from peer the given peer and the given multiaddr // is allowed. AllowReserve(p peer.ID, a ma.Multiaddr) bool // AllowConnect returns true if a source peer, with a given multiaddr is allowed to connect From 1f294d2bb2b1f9ab8928f1c0dacb9448f4badf52 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 15 Feb 2021 10:13:00 +0200 Subject: [PATCH 35/66] fix some small issues - remove context from constructor - remove stream handler when closing the host - remove the awkward cancellation check from handleStream --- v2/relay/relay.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index f6c3080..d86aced 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -50,8 +50,8 @@ type Relay struct { } // New constructs a new limited relay that can provide relay services in the given host. -func New(ctx context.Context, h host.Host, opts ...Option) (*Relay, error) { - ctx, cancel := context.WithCancel(ctx) +func New(h host.Host, opts ...Option) (*Relay, error) { + ctx, cancel := context.WithCancel(context.Background()) r := &Relay{ ctx: ctx, @@ -84,19 +84,13 @@ func (r *Relay) Close() error { select { case <-r.ctx.Done(): default: + r.host.RemoveStreamHandler(ProtoIDv2Hop) r.cancel() } return nil } func (r *Relay) handleStream(s network.Stream) { - select { - case <-r.ctx.Done(): - s.Reset() - return - default: - } - s.SetReadDeadline(time.Now().Add(StreamTimeout)) log.Infof("new relay stream from: %s", s.Conn().RemotePeer()) From 13a9ed784ada53c95d36a75c49ca953af93391ba Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 15 Feb 2021 10:13:06 +0200 Subject: [PATCH 36/66] fix tests --- v2/test/e2e_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/v2/test/e2e_test.go b/v2/test/e2e_test.go index 856637e..bffc224 100644 --- a/v2/test/e2e_test.go +++ b/v2/test/e2e_test.go @@ -121,7 +121,7 @@ func TestBasicRelay(t *testing.T) { rch <- buf[:nread] }) - r, err := relay.New(ctx, hosts[1]) + r, err := relay.New(hosts[1]) if err != nil { t.Fatal(err) } @@ -193,7 +193,7 @@ func TestRelayLimitTime(t *testing.T) { rc := relay.DefaultResources() rc.Limit.Duration = time.Second - r, err := relay.New(ctx, hosts[1], relay.WithResources(rc)) + r, err := relay.New(hosts[1], relay.WithResources(rc)) if err != nil { t.Fatal(err) } @@ -277,7 +277,7 @@ func TestRelayLimitData(t *testing.T) { rc.Limit.Duration = time.Second rc.Limit.Data = 4096 - r, err := relay.New(ctx, hosts[1], relay.WithResources(rc)) + r, err := relay.New(hosts[1], relay.WithResources(rc)) if err != nil { t.Fatal(err) } From 6c7540c57a810a3e40ca75db9dc44026e0be4436 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 15 Feb 2021 12:24:20 +0200 Subject: [PATCH 37/66] address review comments - Add deadline for Reserve calls - Add deadline for dials - Add some comments for things that confuse aarsh. --- v2/client/client.go | 8 ++++++++ v2/client/conn.go | 8 +++++++- v2/client/dial.go | 8 ++++++++ v2/client/handlers.go | 2 ++ v2/client/reservation.go | 4 ++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/v2/client/client.go b/v2/client/client.go index a8fddf9..d326516 100644 --- a/v2/client/client.go +++ b/v2/client/client.go @@ -19,6 +19,14 @@ const ( var log = logging.Logger("p2p-circuit") +// Client implements the client-side of the p2p-circuit/v2 protocol: +// - it implements dialing through v2 relays +// - it listens for incoming connections through v2 relays. +// +// For backwards compatibility with v1 relays and older nodes, the client will +// also accept relay connections through v1 relays and fallback dial peers using p2p-circuit/v1. +// This allows us to use the v2 code as drop in replacement for v1 in a host without breaking +// existing code and interoperability with older nodes. type Client struct { ctx context.Context host host.Host diff --git a/v2/client/conn.go b/v2/client/conn.go index 51fa0f8..dc77076 100644 --- a/v2/client/conn.go +++ b/v2/client/conn.go @@ -114,7 +114,11 @@ func (c *Conn) Stat() network.Stat { return c.stat } -// conn manager hop tagging +// tagHop tags the underlying relay connection so that it can be (somewhat) protected from the +// connection manager as it is an important connection that proxies other connections. +// This is handled here so that the user code doesnt need to bother with this and avoid +// clown shoes situations where a high value peer connection is behind a relayed connection and it is +// implicitly because the connection manager closed the underlying relay connection. func (c *Conn) tagHop() { c.client.mx.Lock() defer c.client.mx.Unlock() @@ -126,6 +130,8 @@ func (c *Conn) tagHop() { } } +// untagHop removes the relay-hop-stream tag if necessary; it is invoked when a relayed connection +// is closed. func (c *Conn) untagHop() { c.client.mx.Lock() defer c.client.mx.Unlock() diff --git a/v2/client/dial.go b/v2/client/dial.go index 980e818..56c1e5a 100644 --- a/v2/client/dial.go +++ b/v2/client/dial.go @@ -18,6 +18,8 @@ import ( const maxMessageSize = 4096 +var DialTimeout = time.Minute + func (c *Client) dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (*Conn, error) { // split /a/p2p-circuit/b into (/a, /p2p-circuit/b) relayaddr, destaddr := ma.SplitFunc(a, func(c ma.Component) bool { @@ -85,6 +87,8 @@ func (c *Client) connectV2(s network.Stream, dest peer.AddrInfo) (*Conn, error) msg.Type = pbv2.HopMessage_CONNECT.Enum() msg.Peer = util.PeerInfoToPeerV2(dest) + s.SetDeadline(time.Now().Add(DialTimeout)) + err := wr.WriteMsg(&msg) if err != nil { s.Reset() @@ -99,6 +103,8 @@ func (c *Client) connectV2(s network.Stream, dest peer.AddrInfo) (*Conn, error) return nil, err } + s.SetDeadline(time.Time{}) + if msg.GetType() != pbv2.HopMessage_STATUS { s.Reset() return nil, fmt.Errorf("unexpected relay response; not a status message (%d)", msg.GetType()) @@ -110,6 +116,8 @@ func (c *Client) connectV2(s network.Stream, dest peer.AddrInfo) (*Conn, error) return nil, fmt.Errorf("error opening relay circuit: %s (%d)", pbv2.Status_name[int32(status)], status) } + // check for a limit provided by the relay; if the limit is not nil, then this is a limited + // relay connection and we mark the connection as transient. var stat network.Stat if limit := msg.GetLimit(); limit != nil { stat.Transient = true diff --git a/v2/client/handlers.go b/v2/client/handlers.go index 7ace6ac..9239fce 100644 --- a/v2/client/handlers.go +++ b/v2/client/handlers.go @@ -65,6 +65,8 @@ func (c *Client) handleStreamV2(s network.Stream) { return } + // check for a limit provided by the relay; if the limit is not nil, then this is a limited + // relay connection and we mark the connection as transient. var stat network.Stat if limit := msg.GetLimit(); limit != nil { stat.Transient = true diff --git a/v2/client/reservation.go b/v2/client/reservation.go index c730203..5277396 100644 --- a/v2/client/reservation.go +++ b/v2/client/reservation.go @@ -13,6 +13,8 @@ import ( "github.com/libp2p/go-libp2p-core/peerstore" ) +var ReserveTimeout = time.Minute + // Reservation is a struct carrying information about a relay/v2 slot reservation. type Reservation struct { // Expiration is the expiration time of the reservation @@ -51,6 +53,8 @@ func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation, var msg pbv2.HopMessage msg.Type = pbv2.HopMessage_RESERVE.Enum() + s.SetDeadline(time.Now().Add(ReserveTimeout)) + if err := wr.WriteMsg(&msg); err != nil { s.Reset() return nil, fmt.Errorf("error writing reservation message: %w", err) From 3087bec0c399d557ed2b4a5b3c5265b594a80ba8 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 15 Feb 2021 16:19:28 +0200 Subject: [PATCH 38/66] humor aarsh and add initializers for slices --- v2/util/pbconv.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/v2/util/pbconv.go b/v2/util/pbconv.go index 5a2df0a..51f3bab 100644 --- a/v2/util/pbconv.go +++ b/v2/util/pbconv.go @@ -22,6 +22,10 @@ func PeerToPeerInfoV1(p *pbv1.CircuitRelay_Peer) (peer.AddrInfo, error) { } var addrs []ma.Multiaddr + if len(p.Addrs) > 0 { + addrs = make([]ma.Multiaddr, len(p.Addrs)) + } + for _, addrBytes := range p.Addrs { a, err := ma.NewMultiaddrBytes(addrBytes) if err == nil { @@ -34,6 +38,10 @@ func PeerToPeerInfoV1(p *pbv1.CircuitRelay_Peer) (peer.AddrInfo, error) { func PeerInfoToPeerV1(pi peer.AddrInfo) *pbv1.CircuitRelay_Peer { var addrs [][]byte + if len(pi.Addrs) > 0 { + addrs = make([][]byte, len(pi.Addrs)) + } + for _, addr := range pi.Addrs { addrs = append(addrs, addr.Bytes()) } @@ -56,6 +64,10 @@ func PeerToPeerInfoV2(p *pbv2.Peer) (peer.AddrInfo, error) { } var addrs []ma.Multiaddr + if len(p.Addrs) > 0 { + addrs = make([]ma.Multiaddr, len(p.Addrs)) + } + for _, addrBytes := range p.Addrs { a, err := ma.NewMultiaddrBytes(addrBytes) if err == nil { @@ -68,6 +80,11 @@ func PeerToPeerInfoV2(p *pbv2.Peer) (peer.AddrInfo, error) { func PeerInfoToPeerV2(pi peer.AddrInfo) *pbv2.Peer { var addrs [][]byte + + if len(pi.Addrs) > 0 { + addrs = make([][]byte, len(pi.Addrs)) + } + for _, addr := range pi.Addrs { addrs = append(addrs, addr.Bytes()) } From b47c1193482deac758c2ed00e829f0c239cc572c Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 15 Feb 2021 16:21:19 +0200 Subject: [PATCH 39/66] comment nitpicks --- v2/relay/acl.go | 2 +- v2/relay/resources.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/v2/relay/acl.go b/v2/relay/acl.go index 1d14e9a..0501051 100644 --- a/v2/relay/acl.go +++ b/v2/relay/acl.go @@ -8,7 +8,7 @@ import ( // ACLFilter is an Access Control mechanism for relayed connect. type ACLFilter interface { - // AllowReserve returns true if a reservation from peer the given peer and the given multiaddr + // AllowReserve returns true if a reservation from a peer with the given peer ID and multiaddr // is allowed. AllowReserve(p peer.ID, a ma.Multiaddr) bool // AllowConnect returns true if a source peer, with a given multiaddr is allowed to connect diff --git a/v2/relay/resources.go b/v2/relay/resources.go index 98c0313..f44be68 100644 --- a/v2/relay/resources.go +++ b/v2/relay/resources.go @@ -26,7 +26,7 @@ type RelayLimit struct { // Duration is the time limit before resetting a relayed connection; defaults to 1min. Duration time.Duration // Data is the limit of data relayed (on each direction) before resetting the connection. - // Defaults to 64KB + // Defaults to 128KB Data int64 } From 82f38081ecb22282c6bc9e111082bc386a4348f8 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 15 Feb 2021 19:45:48 +0200 Subject: [PATCH 40/66] fix bug in slice pre-allocations --- v2/util/pbconv.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/v2/util/pbconv.go b/v2/util/pbconv.go index 51f3bab..a5d7690 100644 --- a/v2/util/pbconv.go +++ b/v2/util/pbconv.go @@ -23,7 +23,7 @@ func PeerToPeerInfoV1(p *pbv1.CircuitRelay_Peer) (peer.AddrInfo, error) { var addrs []ma.Multiaddr if len(p.Addrs) > 0 { - addrs = make([]ma.Multiaddr, len(p.Addrs)) + addrs = make([]ma.Multiaddr, 0, len(p.Addrs)) } for _, addrBytes := range p.Addrs { @@ -39,7 +39,7 @@ func PeerToPeerInfoV1(p *pbv1.CircuitRelay_Peer) (peer.AddrInfo, error) { func PeerInfoToPeerV1(pi peer.AddrInfo) *pbv1.CircuitRelay_Peer { var addrs [][]byte if len(pi.Addrs) > 0 { - addrs = make([][]byte, len(pi.Addrs)) + addrs = make([][]byte, 0, len(pi.Addrs)) } for _, addr := range pi.Addrs { @@ -65,7 +65,7 @@ func PeerToPeerInfoV2(p *pbv2.Peer) (peer.AddrInfo, error) { var addrs []ma.Multiaddr if len(p.Addrs) > 0 { - addrs = make([]ma.Multiaddr, len(p.Addrs)) + addrs = make([]ma.Multiaddr, 0, len(p.Addrs)) } for _, addrBytes := range p.Addrs { @@ -82,7 +82,7 @@ func PeerInfoToPeerV2(pi peer.AddrInfo) *pbv2.Peer { var addrs [][]byte if len(pi.Addrs) > 0 { - addrs = make([][]byte, len(pi.Addrs)) + addrs = make([][]byte, 0, len(pi.Addrs)) } for _, addr := range pi.Addrs { From 57b0a296f2faf18b67e12d91c9b3bcaa1c40c2ae Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 16 Feb 2021 17:13:24 +0200 Subject: [PATCH 41/66] add deadline to connectV1 --- v2/client/dial.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/v2/client/dial.go b/v2/client/dial.go index 56c1e5a..b448e3d 100644 --- a/v2/client/dial.go +++ b/v2/client/dial.go @@ -140,6 +140,8 @@ func (c *Client) connectV1(s network.Stream, dest peer.AddrInfo) (*Conn, error) msg.SrcPeer = util.PeerInfoToPeerV1(c.host.Peerstore().PeerInfo(c.host.ID())) msg.DstPeer = util.PeerInfoToPeerV1(dest) + s.SetDeadline(time.Now().Add(DialTimeout)) + err := wr.WriteMsg(&msg) if err != nil { s.Reset() @@ -154,6 +156,8 @@ func (c *Client) connectV1(s network.Stream, dest peer.AddrInfo) (*Conn, error) return nil, err } + s.SetDeadline(time.Time{}) + if msg.GetType() != pbv1.CircuitRelay_STATUS { s.Reset() return nil, fmt.Errorf("unexpected relay response; not a status message (%d)", msg.GetType()) From 6fed031ad1739c1d5ed70ac3cde345a620c4d29a Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 16 Feb 2021 17:15:47 +0200 Subject: [PATCH 42/66] make Relay.Close thread-safe --- v2/relay/relay.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index d86aced..13bc648 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -37,6 +37,7 @@ var log = logging.Logger("relay") // Relay is the (limited) relay service object. type Relay struct { + closed uint32 ctx context.Context cancel func() @@ -81,9 +82,7 @@ func New(h host.Host, opts ...Option) (*Relay, error) { } func (r *Relay) Close() error { - select { - case <-r.ctx.Done(): - default: + if atomic.CompareAndSwapUint32(&r.closed, 0, 1) { r.host.RemoveStreamHandler(ProtoIDv2Hop) r.cancel() } From 7e8bef0b1a8da5f9918844b868f48265651bcf4e Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 16 Feb 2021 18:09:38 +0200 Subject: [PATCH 43/66] untag peers with reservations when closing the relay --- v2/relay/relay.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 13bc648..962f65a 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -85,6 +85,11 @@ func (r *Relay) Close() error { if atomic.CompareAndSwapUint32(&r.closed, 0, 1) { r.host.RemoveStreamHandler(ProtoIDv2Hop) r.cancel() + r.mx.Lock() + for p := range r.rsvp { + r.host.ConnManager().UntagPeer(p, "relay-reservation") + } + r.mx.Unlock() } return nil } From 49e964928ba423e5705ecfe537ddbde9c5284797 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 16 Feb 2021 21:37:10 +0200 Subject: [PATCH 44/66] gomod: get go-libp2p-asn-util --- go.mod | 1 + go.sum | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/go.mod b/go.mod index cebe62a..719d7b9 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/gogo/protobuf v1.3.1 github.com/ipfs/go-log v1.0.4 github.com/libp2p/go-buffer-pool v0.0.2 + github.com/libp2p/go-libp2p-asn-util v0.0.0-20210211060025-0db24c10d3bd github.com/libp2p/go-libp2p-blankhost v0.2.0 github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee github.com/libp2p/go-libp2p-metrics v0.1.0 diff --git a/go.sum b/go.sum index 3053b46..c3d86ce 100644 --- a/go.sum +++ b/go.sum @@ -125,9 +125,11 @@ github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= @@ -170,6 +172,8 @@ github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwn github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= +github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M= github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= @@ -177,6 +181,8 @@ github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVh github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= +github.com/libp2p/go-libp2p-asn-util v0.0.0-20210211060025-0db24c10d3bd h1:4+wRQ07VJe0ogkb74jFJwhiPuuSbSY1zSUl+tFlNbpg= +github.com/libp2p/go-libp2p-asn-util v0.0.0-20210211060025-0db24c10d3bd/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= github.com/libp2p/go-libp2p-blankhost v0.2.0 h1:3EsGAi0CBGcZ33GwRuXEYJLLPoVWyXJ1bcJzAJjINkk= github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= From 5b7a615dc6e3cc99409ef377fb3210b5e98e236a Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 16 Feb 2021 21:55:00 +0200 Subject: [PATCH 45/66] add IP/ASN reservation constraints --- go.sum | 1 + v2/relay/ipcs.go | 110 ++++++++++++++++++++++++++++++++++++++++++ v2/relay/relay.go | 26 +++++++--- v2/relay/resources.go | 10 ++++ v2/test/ipcs_test.go | 69 ++++++++++++++++++++++++++ 5 files changed, 210 insertions(+), 6 deletions(-) create mode 100644 v2/relay/ipcs.go create mode 100644 v2/test/ipcs_test.go diff --git a/go.sum b/go.sum index c3d86ce..7bd72a7 100644 --- a/go.sum +++ b/go.sum @@ -125,6 +125,7 @@ github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= diff --git a/v2/relay/ipcs.go b/v2/relay/ipcs.go new file mode 100644 index 0000000..167e08e --- /dev/null +++ b/v2/relay/ipcs.go @@ -0,0 +1,110 @@ +package relay + +import ( + "errors" + "net" + + "github.com/libp2p/go-libp2p-core/peer" + + asnutil "github.com/libp2p/go-libp2p-asn-util" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" +) + +var ( + ErrNoIP = errors.New("no IP address associated with peer") + ErrTooManyPeersInIP = errors.New("too many peers in IP address") + ErrTooManyPeersInASN = errors.New("too many peers in ASN") +) + +// IPConstraints implements reservation constraints per IP +type IPConstraints struct { + iplimit, asnlimit int + + peers map[peer.ID]net.IP + ips map[string]map[peer.ID]struct{} + asns map[string]map[peer.ID]struct{} +} + +// NewIPConstraints creates a new IPConstraints object. +// The methods are *not* thread-safe; an external lock must be held if synchronization +// is required. +func NewIPConstraints(rc Resources) *IPConstraints { + return &IPConstraints{ + iplimit: rc.MaxReservationsPerIP, + asnlimit: rc.MaxReservationsPerASN, + + peers: make(map[peer.ID]net.IP), + ips: make(map[string]map[peer.ID]struct{}), + asns: make(map[string]map[peer.ID]struct{}), + } +} + +// AddReservation adds a reservation for a given peer with a given multiaddr. +// If adding this reservation violates IP constraints, an error is returned. +func (ipcs *IPConstraints) AddReservation(p peer.ID, a ma.Multiaddr) error { + ip, err := manet.ToIP(a) + if err != nil { + return ErrNoIP + } + + ips := ip.String() + peersInIP := ipcs.ips[ips] + if len(peersInIP) >= ipcs.iplimit { + return ErrTooManyPeersInIP + } + + var peersInAsn map[peer.ID]struct{} + asn, _ := asnutil.Store.AsnForIPv6(ip) + peersInAsn = ipcs.asns[asn] + if len(peersInAsn) >= ipcs.asnlimit { + return ErrTooManyPeersInASN + } + + ipcs.peers[p] = ip + + if peersInIP == nil { + peersInIP = make(map[peer.ID]struct{}) + ipcs.ips[ips] = peersInIP + } + peersInIP[p] = struct{}{} + + if asn != "" { + if peersInAsn == nil { + peersInAsn = make(map[peer.ID]struct{}) + ipcs.asns[asn] = peersInAsn + } + peersInAsn[p] = struct{}{} + } + + return nil +} + +// RemoveReservation removes a peer from the constraints. +func (ipcs *IPConstraints) RemoveReservation(p peer.ID) { + ip, ok := ipcs.peers[p] + if !ok { + return + } + + ips := ip.String() + asn, _ := asnutil.Store.AsnForIPv6(ip) + + delete(ipcs.peers, p) + + peersInIP, ok := ipcs.ips[ips] + if ok { + delete(peersInIP, p) + if len(peersInIP) == 0 { + delete(ipcs.ips, ips) + } + } + + peersInAsn, ok := ipcs.asns[asn] + if ok { + delete(peersInAsn, p) + if len(peersInAsn) == 0 { + delete(ipcs.asns, asn) + } + } +} diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 962f65a..f4a78db 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -44,6 +44,7 @@ type Relay struct { host host.Host rc Resources acl ACLFilter + ipcs *IPConstraints mx sync.Mutex rsvp map[peer.ID]time.Time @@ -71,6 +72,8 @@ func New(h host.Host, opts ...Option) (*Relay, error) { } } + r.ipcs = NewIPConstraints(r.rc) + h.SetStreamHandler(ProtoIDv2Hop, r.handleStream) h.Network().Notify( &network.NotifyBundle{ @@ -140,12 +143,20 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { now := time.Now() _, exists := r.rsvp[p] - active := len(r.rsvp) - if !exists && active >= r.rc.MaxReservations { - r.mx.Unlock() - log.Debugf("refusing relay reservation for %s; too many reservations", p) - r.handleError(s, pbv2.Status_RESOURCE_LIMIT_EXCEEDED) - return + if !exists { + active := len(r.rsvp) + if active >= r.rc.MaxReservations { + r.mx.Unlock() + log.Debugf("refusing relay reservation for %s; too many reservations", p) + r.handleError(s, pbv2.Status_RESERVATION_REFUSED) + return + } + if err := r.ipcs.AddReservation(p, a); err != nil { + r.mx.Unlock() + log.Debugf("refusing relay reservation for %s; IP constraint violation: %s", p, err) + r.handleError(s, pbv2.Status_RESERVATION_REFUSED) + return + } } r.rsvp[p] = now.Add(r.rc.ReservationTTL) @@ -160,6 +171,7 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { log.Debugf("error writing reservation response; retracting reservation for %s", p) r.mx.Lock() delete(r.rsvp, p) + r.ipcs.RemoveReservation(p) r.host.ConnManager().UntagPeer(p, "relay-reservation") r.mx.Unlock() } @@ -443,6 +455,7 @@ func (r *Relay) gc() { for p, expire := range r.rsvp { if expire.Before(now) { delete(r.rsvp, p) + r.ipcs.RemoveReservation(p) r.host.ConnManager().UntagPeer(p, "relay-reservation") } } @@ -464,4 +477,5 @@ func (r *Relay) disconnected(n network.Network, c network.Conn) { defer r.mx.Unlock() delete(r.rsvp, p) + r.ipcs.RemoveReservation(p) } diff --git a/v2/relay/resources.go b/v2/relay/resources.go index f44be68..9c478a1 100644 --- a/v2/relay/resources.go +++ b/v2/relay/resources.go @@ -19,6 +19,13 @@ type Resources struct { MaxCircuits int // BufferSize is the size of the relayed connection buffers; defaults to 2048. BufferSize int + + // MaxReservationsPerIP is the maximum number of reservations originating from the same + // IP address; default is 4. + MaxReservationsPerIP int + // MaxReservationsPerASN is the maximum number of reservations origination from the same + // ASN; default is 32 + MaxReservationsPerASN int } // RelayLimit are the per relayed connection resource limits. @@ -40,6 +47,9 @@ func DefaultResources() Resources { MaxReservations: 128, MaxCircuits: 16, BufferSize: 2048, + + MaxReservationsPerIP: 4, + MaxReservationsPerASN: 32, } } diff --git a/v2/test/ipcs_test.go b/v2/test/ipcs_test.go new file mode 100644 index 0000000..09a1a9b --- /dev/null +++ b/v2/test/ipcs_test.go @@ -0,0 +1,69 @@ +package test + +import ( + "fmt" + "net" + "testing" + + "github.com/libp2p/go-libp2p-circuit/v2/relay" + + "github.com/libp2p/go-libp2p-core/peer" + + ma "github.com/multiformats/go-multiaddr" +) + +func TestIPConstraints(t *testing.T) { + ipcs := relay.NewIPConstraints(relay.Resources{ + MaxReservationsPerIP: 1, + MaxReservationsPerASN: 2, + }) + + peerA := peer.ID("A") + peerB := peer.ID("B") + peerC := peer.ID("C") + peerD := peer.ID("D") + peerE := peer.ID("E") + + ipA := net.ParseIP("1.2.3.4") + ipB := ipA + ipC := net.ParseIP("2001:200::1") + ipD := net.ParseIP("2001:200::2") + ipE := net.ParseIP("2001:200::3") + + err := ipcs.AddReservation(peerA, ma.StringCast(fmt.Sprintf("/ip4/%s/tcp/1234", ipA))) + if err != nil { + t.Fatal(err) + } + + err = ipcs.AddReservation(peerB, ma.StringCast(fmt.Sprintf("/ip4/%s/tcp/1234", ipB))) + if err != relay.ErrTooManyPeersInIP { + t.Fatalf("unexpected error: %s", err) + } + + ipcs.RemoveReservation(peerA) + err = ipcs.AddReservation(peerB, ma.StringCast(fmt.Sprintf("/ip4/%s/tcp/1234", ipB))) + if err != nil { + t.Fatal(err) + } + + err = ipcs.AddReservation(peerC, ma.StringCast(fmt.Sprintf("/ip6/%s/tcp/1234", ipC))) + if err != nil { + t.Fatal(err) + } + + err = ipcs.AddReservation(peerD, ma.StringCast(fmt.Sprintf("/ip6/%s/tcp/1234", ipD))) + if err != nil { + t.Fatal(err) + } + + err = ipcs.AddReservation(peerE, ma.StringCast(fmt.Sprintf("/ip6/%s/tcp/1234", ipE))) + if err != relay.ErrTooManyPeersInASN { + t.Fatalf("unexpected error: %s", err) + } + + ipcs.RemoveReservation(peerD) + err = ipcs.AddReservation(peerE, ma.StringCast(fmt.Sprintf("/ip6/%s/tcp/1234", ipE))) + if err != nil { + t.Fatal(err) + } +} From 638945365792db660b1651dbd65ccc852832f519 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 17 Feb 2021 12:26:09 +0200 Subject: [PATCH 46/66] gomod: update deps --- go.mod | 6 +++--- go.sum | 31 +++++++++++++++++-------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index 719d7b9..16815d8 100644 --- a/go.mod +++ b/go.mod @@ -8,11 +8,11 @@ require ( github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-libp2p-asn-util v0.0.0-20210211060025-0db24c10d3bd github.com/libp2p/go-libp2p-blankhost v0.2.0 - github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee + github.com/libp2p/go-libp2p-core v0.8.2 github.com/libp2p/go-libp2p-metrics v0.1.0 github.com/libp2p/go-libp2p-peerstore v0.2.6 - github.com/libp2p/go-libp2p-swarm v0.4.1-0.20210204114217-94302e6b940c - github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309 + github.com/libp2p/go-libp2p-swarm v0.4.2 + github.com/libp2p/go-libp2p-transport-upgrader v0.4.2 github.com/libp2p/go-msgio v0.0.6 github.com/libp2p/go-tcp-transport v0.2.0 github.com/multiformats/go-multiaddr v0.3.1 diff --git a/go.sum b/go.sum index 7bd72a7..634ad89 100644 --- a/go.sum +++ b/go.sum @@ -175,8 +175,8 @@ github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOS github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M= -github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= +github.com/libp2p/go-conn-security-multistream v0.2.1 h1:ft6/POSK7F+vl/2qzegnHDaXFU0iWB4yVTYrioC6Zy0= +github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= @@ -195,44 +195,46 @@ github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee h1:M3DUy4DHSFAlYAftWF/vosJM3lnyTQM9UXA9pe0N5RU= -github.com/libp2p/go-libp2p-core v0.8.1-0.20210204112723-43260f46b7ee/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.2 h1:/eaSZACWftJZYm07S0nRxdI84v1hSmgnCXrGOvJdpNQ= +github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= github.com/libp2p/go-libp2p-metrics v0.1.0 h1:v7YMUTHNobFaQeqaMfJJMbnK3EPlZeb6/KFm4gE9dks= github.com/libp2p/go-libp2p-metrics v0.1.0/go.mod h1:rpoJmXWFxnj7qs5sJ02sxSzrhaZvpqBn8GCG6Sx6E1k= github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= -github.com/libp2p/go-libp2p-mplex v0.4.0 h1:ukojv97fEBM3ffCqXuuve2WSHu1HsA4/omMk1h2KFgc= -github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= +github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc= +github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes9v7In4+Qq3U= github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-quic-transport v0.10.0 h1:koDCbWD9CCHwcHZL3/WEvP2A+e/o5/W5L3QS/2SPMA0= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= -github.com/libp2p/go-libp2p-swarm v0.4.1-0.20210204114217-94302e6b940c h1:nOWDDMDP1wvzC94+t5TXk33wDAns7LQWjaiGclaYt64= -github.com/libp2p/go-libp2p-swarm v0.4.1-0.20210204114217-94302e6b940c/go.mod h1:IFaCw0U+is7U1+9ysFWBAalLeYMRhMqO6ttuIawJZB4= +github.com/libp2p/go-libp2p-swarm v0.4.2 h1:rwZUsls+8dImHCcO2LZEa9+QGVF2tBSkywnA0PIYEJg= +github.com/libp2p/go-libp2p-swarm v0.4.2/go.mod h1:gNfZcYwyQJPNKEz3iyPfgwIJu7flqyBQOfCW+8paNCM= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= +github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= github.com/libp2p/go-libp2p-testing v0.4.0 h1:PrwHRi0IGqOwVQWR3xzgigSlhlLfxgfXgkHxr77EghQ= github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= -github.com/libp2p/go-libp2p-transport-upgrader v0.4.0/go.mod h1:J4ko0ObtZSmgn5BX5AmegP+dK3CSnU2lMCKsSq/EY0s= -github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309 h1:XxFG5lVqdn/o0/7F51XiT6xnvCltayYagaANzNPg/jw= -github.com/libp2p/go-libp2p-transport-upgrader v0.4.1-0.20210204114647-8d056c06e309/go.mod h1:wFqIXZJ8k08YwnioC9twyokMXpewf2LKRQYtm34Y/T8= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.2 h1:4JsnbfJzgZeRS9AWN7B9dPqn/LY/HoQTlO9gtdJTIYM= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-yamux v0.5.0 h1:ZzmUhbQE+X7NuYUT2naxN31JyebZfRmpZVhKtRP13ys= github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= -github.com/libp2p/go-mplex v0.2.0 h1:Ov/D+8oBlbRkjBs1R1Iua8hJ8cUfbdiW8EOdZuxcgaI= -github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-mplex v0.3.0 h1:U1T+vmCYJaEoDJPV1aq31N56hS+lJgb397GsylNSgrU= +github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.6 h1:lQ7Uc0kS1wb1EfRxO2Eir/RJoHkHn7t6o+EiwsYIKJA= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= @@ -322,8 +324,9 @@ github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpK github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.14 h1:QoBceQYQQtNUuf6s7wHxnE2c8bhbMqhfGzNI032se/I= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multistream v0.1.1 h1:JlAdpIFhBhGRLxe9W6Om0w++Gd6KMWoFPZL/dEnm9nI= github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= +github.com/multiformats/go-multistream v0.2.1 h1:R5exp4cKvGlePuxg/bn4cnV53K4DxCe+uldxs7QzfrE= +github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= 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/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= From 148d307e4bf190ad9f628a5f0dc84e6ad8cb80cf Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 17 Feb 2021 12:26:16 +0200 Subject: [PATCH 47/66] fix e2e test --- v2/test/e2e_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/v2/test/e2e_test.go b/v2/test/e2e_test.go index bffc224..47cb784 100644 --- a/v2/test/e2e_test.go +++ b/v2/test/e2e_test.go @@ -154,7 +154,7 @@ func TestBasicRelay(t *testing.T) { t.Fatal("expected transient connection") } - s, err := hosts[2].NewStream(network.WithUseTransient(ctx), hosts[0].ID(), "test") + s, err := hosts[2].NewStream(network.WithUseTransient(ctx, "test"), hosts[0].ID(), "test") if err != nil { t.Fatal(err) } @@ -226,7 +226,7 @@ func TestRelayLimitTime(t *testing.T) { t.Fatal("expected transient connection") } - s, err := hosts[2].NewStream(network.WithUseTransient(ctx), hosts[0].ID(), "test") + s, err := hosts[2].NewStream(network.WithUseTransient(ctx, "test"), hosts[0].ID(), "test") if err != nil { t.Fatal(err) } @@ -310,7 +310,7 @@ func TestRelayLimitData(t *testing.T) { t.Fatal("expected transient connection") } - s, err := hosts[2].NewStream(network.WithUseTransient(ctx), hosts[0].ID(), "test") + s, err := hosts[2].NewStream(network.WithUseTransient(ctx, "test"), hosts[0].ID(), "test") if err != nil { t.Fatal(err) } From 68d07f50a4ec2f736e38d0adafd1185e43b39d66 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 18 Feb 2021 12:01:52 +0200 Subject: [PATCH 48/66] increase default limit duration to 2min --- v2/relay/resources.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/v2/relay/resources.go b/v2/relay/resources.go index 9c478a1..345b527 100644 --- a/v2/relay/resources.go +++ b/v2/relay/resources.go @@ -30,7 +30,7 @@ type Resources struct { // RelayLimit are the per relayed connection resource limits. type RelayLimit struct { - // Duration is the time limit before resetting a relayed connection; defaults to 1min. + // Duration is the time limit before resetting a relayed connection; defaults to 2min. Duration time.Duration // Data is the limit of data relayed (on each direction) before resetting the connection. // Defaults to 128KB @@ -56,7 +56,7 @@ func DefaultResources() Resources { // DefaultLimit returns a RelayLimit object with the defaults filled in. func DefaultLimit() *RelayLimit { return &RelayLimit{ - Duration: time.Minute, + Duration: 2 * time.Minute, Data: 1 << 17, // 128K } } From 526fc9270ed61b5e22a883ac976798d229f90404 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 18 Feb 2021 21:15:55 +0200 Subject: [PATCH 49/66] update protocol for vouched relay addrs; provide absolute expiration time instead of TTL --- v2/pb/circuit.pb.go | 139 +++++++++++++++++++++----------------------- v2/pb/circuit.proto | 6 +- 2 files changed, 69 insertions(+), 76 deletions(-) diff --git a/v2/pb/circuit.pb.go b/v2/pb/circuit.pb.go index 9d95ec7..6767be0 100644 --- a/v2/pb/circuit.pb.go +++ b/v2/pb/circuit.pb.go @@ -370,8 +370,8 @@ func (m *Peer) GetAddrs() [][]byte { } type Reservation struct { - Ttl *int32 `protobuf:"varint,1,opt,name=ttl" json:"ttl,omitempty"` - Relay *Peer `protobuf:"bytes,2,opt,name=relay" json:"relay,omitempty"` + Expire *int64 `protobuf:"varint,1,opt,name=expire" json:"expire,omitempty"` + Addrs [][]byte `protobuf:"bytes,2,rep,name=addrs" json:"addrs,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -410,16 +410,16 @@ func (m *Reservation) XXX_DiscardUnknown() { var xxx_messageInfo_Reservation proto.InternalMessageInfo -func (m *Reservation) GetTtl() int32 { - if m != nil && m.Ttl != nil { - return *m.Ttl +func (m *Reservation) GetExpire() int64 { + if m != nil && m.Expire != nil { + return *m.Expire } return 0 } -func (m *Reservation) GetRelay() *Peer { +func (m *Reservation) GetAddrs() [][]byte { if m != nil { - return m.Relay + return m.Addrs } return nil } @@ -493,39 +493,39 @@ func init() { func init() { proto.RegisterFile("circuit.proto", fileDescriptor_ed01bbc211f15e47) } var fileDescriptor_ed01bbc211f15e47 = []byte{ - // 506 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0x4d, 0x8b, 0xd3, 0x40, - 0x18, 0xc7, 0x77, 0xf2, 0x52, 0xe5, 0x69, 0x2d, 0xb3, 0xcf, 0x8a, 0x0d, 0xba, 0xd4, 0x52, 0x44, - 0xcb, 0x22, 0x55, 0x7a, 0x11, 0x8f, 0xb5, 0x99, 0xae, 0xc1, 0x26, 0x29, 0x33, 0xa9, 0xec, 0xad, - 0xc4, 0xcd, 0x20, 0x81, 0x6a, 0x4b, 0x32, 0x15, 0xfa, 0x2d, 0xf4, 0x23, 0xf8, 0x45, 0x3c, 0xaf, - 0x2f, 0x07, 0xef, 0x5e, 0xa4, 0x9f, 0x44, 0x32, 0x59, 0xdb, 0xec, 0x41, 0x14, 0xbc, 0xcd, 0x33, - 0xff, 0xdf, 0x33, 0x93, 0xdf, 0x33, 0x81, 0x1b, 0xe7, 0x69, 0x76, 0xbe, 0x4e, 0x55, 0x7f, 0x95, - 0x2d, 0xd5, 0x12, 0x61, 0x57, 0xbe, 0xea, 0x7e, 0x34, 0x00, 0x9e, 0x2f, 0x57, 0xbe, 0xcc, 0xf3, - 0xf8, 0xb5, 0xc4, 0x47, 0x60, 0xa9, 0xcd, 0x4a, 0x3a, 0xa4, 0x63, 0xf4, 0x9a, 0x83, 0x3b, 0xfd, - 0x3d, 0xd9, 0xdf, 0x53, 0xfd, 0x68, 0xb3, 0x92, 0x5c, 0x83, 0x78, 0x0f, 0xac, 0x95, 0x94, 0x99, - 0x63, 0x74, 0x48, 0xaf, 0x3e, 0xa0, 0xd5, 0x86, 0xa9, 0x94, 0x19, 0xd7, 0x29, 0x3e, 0x85, 0x7a, - 0x26, 0x73, 0x99, 0xbd, 0x8b, 0x55, 0xba, 0x7c, 0xeb, 0x98, 0x1a, 0x6e, 0x55, 0x61, 0xbe, 0x8f, - 0x79, 0x95, 0xc5, 0x07, 0x60, 0x2f, 0xd2, 0x37, 0xa9, 0x72, 0x2c, 0xdd, 0x74, 0x58, 0x6d, 0x9a, - 0x14, 0x01, 0x2f, 0x73, 0x3c, 0x81, 0x5a, 0xae, 0x62, 0xb5, 0xce, 0x1d, 0xbb, 0x43, 0x7a, 0xcd, - 0x01, 0x56, 0x49, 0xa1, 0x13, 0x7e, 0x49, 0x74, 0x1f, 0x82, 0x55, 0x38, 0x60, 0x1d, 0xae, 0x71, - 0x26, 0x18, 0x7f, 0xc9, 0xe8, 0x41, 0x51, 0x8c, 0xc2, 0x20, 0x60, 0xa3, 0x88, 0x12, 0x04, 0xa8, - 0x89, 0x68, 0x18, 0xcd, 0x04, 0x35, 0xba, 0x3f, 0x08, 0xd4, 0x85, 0xda, 0x0f, 0xe9, 0xf1, 0x95, - 0x21, 0x1d, 0x5f, 0xbd, 0xe7, 0x3f, 0xa6, 0xb4, 0x53, 0x35, 0xff, 0x59, 0xd5, 0xfa, 0xab, 0xea, - 0xdd, 0xbd, 0xea, 0x6f, 0xbb, 0x83, 0x8a, 0x1d, 0x29, 0x66, 0x51, 0x7c, 0x03, 0x36, 0xc1, 0x48, - 0x13, 0xed, 0xd4, 0xe0, 0x46, 0x9a, 0xe0, 0x4d, 0xb0, 0xe3, 0x24, 0xc9, 0x72, 0xc7, 0xe8, 0x98, - 0xbd, 0x06, 0x2f, 0x8b, 0xee, 0x29, 0xd4, 0x2b, 0x4f, 0x85, 0x14, 0x4c, 0xa5, 0x16, 0x0e, 0xe9, - 0x90, 0x9e, 0xcd, 0x8b, 0x25, 0xde, 0x07, 0x3b, 0x93, 0x8b, 0x78, 0xf3, 0x47, 0xd7, 0x32, 0xee, - 0x3e, 0x01, 0x5b, 0x3b, 0xe1, 0x6d, 0xb8, 0x9e, 0xac, 0xb3, 0xf2, 0xc7, 0x28, 0xcf, 0xd9, 0xd5, - 0x88, 0x60, 0x25, 0xb1, 0x8a, 0xf5, 0x59, 0x26, 0xd7, 0xeb, 0x93, 0x4f, 0x04, 0x6a, 0xa5, 0x23, - 0xd6, 0xc0, 0x08, 0x5f, 0xd0, 0x04, 0x1d, 0x38, 0x2a, 0x9f, 0x71, 0x18, 0x79, 0x61, 0x30, 0xe7, - 0x6c, 0x3c, 0x13, 0xcc, 0xa5, 0x17, 0x04, 0x8f, 0xa1, 0xc5, 0x99, 0x08, 0x67, 0x7c, 0xc4, 0xe6, - 0x13, 0xcf, 0xf7, 0xa2, 0x39, 0x3b, 0x1b, 0x31, 0xe6, 0x32, 0x97, 0x7e, 0x26, 0x78, 0x0b, 0x0e, - 0xa7, 0x8c, 0xfb, 0x9e, 0x10, 0x45, 0x9b, 0xcb, 0x02, 0x8f, 0xb9, 0xf4, 0x8b, 0xde, 0xbf, 0x9c, - 0x55, 0xb1, 0x3f, 0x1e, 0x7a, 0x13, 0xe6, 0xd2, 0xaf, 0x04, 0x8f, 0xa0, 0x19, 0x84, 0xf3, 0xca, - 0x55, 0xf4, 0x9b, 0x86, 0xfd, 0xe1, 0x64, 0x1c, 0x72, 0x9f, 0xb9, 0x73, 0x9f, 0x09, 0x31, 0x3c, - 0x65, 0xf4, 0xbd, 0x89, 0x2d, 0xc0, 0x59, 0xc0, 0xce, 0xa6, 0x6c, 0x14, 0x55, 0x82, 0x0f, 0xe6, - 0xb3, 0xc6, 0xc5, 0xb6, 0x4d, 0xbe, 0x6f, 0xdb, 0xe4, 0xe7, 0xb6, 0x4d, 0x7e, 0x05, 0x00, 0x00, - 0xff, 0xff, 0x9d, 0xd3, 0x7c, 0x1f, 0x9c, 0x03, 0x00, 0x00, + // 500 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0x4f, 0x8b, 0xd3, 0x40, + 0x18, 0xc6, 0x77, 0x92, 0xb4, 0xca, 0xdb, 0xb5, 0xcc, 0xbe, 0x2b, 0xdb, 0xa0, 0x4b, 0x2d, 0x45, + 0xb0, 0x2c, 0x52, 0xa5, 0x17, 0x11, 0x4f, 0xb5, 0x79, 0xab, 0xc1, 0x26, 0x29, 0x33, 0xa9, 0xec, + 0xad, 0xc4, 0xcd, 0x20, 0x01, 0xb5, 0x21, 0x49, 0xc5, 0xfd, 0x16, 0xfa, 0x11, 0xfc, 0x22, 0x9e, + 0xd7, 0x3f, 0x07, 0xef, 0x5e, 0xa4, 0x9f, 0x44, 0x32, 0xad, 0x6d, 0xf6, 0x20, 0x0a, 0xde, 0xfa, + 0xcc, 0xf3, 0x3c, 0x4c, 0x7f, 0xcf, 0x04, 0xae, 0x9d, 0x25, 0xd9, 0xd9, 0x32, 0x29, 0xfa, 0x69, + 0xb6, 0x28, 0x16, 0x08, 0x5b, 0xf9, 0xa2, 0xfb, 0xd1, 0x00, 0x78, 0xba, 0x48, 0x3d, 0x95, 0xe7, + 0xd1, 0x4b, 0x85, 0xf7, 0xc0, 0x2a, 0xce, 0x53, 0x65, 0xb3, 0x8e, 0xd1, 0x6b, 0x0e, 0x6e, 0xf6, + 0x77, 0xc9, 0xfe, 0x2e, 0xd5, 0x0f, 0xcf, 0x53, 0x25, 0x74, 0x10, 0x6f, 0x83, 0x95, 0x2a, 0x95, + 0xd9, 0x46, 0x87, 0xf5, 0x1a, 0x03, 0x5e, 0x2d, 0x4c, 0x95, 0xca, 0x84, 0x76, 0xf1, 0x21, 0x34, + 0x32, 0x95, 0xab, 0xec, 0x6d, 0x54, 0x24, 0x8b, 0x37, 0xb6, 0xa9, 0xc3, 0xad, 0x6a, 0x58, 0xec, + 0x6c, 0x51, 0xcd, 0xe2, 0x1d, 0xa8, 0xbd, 0x4a, 0x5e, 0x27, 0x85, 0x6d, 0xe9, 0xd2, 0x41, 0xb5, + 0x34, 0x29, 0x0d, 0xb1, 0xf6, 0xf1, 0x04, 0xea, 0x79, 0x11, 0x15, 0xcb, 0xdc, 0xae, 0x75, 0x58, + 0xaf, 0x39, 0xc0, 0x6a, 0x52, 0x6a, 0x47, 0x6c, 0x12, 0xdd, 0xbb, 0x60, 0x95, 0x0c, 0xd8, 0x80, + 0x2b, 0x82, 0x24, 0x89, 0xe7, 0xc4, 0xf7, 0x4a, 0x31, 0x0a, 0x7c, 0x9f, 0x46, 0x21, 0x67, 0x08, + 0x50, 0x97, 0xe1, 0x30, 0x9c, 0x49, 0x6e, 0x74, 0x7f, 0x30, 0x68, 0xc8, 0x62, 0x37, 0xd2, 0xfd, + 0x4b, 0x23, 0x1d, 0x5f, 0xbe, 0xe7, 0x3f, 0x56, 0xda, 0xa2, 0x9a, 0xff, 0x8c, 0x6a, 0xfd, 0x15, + 0xf5, 0xd6, 0x0e, 0xf5, 0x37, 0xdd, 0x5e, 0x85, 0x8e, 0x95, 0x5b, 0x94, 0xff, 0x01, 0x9b, 0x60, + 0x24, 0xb1, 0x66, 0xda, 0x17, 0x46, 0x12, 0xe3, 0x75, 0xa8, 0x45, 0x71, 0x9c, 0xe5, 0xb6, 0xd1, + 0x31, 0x7b, 0xfb, 0x62, 0x2d, 0xba, 0x8f, 0xa0, 0x51, 0x79, 0x2a, 0x3c, 0x82, 0xba, 0x7a, 0x97, + 0x26, 0x59, 0x39, 0x06, 0xeb, 0x99, 0x62, 0xa3, 0xfe, 0x50, 0x7e, 0x00, 0x35, 0xcd, 0x81, 0x37, + 0xe0, 0x6a, 0xbc, 0xcc, 0xd6, 0x1f, 0x43, 0x59, 0xac, 0x89, 0xad, 0x46, 0x04, 0x2b, 0x8e, 0x8a, + 0x48, 0x6f, 0x65, 0x0a, 0xfd, 0xfb, 0xe4, 0x13, 0x83, 0xfa, 0x9a, 0x0b, 0xeb, 0x60, 0x04, 0xcf, + 0x78, 0x8c, 0x36, 0x1c, 0xae, 0x9f, 0x6e, 0x18, 0xba, 0x81, 0x3f, 0x17, 0x34, 0x9e, 0x49, 0x72, + 0xf8, 0x05, 0xc3, 0x63, 0x68, 0x09, 0x92, 0xc1, 0x4c, 0x8c, 0x68, 0x3e, 0x71, 0x3d, 0x37, 0x9c, + 0xd3, 0xe9, 0x88, 0xc8, 0x21, 0x87, 0x7f, 0x66, 0x78, 0x04, 0x07, 0x53, 0x12, 0x9e, 0x2b, 0x65, + 0x59, 0x73, 0xc8, 0x77, 0xc9, 0xe1, 0x5f, 0xf4, 0xf9, 0x66, 0x9f, 0xf2, 0x7c, 0x3c, 0x74, 0x27, + 0xe4, 0xf0, 0xaf, 0x0c, 0x0f, 0xa1, 0xe9, 0x07, 0xf3, 0xca, 0x55, 0xfc, 0x9b, 0x0e, 0x7b, 0xc3, + 0xc9, 0x38, 0x10, 0x1e, 0x39, 0x73, 0x8f, 0xa4, 0x1c, 0x3e, 0x21, 0xfe, 0xde, 0xc4, 0x16, 0xe0, + 0xcc, 0xa7, 0xd3, 0x29, 0x8d, 0xc2, 0x8a, 0xf1, 0xc1, 0x7c, 0xbc, 0x7f, 0xb1, 0x6a, 0xb3, 0xef, + 0xab, 0x36, 0xfb, 0xb9, 0x6a, 0xb3, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xde, 0xd0, 0xd6, 0x2f, + 0x90, 0x03, 0x00, 0x00, } func (m *HopMessage) Marshal() (dAtA []byte, err error) { @@ -735,20 +735,17 @@ func (m *Reservation) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if m.Relay != nil { - { - size, err := m.Relay.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintCircuit(dAtA, i, uint64(size)) + if len(m.Addrs) > 0 { + for iNdEx := len(m.Addrs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Addrs[iNdEx]) + copy(dAtA[i:], m.Addrs[iNdEx]) + i = encodeVarintCircuit(dAtA, i, uint64(len(m.Addrs[iNdEx]))) + i-- + dAtA[i] = 0x12 } - i-- - dAtA[i] = 0x12 } - if m.Ttl != nil { - i = encodeVarintCircuit(dAtA, i, uint64(*m.Ttl)) + if m.Expire != nil { + i = encodeVarintCircuit(dAtA, i, uint64(*m.Expire)) i-- dAtA[i] = 0x8 } @@ -887,12 +884,14 @@ func (m *Reservation) Size() (n int) { } var l int _ = l - if m.Ttl != nil { - n += 1 + sovCircuit(uint64(*m.Ttl)) + if m.Expire != nil { + n += 1 + sovCircuit(uint64(*m.Expire)) } - if m.Relay != nil { - l = m.Relay.Size() - n += 1 + l + sovCircuit(uint64(l)) + if len(m.Addrs) > 0 { + for _, b := range m.Addrs { + l = len(b) + n += 1 + l + sovCircuit(uint64(l)) + } } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) @@ -1458,9 +1457,9 @@ func (m *Reservation) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Expire", wireType) } - var v int32 + var v int64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCircuit @@ -1470,17 +1469,17 @@ func (m *Reservation) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int32(b&0x7F) << shift + v |= int64(b&0x7F) << shift if b < 0x80 { break } } - m.Ttl = &v + m.Expire = &v case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Relay", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Addrs", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCircuit @@ -1490,27 +1489,23 @@ func (m *Reservation) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthCircuit } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthCircuit } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Relay == nil { - m.Relay = &Peer{} - } - if err := m.Relay.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Addrs = append(m.Addrs, make([]byte, postIndex-iNdEx)) + copy(m.Addrs[len(m.Addrs)-1], dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/v2/pb/circuit.proto b/v2/pb/circuit.proto index 5d7e88b..65e98c2 100644 --- a/v2/pb/circuit.proto +++ b/v2/pb/circuit.proto @@ -38,10 +38,8 @@ message Peer { } message Reservation { - optional int32 ttl = 1; // seconds - optional Peer relay = 2; - - // TODO: voucher + optional int64 expire = 1; // Unix expiration time (UTC) + repeated bytes addrs = 2; // vouched relay addrs for reserving peer } message Limit { From 6d34d5bf63e67c68d96c0890f0718594b934568e Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 18 Feb 2021 21:33:19 +0200 Subject: [PATCH 50/66] update for reservation changes --- v2/client/reservation.go | 23 ++++++++++++++--------- v2/relay/relay.go | 29 ++++++++++++++++++----------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/v2/client/reservation.go b/v2/client/reservation.go index 5277396..2135105 100644 --- a/v2/client/reservation.go +++ b/v2/client/reservation.go @@ -11,6 +11,8 @@ import ( "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" + + ma "github.com/multiformats/go-multiaddr" ) var ReserveTimeout = time.Minute @@ -19,9 +21,9 @@ var ReserveTimeout = time.Minute type Reservation struct { // Expiration is the expiration time of the reservation Expiration time.Time - // Relay is the public addresses of the relay, which can be used for constructing - // and advertising relay specific addresses. - Relay peer.AddrInfo + // Addrs contains the vouched public addresses of the reserving peer, which can be + // announced to the network + Addrs []ma.Multiaddr // LimitDuration is the time limit for which the relay will keep a relayed connection // open. If 0, there is no limit. @@ -81,13 +83,16 @@ func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation, } result := &Reservation{} - result.Expiration = time.Now().Add(time.Duration(rsvp.GetTtl()) * time.Second) - - rinfo, err := util.PeerToPeerInfoV2(rsvp.GetRelay()) - if err != nil { - return nil, fmt.Errorf("missing relay info") + result.Expiration = time.Unix(rsvp.GetExpire(), 0) + + for _, ab := range rsvp.GetAddrs() { + a, err := ma.NewMultiaddrBytes(ab) + if err != nil { + log.Warnf("ignoring unparsable relay address: %s", err) + continue + } + result.Addrs = append(result.Addrs, a) } - result.Relay = rinfo limit := msg.GetLimit() if limit != nil { diff --git a/v2/relay/relay.go b/v2/relay/relay.go index f4a78db..0810e4f 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -17,6 +17,7 @@ import ( logging "github.com/ipfs/go-log" pool "github.com/libp2p/go-buffer-pool" + ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) @@ -49,6 +50,8 @@ type Relay struct { mx sync.Mutex rsvp map[peer.ID]time.Time conns map[peer.ID]int + + relayAddr ma.Multiaddr } // New constructs a new limited relay that can provide relay services in the given host. @@ -73,6 +76,7 @@ func New(h host.Host, opts ...Option) (*Relay, error) { } r.ipcs = NewIPConstraints(r.rc) + r.relayAddr = ma.StringCast(fmt.Sprintf("/p2p/%s/p2p-circuit", h.ID())) h.SetStreamHandler(ProtoIDv2Hop, r.handleStream) h.Network().Notify( @@ -159,13 +163,14 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { } } - r.rsvp[p] = now.Add(r.rc.ReservationTTL) + expire := now.Add(r.rc.ReservationTTL) + r.rsvp[p] = expire r.host.ConnManager().TagPeer(p, "relay-reservation", ReservationTagWeight) r.mx.Unlock() log.Debugf("reserving relay slot for %s", p) - err := r.writeResponse(s, pbv2.Status_OK, r.makeReservationMsg(p), r.makeLimitMsg(p)) + err := r.writeResponse(s, pbv2.Status_OK, r.makeReservationMsg(p, expire), r.makeLimitMsg(p)) if err != nil { s.Reset() log.Debugf("error writing reservation response; retracting reservation for %s", p) @@ -400,21 +405,23 @@ func (r *Relay) writeResponse(s network.Stream, status pbv2.Status, rsvp *pbv2.R return wr.WriteMsg(&msg) } -func (r *Relay) makeReservationMsg(p peer.ID) *pbv2.Reservation { - // TODO signed reservation vouchers +func (r *Relay) makeReservationMsg(p peer.ID, expire time.Time) *pbv2.Reservation { + expireUnix := expire.Unix() - ttl := int32(r.rc.ReservationTTL / time.Second) - // TODO cache this - ai := peer.AddrInfo{ID: r.host.ID()} + var addrBytes [][]byte for _, addr := range r.host.Addrs() { - if manet.IsPublicAddr(addr) { - ai.Addrs = append(ai.Addrs, addr) + if !manet.IsPublicAddr(addr) { + continue } + + // TODO sign reservation vouchers for p + raddr := addr.Encapsulate(r.relayAddr) + addrBytes = append(addrBytes, raddr.Bytes()) } return &pbv2.Reservation{ - Ttl: &ttl, - Relay: util.PeerInfoToPeerV2(ai), + Expire: &expireUnix, + Addrs: addrBytes, } } From 16d56168730d8091343975c3cf70077af95f86be Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 18 Feb 2021 23:09:46 +0200 Subject: [PATCH 51/66] add voucher to the reservation pb --- v2/pb/circuit.pb.go | 120 ++++++++++++++++++++++++++++++++------------ v2/pb/circuit.proto | 5 +- 2 files changed, 90 insertions(+), 35 deletions(-) diff --git a/v2/pb/circuit.pb.go b/v2/pb/circuit.pb.go index 6767be0..bab44a7 100644 --- a/v2/pb/circuit.pb.go +++ b/v2/pb/circuit.pb.go @@ -372,6 +372,7 @@ func (m *Peer) GetAddrs() [][]byte { type Reservation struct { Expire *int64 `protobuf:"varint,1,opt,name=expire" json:"expire,omitempty"` Addrs [][]byte `protobuf:"bytes,2,rep,name=addrs" json:"addrs,omitempty"` + Voucher []byte `protobuf:"bytes,3,opt,name=voucher" json:"voucher,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -424,6 +425,13 @@ func (m *Reservation) GetAddrs() [][]byte { return nil } +func (m *Reservation) GetVoucher() []byte { + if m != nil { + return m.Voucher + } + return nil +} + type Limit struct { Duration *int32 `protobuf:"varint,1,opt,name=duration" json:"duration,omitempty"` Data *int64 `protobuf:"varint,2,opt,name=data" json:"data,omitempty"` @@ -493,39 +501,40 @@ func init() { func init() { proto.RegisterFile("circuit.proto", fileDescriptor_ed01bbc211f15e47) } var fileDescriptor_ed01bbc211f15e47 = []byte{ - // 500 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0x4f, 0x8b, 0xd3, 0x40, - 0x18, 0xc6, 0x77, 0x92, 0xb4, 0xca, 0xdb, 0xb5, 0xcc, 0xbe, 0x2b, 0xdb, 0xa0, 0x4b, 0x2d, 0x45, - 0xb0, 0x2c, 0x52, 0xa5, 0x17, 0x11, 0x4f, 0xb5, 0x79, 0xab, 0xc1, 0x26, 0x29, 0x33, 0xa9, 0xec, - 0xad, 0xc4, 0xcd, 0x20, 0x01, 0xb5, 0x21, 0x49, 0xc5, 0xfd, 0x16, 0xfa, 0x11, 0xfc, 0x22, 0x9e, - 0xd7, 0x3f, 0x07, 0xef, 0x5e, 0xa4, 0x9f, 0x44, 0x32, 0xad, 0x6d, 0xf6, 0x20, 0x0a, 0xde, 0xfa, - 0xcc, 0xf3, 0x3c, 0x4c, 0x7f, 0xcf, 0x04, 0xae, 0x9d, 0x25, 0xd9, 0xd9, 0x32, 0x29, 0xfa, 0x69, - 0xb6, 0x28, 0x16, 0x08, 0x5b, 0xf9, 0xa2, 0xfb, 0xd1, 0x00, 0x78, 0xba, 0x48, 0x3d, 0x95, 0xe7, - 0xd1, 0x4b, 0x85, 0xf7, 0xc0, 0x2a, 0xce, 0x53, 0x65, 0xb3, 0x8e, 0xd1, 0x6b, 0x0e, 0x6e, 0xf6, - 0x77, 0xc9, 0xfe, 0x2e, 0xd5, 0x0f, 0xcf, 0x53, 0x25, 0x74, 0x10, 0x6f, 0x83, 0x95, 0x2a, 0x95, - 0xd9, 0x46, 0x87, 0xf5, 0x1a, 0x03, 0x5e, 0x2d, 0x4c, 0x95, 0xca, 0x84, 0x76, 0xf1, 0x21, 0x34, - 0x32, 0x95, 0xab, 0xec, 0x6d, 0x54, 0x24, 0x8b, 0x37, 0xb6, 0xa9, 0xc3, 0xad, 0x6a, 0x58, 0xec, - 0x6c, 0x51, 0xcd, 0xe2, 0x1d, 0xa8, 0xbd, 0x4a, 0x5e, 0x27, 0x85, 0x6d, 0xe9, 0xd2, 0x41, 0xb5, - 0x34, 0x29, 0x0d, 0xb1, 0xf6, 0xf1, 0x04, 0xea, 0x79, 0x11, 0x15, 0xcb, 0xdc, 0xae, 0x75, 0x58, - 0xaf, 0x39, 0xc0, 0x6a, 0x52, 0x6a, 0x47, 0x6c, 0x12, 0xdd, 0xbb, 0x60, 0x95, 0x0c, 0xd8, 0x80, - 0x2b, 0x82, 0x24, 0x89, 0xe7, 0xc4, 0xf7, 0x4a, 0x31, 0x0a, 0x7c, 0x9f, 0x46, 0x21, 0x67, 0x08, - 0x50, 0x97, 0xe1, 0x30, 0x9c, 0x49, 0x6e, 0x74, 0x7f, 0x30, 0x68, 0xc8, 0x62, 0x37, 0xd2, 0xfd, - 0x4b, 0x23, 0x1d, 0x5f, 0xbe, 0xe7, 0x3f, 0x56, 0xda, 0xa2, 0x9a, 0xff, 0x8c, 0x6a, 0xfd, 0x15, - 0xf5, 0xd6, 0x0e, 0xf5, 0x37, 0xdd, 0x5e, 0x85, 0x8e, 0x95, 0x5b, 0x94, 0xff, 0x01, 0x9b, 0x60, - 0x24, 0xb1, 0x66, 0xda, 0x17, 0x46, 0x12, 0xe3, 0x75, 0xa8, 0x45, 0x71, 0x9c, 0xe5, 0xb6, 0xd1, - 0x31, 0x7b, 0xfb, 0x62, 0x2d, 0xba, 0x8f, 0xa0, 0x51, 0x79, 0x2a, 0x3c, 0x82, 0xba, 0x7a, 0x97, - 0x26, 0x59, 0x39, 0x06, 0xeb, 0x99, 0x62, 0xa3, 0xfe, 0x50, 0x7e, 0x00, 0x35, 0xcd, 0x81, 0x37, - 0xe0, 0x6a, 0xbc, 0xcc, 0xd6, 0x1f, 0x43, 0x59, 0xac, 0x89, 0xad, 0x46, 0x04, 0x2b, 0x8e, 0x8a, - 0x48, 0x6f, 0x65, 0x0a, 0xfd, 0xfb, 0xe4, 0x13, 0x83, 0xfa, 0x9a, 0x0b, 0xeb, 0x60, 0x04, 0xcf, - 0x78, 0x8c, 0x36, 0x1c, 0xae, 0x9f, 0x6e, 0x18, 0xba, 0x81, 0x3f, 0x17, 0x34, 0x9e, 0x49, 0x72, - 0xf8, 0x05, 0xc3, 0x63, 0x68, 0x09, 0x92, 0xc1, 0x4c, 0x8c, 0x68, 0x3e, 0x71, 0x3d, 0x37, 0x9c, - 0xd3, 0xe9, 0x88, 0xc8, 0x21, 0x87, 0x7f, 0x66, 0x78, 0x04, 0x07, 0x53, 0x12, 0x9e, 0x2b, 0x65, - 0x59, 0x73, 0xc8, 0x77, 0xc9, 0xe1, 0x5f, 0xf4, 0xf9, 0x66, 0x9f, 0xf2, 0x7c, 0x3c, 0x74, 0x27, - 0xe4, 0xf0, 0xaf, 0x0c, 0x0f, 0xa1, 0xe9, 0x07, 0xf3, 0xca, 0x55, 0xfc, 0x9b, 0x0e, 0x7b, 0xc3, - 0xc9, 0x38, 0x10, 0x1e, 0x39, 0x73, 0x8f, 0xa4, 0x1c, 0x3e, 0x21, 0xfe, 0xde, 0xc4, 0x16, 0xe0, - 0xcc, 0xa7, 0xd3, 0x29, 0x8d, 0xc2, 0x8a, 0xf1, 0xc1, 0x7c, 0xbc, 0x7f, 0xb1, 0x6a, 0xb3, 0xef, - 0xab, 0x36, 0xfb, 0xb9, 0x6a, 0xb3, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xde, 0xd0, 0xd6, 0x2f, - 0x90, 0x03, 0x00, 0x00, + // 515 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0xcf, 0x8a, 0xd3, 0x50, + 0x14, 0xc6, 0xe7, 0x26, 0x69, 0x47, 0x4e, 0x6b, 0xc9, 0x9c, 0x91, 0x69, 0xd0, 0xa1, 0x96, 0x22, + 0x58, 0x06, 0xa9, 0xd2, 0x8d, 0xb8, 0xac, 0xcd, 0xa9, 0x06, 0x9b, 0xa4, 0xdc, 0x9b, 0xca, 0xec, + 0x4a, 0x6c, 0x2e, 0x1a, 0x50, 0x1b, 0x92, 0x74, 0x70, 0xde, 0x42, 0x1f, 0xc1, 0x17, 0x71, 0x3d, + 0xfe, 0x59, 0xb8, 0x77, 0x23, 0x7d, 0x12, 0xc9, 0x6d, 0xa7, 0xcd, 0x80, 0xa0, 0x30, 0xbb, 0x7c, + 0xf7, 0xfb, 0x4e, 0x6e, 0x7e, 0xdf, 0x09, 0xdc, 0x9c, 0xc7, 0xe9, 0x7c, 0x19, 0xe7, 0xbd, 0x24, + 0x5d, 0xe4, 0x0b, 0x84, 0xad, 0x7c, 0xd5, 0xf9, 0xac, 0x01, 0x3c, 0x5f, 0x24, 0xae, 0xcc, 0xb2, + 0xf0, 0xb5, 0xc4, 0x87, 0x60, 0xe4, 0xe7, 0x89, 0xb4, 0x58, 0x5b, 0xeb, 0x36, 0xfa, 0x77, 0x7a, + 0xbb, 0x64, 0x6f, 0x97, 0xea, 0x05, 0xe7, 0x89, 0xe4, 0x2a, 0x88, 0xf7, 0xc0, 0x48, 0xa4, 0x4c, + 0x2d, 0xad, 0xcd, 0xba, 0xb5, 0xbe, 0x59, 0x1e, 0x98, 0x48, 0x99, 0x72, 0xe5, 0xe2, 0x13, 0xa8, + 0xa5, 0x32, 0x93, 0xe9, 0x59, 0x98, 0xc7, 0x8b, 0xf7, 0x96, 0xae, 0xc2, 0xcd, 0x72, 0x98, 0xef, + 0x6c, 0x5e, 0xce, 0xe2, 0x7d, 0xa8, 0xbc, 0x8d, 0xdf, 0xc5, 0xb9, 0x65, 0xa8, 0xa1, 0x83, 0xf2, + 0xd0, 0xb8, 0x30, 0xf8, 0xda, 0xc7, 0x13, 0xa8, 0x66, 0x79, 0x98, 0x2f, 0x33, 0xab, 0xd2, 0x66, + 0xdd, 0x46, 0x1f, 0xcb, 0x49, 0xa1, 0x1c, 0xbe, 0x49, 0x74, 0x1e, 0x80, 0x51, 0x30, 0x60, 0x0d, + 0xf6, 0x39, 0x09, 0xe2, 0x2f, 0xc9, 0xdc, 0x2b, 0xc4, 0xd0, 0xf7, 0x3c, 0x1a, 0x06, 0x26, 0x43, + 0x80, 0xaa, 0x08, 0x06, 0xc1, 0x54, 0x98, 0x5a, 0xe7, 0x17, 0x83, 0x9a, 0xc8, 0x77, 0x25, 0x3d, + 0xba, 0x52, 0xd2, 0xf1, 0xd5, 0x7b, 0xae, 0xd1, 0xd2, 0x16, 0x55, 0xff, 0x6f, 0x54, 0xe3, 0x9f, + 0xa8, 0x77, 0x77, 0xa8, 0x97, 0x74, 0x7b, 0x25, 0x3a, 0x56, 0x74, 0x51, 0x7c, 0x03, 0x36, 0x40, + 0x8b, 0x23, 0xc5, 0x54, 0xe7, 0x5a, 0x1c, 0xe1, 0x2d, 0xa8, 0x84, 0x51, 0x94, 0x66, 0x96, 0xd6, + 0xd6, 0xbb, 0x75, 0xbe, 0x16, 0x9d, 0x29, 0xd4, 0x4a, 0xab, 0xc2, 0x23, 0xa8, 0xca, 0x0f, 0x49, + 0x9c, 0x16, 0x65, 0xb0, 0xae, 0xce, 0x37, 0xea, 0xef, 0xc3, 0x68, 0xc1, 0xfe, 0xd9, 0x62, 0x39, + 0x7f, 0x23, 0x53, 0x85, 0x58, 0xe7, 0x97, 0xb2, 0xf3, 0x18, 0x2a, 0x8a, 0x10, 0x6f, 0xc3, 0x8d, + 0x68, 0x99, 0xae, 0x7f, 0x93, 0xe2, 0x95, 0x15, 0xbe, 0xd5, 0x88, 0x60, 0x44, 0x61, 0x1e, 0xaa, + 0x16, 0x75, 0xae, 0x9e, 0x4f, 0xbe, 0x30, 0xa8, 0xae, 0x89, 0xb1, 0x0a, 0x9a, 0xff, 0xc2, 0x8c, + 0xd0, 0x82, 0xc3, 0xf5, 0x52, 0x07, 0x81, 0xe3, 0x7b, 0x33, 0x4e, 0xa3, 0xa9, 0x20, 0xdb, 0xbc, + 0x60, 0x78, 0x0c, 0x4d, 0x4e, 0xc2, 0x9f, 0xf2, 0x21, 0xcd, 0xc6, 0x8e, 0xeb, 0x04, 0x33, 0x3a, + 0x1d, 0x12, 0xd9, 0x64, 0x9b, 0x5f, 0x19, 0x1e, 0xc1, 0xc1, 0x84, 0xb8, 0xeb, 0x08, 0x51, 0x8c, + 0xd9, 0xe4, 0x39, 0x64, 0x9b, 0xdf, 0xd4, 0xf9, 0xa6, 0xb9, 0xe2, 0x7c, 0x34, 0x70, 0xc6, 0x64, + 0x9b, 0xdf, 0x19, 0x1e, 0x42, 0xc3, 0xf3, 0x67, 0xa5, 0xab, 0xcc, 0x1f, 0x2a, 0xec, 0x0e, 0xc6, + 0x23, 0x9f, 0xbb, 0x64, 0xcf, 0x5c, 0x12, 0x62, 0xf0, 0x8c, 0xcc, 0x8f, 0x3a, 0x36, 0x01, 0xa7, + 0x1e, 0x9d, 0x4e, 0x68, 0x18, 0x94, 0x8c, 0x4f, 0xfa, 0xd3, 0xfa, 0xc5, 0xaa, 0xc5, 0x7e, 0xae, + 0x5a, 0xec, 0xf7, 0xaa, 0xc5, 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0x83, 0xf2, 0x9c, 0x78, 0xaa, + 0x03, 0x00, 0x00, } func (m *HopMessage) Marshal() (dAtA []byte, err error) { @@ -735,6 +744,13 @@ func (m *Reservation) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Voucher != nil { + i -= len(m.Voucher) + copy(dAtA[i:], m.Voucher) + i = encodeVarintCircuit(dAtA, i, uint64(len(m.Voucher))) + i-- + dAtA[i] = 0x1a + } if len(m.Addrs) > 0 { for iNdEx := len(m.Addrs) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Addrs[iNdEx]) @@ -893,6 +909,10 @@ func (m *Reservation) Size() (n int) { n += 1 + l + sovCircuit(uint64(l)) } } + if m.Voucher != nil { + l = len(m.Voucher) + n += 1 + l + sovCircuit(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -1507,6 +1527,40 @@ func (m *Reservation) Unmarshal(dAtA []byte) error { m.Addrs = append(m.Addrs, make([]byte, postIndex-iNdEx)) copy(m.Addrs[len(m.Addrs)-1], dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Voucher", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCircuit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCircuit + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCircuit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Voucher = append(m.Voucher[:0], dAtA[iNdEx:postIndex]...) + if m.Voucher == nil { + m.Voucher = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCircuit(dAtA[iNdEx:]) diff --git a/v2/pb/circuit.proto b/v2/pb/circuit.proto index 65e98c2..e3f8236 100644 --- a/v2/pb/circuit.proto +++ b/v2/pb/circuit.proto @@ -38,8 +38,9 @@ message Peer { } message Reservation { - optional int64 expire = 1; // Unix expiration time (UTC) - repeated bytes addrs = 2; // vouched relay addrs for reserving peer + optional int64 expire = 1; // Unix expiration time (UTC) + repeated bytes addrs = 2; // relay addrs for reserving peer + optional bytes voucher = 3; // reservation voucher } message Limit { From 1cec70e0e872273ebc6cc0e4aea8d8b7323968a4 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 18 Feb 2021 23:10:09 +0200 Subject: [PATCH 52/66] TODO about reservation vouchers --- v2/relay/relay.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 0810e4f..1b95773 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -414,11 +414,12 @@ func (r *Relay) makeReservationMsg(p peer.ID, expire time.Time) *pbv2.Reservatio continue } - // TODO sign reservation vouchers for p raddr := addr.Encapsulate(r.relayAddr) addrBytes = append(addrBytes, raddr.Bytes()) } + // TODO sign reservation voucher for p + return &pbv2.Reservation{ Expire: &expireUnix, Addrs: addrBytes, From 4ec7298fcf02badc0d06e7d5484ab5cef3a9f290 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 19 Feb 2021 23:10:06 +0200 Subject: [PATCH 53/66] deduplicate protocol ID definitions between relay and client --- v2/client/client.go | 12 ++++-------- v2/client/dial.go | 7 ++++--- v2/client/reservation.go | 3 ++- v2/proto/protocol.go | 7 +++++++ v2/relay/relay.go | 10 ++++------ 5 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 v2/proto/protocol.go diff --git a/v2/client/client.go b/v2/client/client.go index d326516..c846b9a 100644 --- a/v2/client/client.go +++ b/v2/client/client.go @@ -4,6 +4,8 @@ import ( "context" "sync" + "github.com/libp2p/go-libp2p-circuit/v2/proto" + "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" @@ -11,12 +13,6 @@ import ( tptu "github.com/libp2p/go-libp2p-transport-upgrader" ) -const ( - ProtoIDv1 = "/libp2p/circuit/relay/0.1.0" - ProtoIDv2Hop = "/libp2p/circuit/relay/0.2.0/hop" - ProtoIDv2Stop = "/libp2p/circuit/relay/0.2.0/stop" -) - var log = logging.Logger("p2p-circuit") // Client implements the client-side of the p2p-circuit/v2 protocol: @@ -57,6 +53,6 @@ func New(ctx context.Context, h host.Host, upgrader *tptu.Upgrader) (*Client, er // Start registers the circuit (client) protocol stream handlers func (c *Client) Start() { - c.host.SetStreamHandler(ProtoIDv1, c.handleStreamV1) - c.host.SetStreamHandler(ProtoIDv2Stop, c.handleStreamV2) + c.host.SetStreamHandler(proto.ProtoIDv1, c.handleStreamV1) + c.host.SetStreamHandler(proto.ProtoIDv2Stop, c.handleStreamV2) } diff --git a/v2/client/dial.go b/v2/client/dial.go index b448e3d..2b7cf72 100644 --- a/v2/client/dial.go +++ b/v2/client/dial.go @@ -7,6 +7,7 @@ import ( pbv1 "github.com/libp2p/go-libp2p-circuit/pb" pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + "github.com/libp2p/go-libp2p-circuit/v2/proto" "github.com/libp2p/go-libp2p-circuit/v2/util" "github.com/libp2p/go-libp2p-core/network" @@ -59,16 +60,16 @@ func (c *Client) dialPeer(ctx context.Context, relay, dest peer.AddrInfo) (*Conn c.host.Peerstore().AddAddrs(relay.ID, relay.Addrs, peerstore.TempAddrTTL) } - s, err := c.host.NewStream(ctx, relay.ID, ProtoIDv2Hop, ProtoIDv1) + s, err := c.host.NewStream(ctx, relay.ID, proto.ProtoIDv2Hop, proto.ProtoIDv1) if err != nil { return nil, fmt.Errorf("error opening hop stream to relay: %w", err) } switch s.Protocol() { - case ProtoIDv2Hop: + case proto.ProtoIDv2Hop: return c.connectV2(s, dest) - case ProtoIDv1: + case proto.ProtoIDv1: return c.connectV1(s, dest) default: diff --git a/v2/client/reservation.go b/v2/client/reservation.go index 2135105..c84102f 100644 --- a/v2/client/reservation.go +++ b/v2/client/reservation.go @@ -6,6 +6,7 @@ import ( "time" pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + "github.com/libp2p/go-libp2p-circuit/v2/proto" "github.com/libp2p/go-libp2p-circuit/v2/util" "github.com/libp2p/go-libp2p-core/host" @@ -42,7 +43,7 @@ func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation, h.Peerstore().AddAddrs(ai.ID, ai.Addrs, peerstore.TempAddrTTL) } - s, err := h.NewStream(ctx, ai.ID, ProtoIDv2Hop) + s, err := h.NewStream(ctx, ai.ID, proto.ProtoIDv2Hop) if err != nil { return nil, err } diff --git a/v2/proto/protocol.go b/v2/proto/protocol.go new file mode 100644 index 0000000..d27fc50 --- /dev/null +++ b/v2/proto/protocol.go @@ -0,0 +1,7 @@ +package proto + +const ( + ProtoIDv1 = "/libp2p/circuit/relay/0.1.0" + ProtoIDv2Hop = "/libp2p/circuit/relay/0.2.0/hop" + ProtoIDv2Stop = "/libp2p/circuit/relay/0.2.0/stop" +) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 1b95773..8ebfeae 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -9,6 +9,7 @@ import ( "time" pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + "github.com/libp2p/go-libp2p-circuit/v2/proto" "github.com/libp2p/go-libp2p-circuit/v2/util" "github.com/libp2p/go-libp2p-core/host" @@ -22,9 +23,6 @@ import ( ) const ( - ProtoIDv2Hop = "/libp2p/circuit/relay/0.2.0/hop" - ProtoIDv2Stop = "/libp2p/circuit/relay/0.2.0/stop" - ReservationTagWeight = 10 StreamTimeout = time.Minute @@ -78,7 +76,7 @@ func New(h host.Host, opts ...Option) (*Relay, error) { r.ipcs = NewIPConstraints(r.rc) r.relayAddr = ma.StringCast(fmt.Sprintf("/p2p/%s/p2p-circuit", h.ID())) - h.SetStreamHandler(ProtoIDv2Hop, r.handleStream) + h.SetStreamHandler(proto.ProtoIDv2Hop, r.handleStream) h.Network().Notify( &network.NotifyBundle{ DisconnectedF: r.disconnected, @@ -90,7 +88,7 @@ func New(h host.Host, opts ...Option) (*Relay, error) { func (r *Relay) Close() error { if atomic.CompareAndSwapUint32(&r.closed, 0, 1) { - r.host.RemoveStreamHandler(ProtoIDv2Hop) + r.host.RemoveStreamHandler(proto.ProtoIDv2Hop) r.cancel() r.mx.Lock() for p := range r.rsvp { @@ -237,7 +235,7 @@ func (r *Relay) handleConnect(s network.Stream, msg *pbv2.HopMessage) { ctx = network.WithNoDial(ctx, "relay connect") - bs, err := r.host.NewStream(ctx, dest.ID, ProtoIDv2Stop) + bs, err := r.host.NewStream(ctx, dest.ID, proto.ProtoIDv2Stop) if err != nil { log.Debugf("error opening relay stream to %s: %s", dest.ID, err) cleanup() From c7b3913dda495100436d1d1f32b397c07047e9d1 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 19 Feb 2021 23:59:05 +0200 Subject: [PATCH 54/66] add reservation vouchers --- v2/proto/voucher.go | 139 +++++++++++++++++++++++++++++++++++++++ v2/proto/voucher_test.go | 68 +++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 v2/proto/voucher.go create mode 100644 v2/proto/voucher_test.go diff --git a/v2/proto/voucher.go b/v2/proto/voucher.go new file mode 100644 index 0000000..3669de4 --- /dev/null +++ b/v2/proto/voucher.go @@ -0,0 +1,139 @@ +package proto + +import ( + "bytes" + "encoding/binary" + "fmt" + "time" + + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" +) + +type ReservationVoucher struct { + // Relay is the ID of the peer providing relay service + Relay peer.ID + // Peer is the ID of the peer receiving relay service through Relay + Peer peer.ID + // Expiration is the expiration time of the reservation + Expiration time.Time + // Signature is the signature of this voucher, as produced by the Relay peer + Signature []byte +} + +func (rv *ReservationVoucher) bytes() []byte { + buf := make([]byte, 1024) + relayBytes := []byte(rv.Relay) + peerBytes := []byte(rv.Peer) + expireUnix := rv.Expiration.Unix() + + n := binary.PutUvarint(buf, uint64(len(relayBytes))) + n += copy(buf[n:], relayBytes) + n += binary.PutUvarint(buf[n:], uint64(len(peerBytes))) + n += copy(buf[n:], peerBytes) + n += binary.PutUvarint(buf[n:], uint64(expireUnix)) + + return buf[:n] +} + +func (rv *ReservationVoucher) Sign(privk crypto.PrivKey) error { + if rv.Signature != nil { + return nil + } + + blob := append([]byte("libp2p-relay-rsvp:"), rv.bytes()...) + + sig, err := privk.Sign(blob) + if err != nil { + return err + } + + rv.Signature = sig + return nil +} + +func (rv *ReservationVoucher) Verify(pubk crypto.PubKey) error { + if rv.Signature == nil { + return fmt.Errorf("missing signature") + } + + blob := append([]byte("libp2p-relay-rsvp:"), rv.bytes()...) + + ok, err := pubk.Verify(blob, rv.Signature) + if err != nil { + return fmt.Errorf("signature verification error: %w", err) + } + if !ok { + return fmt.Errorf("signature verifcation failed") + } + + return nil +} + +func (rv *ReservationVoucher) Marshal() ([]byte, error) { + if rv.Signature == nil { + return nil, fmt.Errorf("cannot marshal unsigned reservation voucher") + } + + blob := rv.bytes() + result := make([]byte, len(blob)+len(rv.Signature)) + copy(result, blob) + copy(result[len(blob):], rv.Signature) + + return result, nil +} + +func (rv *ReservationVoucher) Unmarshal(blob []byte) error { + rd := bytes.NewReader(blob) + + readID := func() (peer.ID, error) { + idLen, err := binary.ReadUvarint(rd) + if err != nil { + return "", fmt.Errorf("error reading ID length: %w", err) + } + if idLen > uint64(rd.Len()) { + return "", fmt.Errorf("error reading ID: ID length exceeds available bytes") + } + + idBytes := make([]byte, int(idLen)) + n, err := rd.Read(idBytes) + if err != nil { + return "", fmt.Errorf("error reading ID: %w", err) + } + if n != len(idBytes) { + return "", fmt.Errorf("error reading ID: not enough bytes read") + } + + return peer.IDFromBytes(idBytes) + } + + var err error + + rv.Relay, err = readID() + if err != nil { + return fmt.Errorf("error reading relay ID: %w", err) + } + + rv.Peer, err = readID() + if err != nil { + return fmt.Errorf("error reading peer ID: %w", err) + } + + expireUnix, err := binary.ReadUvarint(rd) + if err != nil { + return fmt.Errorf("error reading reservation expiration: %w", err) + } + rv.Expiration = time.Unix(int64(expireUnix), 0) + + sig := make([]byte, rd.Len()) + n, err := rd.Read(sig) + if err != nil { + return fmt.Errorf("error reading signature: %w", err) + } + if n != len(sig) { + return fmt.Errorf("error reading signature: not enough bytes read") + } + rv.Signature = sig + + return nil +} diff --git a/v2/proto/voucher_test.go b/v2/proto/voucher_test.go new file mode 100644 index 0000000..eb61c0a --- /dev/null +++ b/v2/proto/voucher_test.go @@ -0,0 +1,68 @@ +package proto + +import ( + "testing" + "time" + + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" +) + +func TestReservationVoucher(t *testing.T) { + relayPrivk, relayPubk, err := crypto.GenerateKeyPair(crypto.Ed25519, 0) + if err != nil { + t.Fatal(err) + } + + _, peerPubk, err := crypto.GenerateKeyPair(crypto.Ed25519, 0) + if err != nil { + t.Fatal(err) + } + + relayID, err := peer.IDFromPublicKey(relayPubk) + if err != nil { + t.Fatal(err) + } + + peerID, err := peer.IDFromPublicKey(peerPubk) + if err != nil { + t.Fatal(err) + } + + rsvp := &ReservationVoucher{ + Relay: relayID, + Peer: peerID, + Expiration: time.Now().Add(time.Hour), + } + + err = rsvp.Sign(relayPrivk) + if err != nil { + t.Fatal(err) + } + + blob, err := rsvp.Marshal() + if err != nil { + t.Fatal(err) + } + + rsvp2 := new(ReservationVoucher) + err = rsvp2.Unmarshal(blob) + if err != nil { + t.Fatal(err) + } + + err = rsvp2.Verify(relayPubk) + if err != nil { + t.Fatal(err) + } + + if rsvp.Relay != rsvp2.Relay { + t.Fatal("relay IDs don't match") + } + if rsvp.Peer != rsvp2.Peer { + t.Fatal("peer IDs don't match") + } + if rsvp.Expiration.Unix() != rsvp2.Expiration.Unix() { + t.Fatal("expirations don't match") + } +} From 533abb2866127c6c173ee62040fe30f3e53adcc7 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sat, 20 Feb 2021 00:11:35 +0200 Subject: [PATCH 55/66] emit and consume reservation vouchers --- v2/client/reservation.go | 20 +++++++++++++++++++- v2/relay/relay.go | 26 +++++++++++++++++++++++--- v2/test/e2e_test.go | 6 +++++- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/v2/client/reservation.go b/v2/client/reservation.go index c84102f..975fdd1 100644 --- a/v2/client/reservation.go +++ b/v2/client/reservation.go @@ -33,7 +33,8 @@ type Reservation struct { // resetting a relayed connection. LimitData int64 - // TODO reservation voucher + // Voucher is a signed reservation voucher provided by the relay + Voucher *proto.ReservationVoucher } // Reserve reserves a slot in a relay and returns the reservation information. @@ -95,6 +96,23 @@ func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation, result.Addrs = append(result.Addrs, a) } + voucherBytes := rsvp.GetVoucher() + if voucherBytes != nil { + voucher := new(proto.ReservationVoucher) + + err := voucher.Unmarshal(voucherBytes) + if err != nil { + return nil, fmt.Errorf("error unmarshalling reservation voucher from relay: %w", err) + } + + err = voucher.Verify(h.Peerstore().PubKey(ai.ID)) + if err != nil { + return nil, fmt.Errorf("error verifying voucher from relay: %w", err) + } + + result.Voucher = voucher + } + limit := msg.GetLimit() if limit != nil { result.LimitDuration = time.Duration(limit.GetDuration()) * time.Second diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 8ebfeae..a2ae818 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -416,12 +416,32 @@ func (r *Relay) makeReservationMsg(p peer.ID, expire time.Time) *pbv2.Reservatio addrBytes = append(addrBytes, raddr.Bytes()) } - // TODO sign reservation voucher for p - - return &pbv2.Reservation{ + rsvp := &pbv2.Reservation{ Expire: &expireUnix, Addrs: addrBytes, } + + voucher := &proto.ReservationVoucher{ + Relay: r.host.ID(), + Peer: p, + Expiration: expire, + } + + err := voucher.Sign(r.host.Peerstore().PrivKey(r.host.ID())) + if err != nil { + log.Errorf("error signing voucher for %s: %s", p, err) + return rsvp + } + + blob, err := voucher.Marshal() + if err != nil { + log.Errorf("error marshalling voucher for %s: %s", p, err) + return rsvp + } + + rsvp.Voucher = blob + + return rsvp } func (r *Relay) makeLimitMsg(p peer.ID) *pbv2.Limit { diff --git a/v2/test/e2e_test.go b/v2/test/e2e_test.go index 47cb784..1435c45 100644 --- a/v2/test/e2e_test.go +++ b/v2/test/e2e_test.go @@ -131,11 +131,15 @@ func TestBasicRelay(t *testing.T) { connect(t, hosts[1], hosts[2]) rinfo := hosts[1].Peerstore().PeerInfo(hosts[1].ID()) - _, err = client.Reserve(ctx, hosts[0], rinfo) + rsvp, err := client.Reserve(ctx, hosts[0], rinfo) if err != nil { t.Fatal(err) } + if rsvp.Voucher == nil { + t.Fatal("no reservation voucher") + } + raddr, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s/p2p-circuit/p2p/%s", hosts[1].ID(), hosts[0].ID())) if err != nil { t.Fatal(err) From a3d765a7ff4f9bca5d3d1291fe6f97148a537253 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 24 Feb 2021 13:22:49 +0200 Subject: [PATCH 56/66] improve limit data test --- v2/test/e2e_test.go | 46 ++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/v2/test/e2e_test.go b/v2/test/e2e_test.go index 1435c45..ee7a8a7 100644 --- a/v2/test/e2e_test.go +++ b/v2/test/e2e_test.go @@ -263,14 +263,16 @@ func TestRelayLimitData(t *testing.T) { defer s.Close() defer close(rch) - buf := make([]byte, 4096) - n, err := s.Read(buf) - if err != nil { - t.Fatal(err) + buf := make([]byte, 1024) + for i := 0; i < 3; i++ { + n, err := s.Read(buf) + if err != nil { + t.Fatal(err) + } + rch <- n } - rch <- n - n, err = s.Read(buf) + n, err := s.Read(buf) if err != mux.ErrReset { t.Fatalf("expected reset but got %s", err) } @@ -320,22 +322,24 @@ func TestRelayLimitData(t *testing.T) { } buf := make([]byte, 1024) - _, err = rand.Read(buf) - if err != nil { - t.Fatal(err) - } + for i := 0; i < 3; i++ { + _, err = rand.Read(buf) + if err != nil { + t.Fatal(err) + } - n, err := s.Write(buf) - if err != nil { - t.Fatal(err) - } - if n != len(buf) { - t.Fatalf("expected to write %d bytes but wrote %d", len(buf), n) - } + n, err := s.Write(buf) + if err != nil { + t.Fatal(err) + } + if n != len(buf) { + t.Fatalf("expected to write %d bytes but wrote %d", len(buf), n) + } - n = <-rch - if n != len(buf) { - t.Fatalf("expected to read %d bytes but read %d", len(buf), n) + n = <-rch + if n != len(buf) { + t.Fatalf("expected to read %d bytes but read %d", len(buf), n) + } } buf = make([]byte, 4096) @@ -346,7 +350,7 @@ func TestRelayLimitData(t *testing.T) { s.Write(buf) - n = <-rch + n := <-rch if n != 0 { t.Fatalf("expected to read 0 bytes but read %d", n) } From 75b4777d4e5479ececb8e8e89aa5e9774706e3e3 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 24 Feb 2021 14:28:36 +0200 Subject: [PATCH 57/66] deduplicate concurrent relay dials to the samke peer --- v2/client/client.go | 21 ++++++++++++++------- v2/client/dial.go | 32 +++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/v2/client/client.go b/v2/client/client.go index c846b9a..722ddf9 100644 --- a/v2/client/client.go +++ b/v2/client/client.go @@ -30,8 +30,9 @@ type Client struct { incoming chan accept - mx sync.Mutex - hopCount map[peer.ID]int + mx sync.Mutex + activeDials map[peer.ID]*completion + hopCount map[peer.ID]int } type accept struct { @@ -39,15 +40,21 @@ type accept struct { writeResponse func() error } +type completion struct { + ch chan struct{} + err error +} + // New constructs a new p2p-circuit/v2 client, attached to the given host and using the given // upgrader to perform connection upgrades. func New(ctx context.Context, h host.Host, upgrader *tptu.Upgrader) (*Client, error) { return &Client{ - ctx: ctx, - host: h, - upgrader: upgrader, - incoming: make(chan accept), - hopCount: make(map[peer.ID]int), + ctx: ctx, + host: h, + upgrader: upgrader, + incoming: make(chan accept), + activeDials: make(map[peer.ID]*completion), + hopCount: make(map[peer.ID]int), }, nil } diff --git a/v2/client/dial.go b/v2/client/dial.go index 2b7cf72..fc5e957 100644 --- a/v2/client/dial.go +++ b/v2/client/dial.go @@ -50,7 +50,37 @@ func (c *Client) dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (*Conn, er return nil, fmt.Errorf("error parsing relay multiaddr '%s': %w", relayaddr, err) } - return c.dialPeer(ctx, *rinfo, dinfo) +retry: + c.mx.Lock() + dedup, active := c.activeDials[p] + if !active { + dedup = &completion{ch: make(chan struct{})} + c.activeDials[p] = dedup + } + c.mx.Unlock() + + if active { + select { + case <-dedup.ch: + if dedup.err != nil { + goto retry + } + return nil, fmt.Errorf("concurrent active dial succeeded") + + case <-ctx.Done(): + return nil, ctx.Err() + } + } + + conn, err := c.dialPeer(ctx, *rinfo, dinfo) + + c.mx.Lock() + dedup.err = err + close(dedup.ch) + delete(c.activeDials, p) + c.mx.Unlock() + + return conn, err } func (c *Client) dialPeer(ctx context.Context, relay, dest peer.AddrInfo) (*Conn, error) { From 470c08899e910d8d6981c4667748af565eaab77c Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 25 Feb 2021 13:48:47 +0200 Subject: [PATCH 58/66] improve dialer deduplication --- v2/client/client.go | 5 +++-- v2/client/dial.go | 44 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/v2/client/client.go b/v2/client/client.go index 722ddf9..d1740e2 100644 --- a/v2/client/client.go +++ b/v2/client/client.go @@ -41,8 +41,9 @@ type accept struct { } type completion struct { - ch chan struct{} - err error + ch chan struct{} + relay peer.ID + err error } // New constructs a new p2p-circuit/v2 client, attached to the given host and using the given diff --git a/v2/client/dial.go b/v2/client/dial.go index fc5e957..20b64f9 100644 --- a/v2/client/dial.go +++ b/v2/client/dial.go @@ -21,6 +21,25 @@ const maxMessageSize = 4096 var DialTimeout = time.Minute +// relay protocol errors; used for signalling deduplication +type relayError struct { + err string +} + +func (e relayError) Error() string { + return e.err +} + +func newRelayError(t string, args ...interface{}) error { + return relayError{err: fmt.Sprintf(t, args...)} +} + +func isRelayError(err error) bool { + _, ok := err.(relayError) + return ok +} + +// dialer func (c *Client) dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (*Conn, error) { // split /a/p2p-circuit/b into (/a, /p2p-circuit/b) relayaddr, destaddr := ma.SplitFunc(a, func(c ma.Component) bool { @@ -50,11 +69,12 @@ func (c *Client) dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (*Conn, er return nil, fmt.Errorf("error parsing relay multiaddr '%s': %w", relayaddr, err) } + // deduplicate active relay dials to the same peer retry: c.mx.Lock() dedup, active := c.activeDials[p] if !active { - dedup = &completion{ch: make(chan struct{})} + dedup = &completion{ch: make(chan struct{}), relay: rinfo.ID} c.activeDials[p] = dedup } c.mx.Unlock() @@ -63,8 +83,20 @@ retry: select { case <-dedup.ch: if dedup.err != nil { - goto retry + if dedup.relay != rinfo.ID { + // different relay, retry + goto retry + } + + if !isRelayError(dedup.err) { + // not a relay protocol error, retry + goto retry + } + + // don't try the same relay if it failed to connect with a protocol error + return nil, fmt.Errorf("concurrent active dial through the same relay failed with a protocol error") } + return nil, fmt.Errorf("concurrent active dial succeeded") case <-ctx.Done(): @@ -138,13 +170,13 @@ func (c *Client) connectV2(s network.Stream, dest peer.AddrInfo) (*Conn, error) if msg.GetType() != pbv2.HopMessage_STATUS { s.Reset() - return nil, fmt.Errorf("unexpected relay response; not a status message (%d)", msg.GetType()) + return nil, newRelayError("unexpected relay response; not a status message (%d)", msg.GetType()) } status := msg.GetStatus() if status != pbv2.Status_OK { s.Reset() - return nil, fmt.Errorf("error opening relay circuit: %s (%d)", pbv2.Status_name[int32(status)], status) + return nil, newRelayError("error opening relay circuit: %s (%d)", pbv2.Status_name[int32(status)], status) } // check for a limit provided by the relay; if the limit is not nil, then this is a limited @@ -191,13 +223,13 @@ func (c *Client) connectV1(s network.Stream, dest peer.AddrInfo) (*Conn, error) if msg.GetType() != pbv1.CircuitRelay_STATUS { s.Reset() - return nil, fmt.Errorf("unexpected relay response; not a status message (%d)", msg.GetType()) + return nil, newRelayError("unexpected relay response; not a status message (%d)", msg.GetType()) } status := msg.GetCode() if status != pbv1.CircuitRelay_SUCCESS { s.Reset() - return nil, fmt.Errorf("error opening relay circuit: %s (%d)", pbv1.CircuitRelay_Status_name[int32(status)], status) + return nil, newRelayError("error opening relay circuit: %s (%d)", pbv1.CircuitRelay_Status_name[int32(status)], status) } return &Conn{stream: s, remote: dest, client: c}, nil From 233315156e04e95dd04ac6e8bd39c0df7e7618b0 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 9 Mar 2021 10:13:35 +0200 Subject: [PATCH 59/66] add a short timeout to dialing the relay in order to aid deduplication --- v2/client/dial.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/v2/client/dial.go b/v2/client/dial.go index 20b64f9..0ce1c18 100644 --- a/v2/client/dial.go +++ b/v2/client/dial.go @@ -20,6 +20,7 @@ import ( const maxMessageSize = 4096 var DialTimeout = time.Minute +var DialRelayTimeout = 5 * time.Second // relay protocol errors; used for signalling deduplication type relayError struct { @@ -122,7 +123,9 @@ func (c *Client) dialPeer(ctx context.Context, relay, dest peer.AddrInfo) (*Conn c.host.Peerstore().AddAddrs(relay.ID, relay.Addrs, peerstore.TempAddrTTL) } - s, err := c.host.NewStream(ctx, relay.ID, proto.ProtoIDv2Hop, proto.ProtoIDv1) + dialCtx, cancel := context.WithTimeout(ctx, DialRelayTimeout) + defer cancel() + s, err := c.host.NewStream(dialCtx, relay.ID, proto.ProtoIDv2Hop, proto.ProtoIDv1) if err != nil { return nil, fmt.Errorf("error opening hop stream to relay: %w", err) } From 84c6610f74583247c1a609faf78e591235a08ac9 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 9 Mar 2021 10:24:47 +0200 Subject: [PATCH 60/66] gomod: fix go1.16 madness --- go.mod | 4 ++-- go.sum | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 16815d8..cf8a6d1 100644 --- a/go.mod +++ b/go.mod @@ -8,10 +8,10 @@ require ( github.com/libp2p/go-buffer-pool v0.0.2 github.com/libp2p/go-libp2p-asn-util v0.0.0-20210211060025-0db24c10d3bd github.com/libp2p/go-libp2p-blankhost v0.2.0 - github.com/libp2p/go-libp2p-core v0.8.2 + github.com/libp2p/go-libp2p-core v0.8.3 github.com/libp2p/go-libp2p-metrics v0.1.0 github.com/libp2p/go-libp2p-peerstore v0.2.6 - github.com/libp2p/go-libp2p-swarm v0.4.2 + github.com/libp2p/go-libp2p-swarm v0.4.3 github.com/libp2p/go-libp2p-transport-upgrader v0.4.2 github.com/libp2p/go-msgio v0.0.6 github.com/libp2p/go-tcp-transport v0.2.0 diff --git a/go.sum b/go.sum index 634ad89..8312dfe 100644 --- a/go.sum +++ b/go.sum @@ -198,8 +198,9 @@ github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.2 h1:/eaSZACWftJZYm07S0nRxdI84v1hSmgnCXrGOvJdpNQ= github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.3 h1:BZTReEF6o8g/n4DwxTyeFannOeae35Xy0TD+mES3CNE= +github.com/libp2p/go-libp2p-core v0.8.3/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= github.com/libp2p/go-libp2p-metrics v0.1.0 h1:v7YMUTHNobFaQeqaMfJJMbnK3EPlZeb6/KFm4gE9dks= @@ -214,8 +215,8 @@ github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6n github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-quic-transport v0.10.0 h1:koDCbWD9CCHwcHZL3/WEvP2A+e/o5/W5L3QS/2SPMA0= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= -github.com/libp2p/go-libp2p-swarm v0.4.2 h1:rwZUsls+8dImHCcO2LZEa9+QGVF2tBSkywnA0PIYEJg= -github.com/libp2p/go-libp2p-swarm v0.4.2/go.mod h1:gNfZcYwyQJPNKEz3iyPfgwIJu7flqyBQOfCW+8paNCM= +github.com/libp2p/go-libp2p-swarm v0.4.3 h1:tAdkIj9gxMernQ6FTDPALnb8zAiw8xmcYz85FfA4oME= +github.com/libp2p/go-libp2p-swarm v0.4.3/go.mod h1:mmxP1pGBSc1Arw4F5DIjcpjFAmsRzA1KADuMtMuCT4g= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= From 30b71a393f0c25fa14cadd0f6a45814dce49d0e2 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 4 Jun 2021 11:55:19 +0300 Subject: [PATCH 61/66] spec compliance: don't include p2p-circuit in reservation addrs --- v2/relay/relay.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/v2/relay/relay.go b/v2/relay/relay.go index a2ae818..eed3c2c 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -49,7 +49,7 @@ type Relay struct { rsvp map[peer.ID]time.Time conns map[peer.ID]int - relayAddr ma.Multiaddr + selfAddr ma.Multiaddr } // New constructs a new limited relay that can provide relay services in the given host. @@ -74,7 +74,7 @@ func New(h host.Host, opts ...Option) (*Relay, error) { } r.ipcs = NewIPConstraints(r.rc) - r.relayAddr = ma.StringCast(fmt.Sprintf("/p2p/%s/p2p-circuit", h.ID())) + r.selfAddr = ma.StringCast(fmt.Sprintf("/p2p/%s", h.ID())) h.SetStreamHandler(proto.ProtoIDv2Hop, r.handleStream) h.Network().Notify( @@ -412,8 +412,8 @@ func (r *Relay) makeReservationMsg(p peer.ID, expire time.Time) *pbv2.Reservatio continue } - raddr := addr.Encapsulate(r.relayAddr) - addrBytes = append(addrBytes, raddr.Bytes()) + addr = addr.Encapsulate(r.selfAddr) + addrBytes = append(addrBytes, addr.Bytes()) } rsvp := &pbv2.Reservation{ From ffa309e1b389f5219a405efb021ec0820a61f520 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 4 Jun 2021 12:01:52 +0300 Subject: [PATCH 62/66] spec compliance: refuse reservation and connection attempts over relayed connections --- v2/relay/relay.go | 14 ++++++++++++++ v2/util/ma.go | 10 ++++++++++ 2 files changed, 24 insertions(+) create mode 100644 v2/util/ma.go diff --git a/v2/relay/relay.go b/v2/relay/relay.go index eed3c2c..55b8ed5 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -135,6 +135,12 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { p := s.Conn().RemotePeer() a := s.Conn().RemoteMultiaddr() + if util.IsRelayAddr(a) { + log.Debugf("refusing relay reservation for %s; reservation attempt over relay connection") + r.handleError(s, pbv2.Status_PERMISSION_DENIED) + return + } + if r.acl != nil && !r.acl.AllowReserve(p, a) { log.Debugf("refusing relay reservation for %s; permission denied", p) r.handleError(s, pbv2.Status_PERMISSION_DENIED) @@ -182,6 +188,14 @@ func (r *Relay) handleReserve(s network.Stream, msg *pbv2.HopMessage) { func (r *Relay) handleConnect(s network.Stream, msg *pbv2.HopMessage) { src := s.Conn().RemotePeer() + a := s.Conn().RemoteMultiaddr() + + if util.IsRelayAddr(a) { + log.Debugf("refusing connection from %s; connection attempt over relay connection") + r.handleError(s, pbv2.Status_PERMISSION_DENIED) + return + } + dest, err := util.PeerToPeerInfoV2(msg.GetPeer()) if err != nil { r.handleError(s, pbv2.Status_MALFORMED_MESSAGE) diff --git a/v2/util/ma.go b/v2/util/ma.go new file mode 100644 index 0000000..0dd820e --- /dev/null +++ b/v2/util/ma.go @@ -0,0 +1,10 @@ +package util + +import ( + ma "github.com/multiformats/go-multiaddr" +) + +func IsRelayAddr(a ma.Multiaddr) bool { + _, err := a.ValueForProtocol(ma.P_CIRCUIT) + return err == nil +} From 12eefbc827535748656731217d1a8b4ea29f27e7 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 4 Jun 2021 12:02:06 +0300 Subject: [PATCH 63/66] test shim: add empty file in test directory --- v2/test/empty.go | 1 + 1 file changed, 1 insertion(+) create mode 100644 v2/test/empty.go diff --git a/v2/test/empty.go b/v2/test/empty.go new file mode 100644 index 0000000..56e5404 --- /dev/null +++ b/v2/test/empty.go @@ -0,0 +1 @@ +package test From b4d0d1a42f750fb41eda543b27e3928c2e183bce Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 4 Jun 2021 12:07:58 +0300 Subject: [PATCH 64/66] spec compliance: update protobuf --- v2/client/reservation.go | 4 +- v2/pb/circuit.pb.go | 90 ++++++++++++++++++++-------------------- v2/pb/circuit.proto | 6 +-- v2/relay/relay.go | 6 +-- 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/v2/client/reservation.go b/v2/client/reservation.go index 975fdd1..f874061 100644 --- a/v2/client/reservation.go +++ b/v2/client/reservation.go @@ -31,7 +31,7 @@ type Reservation struct { LimitDuration time.Duration // LimitData is the number of bytes that the relay will relay in each direction before // resetting a relayed connection. - LimitData int64 + LimitData uint64 // Voucher is a signed reservation voucher provided by the relay Voucher *proto.ReservationVoucher @@ -85,7 +85,7 @@ func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation, } result := &Reservation{} - result.Expiration = time.Unix(rsvp.GetExpire(), 0) + result.Expiration = time.Unix(int64(rsvp.GetExpire()), 0) for _, ab := range rsvp.GetAddrs() { a, err := ma.NewMultiaddrBytes(ab) diff --git a/v2/pb/circuit.pb.go b/v2/pb/circuit.pb.go index bab44a7..f908d0d 100644 --- a/v2/pb/circuit.pb.go +++ b/v2/pb/circuit.pb.go @@ -370,7 +370,7 @@ func (m *Peer) GetAddrs() [][]byte { } type Reservation struct { - Expire *int64 `protobuf:"varint,1,opt,name=expire" json:"expire,omitempty"` + Expire *uint64 `protobuf:"varint,1,opt,name=expire" json:"expire,omitempty"` Addrs [][]byte `protobuf:"bytes,2,rep,name=addrs" json:"addrs,omitempty"` Voucher []byte `protobuf:"bytes,3,opt,name=voucher" json:"voucher,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -411,7 +411,7 @@ func (m *Reservation) XXX_DiscardUnknown() { var xxx_messageInfo_Reservation proto.InternalMessageInfo -func (m *Reservation) GetExpire() int64 { +func (m *Reservation) GetExpire() uint64 { if m != nil && m.Expire != nil { return *m.Expire } @@ -433,8 +433,8 @@ func (m *Reservation) GetVoucher() []byte { } type Limit struct { - Duration *int32 `protobuf:"varint,1,opt,name=duration" json:"duration,omitempty"` - Data *int64 `protobuf:"varint,2,opt,name=data" json:"data,omitempty"` + Duration *uint32 `protobuf:"varint,1,opt,name=duration" json:"duration,omitempty"` + Data *uint64 `protobuf:"varint,2,opt,name=data" json:"data,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -473,14 +473,14 @@ func (m *Limit) XXX_DiscardUnknown() { var xxx_messageInfo_Limit proto.InternalMessageInfo -func (m *Limit) GetDuration() int32 { +func (m *Limit) GetDuration() uint32 { if m != nil && m.Duration != nil { return *m.Duration } return 0 } -func (m *Limit) GetData() int64 { +func (m *Limit) GetData() uint64 { if m != nil && m.Data != nil { return *m.Data } @@ -501,40 +501,40 @@ func init() { func init() { proto.RegisterFile("circuit.proto", fileDescriptor_ed01bbc211f15e47) } var fileDescriptor_ed01bbc211f15e47 = []byte{ - // 515 bytes of a gzipped FileDescriptorProto + // 516 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0xcf, 0x8a, 0xd3, 0x50, - 0x14, 0xc6, 0xe7, 0x26, 0x69, 0x47, 0x4e, 0x6b, 0xc9, 0x9c, 0x91, 0x69, 0xd0, 0xa1, 0x96, 0x22, - 0x58, 0x06, 0xa9, 0xd2, 0x8d, 0xb8, 0xac, 0xcd, 0xa9, 0x06, 0x9b, 0xa4, 0xdc, 0x9b, 0xca, 0xec, - 0x4a, 0x6c, 0x2e, 0x1a, 0x50, 0x1b, 0x92, 0x74, 0x70, 0xde, 0x42, 0x1f, 0xc1, 0x17, 0x71, 0x3d, - 0xfe, 0x59, 0xb8, 0x77, 0x23, 0x7d, 0x12, 0xc9, 0x6d, 0xa7, 0xcd, 0x80, 0xa0, 0x30, 0xbb, 0x7c, - 0xf7, 0xfb, 0x4e, 0x6e, 0x7e, 0xdf, 0x09, 0xdc, 0x9c, 0xc7, 0xe9, 0x7c, 0x19, 0xe7, 0xbd, 0x24, - 0x5d, 0xe4, 0x0b, 0x84, 0xad, 0x7c, 0xd5, 0xf9, 0xac, 0x01, 0x3c, 0x5f, 0x24, 0xae, 0xcc, 0xb2, - 0xf0, 0xb5, 0xc4, 0x87, 0x60, 0xe4, 0xe7, 0x89, 0xb4, 0x58, 0x5b, 0xeb, 0x36, 0xfa, 0x77, 0x7a, - 0xbb, 0x64, 0x6f, 0x97, 0xea, 0x05, 0xe7, 0x89, 0xe4, 0x2a, 0x88, 0xf7, 0xc0, 0x48, 0xa4, 0x4c, - 0x2d, 0xad, 0xcd, 0xba, 0xb5, 0xbe, 0x59, 0x1e, 0x98, 0x48, 0x99, 0x72, 0xe5, 0xe2, 0x13, 0xa8, - 0xa5, 0x32, 0x93, 0xe9, 0x59, 0x98, 0xc7, 0x8b, 0xf7, 0x96, 0xae, 0xc2, 0xcd, 0x72, 0x98, 0xef, - 0x6c, 0x5e, 0xce, 0xe2, 0x7d, 0xa8, 0xbc, 0x8d, 0xdf, 0xc5, 0xb9, 0x65, 0xa8, 0xa1, 0x83, 0xf2, - 0xd0, 0xb8, 0x30, 0xf8, 0xda, 0xc7, 0x13, 0xa8, 0x66, 0x79, 0x98, 0x2f, 0x33, 0xab, 0xd2, 0x66, - 0xdd, 0x46, 0x1f, 0xcb, 0x49, 0xa1, 0x1c, 0xbe, 0x49, 0x74, 0x1e, 0x80, 0x51, 0x30, 0x60, 0x0d, - 0xf6, 0x39, 0x09, 0xe2, 0x2f, 0xc9, 0xdc, 0x2b, 0xc4, 0xd0, 0xf7, 0x3c, 0x1a, 0x06, 0x26, 0x43, - 0x80, 0xaa, 0x08, 0x06, 0xc1, 0x54, 0x98, 0x5a, 0xe7, 0x17, 0x83, 0x9a, 0xc8, 0x77, 0x25, 0x3d, - 0xba, 0x52, 0xd2, 0xf1, 0xd5, 0x7b, 0xae, 0xd1, 0xd2, 0x16, 0x55, 0xff, 0x6f, 0x54, 0xe3, 0x9f, - 0xa8, 0x77, 0x77, 0xa8, 0x97, 0x74, 0x7b, 0x25, 0x3a, 0x56, 0x74, 0x51, 0x7c, 0x03, 0x36, 0x40, - 0x8b, 0x23, 0xc5, 0x54, 0xe7, 0x5a, 0x1c, 0xe1, 0x2d, 0xa8, 0x84, 0x51, 0x94, 0x66, 0x96, 0xd6, - 0xd6, 0xbb, 0x75, 0xbe, 0x16, 0x9d, 0x29, 0xd4, 0x4a, 0xab, 0xc2, 0x23, 0xa8, 0xca, 0x0f, 0x49, - 0x9c, 0x16, 0x65, 0xb0, 0xae, 0xce, 0x37, 0xea, 0xef, 0xc3, 0x68, 0xc1, 0xfe, 0xd9, 0x62, 0x39, - 0x7f, 0x23, 0x53, 0x85, 0x58, 0xe7, 0x97, 0xb2, 0xf3, 0x18, 0x2a, 0x8a, 0x10, 0x6f, 0xc3, 0x8d, - 0x68, 0x99, 0xae, 0x7f, 0x93, 0xe2, 0x95, 0x15, 0xbe, 0xd5, 0x88, 0x60, 0x44, 0x61, 0x1e, 0xaa, - 0x16, 0x75, 0xae, 0x9e, 0x4f, 0xbe, 0x30, 0xa8, 0xae, 0x89, 0xb1, 0x0a, 0x9a, 0xff, 0xc2, 0x8c, - 0xd0, 0x82, 0xc3, 0xf5, 0x52, 0x07, 0x81, 0xe3, 0x7b, 0x33, 0x4e, 0xa3, 0xa9, 0x20, 0xdb, 0xbc, - 0x60, 0x78, 0x0c, 0x4d, 0x4e, 0xc2, 0x9f, 0xf2, 0x21, 0xcd, 0xc6, 0x8e, 0xeb, 0x04, 0x33, 0x3a, - 0x1d, 0x12, 0xd9, 0x64, 0x9b, 0x5f, 0x19, 0x1e, 0xc1, 0xc1, 0x84, 0xb8, 0xeb, 0x08, 0x51, 0x8c, - 0xd9, 0xe4, 0x39, 0x64, 0x9b, 0xdf, 0xd4, 0xf9, 0xa6, 0xb9, 0xe2, 0x7c, 0x34, 0x70, 0xc6, 0x64, - 0x9b, 0xdf, 0x19, 0x1e, 0x42, 0xc3, 0xf3, 0x67, 0xa5, 0xab, 0xcc, 0x1f, 0x2a, 0xec, 0x0e, 0xc6, - 0x23, 0x9f, 0xbb, 0x64, 0xcf, 0x5c, 0x12, 0x62, 0xf0, 0x8c, 0xcc, 0x8f, 0x3a, 0x36, 0x01, 0xa7, - 0x1e, 0x9d, 0x4e, 0x68, 0x18, 0x94, 0x8c, 0x4f, 0xfa, 0xd3, 0xfa, 0xc5, 0xaa, 0xc5, 0x7e, 0xae, - 0x5a, 0xec, 0xf7, 0xaa, 0xc5, 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0x83, 0xf2, 0x9c, 0x78, 0xaa, - 0x03, 0x00, 0x00, + 0x14, 0xc6, 0xe7, 0xa6, 0x69, 0x47, 0x4e, 0x3b, 0xe5, 0xce, 0x19, 0x99, 0x09, 0x3a, 0x8c, 0xa5, + 0x08, 0x96, 0x41, 0xaa, 0x74, 0x23, 0x2e, 0x6b, 0x73, 0xaa, 0xc1, 0x26, 0x29, 0xf7, 0xa6, 0x32, + 0xbb, 0x12, 0x9b, 0x8b, 0x06, 0xd4, 0x86, 0x24, 0x1d, 0x9c, 0xb7, 0xd0, 0x47, 0xf0, 0x45, 0x5c, + 0x8f, 0x7f, 0x16, 0xee, 0xdd, 0x48, 0x9f, 0x44, 0x72, 0xdb, 0x69, 0x33, 0x20, 0x28, 0xb8, 0xcb, + 0x77, 0xbf, 0xef, 0xe4, 0xe6, 0xf7, 0x9d, 0xc0, 0xde, 0x2c, 0x4e, 0x67, 0x8b, 0x38, 0xef, 0x26, + 0xe9, 0x3c, 0x9f, 0x23, 0x6c, 0xe4, 0xcb, 0xf6, 0x27, 0x03, 0xe0, 0xd9, 0x3c, 0x71, 0x55, 0x96, + 0x85, 0xaf, 0x14, 0x3e, 0x00, 0x33, 0xbf, 0x48, 0x94, 0xc5, 0x5a, 0x46, 0xa7, 0xd9, 0xbb, 0xdd, + 0xdd, 0x26, 0xbb, 0xdb, 0x54, 0x37, 0xb8, 0x48, 0x94, 0xd0, 0x41, 0xbc, 0x0b, 0x66, 0xa2, 0x54, + 0x6a, 0x19, 0x2d, 0xd6, 0xa9, 0xf7, 0x78, 0x79, 0x60, 0xac, 0x54, 0x2a, 0xb4, 0x8b, 0x8f, 0xa1, + 0x9e, 0xaa, 0x4c, 0xa5, 0xe7, 0x61, 0x1e, 0xcf, 0xdf, 0x59, 0x15, 0x1d, 0x3e, 0x2a, 0x87, 0xc5, + 0xd6, 0x16, 0xe5, 0x2c, 0xde, 0x83, 0xea, 0x9b, 0xf8, 0x6d, 0x9c, 0x5b, 0xa6, 0x1e, 0xda, 0x2f, + 0x0f, 0x8d, 0x0a, 0x43, 0xac, 0x7c, 0x3c, 0x85, 0x5a, 0x96, 0x87, 0xf9, 0x22, 0xb3, 0xaa, 0x2d, + 0xd6, 0x69, 0xf6, 0xb0, 0x9c, 0x94, 0xda, 0x11, 0xeb, 0x44, 0xfb, 0x3e, 0x98, 0x05, 0x03, 0xd6, + 0x61, 0x57, 0x90, 0x24, 0xf1, 0x82, 0xf8, 0x4e, 0x21, 0x06, 0xbe, 0xe7, 0xd1, 0x20, 0xe0, 0x0c, + 0x01, 0x6a, 0x32, 0xe8, 0x07, 0x13, 0xc9, 0x8d, 0xf6, 0x4f, 0x06, 0x75, 0x99, 0x6f, 0x4b, 0x7a, + 0x78, 0xad, 0xa4, 0xe3, 0xeb, 0xf7, 0xfc, 0x47, 0x4b, 0x1b, 0xd4, 0xca, 0x3f, 0xa3, 0x9a, 0x7f, + 0x45, 0xbd, 0xb3, 0x45, 0xbd, 0xa2, 0xdb, 0x29, 0xd1, 0xb1, 0xa2, 0x8b, 0xe2, 0x1b, 0xb0, 0x09, + 0x46, 0x1c, 0x69, 0xa6, 0x86, 0x30, 0xe2, 0x08, 0x6f, 0x42, 0x35, 0x8c, 0xa2, 0x34, 0xb3, 0x8c, + 0x56, 0xa5, 0xd3, 0x10, 0x2b, 0xd1, 0x9e, 0x40, 0xbd, 0xb4, 0x2a, 0x3c, 0x84, 0x9a, 0x7a, 0x9f, + 0xc4, 0x69, 0x51, 0x06, 0xeb, 0x98, 0x62, 0xad, 0xfe, 0x3c, 0x8c, 0x16, 0xec, 0x9e, 0xcf, 0x17, + 0xb3, 0xd7, 0x2a, 0xd5, 0x88, 0x0d, 0x71, 0x25, 0xdb, 0x8f, 0xa0, 0xaa, 0x09, 0xf1, 0x16, 0xdc, + 0x88, 0x16, 0xe9, 0xea, 0x37, 0x29, 0x5e, 0xb9, 0x27, 0x36, 0x1a, 0x11, 0xcc, 0x28, 0xcc, 0x43, + 0xdd, 0xa2, 0x29, 0xf4, 0xf3, 0xe9, 0x67, 0x06, 0xb5, 0x15, 0x31, 0xd6, 0xc0, 0xf0, 0x9f, 0xf3, + 0x08, 0x2d, 0x38, 0x58, 0x2d, 0xb5, 0x1f, 0x38, 0xbe, 0x37, 0x15, 0x34, 0x9c, 0x48, 0xb2, 0xf9, + 0x25, 0xc3, 0x63, 0x38, 0x12, 0x24, 0xfd, 0x89, 0x18, 0xd0, 0x74, 0xe4, 0xb8, 0x4e, 0x30, 0xa5, + 0xb3, 0x01, 0x91, 0x4d, 0x36, 0xff, 0xc2, 0xf0, 0x10, 0xf6, 0xc7, 0x24, 0x5c, 0x47, 0xca, 0x62, + 0xcc, 0x26, 0xcf, 0x21, 0x9b, 0x7f, 0xd5, 0xe7, 0xeb, 0xe6, 0x8a, 0xf3, 0x61, 0xdf, 0x19, 0x91, + 0xcd, 0xbf, 0x31, 0x3c, 0x80, 0xa6, 0xe7, 0x4f, 0x4b, 0x57, 0xf1, 0xef, 0x3a, 0xec, 0xf6, 0x47, + 0x43, 0x5f, 0xb8, 0x64, 0x4f, 0x5d, 0x92, 0xb2, 0xff, 0x94, 0xf8, 0x87, 0x0a, 0x1e, 0x01, 0x4e, + 0x3c, 0x3a, 0x1b, 0xd3, 0x20, 0x28, 0x19, 0x1f, 0x2b, 0x4f, 0x1a, 0x97, 0xcb, 0x13, 0xf6, 0x63, + 0x79, 0xc2, 0x7e, 0x2d, 0x4f, 0xd8, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa7, 0x24, 0x77, 0x69, + 0xaa, 0x03, 0x00, 0x00, } func (m *HopMessage) Marshal() (dAtA []byte, err error) { @@ -1479,7 +1479,7 @@ func (m *Reservation) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Expire", wireType) } - var v int64 + var v uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCircuit @@ -1489,7 +1489,7 @@ func (m *Reservation) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int64(b&0x7F) << shift + v |= uint64(b&0x7F) << shift if b < 0x80 { break } @@ -1619,7 +1619,7 @@ func (m *Limit) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) } - var v int32 + var v uint32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCircuit @@ -1629,7 +1629,7 @@ func (m *Limit) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int32(b&0x7F) << shift + v |= uint32(b&0x7F) << shift if b < 0x80 { break } @@ -1639,7 +1639,7 @@ func (m *Limit) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) } - var v int64 + var v uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCircuit @@ -1649,7 +1649,7 @@ func (m *Limit) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int64(b&0x7F) << shift + v |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/v2/pb/circuit.proto b/v2/pb/circuit.proto index e3f8236..b73555c 100644 --- a/v2/pb/circuit.proto +++ b/v2/pb/circuit.proto @@ -38,14 +38,14 @@ message Peer { } message Reservation { - optional int64 expire = 1; // Unix expiration time (UTC) + optional uint64 expire = 1; // Unix expiration time (UTC) repeated bytes addrs = 2; // relay addrs for reserving peer optional bytes voucher = 3; // reservation voucher } message Limit { - optional int32 duration = 1; // seconds - optional int64 data = 2; // bytes + optional uint32 duration = 1; // seconds + optional uint64 data = 2; // bytes } enum Status { diff --git a/v2/relay/relay.go b/v2/relay/relay.go index 55b8ed5..f092d9a 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -418,7 +418,7 @@ func (r *Relay) writeResponse(s network.Stream, status pbv2.Status, rsvp *pbv2.R } func (r *Relay) makeReservationMsg(p peer.ID, expire time.Time) *pbv2.Reservation { - expireUnix := expire.Unix() + expireUnix := uint64(expire.Unix()) var addrBytes [][]byte for _, addr := range r.host.Addrs() { @@ -463,8 +463,8 @@ func (r *Relay) makeLimitMsg(p peer.ID) *pbv2.Limit { return nil } - duration := int32(r.rc.Limit.Duration / time.Second) - data := int64(r.rc.Limit.Data) + duration := uint32(r.rc.Limit.Duration / time.Second) + data := uint64(r.rc.Limit.Data) return &pbv2.Limit{ Duration: &duration, From e1bbd83b206cbbc51fd21ade2b703c32b9b53566 Mon Sep 17 00:00:00 2001 From: vyzo Date: Fri, 4 Jun 2021 12:38:11 +0300 Subject: [PATCH 65/66] spec compliance: use libp2p envelopes for reservation vouchers --- v2/client/reservation.go | 13 +- v2/pb/voucher.pb.go | 438 +++++++++++++++++++++++++++++++++++++++ v2/pb/voucher.proto | 9 + v2/proto/voucher.go | 137 ++++-------- v2/proto/voucher_test.go | 14 +- v2/relay/relay.go | 7 +- 6 files changed, 499 insertions(+), 119 deletions(-) create mode 100644 v2/pb/voucher.pb.go create mode 100644 v2/pb/voucher.proto diff --git a/v2/client/reservation.go b/v2/client/reservation.go index f874061..49b0a47 100644 --- a/v2/client/reservation.go +++ b/v2/client/reservation.go @@ -12,6 +12,7 @@ import ( "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p-core/record" ma "github.com/multiformats/go-multiaddr" ) @@ -98,16 +99,14 @@ func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation, voucherBytes := rsvp.GetVoucher() if voucherBytes != nil { - voucher := new(proto.ReservationVoucher) - - err := voucher.Unmarshal(voucherBytes) + _, rec, err := record.ConsumeEnvelope(voucherBytes, proto.RecordDomain) if err != nil { - return nil, fmt.Errorf("error unmarshalling reservation voucher from relay: %w", err) + return nil, fmt.Errorf("error consuming voucher envelope: %w", err) } - err = voucher.Verify(h.Peerstore().PubKey(ai.ID)) - if err != nil { - return nil, fmt.Errorf("error verifying voucher from relay: %w", err) + voucher, ok := rec.(*proto.ReservationVoucher) + if !ok { + return nil, fmt.Errorf("unexpected voucher record type: %+T", rec) } result.Voucher = voucher diff --git a/v2/pb/voucher.pb.go b/v2/pb/voucher.pb.go new file mode 100644 index 0000000..6fed008 --- /dev/null +++ b/v2/pb/voucher.pb.go @@ -0,0 +1,438 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: voucher.proto + +package circuit_pb + +import ( + fmt "fmt" + github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type ReservationVoucher struct { + Relay []byte `protobuf:"bytes,1,req,name=relay" json:"relay,omitempty"` + Peer []byte `protobuf:"bytes,2,req,name=peer" json:"peer,omitempty"` + Expiration *uint64 `protobuf:"varint,3,req,name=expiration" json:"expiration,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ReservationVoucher) Reset() { *m = ReservationVoucher{} } +func (m *ReservationVoucher) String() string { return proto.CompactTextString(m) } +func (*ReservationVoucher) ProtoMessage() {} +func (*ReservationVoucher) Descriptor() ([]byte, []int) { + return fileDescriptor_a22a9b0d3335ba25, []int{0} +} +func (m *ReservationVoucher) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ReservationVoucher) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ReservationVoucher.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ReservationVoucher) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReservationVoucher.Merge(m, src) +} +func (m *ReservationVoucher) XXX_Size() int { + return m.Size() +} +func (m *ReservationVoucher) XXX_DiscardUnknown() { + xxx_messageInfo_ReservationVoucher.DiscardUnknown(m) +} + +var xxx_messageInfo_ReservationVoucher proto.InternalMessageInfo + +func (m *ReservationVoucher) GetRelay() []byte { + if m != nil { + return m.Relay + } + return nil +} + +func (m *ReservationVoucher) GetPeer() []byte { + if m != nil { + return m.Peer + } + return nil +} + +func (m *ReservationVoucher) GetExpiration() uint64 { + if m != nil && m.Expiration != nil { + return *m.Expiration + } + return 0 +} + +func init() { + proto.RegisterType((*ReservationVoucher)(nil), "circuit.pb.ReservationVoucher") +} + +func init() { proto.RegisterFile("voucher.proto", fileDescriptor_a22a9b0d3335ba25) } + +var fileDescriptor_a22a9b0d3335ba25 = []byte{ + // 135 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2d, 0xcb, 0x2f, 0x4d, + 0xce, 0x48, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4a, 0xce, 0x2c, 0x4a, 0x2e, + 0xcd, 0x2c, 0xd1, 0x2b, 0x48, 0x52, 0x8a, 0xe3, 0x12, 0x0a, 0x4a, 0x2d, 0x4e, 0x2d, 0x2a, 0x4b, + 0x2c, 0xc9, 0xcc, 0xcf, 0x0b, 0x83, 0xa8, 0x13, 0x12, 0xe1, 0x62, 0x2d, 0x4a, 0xcd, 0x49, 0xac, + 0x94, 0x60, 0x54, 0x60, 0xd2, 0xe0, 0x09, 0x82, 0x70, 0x84, 0x84, 0xb8, 0x58, 0x0a, 0x52, 0x53, + 0x8b, 0x24, 0x98, 0xc0, 0x82, 0x60, 0xb6, 0x90, 0x1c, 0x17, 0x57, 0x6a, 0x45, 0x41, 0x66, 0x11, + 0x58, 0xbb, 0x04, 0xb3, 0x02, 0x93, 0x06, 0x4b, 0x10, 0x92, 0x88, 0x13, 0xcf, 0x89, 0x47, 0x72, + 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x08, 0x08, 0x00, 0x00, 0xff, 0xff, 0xc0, + 0x81, 0x3a, 0xee, 0x89, 0x00, 0x00, 0x00, +} + +func (m *ReservationVoucher) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ReservationVoucher) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ReservationVoucher) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Expiration == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("expiration") + } else { + i = encodeVarintVoucher(dAtA, i, uint64(*m.Expiration)) + i-- + dAtA[i] = 0x18 + } + if m.Peer == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("peer") + } else { + i -= len(m.Peer) + copy(dAtA[i:], m.Peer) + i = encodeVarintVoucher(dAtA, i, uint64(len(m.Peer))) + i-- + dAtA[i] = 0x12 + } + if m.Relay == nil { + return 0, github_com_gogo_protobuf_proto.NewRequiredNotSetError("relay") + } else { + i -= len(m.Relay) + copy(dAtA[i:], m.Relay) + i = encodeVarintVoucher(dAtA, i, uint64(len(m.Relay))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintVoucher(dAtA []byte, offset int, v uint64) int { + offset -= sovVoucher(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ReservationVoucher) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Relay != nil { + l = len(m.Relay) + n += 1 + l + sovVoucher(uint64(l)) + } + if m.Peer != nil { + l = len(m.Peer) + n += 1 + l + sovVoucher(uint64(l)) + } + if m.Expiration != nil { + n += 1 + sovVoucher(uint64(*m.Expiration)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovVoucher(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozVoucher(x uint64) (n int) { + return sovVoucher(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ReservationVoucher) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVoucher + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ReservationVoucher: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ReservationVoucher: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Relay", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVoucher + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthVoucher + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthVoucher + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Relay = append(m.Relay[:0], dAtA[iNdEx:postIndex]...) + if m.Relay == nil { + m.Relay = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Peer", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVoucher + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthVoucher + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthVoucher + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Peer = append(m.Peer[:0], dAtA[iNdEx:postIndex]...) + if m.Peer == nil { + m.Peer = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Expiration", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVoucher + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Expiration = &v + hasFields[0] |= uint64(0x00000004) + default: + iNdEx = preIndex + skippy, err := skipVoucher(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthVoucher + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthVoucher + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("relay") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("peer") + } + if hasFields[0]&uint64(0x00000004) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("expiration") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipVoucher(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowVoucher + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowVoucher + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowVoucher + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthVoucher + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupVoucher + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthVoucher + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthVoucher = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowVoucher = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupVoucher = fmt.Errorf("proto: unexpected end of group") +) diff --git a/v2/pb/voucher.proto b/v2/pb/voucher.proto new file mode 100644 index 0000000..0864402 --- /dev/null +++ b/v2/pb/voucher.proto @@ -0,0 +1,9 @@ +syntax = "proto2"; + +package circuit.pb; + +message ReservationVoucher { + required bytes relay = 1; + required bytes peer = 2; + required uint64 expiration = 3; +} diff --git a/v2/proto/voucher.go b/v2/proto/voucher.go index 3669de4..76db111 100644 --- a/v2/proto/voucher.go +++ b/v2/proto/voucher.go @@ -1,15 +1,23 @@ package proto import ( - "bytes" - "encoding/binary" - "fmt" "time" - "github.com/libp2p/go-libp2p-core/crypto" + pbv2 "github.com/libp2p/go-libp2p-circuit/v2/pb" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/record" ) +const RecordDomain = "libp2p-relay-rsvp" + +// TODO: register in multicodec table in https://github.com/multiformats/multicodec +var RecordCodec = []byte{0x03, 0x02} + +func init() { + record.RegisterType(&ReservationVoucher{}) +} + type ReservationVoucher struct { // Relay is the ID of the peer providing relay service Relay peer.ID @@ -17,123 +25,48 @@ type ReservationVoucher struct { Peer peer.ID // Expiration is the expiration time of the reservation Expiration time.Time - // Signature is the signature of this voucher, as produced by the Relay peer - Signature []byte } -func (rv *ReservationVoucher) bytes() []byte { - buf := make([]byte, 1024) - relayBytes := []byte(rv.Relay) - peerBytes := []byte(rv.Peer) - expireUnix := rv.Expiration.Unix() +var _ record.Record = (*ReservationVoucher)(nil) - n := binary.PutUvarint(buf, uint64(len(relayBytes))) - n += copy(buf[n:], relayBytes) - n += binary.PutUvarint(buf[n:], uint64(len(peerBytes))) - n += copy(buf[n:], peerBytes) - n += binary.PutUvarint(buf[n:], uint64(expireUnix)) - - return buf[:n] +func (rv *ReservationVoucher) Domain() string { + return RecordDomain } -func (rv *ReservationVoucher) Sign(privk crypto.PrivKey) error { - if rv.Signature != nil { - return nil - } - - blob := append([]byte("libp2p-relay-rsvp:"), rv.bytes()...) - - sig, err := privk.Sign(blob) - if err != nil { - return err - } - - rv.Signature = sig - return nil +func (rv *ReservationVoucher) Codec() []byte { + return RecordCodec } -func (rv *ReservationVoucher) Verify(pubk crypto.PubKey) error { - if rv.Signature == nil { - return fmt.Errorf("missing signature") +func (rv *ReservationVoucher) MarshalRecord() ([]byte, error) { + relay := []byte(rv.Relay) + peer := []byte(rv.Peer) + expiration := uint64(rv.Expiration.Unix()) + pbrv := &pbv2.ReservationVoucher{ + Relay: relay, + Peer: peer, + Expiration: &expiration, } - blob := append([]byte("libp2p-relay-rsvp:"), rv.bytes()...) - - ok, err := pubk.Verify(blob, rv.Signature) - if err != nil { - return fmt.Errorf("signature verification error: %w", err) - } - if !ok { - return fmt.Errorf("signature verifcation failed") - } - - return nil + return pbrv.Marshal() } -func (rv *ReservationVoucher) Marshal() ([]byte, error) { - if rv.Signature == nil { - return nil, fmt.Errorf("cannot marshal unsigned reservation voucher") - } - - blob := rv.bytes() - result := make([]byte, len(blob)+len(rv.Signature)) - copy(result, blob) - copy(result[len(blob):], rv.Signature) - - return result, nil -} - -func (rv *ReservationVoucher) Unmarshal(blob []byte) error { - rd := bytes.NewReader(blob) - - readID := func() (peer.ID, error) { - idLen, err := binary.ReadUvarint(rd) - if err != nil { - return "", fmt.Errorf("error reading ID length: %w", err) - } - if idLen > uint64(rd.Len()) { - return "", fmt.Errorf("error reading ID: ID length exceeds available bytes") - } - - idBytes := make([]byte, int(idLen)) - n, err := rd.Read(idBytes) - if err != nil { - return "", fmt.Errorf("error reading ID: %w", err) - } - if n != len(idBytes) { - return "", fmt.Errorf("error reading ID: not enough bytes read") - } - - return peer.IDFromBytes(idBytes) - } - - var err error - - rv.Relay, err = readID() - if err != nil { - return fmt.Errorf("error reading relay ID: %w", err) - } - - rv.Peer, err = readID() +func (rv *ReservationVoucher) UnmarshalRecord(blob []byte) error { + pbrv := pbv2.ReservationVoucher{} + err := pbrv.Unmarshal(blob) if err != nil { - return fmt.Errorf("error reading peer ID: %w", err) + return err } - expireUnix, err := binary.ReadUvarint(rd) + rv.Relay, err = peer.IDFromBytes(pbrv.GetRelay()) if err != nil { - return fmt.Errorf("error reading reservation expiration: %w", err) + return err } - rv.Expiration = time.Unix(int64(expireUnix), 0) - sig := make([]byte, rd.Len()) - n, err := rd.Read(sig) + rv.Peer, err = peer.IDFromBytes(pbrv.GetPeer()) if err != nil { - return fmt.Errorf("error reading signature: %w", err) - } - if n != len(sig) { - return fmt.Errorf("error reading signature: not enough bytes read") + return err } - rv.Signature = sig + rv.Expiration = time.Unix(int64(pbrv.GetExpiration()), 0) return nil } diff --git a/v2/proto/voucher_test.go b/v2/proto/voucher_test.go index eb61c0a..ce450e7 100644 --- a/v2/proto/voucher_test.go +++ b/v2/proto/voucher_test.go @@ -6,6 +6,7 @@ import ( "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/record" ) func TestReservationVoucher(t *testing.T) { @@ -35,25 +36,24 @@ func TestReservationVoucher(t *testing.T) { Expiration: time.Now().Add(time.Hour), } - err = rsvp.Sign(relayPrivk) + envelope, err := record.Seal(rsvp, relayPrivk) if err != nil { t.Fatal(err) } - blob, err := rsvp.Marshal() + blob, err := envelope.Marshal() if err != nil { t.Fatal(err) } - rsvp2 := new(ReservationVoucher) - err = rsvp2.Unmarshal(blob) + envelope, rec, err := record.ConsumeEnvelope(blob, RecordDomain) if err != nil { t.Fatal(err) } - err = rsvp2.Verify(relayPubk) - if err != nil { - t.Fatal(err) + rsvp2, ok := rec.(*ReservationVoucher) + if !ok { + t.Fatalf("invalid record type %+T", rec) } if rsvp.Relay != rsvp2.Relay { diff --git a/v2/relay/relay.go b/v2/relay/relay.go index f092d9a..f1fa5ad 100644 --- a/v2/relay/relay.go +++ b/v2/relay/relay.go @@ -15,6 +15,7 @@ import ( "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/record" logging "github.com/ipfs/go-log" pool "github.com/libp2p/go-buffer-pool" @@ -441,13 +442,13 @@ func (r *Relay) makeReservationMsg(p peer.ID, expire time.Time) *pbv2.Reservatio Expiration: expire, } - err := voucher.Sign(r.host.Peerstore().PrivKey(r.host.ID())) + envelope, err := record.Seal(voucher, r.host.Peerstore().PrivKey(r.host.ID())) if err != nil { - log.Errorf("error signing voucher for %s: %s", p, err) + log.Errorf("error sealing voucher for %s: %s", p, err) return rsvp } - blob, err := voucher.Marshal() + blob, err := envelope.Marshal() if err != nil { log.Errorf("error marshalling voucher for %s: %s", p, err) return rsvp From 97ec1d687581b6fba2880e8de84d8c59dda62a79 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 30 Jun 2021 11:38:16 -0700 Subject: [PATCH 66/66] fix staticcheck --- go.mod | 1 - go.sum | 3 --- v2/proto/voucher_test.go | 2 +- v2/test/compat_test.go | 6 ++++++ v2/test/e2e_test.go | 5 ++++- v2/util/io.go | 2 +- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index cf8a6d1..5f9c0d7 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.0.0-20210211060025-0db24c10d3bd github.com/libp2p/go-libp2p-blankhost v0.2.0 github.com/libp2p/go-libp2p-core v0.8.3 - github.com/libp2p/go-libp2p-metrics v0.1.0 github.com/libp2p/go-libp2p-peerstore v0.2.6 github.com/libp2p/go-libp2p-swarm v0.4.3 github.com/libp2p/go-libp2p-transport-upgrader v0.4.2 diff --git a/go.sum b/go.sum index 8312dfe..1e9d1a1 100644 --- a/go.sum +++ b/go.sum @@ -203,8 +203,6 @@ github.com/libp2p/go-libp2p-core v0.8.3 h1:BZTReEF6o8g/n4DwxTyeFannOeae35Xy0TD+m github.com/libp2p/go-libp2p-core v0.8.3/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= -github.com/libp2p/go-libp2p-metrics v0.1.0 h1:v7YMUTHNobFaQeqaMfJJMbnK3EPlZeb6/KFm4gE9dks= -github.com/libp2p/go-libp2p-metrics v0.1.0/go.mod h1:rpoJmXWFxnj7qs5sJ02sxSzrhaZvpqBn8GCG6Sx6E1k= github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc= @@ -452,7 +450,6 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/v2/proto/voucher_test.go b/v2/proto/voucher_test.go index ce450e7..148bd77 100644 --- a/v2/proto/voucher_test.go +++ b/v2/proto/voucher_test.go @@ -46,7 +46,7 @@ func TestReservationVoucher(t *testing.T) { t.Fatal(err) } - envelope, rec, err := record.ConsumeEnvelope(blob, RecordDomain) + _, rec, err := record.ConsumeEnvelope(blob, RecordDomain) if err != nil { t.Fatal(err) } diff --git a/v2/test/compat_test.go b/v2/test/compat_test.go index 5fe10e4..bcecba0 100644 --- a/v2/test/compat_test.go +++ b/v2/test/compat_test.go @@ -86,6 +86,9 @@ func TestRelayCompatV2DialV1(t *testing.T) { msg := []byte("relay works!") nwritten, err := s.Write(msg) + if err != nil { + t.Fatal(err) + } if nwritten != len(msg) { t.Fatalf("expected to write %d bytes, but wrote %d instead", len(msg), nwritten) } @@ -159,6 +162,9 @@ func TestRelayCompatV1DialV2(t *testing.T) { msg := []byte("relay works!") nwritten, err := s.Write(msg) + if err != nil { + t.Fatal(err) + } if nwritten != len(msg) { t.Fatalf("expected to write %d bytes, but wrote %d instead", len(msg), nwritten) } diff --git a/v2/test/e2e_test.go b/v2/test/e2e_test.go index ee7a8a7..7f640f5 100644 --- a/v2/test/e2e_test.go +++ b/v2/test/e2e_test.go @@ -20,7 +20,7 @@ import ( logging "github.com/ipfs/go-log" bhost "github.com/libp2p/go-libp2p-blankhost" - metrics "github.com/libp2p/go-libp2p-metrics" + metrics "github.com/libp2p/go-libp2p-core/metrics" pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem" swarm "github.com/libp2p/go-libp2p-swarm" swarmt "github.com/libp2p/go-libp2p-swarm/testing" @@ -165,6 +165,9 @@ func TestBasicRelay(t *testing.T) { msg := []byte("relay works!") nwritten, err := s.Write(msg) + if err != nil { + t.Fatal(err) + } if nwritten != len(msg) { t.Fatalf("expected to write %d bytes, but wrote %d instead", len(msg), nwritten) } diff --git a/v2/util/io.go b/v2/util/io.go index 4f154e4..911bad1 100644 --- a/v2/util/io.go +++ b/v2/util/io.go @@ -50,7 +50,7 @@ func (d *DelimitedReader) ReadMsg(msg proto.Message) error { } if uint64(len(d.buf)) < mlen { - return errors.New("Message too large") + return errors.New("message too large") } buf := d.buf[:mlen]