aboutsummaryrefslogtreecommitdiff
path: root/cmd/dendrite-demo-yggdrasil
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2020-07-16 13:52:08 +0100
committerNeil Alexander <neilalexander@users.noreply.github.com>2020-07-16 13:52:08 +0100
commite5208c2ec9b5e1878c3f9860c98de29a9d95ca18 (patch)
tree1661c2f912202d2aea4130c2ac55e77d47ecbbcb /cmd/dendrite-demo-yggdrasil
parentf5e7e7513ca0ecddafc967e3b20f35cb1201a151 (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.go35
-rw-r--r--cmd/dendrite-demo-yggdrasil/yggconn/client.go27
-rw-r--r--cmd/dendrite-demo-yggdrasil/yggconn/node.go44
-rw-r--r--cmd/dendrite-demo-yggdrasil/yggconn/session.go49
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
+ },
}
}