mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-30 18:35:18 +00:00
102 lines
2.4 KiB
Go
102 lines
2.4 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"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/transport"
|
|
|
|
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(h host.Host, upgrader transport.Upgrader) error {
|
|
n, ok := h.Network().(transport.TransportNetwork)
|
|
if !ok {
|
|
return fmt.Errorf("%v is not a transport network", h.Network())
|
|
}
|
|
|
|
c, err := New(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)
|
|
var _ io.Closer = (*Client)(nil)
|
|
|
|
func (c *Client) Dial(ctx context.Context, a ma.Multiaddr, p peer.ID) (transport.CapableConn, error) {
|
|
connScope, err := c.host.Network().ResourceManager().OpenConnection(network.DirOutbound, false, a)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
conn, err := c.dialAndUpgrade(ctx, a, p, connScope)
|
|
if err != nil {
|
|
connScope.Done()
|
|
return nil, err
|
|
}
|
|
return conn, nil
|
|
}
|
|
|
|
func (c *Client) dialAndUpgrade(ctx context.Context, a ma.Multiaddr, p peer.ID, connScope network.ConnManagementScope) (transport.CapableConn, error) {
|
|
if err := connScope.SetPeer(p); err != nil {
|
|
return nil, err
|
|
}
|
|
conn, err := c.dial(ctx, a, p)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
conn.tagHop()
|
|
cc, err := c.upgrader.Upgrade(ctx, c, conn, network.DirOutbound, p, connScope)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return capableConn{cc.(capableConnWithStat)}, nil
|
|
}
|
|
|
|
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
|
|
}
|