From c890e29508c309eaa9d25e34fb6c3e3c2ad81520 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 27 Nov 2025 00:09:06 +0000 Subject: [PATCH] Switch to experimental yggquic branch --- go.mod | 6 +- go.sum | 4 + internal/transport/yggdrasil.go | 162 ++------------------------------ 3 files changed, 18 insertions(+), 154 deletions(-) diff --git a/go.mod b/go.mod index eb891d4..a0872ac 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.22 toolchain go1.23.0 require ( - github.com/Arceliar/ironwood v0.0.0-20241213013129-743fe2fccbd3 github.com/emersion/go-imap v1.2.1 github.com/emersion/go-imap-idle v0.0.0-20210907174914-db2568431445 github.com/emersion/go-message v0.17.0 @@ -14,14 +13,15 @@ require ( github.com/fatih/color v1.18.0 github.com/gologme/log v1.3.0 github.com/mattn/go-sqlite3 v1.14.24 - github.com/quic-go/quic-go v0.48.2 github.com/yggdrasil-network/yggdrasil-go v0.5.12 + github.com/yggdrasil-network/yggquic v0.0.0-20251127000438-f4f94a6def24 go.uber.org/atomic v1.11.0 golang.org/x/crypto v0.31.0 golang.org/x/term v0.27.0 ) require ( + github.com/Arceliar/ironwood v0.0.0-20241213013129-743fe2fccbd3 // indirect github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/bits-and-blooms/bloom/v3 v3.7.0 // indirect @@ -32,7 +32,9 @@ require ( github.com/hjson/hjson-go/v4 v4.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/neilalexander/generique v0.0.0-20251127000013-def6a5bd842a // indirect github.com/onsi/ginkgo/v2 v2.13.0 // indirect + github.com/quic-go/quic-go v0.48.2 // indirect github.com/wlynxg/anet v0.0.5 // indirect go.uber.org/mock v0.4.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect diff --git a/go.sum b/go.sum index 010efd4..c8c0c79 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/neilalexander/generique v0.0.0-20251127000013-def6a5bd842a h1:iV/ivYwvXCsNOEFIc4YjQNbq+pmTqhON/rFQcjYLEPs= +github.com/neilalexander/generique v0.0.0-20251127000013-def6a5bd842a/go.mod h1:dJzRxTIvxTW+LULsKqkBmaYRrXiGbee6mvvUPoj/Pvk= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= @@ -73,6 +75,8 @@ github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/yggdrasil-network/yggdrasil-go v0.5.12 h1:SaQ8d59JP+uFy+nOWXTx1ETM5r2uCfe1Gt/d+IodHJw= github.com/yggdrasil-network/yggdrasil-go v0.5.12/go.mod h1:u4DU6dpTfWmVs8r0WjW1T3UpGyeUh9vRrS8zngvncwM= +github.com/yggdrasil-network/yggquic v0.0.0-20251127000438-f4f94a6def24 h1:G7+Q8WCBRqSEidXz0jMcTIPibo7SImRbrvPHRsMsYM4= +github.com/yggdrasil-network/yggquic v0.0.0-20251127000438-f4f94a6def24/go.mod h1:AbOaTarCfQS5wB/YuUtAho9UeBhBEYgEylK+9SyPiwM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= diff --git a/internal/transport/yggdrasil.go b/internal/transport/yggdrasil.go index 59edd74..3e0f2ba 100644 --- a/internal/transport/yggdrasil.go +++ b/internal/transport/yggdrasil.go @@ -9,45 +9,23 @@ package transport import ( - "context" "crypto/ed25519" - "crypto/tls" "encoding/hex" "fmt" "log" "net" "regexp" - "sync" - "time" - iwt "github.com/Arceliar/ironwood/types" "github.com/fatih/color" gologme "github.com/gologme/log" - "github.com/quic-go/quic-go" "github.com/yggdrasil-network/yggdrasil-go/src/config" "github.com/yggdrasil-network/yggdrasil-go/src/core" "github.com/yggdrasil-network/yggdrasil-go/src/multicast" + "github.com/yggdrasil-network/yggquic" ) type YggdrasilTransport struct { - listener *quic.Listener - yggdrasil net.PacketConn - transport *quic.Transport - tlsConfig *tls.Config - quicConfig *quic.Config - incoming chan *yggdrasilSession - sessions sync.Map // string -> quic.Connection - dials sync.Map // string -> *yggdrasilDial -} - -type yggdrasilSession struct { - quic.Connection - quic.Stream -} - -type yggdrasilDial struct { - context.Context - context.CancelFunc + yggquic *yggquic.YggdrasilTransport } func NewYggdrasilTransport(log *log.Logger, sk ed25519.PrivateKey, pk ed25519.PublicKey, peers []string, mcast bool, mcastregexp string) (*YggdrasilTransport, error) { @@ -96,140 +74,20 @@ func NewYggdrasilTransport(log *log.Logger, sk ed25519.PrivateKey, pk ed25519.Pu } } - tr := &YggdrasilTransport{ - tlsConfig: &tls.Config{ - ServerName: hex.EncodeToString(ygg.PublicKey()), - Certificates: []tls.Certificate{ - *cfg.Certificate, - }, - InsecureSkipVerify: true, - }, - quicConfig: &quic.Config{ - HandshakeIdleTimeout: time.Second * 5, - MaxIdleTimeout: time.Second * 60, - }, - transport: &quic.Transport{ - Conn: ygg, - }, - yggdrasil: ygg, - incoming: make(chan *yggdrasilSession, 1), + yq, err := yggquic.New(ygg, *cfg.Certificate, nil) + if err != nil { + panic(err) } - if tr.listener, err = tr.transport.Listen(tr.tlsConfig, tr.quicConfig); err != nil { - return nil, fmt.Errorf("quic.Listen: %w", err) - } - - go tr.connectionAcceptLoop() - return tr, nil -} - -func (t *YggdrasilTransport) connectionAcceptLoop() { - for { - qc, err := t.listener.Accept(context.TODO()) - if err != nil { - return - } - - host := qc.RemoteAddr().String() - if eqc, ok := t.sessions.LoadAndDelete(host); ok { - eqc := eqc.(quic.Connection) - _ = eqc.CloseWithError(0, "Connection replaced") - } - t.sessions.Store(host, qc) - if dial, ok := t.dials.LoadAndDelete(host); ok { - dial := dial.(*yggdrasilDial) - dial.CancelFunc() - } - - go t.streamAcceptLoop(qc) - } -} - -func (t *YggdrasilTransport) streamAcceptLoop(qc quic.Connection) { - host := qc.RemoteAddr().String() - - defer qc.CloseWithError(0, "Timed out") // nolint:errcheck - defer t.sessions.Delete(host) - - for { - qs, err := qc.AcceptStream(context.Background()) - if err != nil { - break - } - t.incoming <- &yggdrasilSession{qc, qs} - } + return &YggdrasilTransport{ + yggquic: yq, + }, nil } func (t *YggdrasilTransport) Dial(host string) (net.Conn, error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) - defer cancel() - var retry bool -retry: - qc, ok := t.sessions.Load(host) - if !ok { - if dial, ok := t.dials.Load(host); ok { - <-dial.(*yggdrasilDial).Done() - } - if qc, ok = t.sessions.Load(host); !ok { - dialctx, dialcancel := context.WithCancel(ctx) - defer dialcancel() - - t.dials.Store(host, &yggdrasilDial{dialctx, dialcancel}) - defer t.dials.Delete(host) - - addr := make(iwt.Addr, ed25519.PublicKeySize) - k, err := hex.DecodeString(host) - if err != nil { - return nil, err - } - copy(addr, k) - - if qc, err = t.transport.Dial(dialctx, addr, t.tlsConfig, t.quicConfig); err != nil { - return nil, err - } - - qc := qc.(quic.Connection) - t.sessions.Store(host, qc) - go t.streamAcceptLoop(qc) - } - } - if qc == nil { - return nil, net.ErrClosed - } else { - qc := qc.(quic.Connection) - qs, err := qc.OpenStreamSync(ctx) - if err != nil { - if !retry { - retry = true - goto retry - } - return nil, err - } - // For some reason this is needed to kick the stream - _, err = qs.Write([]byte(" ")) - return &yggdrasilSession{qc, qs}, err - } + return t.yggquic.Dial("yggdrasil", host) } func (t *YggdrasilTransport) Listener() net.Listener { - return &yggdrasilListener{t} -} - -type yggdrasilListener struct { - *YggdrasilTransport -} - -func (t *yggdrasilListener) Accept() (net.Conn, error) { - return <-t.incoming, nil -} - -func (t *yggdrasilListener) Addr() net.Addr { - return t.listener.Addr() -} - -func (t *yggdrasilListener) Close() error { - if err := t.listener.Close(); err != nil { - return err - } - return t.yggdrasil.Close() + return t.yggquic }