The mesh runs on the seat's bus alone (novox/hq ADR 0131, design 28 task 5.5). The host's old dialling and enrolment paths are deleted with the switch that chose between them; a membership or a token naming another bus is refused before anything is sent, rather than dialled on a transport that no longer exists.
54 lines
2.0 KiB
Go
54 lines
2.0 KiB
Go
package link
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// The enrolment conversation, as the host's own words for it.
|
|
//
|
|
// **Its own seam rather than part of Link**, because almost nothing about it is the same. The
|
|
// credential is a one-time secret rather than this node's own; there is no declaration to hear; the
|
|
// whole exchange is a single question asked and possibly asked again. And the stakes differ: a node
|
|
// that fails here is not in the mesh at all, where a node that fails in Link has merely lost touch
|
|
// with one it belongs to.
|
|
|
|
// Approach is how a node reaches a mesh it does not yet belong to.
|
|
//
|
|
// The three things a token carries about where to go, and nothing about who is asking: the address,
|
|
// the certificate that address must present, and which bus is at the other end — the mesh's own
|
|
// (hearing.go), and a token naming any other is refused before anything is sent.
|
|
type Approach struct {
|
|
Address string
|
|
Fingerprint string
|
|
Transport string
|
|
}
|
|
|
|
// Asking is one open enrolment conversation.
|
|
type Asking interface {
|
|
// Ask puts the request to the mesh and waits for one answer, or says why none came.
|
|
//
|
|
// Called again, with the same bytes, while the mesh says "try again": the keys this node
|
|
// generated are the ones it keeps, so the same request is the same enrolment and the mesh holds
|
|
// the token for it (novox/hq issue 083).
|
|
Ask(ctx context.Context, request []byte, wait time.Duration) ([]byte, error)
|
|
|
|
// Close lets go of the connection made with the token.
|
|
Close()
|
|
}
|
|
|
|
// Present opens an enrolment conversation with the mesh.
|
|
//
|
|
// The connection is made before anything is sent, and the certificate is checked while it is being
|
|
// made — so a node pointed at the wrong bus finds out before its token has left the machine (ADR
|
|
// 0004).
|
|
func Present(ctx context.Context, to Approach, node, secret string,
|
|
timeout time.Duration) (Asking, error) {
|
|
|
|
if to.Transport != OnNATS {
|
|
return nil, fmt.Errorf("this token is for the %q bus, and the mesh's bus is %s", to.Transport, OnNATS)
|
|
}
|
|
return presentNats(ctx, to, node, secret, timeout)
|
|
}
|