Program using libp2p to connect using TCP, QUIC or both

303 Views Asked by At

I a m writting a P2P application, and I want to decide to send a message to a peer using TCP or QUIC, for a benchmark of the protocols and also for leting the user decide (I want the quic protocol to the the pefered one). But i am having trouble to do so. Currently I divide the the remote host addr into quic and tcp addreses and then issue a connectin with each one, but sometimes the tcp addr connect to udp and viceversa. I dont know if this is the best approach

I have tried to slit the addrs, connecting using TCP, QUIC and also to the addr received from the DHT rendezvous.

        quicaddr := selectAddrs(peeraddr.Addrs, "quic")
        tcpaddr := selectAddrs(peeraddr.Addrs, "tcp")

        fmt.Println("[*] Using TCP protocol")
        var peeraddrTCP peer.AddrInfo
        peeraddrTCP.ID = peeraddr.ID
        peeraddrTCP.Addrs = tcpaddr

        fmt.Println(peeraddrTCP.Addrs)
        err = Host.Connect(ctx, peeraddrTCP)
        conn2 := Host.Network().ConnsToPeer(peeraddr.ID)
        for _, c := range conn2 {
            fmt.Println("Using: ", c.ConnState().Transport)
            fmt.Println(c.RemoteMultiaddr())
            available_add = append(available_add, c.RemoteMultiaddr())
            c.Close()

        }

        fmt.Println("[*] Using QUIC protocol")
        var peeraddrQUIC peer.AddrInfo
        peeraddrQUIC.ID = peeraddr.ID
        peeraddrQUIC.Addrs = quicaddr
        fmt.Println(peeraddrQUIC.Addrs)

        err = Host.Connect(ctx, peeraddrQUIC)

        conn1 := Host.Network().ConnsToPeer(peeraddrQUIC.ID)
        for _, c := range conn1 {
            fmt.Println("Using: ", c.ConnState().Transport)
            fmt.Println(c.RemoteMultiaddr())
            available_add = append(available_add, c.RemoteMultiaddr())
            c.Close()
        }

Basically I would like to know if it is posible to have one connection with both tcp and quic. Sorry for my english.

1

There are 1 best solutions below

2
On

I made a function to change to QUIC or TCP i post it in case anyone is interested, in anyone has a better options please share, thanks!

func setTransport(ctx context.Context, peerid peer.ID, preferQUIC bool) bool {

// get peer addrinfo from id
peeraddr := Host.Peerstore().PeerInfo(peerid)
var addrs []multiaddr.Multiaddr

conn := Host.Network().ConnsToPeer(peeraddr.ID)
for _, c := range conn {
    fmt.Println("Currently Using : ", c.ConnState().Transport)

    // if we want to use quic and the connection is quic, return
    if c.ConnState().Transport == "quic" && preferQUIC {
        fmt.Println("[*] Using QUIC protocol")
        return true
    }
    // if we want to use tcp and the connection is tcp, return
    if c.ConnState().Transport == "tcp" && !preferQUIC {
        fmt.Println("[*] Using TCP protocol")

        return true
    }
    //conn is tcp and we want quic
    if c.ConnState().Transport == "tcp" {
        fmt.Println("[*] Changing to QUIC protocol")
        addrs = selectAddrs(peeraddr.Addrs, true, false)

    }
    //conn is quic and we want tcp
    if c.ConnState().Transport == "quic" {

        fmt.Println("[*] Changing to TCP protocol")
        addrs = selectAddrs(peeraddr.Addrs, false, true)

    }

}
if len(addrs) == 0 {

    fmt.Print("Not Supported", peeraddr.Addrs, preferQUIC, "current transport", conn)
    return false

}

Host.Peerstore().ClearAddrs(peeraddr.ID) //maybe this inst needed ???
Host.Peerstore().AddAddrs(peeraddr.ID, addrs, time.Hour*1) //maybe this inst needed ???
closeConns(peeraddr.ID) // need to close conns, else the previous transport will not change

var NewPeer peer.AddrInfo
NewPeer.ID = peeraddr.ID
NewPeer.Addrs = addrs //selected addr containing desired trp

err := Host.Connect(ctx, NewPeer)

if err != nil {

    fmt.Println("Error connecting to ", addrs, err)
    return false
}

singleconn := Host.Network().ConnsToPeer(peeraddr.ID)[0]
if preferQUIC && singleconn.ConnState().Transport == "quic" {
    fmt.Println("[*] Succesfully changed to QUIC")
    return true

} else if !preferQUIC && singleconn.ConnState().Transport == "tcp" {
    fmt.Println("[*] Succesfully changed to TCP")
    return true

} else {
    fmt.Println("Error changing transport")
    return false
}

}