Browse Source

quic: make server cmd use RFC 9000 instead of draft-29 (#2753)

* quic: make server cmd use RFC 9000 instead of draft-29

* Move code to lib and add a test

* Change example to not rely on specific port

* Replace 0.0.0.0 with localhost

---------

Co-authored-by: Leon Rinkel <leon@rinkel.me>
pull/2763/head
Marco Munizaga 7 months ago
committed by GitHub
parent
commit
a2da8e0269
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 12
      p2p/http/example_test.go
  2. 63
      p2p/transport/quic/cmd/client/main.go
  3. 129
      p2p/transport/quic/cmd/lib/lib.go
  4. 30
      p2p/transport/quic/cmd/lib/lib_test.go
  5. 71
      p2p/transport/quic/cmd/server/main.go

12
p2p/http/example_test.go

@ -57,7 +57,7 @@ func ExampleHost_withAStockGoHTTPClient() {
}
func ExampleHost_listenOnHTTPTransportAndStreams() {
serverStreamHost, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/udp/50124/quic-v1"))
serverStreamHost, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/udp/0/quic-v1"))
if err != nil {
log.Fatal(err)
}
@ -65,14 +65,18 @@ func ExampleHost_listenOnHTTPTransportAndStreams() {
server := libp2phttp.Host{
InsecureAllowHTTP: true, // For our example, we'll allow insecure HTTP
ListenAddrs: []ma.Multiaddr{ma.StringCast("/ip4/127.0.0.1/tcp/50124/http")},
ListenAddrs: []ma.Multiaddr{ma.StringCast("/ip4/127.0.0.1/tcp/0/http")},
StreamHost: serverStreamHost,
}
go server.Serve()
defer server.Close()
fmt.Println("Server listening on:", server.Addrs())
// Output: Server listening on: [/ip4/127.0.0.1/udp/50124/quic-v1 /ip4/127.0.0.1/tcp/50124/http]
for _, a := range server.Addrs() {
_, transport := ma.SplitLast(a)
fmt.Printf("Server listening on transport: %s\n", transport)
}
// Output: Server listening on transport: /quic-v1
// Server listening on transport: /http
}
func ExampleHost_overLibp2pStreams() {

63
p2p/transport/quic/cmd/client/main.go

@ -1,20 +1,11 @@
package main
import (
"context"
"crypto/rand"
"fmt"
"io"
"log"
"os"
ic "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
ma "github.com/multiformats/go-multiaddr"
"github.com/quic-go/quic-go"
cmdlib "github.com/libp2p/go-libp2p/p2p/transport/quic/cmd/lib"
)
func main() {
@ -22,57 +13,7 @@ func main() {
fmt.Printf("Usage: %s <multiaddr> <peer id>", os.Args[0])
return
}
if err := run(os.Args[1], os.Args[2]); err != nil {
if err := cmdlib.RunClient(os.Args[1], os.Args[2]); err != nil {
log.Fatalf(err.Error())
}
}
func run(raddr string, p string) error {
peerID, err := peer.Decode(p)
if err != nil {
return err
}
addr, err := ma.NewMultiaddr(raddr)
if err != nil {
return err
}
priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader)
if err != nil {
return err
}
reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
if err != nil {
return err
}
t, err := libp2pquic.NewTransport(priv, reuse, nil, nil, nil)
if err != nil {
return err
}
log.Printf("Dialing %s\n", addr.String())
conn, err := t.Dial(context.Background(), addr, peerID)
if err != nil {
return err
}
defer conn.Close()
str, err := conn.OpenStream(context.Background())
if err != nil {
return err
}
defer str.Close()
const msg = "Hello world!"
log.Printf("Sending: %s\n", msg)
if _, err := str.Write([]byte(msg)); err != nil {
return err
}
if err := str.CloseWrite(); err != nil {
return err
}
data, err := io.ReadAll(str)
if err != nil {
return err
}
log.Printf("Received: %s\n", data)
return nil
}

129
p2p/transport/quic/cmd/lib/lib.go

@ -0,0 +1,129 @@
package cmdlib
import (
"context"
"crypto/rand"
"fmt"
"io"
"log"
ic "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
tpt "github.com/libp2p/go-libp2p/core/transport"
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
ma "github.com/multiformats/go-multiaddr"
"github.com/quic-go/quic-go"
)
func RunClient(raddr string, p string) error {
peerID, err := peer.Decode(p)
if err != nil {
return err
}
addr, err := ma.NewMultiaddr(raddr)
if err != nil {
return err
}
priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader)
if err != nil {
return err
}
reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
if err != nil {
return err
}
t, err := libp2pquic.NewTransport(priv, reuse, nil, nil, nil)
if err != nil {
return err
}
log.Printf("Dialing %s\n", addr.String())
conn, err := t.Dial(context.Background(), addr, peerID)
if err != nil {
return err
}
defer conn.Close()
str, err := conn.OpenStream(context.Background())
if err != nil {
return err
}
defer str.Close()
const msg = "Hello world!"
log.Printf("Sending: %s\n", msg)
if _, err := str.Write([]byte(msg)); err != nil {
return err
}
if err := str.CloseWrite(); err != nil {
return err
}
data, err := io.ReadAll(str)
if err != nil {
return err
}
log.Printf("Received: %s\n", data)
return nil
}
func RunServer(port string, location chan peer.AddrInfo) error {
addr, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/udp/%s/quic-v1", port))
if err != nil {
return err
}
priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader)
if err != nil {
return err
}
peerID, err := peer.IDFromPrivateKey(priv)
if err != nil {
return err
}
reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
if err != nil {
return err
}
t, err := libp2pquic.NewTransport(priv, reuse, nil, nil, nil)
if err != nil {
return err
}
ln, err := t.Listen(addr)
if err != nil {
return err
}
fmt.Printf("Listening. Now run: go run cmd/client/main.go %s %s\n", ln.Multiaddr(), peerID)
if location != nil {
location <- peer.AddrInfo{ID: peerID, Addrs: []ma.Multiaddr{ln.Multiaddr()}}
}
for {
conn, err := ln.Accept()
if err != nil {
return err
}
log.Printf("Accepted new connection from %s (%s)\n", conn.RemotePeer(), conn.RemoteMultiaddr())
go func() {
if err := handleConn(conn); err != nil {
log.Printf("handling conn failed: %s", err.Error())
}
}()
}
}
func handleConn(conn tpt.CapableConn) error {
str, err := conn.AcceptStream()
if err != nil {
return err
}
data, err := io.ReadAll(str)
if err != nil {
return err
}
log.Printf("Received: %s\n", data)
if _, err := str.Write(data); err != nil {
return err
}
return str.Close()
}

30
p2p/transport/quic/cmd/lib/lib_test.go

@ -0,0 +1,30 @@
package cmdlib
import (
"testing"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/multiformats/go-multiaddr"
)
func TestCmd(t *testing.T) {
serverLocation := make(chan peer.AddrInfo)
go RunServer("0", serverLocation)
l := <-serverLocation
ip, rest := multiaddr.SplitFirst(l.Addrs[0])
if ip.Protocol().Code == multiaddr.P_IP4 && ip.Value() == "0.0.0.0" {
// Windows can't dial to 0.0.0.0 so replace with localhost
var err error
ip, err = multiaddr.NewComponent("ip4", "127.0.0.1")
if err != nil {
t.Fatal(err)
}
}
err := RunClient(multiaddr.Join(ip, rest).String(), l.ID.String())
if err != nil {
t.Fatal(err)
}
}

71
p2p/transport/quic/cmd/server/main.go

@ -1,20 +1,11 @@
package main
import (
"crypto/rand"
"fmt"
"io"
"log"
"os"
ic "github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
tpt "github.com/libp2p/go-libp2p/core/transport"
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
ma "github.com/multiformats/go-multiaddr"
"github.com/quic-go/quic-go"
cmdlib "github.com/libp2p/go-libp2p/p2p/transport/quic/cmd/lib"
)
func main() {
@ -22,65 +13,7 @@ func main() {
fmt.Printf("Usage: %s <port>", os.Args[0])
return
}
if err := run(os.Args[1]); err != nil {
if err := cmdlib.RunServer(os.Args[1], nil); err != nil {
log.Fatalf(err.Error())
}
}
func run(port string) error {
addr, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/udp/%s/quic", port))
if err != nil {
return err
}
priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader)
if err != nil {
return err
}
peerID, err := peer.IDFromPrivateKey(priv)
if err != nil {
return err
}
reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
if err != nil {
return err
}
t, err := libp2pquic.NewTransport(priv, reuse, nil, nil, nil)
if err != nil {
return err
}
ln, err := t.Listen(addr)
if err != nil {
return err
}
fmt.Printf("Listening. Now run: go run cmd/client/main.go %s %s\n", ln.Multiaddr(), peerID)
for {
conn, err := ln.Accept()
if err != nil {
return err
}
log.Printf("Accepted new connection from %s (%s)\n", conn.RemotePeer(), conn.RemoteMultiaddr())
go func() {
if err := handleConn(conn); err != nil {
log.Printf("handling conn failed: %s", err.Error())
}
}()
}
}
func handleConn(conn tpt.CapableConn) error {
str, err := conn.AcceptStream()
if err != nil {
return err
}
data, err := io.ReadAll(str)
if err != nil {
return err
}
log.Printf("Received: %s\n", data)
if _, err := str.Write(data); err != nil {
return err
}
return str.Close()
}

Loading…
Cancel
Save