diff options
author | Neil Alexander <neilalexander@users.noreply.github.com> | 2020-07-16 13:52:08 +0100 |
---|---|---|
committer | Neil Alexander <neilalexander@users.noreply.github.com> | 2020-07-16 13:52:08 +0100 |
commit | e5208c2ec9b5e1878c3f9860c98de29a9d95ca18 (patch) | |
tree | 1661c2f912202d2aea4130c2ac55e77d47ecbbcb /cmd/dendrite-demo-yggdrasil | |
parent | f5e7e7513ca0ecddafc967e3b20f35cb1201a151 (diff) |
Yggdrasil demo updates ("Bare QUIC")
Squashed commit of the following:
commit 86c2388e13ffdbabdd50cea205652dccc40e1860
Merge: b0a3ee6c f5e7e751
Author: Neil Alexander <neilalexander@users.noreply.github.com>
Date: Thu Jul 16 13:47:10 2020 +0100
Merge branch 'master' into neilalexander/yggbarequic
commit b0a3ee6c5c063962384bb91c59ec753ddc8cfe5f
Author: Neil Alexander <neilalexander@users.noreply.github.com>
Date: Thu Jul 16 13:42:22 2020 +0100
Add support for broadcasting wake-up EDUs to known hosts
commit 8a5c2020b3a4b705b5d5686a9e71990a49e6d471
Author: Neil Alexander <neilalexander@users.noreply.github.com>
Date: Thu Jul 16 13:42:10 2020 +0100
Bare QUIC demo working
commit d3939b3d6568cf4262c0391486a5203873b68bfc
Author: Neil Alexander <neilalexander@users.noreply.github.com>
Date: Wed Jul 15 11:42:43 2020 +0100
Support bare Yggdrasil sessions with encrypted QUIC
Diffstat (limited to 'cmd/dendrite-demo-yggdrasil')
-rw-r--r-- | cmd/dendrite-demo-yggdrasil/main.go | 35 | ||||
-rw-r--r-- | cmd/dendrite-demo-yggdrasil/yggconn/client.go | 27 | ||||
-rw-r--r-- | cmd/dendrite-demo-yggdrasil/yggconn/node.go | 44 | ||||
-rw-r--r-- | cmd/dendrite-demo-yggdrasil/yggconn/session.go | 49 |
4 files changed, 60 insertions, 95 deletions
diff --git a/cmd/dendrite-demo-yggdrasil/main.go b/cmd/dendrite-demo-yggdrasil/main.go index 33bcd102..7ab90000 100644 --- a/cmd/dendrite-demo-yggdrasil/main.go +++ b/cmd/dendrite-demo-yggdrasil/main.go @@ -17,7 +17,6 @@ package main import ( "context" "crypto/tls" - "encoding/hex" "flag" "fmt" "net" @@ -42,7 +41,6 @@ import ( "github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/userapi" "github.com/matrix-org/gomatrixserverlib" - "github.com/yggdrasil-network/yggdrasil-go/src/crypto" "github.com/sirupsen/logrus" ) @@ -158,31 +156,6 @@ func main() { base.UseHTTPAPIs, ) - ygg.NewSession = func(serverName gomatrixserverlib.ServerName) { - logrus.Infof("Found new session %q", serverName) - req := &api.PerformServersAliveRequest{ - Servers: []gomatrixserverlib.ServerName{serverName}, - } - res := &api.PerformServersAliveResponse{} - if err := fsAPI.PerformServersAlive(context.TODO(), req, res); err != nil { - logrus.WithError(err).Warn("Failed to notify server alive due to new session") - } - } - - ygg.NotifyLinkNew(func(_ crypto.BoxPubKey, sigPubKey crypto.SigPubKey, linkType, remote string) { - serverName := hex.EncodeToString(sigPubKey[:]) - logrus.Infof("Found new peer %q", serverName) - req := &api.PerformServersAliveRequest{ - Servers: []gomatrixserverlib.ServerName{ - gomatrixserverlib.ServerName(serverName), - }, - } - res := &api.PerformServersAliveResponse{} - if err := fsAPI.PerformServersAlive(context.TODO(), req, res); err != nil { - logrus.WithError(err).Warn("Failed to notify server alive due to new session") - } - }) - // Build both ends of a HTTP multiplex. httpServer := &http.Server{ Addr: ":0", @@ -205,6 +178,14 @@ func main() { logrus.Info("Listening on ", httpBindAddr) logrus.Fatal(http.ListenAndServe(httpBindAddr, base.BaseMux)) }() + go func() { + logrus.Info("Sending wake-up message to known nodes") + req := &api.PerformBroadcastEDURequest{} + res := &api.PerformBroadcastEDUResponse{} + if err := fsAPI.PerformBroadcastEDU(context.TODO(), req, res); err != nil { + logrus.WithError(err).Error("Failed to send wake-up message to known nodes") + } + }() select {} } diff --git a/cmd/dendrite-demo-yggdrasil/yggconn/client.go b/cmd/dendrite-demo-yggdrasil/yggconn/client.go index b74468db..c5b3eb72 100644 --- a/cmd/dendrite-demo-yggdrasil/yggconn/client.go +++ b/cmd/dendrite-demo-yggdrasil/yggconn/client.go @@ -1,35 +1,13 @@ package yggconn import ( - "context" - "crypto/ed25519" - "encoding/hex" - "fmt" - "net" "net/http" - "strings" "time" - "github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/convert" "github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/gomatrixserverlib" ) -func (n *Node) yggdialer(_, address string) (net.Conn, error) { - tokens := strings.Split(address, ":") - raw, err := hex.DecodeString(tokens[0]) - if err != nil { - return nil, fmt.Errorf("hex.DecodeString: %w", err) - } - converted := convert.Ed25519PublicKeyToCurve25519(ed25519.PublicKey(raw)) - convhex := hex.EncodeToString(converted) - return n.Dial("curve25519", convhex) -} - -func (n *Node) yggdialerctx(ctx context.Context, network, address string) (net.Conn, error) { - return n.yggdialer(network, address) -} - type yggroundtripper struct { inner *http.Transport } @@ -49,7 +27,7 @@ func (n *Node) CreateClient( TLSHandshakeTimeout: 20 * time.Second, ResponseHeaderTimeout: 10 * time.Second, IdleConnTimeout: 60 * time.Second, - DialContext: n.yggdialerctx, + DialContext: n.DialerContext, }, }, ) @@ -66,7 +44,8 @@ func (n *Node) CreateFederationClient( TLSHandshakeTimeout: 20 * time.Second, ResponseHeaderTimeout: 10 * time.Second, IdleConnTimeout: 60 * time.Second, - DialContext: n.yggdialerctx, + DialContext: n.DialerContext, + TLSClientConfig: n.tlsConfig, }, }, ) diff --git a/cmd/dendrite-demo-yggdrasil/yggconn/node.go b/cmd/dendrite-demo-yggdrasil/yggconn/node.go index 2bc300c8..67aec050 100644 --- a/cmd/dendrite-demo-yggdrasil/yggconn/node.go +++ b/cmd/dendrite-demo-yggdrasil/yggconn/node.go @@ -20,6 +20,7 @@ import ( "crypto/tls" "encoding/hex" "encoding/json" + "errors" "fmt" "io/ioutil" "log" @@ -33,9 +34,7 @@ import ( "github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/convert" "github.com/matrix-org/gomatrixserverlib" - yggdrasiladmin "github.com/yggdrasil-network/yggdrasil-go/src/admin" yggdrasilconfig "github.com/yggdrasil-network/yggdrasil-go/src/config" - "github.com/yggdrasil-network/yggdrasil-go/src/crypto" yggdrasilmulticast "github.com/yggdrasil-network/yggdrasil-go/src/multicast" "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil" @@ -46,10 +45,8 @@ type Node struct { core *yggdrasil.Core config *yggdrasilconfig.NodeConfig state *yggdrasilconfig.NodeState - admin *yggdrasiladmin.AdminSocket multicast *yggdrasilmulticast.Multicast log *gologme.Logger - packetConn *yggdrasil.PacketConn listener quic.Listener tlsConfig *tls.Config quicConfig *quic.Config @@ -58,15 +55,10 @@ type Node struct { NewSession func(remote gomatrixserverlib.ServerName) } -func (n *Node) BuildName() string { - return "dendrite" -} - -func (n *Node) BuildVersion() string { - return "dev" -} - func (n *Node) Dialer(_, address string) (net.Conn, error) { + if len(n.core.GetSwitchPeers()) == 0 { + return nil, errors.New("no peer connections available") + } tokens := strings.Split(address, ":") raw, err := hex.DecodeString(tokens[0]) if err != nil { @@ -86,12 +78,10 @@ func Setup(instanceName, storageDirectory string) (*Node, error) { n := &Node{ core: &yggdrasil.Core{}, config: yggdrasilconfig.GenerateConfig(), - admin: &yggdrasiladmin.AdminSocket{}, multicast: &yggdrasilmulticast.Multicast{}, log: gologme.New(os.Stdout, "YGG ", log.Flags()), incoming: make(chan QUICStream), } - n.core.SetBuildInfo(n) yggfile := fmt.Sprintf("%s/%s-yggdrasil.conf", storageDirectory, instanceName) if _, err := os.Stat(yggfile); !os.IsNotExist(err) { @@ -132,20 +122,22 @@ func Setup(instanceName, storageDirectory string) (*Node, error) { panic(err) } - n.packetConn = n.core.PacketConn() n.tlsConfig = n.generateTLSConfig() n.quicConfig = &quic.Config{ MaxIncomingStreams: 0, MaxIncomingUniStreams: 0, KeepAlive: true, - MaxIdleTimeout: time.Minute * 15, - HandshakeTimeout: time.Second * 15, + MaxIdleTimeout: time.Minute * 30, + HandshakeTimeout: time.Second * 30, } n.log.Println("Public curve25519:", n.core.EncryptionPublicKey()) n.log.Println("Public ed25519:", n.core.SigningPublicKey()) - go n.listenFromYgg() + go func() { + time.Sleep(time.Second) + n.listenFromYgg() + }() return n, nil } @@ -193,9 +185,11 @@ func (n *Node) KnownNodes() []gomatrixserverlib.ServerName { nodemap := map[string]struct{}{ "b5ae50589e50991dd9dd7d59c5c5f7a4521e8da5b603b7f57076272abc58b374": struct{}{}, } - for _, peer := range n.core.GetSwitchPeers() { - nodemap[hex.EncodeToString(peer.SigningKey[:])] = struct{}{} - } + /* + for _, peer := range n.core.GetSwitchPeers() { + nodemap[hex.EncodeToString(peer.SigningKey[:])] = struct{}{} + } + */ n.sessions.Range(func(_, v interface{}) bool { session, ok := v.(quic.Session) if !ok { @@ -266,11 +260,3 @@ func (n *Node) SetStaticPeer(uri string) error { } return nil } - -func (n *Node) NotifyLinkNew(f func(boxPubKey crypto.BoxPubKey, sigPubKey crypto.SigPubKey, linkType, remote string)) { - n.core.NotifyLinkNew(f) -} - -func (n *Node) NotifyLinkGone(f func(boxPubKey crypto.BoxPubKey, sigPubKey crypto.SigPubKey, linkType, remote string)) { - n.core.NotifyLinkGone(f) -} diff --git a/cmd/dendrite-demo-yggdrasil/yggconn/session.go b/cmd/dendrite-demo-yggdrasil/yggconn/session.go index ff77e64f..0d231f6d 100644 --- a/cmd/dendrite-demo-yggdrasil/yggconn/session.go +++ b/cmd/dendrite-demo-yggdrasil/yggconn/session.go @@ -24,19 +24,19 @@ import ( "encoding/hex" "encoding/pem" "errors" + "fmt" "math/big" "net" "time" "github.com/lucas-clemente/quic-go" - "github.com/matrix-org/gomatrixserverlib" "github.com/yggdrasil-network/yggdrasil-go/src/crypto" ) func (n *Node) listenFromYgg() { var err error n.listener, err = quic.Listen( - n.packetConn, // yggdrasil.PacketConn + n.core, // yggdrasil.PacketConn n.tlsConfig, // TLS config n.quicConfig, // QUIC config ) @@ -45,24 +45,25 @@ func (n *Node) listenFromYgg() { } for { + n.log.Infoln("Waiting to accept QUIC sessions") session, err := n.listener.Accept(context.TODO()) if err != nil { n.log.Println("n.listener.Accept:", err) return } - go n.listenFromQUIC(session) + if len(session.ConnectionState().PeerCertificates) != 1 { + _ = session.CloseWithError(0, "expected a peer certificate") + continue + } + address := session.ConnectionState().PeerCertificates[0].Subject.CommonName + n.log.Infoln("Accepted connection from", address) + go n.listenFromQUIC(session, address) } } -func (n *Node) listenFromQUIC(session quic.Session) { - n.sessions.Store(session.RemoteAddr().String(), session) - defer n.sessions.Delete(session.RemoteAddr()) - if n.NewSession != nil { - if len(session.ConnectionState().PeerCertificates) == 1 { - subjectName := session.ConnectionState().PeerCertificates[0].Subject.CommonName - go n.NewSession(gomatrixserverlib.ServerName(subjectName)) - } - } +func (n *Node) listenFromQUIC(session quic.Session, address string) { + n.sessions.Store(address, session) + defer n.sessions.Delete(address) for { st, err := session.AcceptStream(context.TODO()) if err != nil { @@ -107,10 +108,23 @@ func (n *Node) DialContext(ctx context.Context, network, address string) (net.Co } var pubKey crypto.BoxPubKey copy(pubKey[:], dest) + nodeID := crypto.GetNodeID(&pubKey) + nodeMask := &crypto.NodeID{} + for i := range nodeMask { + nodeMask[i] = 0xFF + } + + fmt.Println("Resolving coords") + coords, err := n.core.Resolve(nodeID, nodeMask) + if err != nil { + return nil, fmt.Errorf("n.core.Resolve: %w", err) + } + fmt.Println("Found coords:", coords) + fmt.Println("Dialling") session, err = quic.Dial( - n.packetConn, // yggdrasil.PacketConn - &pubKey, // dial address + n.core, // yggdrasil.PacketConn + coords, // dial address address, // dial SNI n.tlsConfig, // TLS config n.quicConfig, // QUIC config @@ -119,7 +133,8 @@ func (n *Node) DialContext(ctx context.Context, network, address string) (net.Co n.log.Println("n.dialer.DialContext:", err) return nil, err } - go n.listenFromQUIC(session) + fmt.Println("Dial OK") + go n.listenFromQUIC(session, address) } st, err := session.OpenStream() if err != nil { @@ -157,5 +172,9 @@ func (n *Node) generateTLSConfig() *tls.Config { Certificates: []tls.Certificate{tlsCert}, NextProtos: []string{"quic-matrix-ygg"}, InsecureSkipVerify: true, + ClientAuth: tls.RequireAnyClientCert, + GetClientCertificate: func(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { + return &tlsCert, nil + }, } } |