mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-08-01 13:52:46 +00:00
Support bare Yggdrasil sessions with encrypted QUIC
This commit is contained in:
parent
9cc52f47f3
commit
d3939b3d65
6 changed files with 50 additions and 90 deletions
|
@ -32,7 +32,6 @@ import (
|
|||
"github.com/matrix-org/dendrite/eduserver"
|
||||
"github.com/matrix-org/dendrite/eduserver/cache"
|
||||
"github.com/matrix-org/dendrite/federationsender"
|
||||
"github.com/matrix-org/dendrite/federationsender/api"
|
||||
"github.com/matrix-org/dendrite/internal"
|
||||
"github.com/matrix-org/dendrite/internal/config"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
|
@ -40,7 +39,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"
|
||||
)
|
||||
|
@ -154,30 +152,6 @@ func main() {
|
|||
base.UseHTTPAPIs,
|
||||
)
|
||||
|
||||
ygg.NotifySessionNew(func(boxPubKey crypto.BoxPubKey) {
|
||||
req := &api.PerformServersAliveRequest{
|
||||
Servers: []gomatrixserverlib.ServerName{
|
||||
gomatrixserverlib.ServerName(boxPubKey.String()),
|
||||
},
|
||||
}
|
||||
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(boxPubKey crypto.BoxPubKey, linkType, remote string) {
|
||||
req := &api.PerformServersAliveRequest{
|
||||
Servers: []gomatrixserverlib.ServerName{
|
||||
gomatrixserverlib.ServerName(boxPubKey.String()),
|
||||
},
|
||||
}
|
||||
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 link")
|
||||
}
|
||||
})
|
||||
|
||||
// Build both ends of a HTTP multiplex.
|
||||
httpServer := &http.Server{
|
||||
Addr: ":0",
|
||||
|
|
|
@ -65,6 +65,7 @@ func (n *Node) CreateFederationClient(
|
|||
ResponseHeaderTimeout: 15 * time.Second,
|
||||
IdleConnTimeout: 60 * time.Second,
|
||||
DialContext: n.yggdialerctx,
|
||||
TLSClientConfig: n.tlsConfig,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
|
|
@ -33,9 +33,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 +44,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
|
||||
|
@ -85,12 +81,11 @@ 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)
|
||||
//n.core.SetBuildInfo(n)
|
||||
|
||||
yggfile := fmt.Sprintf("%s/%s-yggdrasil.conf", storageDirectory, instanceName)
|
||||
if _, err := os.Stat(yggfile); !os.IsNotExist(err) {
|
||||
|
@ -131,20 +126,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.Second * 60,
|
||||
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
|
||||
}
|
||||
|
@ -190,9 +187,11 @@ func (n *Node) PeerCount() int {
|
|||
|
||||
func (n *Node) KnownNodes() []gomatrixserverlib.ServerName {
|
||||
nodemap := map[string]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 {
|
||||
|
@ -263,19 +262,3 @@ func (n *Node) SetStaticPeer(uri string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *Node) NotifyLinkNew(f func(boxPubKey crypto.BoxPubKey, linkType, remote string)) {
|
||||
n.core.NotifyLinkNew(f)
|
||||
}
|
||||
|
||||
func (n *Node) NotifyLinkGone(f func(boxPubKey crypto.BoxPubKey, linkType, remote string)) {
|
||||
n.core.NotifyLinkGone(f)
|
||||
}
|
||||
|
||||
func (n *Node) NotifySessionNew(f func(boxPubKey crypto.BoxPubKey)) {
|
||||
n.core.NotifySessionNew(f)
|
||||
}
|
||||
|
||||
func (n *Node) NotifySessionGone(f func(boxPubKey crypto.BoxPubKey)) {
|
||||
n.core.NotifySessionGone(f)
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"time"
|
||||
|
@ -35,7 +36,7 @@ import (
|
|||
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
|
||||
)
|
||||
|
@ -44,18 +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")
|
||||
return
|
||||
}
|
||||
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())
|
||||
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 {
|
||||
|
@ -100,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
|
||||
|
@ -112,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 {
|
||||
|
@ -150,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
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue