mirror of
https://codeberg.org/cunicu/cunicu.git
synced 2025-11-03 03:33:18 +08:00
pdisc: add first version of peer discovery
Signed-off-by: Steffen Vogel <post@steffenvogel.de>
This commit is contained in:
@@ -3,15 +3,18 @@ package core
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
|
||||
"riasc.eu/wice/pkg/crypto"
|
||||
"riasc.eu/wice/pkg/device"
|
||||
"riasc.eu/wice/pkg/util"
|
||||
"riasc.eu/wice/pkg/util/buildinfo"
|
||||
"riasc.eu/wice/pkg/wg"
|
||||
|
||||
proto "riasc.eu/wice/pkg/proto"
|
||||
@@ -254,16 +257,17 @@ func (i *Interface) Configure(cfg *wg.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Interface) AddPeer(pk crypto.Key) error {
|
||||
cfg := wgtypes.Config{
|
||||
Peers: []wgtypes.PeerConfig{
|
||||
{
|
||||
PublicKey: wgtypes.Key(pk),
|
||||
},
|
||||
},
|
||||
func (i *Interface) AddPeer(pcfg *wgtypes.PeerConfig) error {
|
||||
return i.client.ConfigureDevice(i.Name(), wgtypes.Config{
|
||||
Peers: []wgtypes.PeerConfig{*pcfg},
|
||||
})
|
||||
}
|
||||
|
||||
return i.client.ConfigureDevice(i.Name(), cfg)
|
||||
func (i *Interface) UpdatePeer(pcfg *wgtypes.PeerConfig) error {
|
||||
pcfg2 := *pcfg
|
||||
pcfg2.UpdateOnly = true
|
||||
|
||||
return i.AddPeer(&pcfg2)
|
||||
}
|
||||
|
||||
func (i *Interface) RemovePeer(pk crypto.Key) error {
|
||||
@@ -344,13 +348,41 @@ func (i *Interface) MarshalWithPeers(cb func(p *Peer) *coreproto.Peer) *coreprot
|
||||
return q
|
||||
}
|
||||
|
||||
func (i *Interface) MarshalDescription() (*pdiscproto.PeerDescription, error) {
|
||||
func (i *Interface) MarshalDescription(chg pdiscproto.PeerDescriptionChange, pkOld *crypto.Key) (*pdiscproto.PeerDescription, error) {
|
||||
allowedIPs := []*net.IPNet{
|
||||
i.PublicKey().IPv6Address(),
|
||||
i.PublicKey().IPv4Address(),
|
||||
}
|
||||
|
||||
// Only allow a single IP from the network
|
||||
for _, allowedIP := range allowedIPs {
|
||||
for i := range allowedIP.Mask {
|
||||
allowedIP.Mask[i] = 0xff
|
||||
}
|
||||
}
|
||||
|
||||
hn, err := os.Hostname()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get hostname: %w", err)
|
||||
}
|
||||
|
||||
return &pdiscproto.PeerDescription{
|
||||
pd := &pdiscproto.PeerDescription{
|
||||
Change: chg,
|
||||
Hostname: hn,
|
||||
}, nil
|
||||
AllowedIps: util.StringSlice(allowedIPs),
|
||||
BuildInfo: buildinfo.BuildInfo(),
|
||||
}
|
||||
|
||||
if pkOld != nil {
|
||||
if pd.Change != pdiscproto.PeerDescriptionChange_PEER_UPDATE {
|
||||
return nil, fmt.Errorf("can not change public key in non-update message")
|
||||
}
|
||||
|
||||
pd.PublicKeyNew = i.PublicKey().Bytes()
|
||||
pd.PublicKey = pkOld.Bytes()
|
||||
} else {
|
||||
pd.PublicKey = i.PublicKey().Bytes()
|
||||
}
|
||||
|
||||
return pd, nil
|
||||
}
|
||||
|
||||
@@ -142,6 +142,12 @@ func (d *Daemon) Restart() {
|
||||
}
|
||||
|
||||
func (d *Daemon) Close() error {
|
||||
for _, dev := range d.devices {
|
||||
if err := dev.Close(); err != nil {
|
||||
return fmt.Errorf("failed to delete device: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := d.Watcher.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close interface: %w", err)
|
||||
}
|
||||
@@ -156,12 +162,6 @@ func (d *Daemon) Close() error {
|
||||
return fmt.Errorf("failed to close WireGuard client: %w", err)
|
||||
}
|
||||
|
||||
for _, dev := range d.devices {
|
||||
if err := dev.Close(); err != nil {
|
||||
return fmt.Errorf("failed to delete device: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
d.logger.Debug("Closed daemon")
|
||||
|
||||
if d.reexecOnClose {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"riasc.eu/wice/pkg/feat/cfgsync"
|
||||
"riasc.eu/wice/pkg/feat/epdisc"
|
||||
"riasc.eu/wice/pkg/feat/hsync"
|
||||
"riasc.eu/wice/pkg/feat/pdisc"
|
||||
"riasc.eu/wice/pkg/feat/rtsync"
|
||||
"riasc.eu/wice/pkg/signaling"
|
||||
"riasc.eu/wice/pkg/watcher"
|
||||
@@ -43,5 +44,9 @@ func NewFeatures(w *watcher.Watcher, cfg *config.Config, c *wgctrl.Client, b sig
|
||||
feats = append(feats, ep)
|
||||
}
|
||||
|
||||
if cfg.Community != "" {
|
||||
feats = append(feats, pdisc.New(w, c, b, cfg.Community))
|
||||
}
|
||||
|
||||
return feats, ep
|
||||
}
|
||||
|
||||
214
pkg/feat/pdisc/pdisc.go
Normal file
214
pkg/feat/pdisc/pdisc.go
Normal file
@@ -0,0 +1,214 @@
|
||||
// Package pdisc implements peer discovery based on a shared community passphrase.
|
||||
package pdisc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
|
||||
"riasc.eu/wice/pkg/core"
|
||||
"riasc.eu/wice/pkg/crypto"
|
||||
"riasc.eu/wice/pkg/signaling"
|
||||
"riasc.eu/wice/pkg/watcher"
|
||||
"riasc.eu/wice/pkg/wg"
|
||||
|
||||
pdiscproto "riasc.eu/wice/pkg/proto/feat/pdisc"
|
||||
)
|
||||
|
||||
type PeerDiscovery struct {
|
||||
backend signaling.Backend
|
||||
watcher *watcher.Watcher
|
||||
|
||||
community crypto.Key
|
||||
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func New(w *watcher.Watcher, c *wgctrl.Client, b signaling.Backend, community string) *PeerDiscovery {
|
||||
pd := &PeerDiscovery{
|
||||
backend: b,
|
||||
watcher: w,
|
||||
community: crypto.GenerateKeyFromPassword(community),
|
||||
logger: zap.L().Named("pdisc"),
|
||||
}
|
||||
|
||||
w.OnInterface(pd)
|
||||
|
||||
return pd
|
||||
}
|
||||
|
||||
func (pd *PeerDiscovery) Start() error {
|
||||
pd.logger.Info("Started peer discovery")
|
||||
|
||||
// Subscribe to peer updates
|
||||
// TODO: Support per-interface communities
|
||||
|
||||
kp := &crypto.KeyPair{
|
||||
Ours: pd.community,
|
||||
Theirs: signaling.AnyKey,
|
||||
}
|
||||
if _, err := pd.backend.Subscribe(context.Background(), kp, pd); err != nil {
|
||||
return fmt.Errorf("failed to subscribe on peer discovery channel: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pd *PeerDiscovery) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pd *PeerDiscovery) OnInterfaceAdded(i *core.Interface) {
|
||||
i.OnModified(pd)
|
||||
|
||||
// Ignore interface which dont have a private key yet
|
||||
if !i.PrivateKey().IsSet() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := pd.sendPeerDescription(i, pdiscproto.PeerDescriptionChange_PEER_ADD, nil); err != nil {
|
||||
pd.logger.Error("Failed to send peer description", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (pd *PeerDiscovery) OnInterfaceRemoved(i *core.Interface) {
|
||||
// Ignore interface which dont have a private key yet
|
||||
if !i.PrivateKey().IsSet() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := pd.sendPeerDescription(i, pdiscproto.PeerDescriptionChange_PEER_REMOVE, nil); err != nil {
|
||||
pd.logger.Error("Failed to send peer description", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (pd *PeerDiscovery) OnInterfaceModified(i *core.Interface, old *wg.Device, m core.InterfaceModifier) {
|
||||
// Ignore interface which dont have a private key yet
|
||||
if !i.PrivateKey().IsSet() {
|
||||
return
|
||||
}
|
||||
|
||||
// Only send an update if the private key changed.
|
||||
// There are currently no other attributes which would need to be reannounced
|
||||
if m.Is(core.InterfaceModifiedPrivateKey) {
|
||||
if skOld := crypto.Key(old.PrivateKey); skOld.IsSet() {
|
||||
pkOld := skOld.PublicKey()
|
||||
if err := pd.sendPeerDescription(i, pdiscproto.PeerDescriptionChange_PEER_UPDATE, &pkOld); err != nil {
|
||||
pd.logger.Error("Failed to send peer description", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (pd *PeerDiscovery) OnSignalingMessage(kp *crypto.PublicKeyPair, msg *signaling.Message) {
|
||||
if msg.Peer != nil {
|
||||
if i := pd.watcher.Interfaces.ByPublicKey(kp.Theirs); i != nil {
|
||||
// Received our own peer description. Ignoring...
|
||||
return
|
||||
}
|
||||
|
||||
if err := pd.onPeerDescription(msg.Peer); err != nil {
|
||||
pd.logger.Error("Failed to handle peer description", zap.Error(err), zap.Any("pd", msg.Peer))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (pd *PeerDiscovery) onPeerDescription(pdisc *pdiscproto.PeerDescription) error {
|
||||
pk, err := crypto.ParseKeyBytes(pdisc.PublicKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid public key: %w", err)
|
||||
}
|
||||
|
||||
p := pd.watcher.PeerByKey(&pk)
|
||||
cfg := pdisc.Config()
|
||||
|
||||
switch pdisc.Change {
|
||||
case pdiscproto.PeerDescriptionChange_PEER_ADD:
|
||||
if p != nil {
|
||||
pd.logger.Warn("Peer already exists. Updating it instead", zap.String("intf", p.Interface.Name()))
|
||||
pdisc.Change = pdiscproto.PeerDescriptionChange_PEER_UPDATE
|
||||
}
|
||||
|
||||
case pdiscproto.PeerDescriptionChange_PEER_UPDATE:
|
||||
if p == nil {
|
||||
pd.logger.Warn("Peer does not exist exists yet. Adding it instead")
|
||||
pdisc.Change = pdiscproto.PeerDescriptionChange_PEER_ADD
|
||||
}
|
||||
|
||||
default:
|
||||
if p == nil {
|
||||
return fmt.Errorf("cant remove non-existing peer")
|
||||
}
|
||||
}
|
||||
|
||||
switch pdisc.Change {
|
||||
case pdiscproto.PeerDescriptionChange_PEER_ADD:
|
||||
for _, i := range pd.watcher.Interfaces {
|
||||
if err := i.AddPeer(&cfg); err != nil {
|
||||
return fmt.Errorf("failed to add peer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
case pdiscproto.PeerDescriptionChange_PEER_UPDATE:
|
||||
if pdisc.PublicKeyNew != nil {
|
||||
// Remove old peer
|
||||
if err := p.Interface.RemovePeer(pk); err != nil {
|
||||
return fmt.Errorf("failed to remove peer: %w", err)
|
||||
}
|
||||
|
||||
// Re-add peer with new public key
|
||||
if err := p.Interface.AddPeer(&cfg); err != nil {
|
||||
return fmt.Errorf("failed to add peer: %w", err)
|
||||
}
|
||||
} else {
|
||||
if err := p.Interface.UpdatePeer(&cfg); err != nil {
|
||||
return fmt.Errorf("failed to remove peer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
case pdiscproto.PeerDescriptionChange_PEER_REMOVE:
|
||||
if err := p.Interface.RemovePeer(pk); err != nil {
|
||||
return fmt.Errorf("failed to remove peer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Re-announce ourself in case this is a new peer we didnt knew already
|
||||
if p == nil {
|
||||
time.AfterFunc(1*time.Second, func() {
|
||||
for _, i := range pd.watcher.Interfaces {
|
||||
if err := pd.sendPeerDescription(i, pdiscproto.PeerDescriptionChange_PEER_ADD, nil); err != nil {
|
||||
pd.logger.Error("Failed to send peer description", zap.Error(err))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pd *PeerDiscovery) sendPeerDescription(i *core.Interface, chg pdiscproto.PeerDescriptionChange, pkOld *crypto.Key) error {
|
||||
d, err := i.MarshalDescription(chg, pkOld)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate peer description: %w", err)
|
||||
}
|
||||
|
||||
msg := &signaling.Message{
|
||||
Peer: d,
|
||||
}
|
||||
|
||||
kp := &crypto.KeyPair{
|
||||
Ours: i.PrivateKey(),
|
||||
Theirs: pd.community.PublicKey(),
|
||||
}
|
||||
|
||||
if err := pd.backend.Publish(context.Background(), kp, msg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pd.logger.Debug("Send peer description", zap.Any("description", d))
|
||||
|
||||
return nil
|
||||
}
|
||||
34
pkg/proto/feat/pdisc/pdisc.go
Normal file
34
pkg/proto/feat/pdisc/pdisc.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package pdisc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"riasc.eu/wice/pkg/crypto"
|
||||
)
|
||||
|
||||
func (pd *PeerDescription) Config() wgtypes.PeerConfig {
|
||||
var pk crypto.Key
|
||||
if pd.PublicKeyNew != nil {
|
||||
pk, _ = crypto.ParseKeyBytes(pd.PublicKeyNew)
|
||||
} else {
|
||||
pk, _ = crypto.ParseKeyBytes(pd.PublicKey)
|
||||
}
|
||||
|
||||
allowedIPs := []net.IPNet{}
|
||||
for _, allowedIP := range pd.AllowedIps {
|
||||
_, ipnet, err := net.ParseCIDR(allowedIP)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to parse WireGuard AllowedIP: %w", err))
|
||||
}
|
||||
|
||||
allowedIPs = append(allowedIPs, *ipnet)
|
||||
}
|
||||
|
||||
return wgtypes.PeerConfig{
|
||||
ReplaceAllowedIPs: true,
|
||||
PublicKey: wgtypes.Key(pk),
|
||||
AllowedIPs: allowedIPs,
|
||||
}
|
||||
}
|
||||
266
pkg/proto/feat/pdisc/pdisc.pb.go
Normal file
266
pkg/proto/feat/pdisc/pdisc.pb.go
Normal file
@@ -0,0 +1,266 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc v3.6.1
|
||||
// source: feat/pdisc.proto
|
||||
|
||||
package pdisc
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
proto "riasc.eu/wice/pkg/proto"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type PeerDescriptionChange int32
|
||||
|
||||
const (
|
||||
PeerDescriptionChange_PEER_ADD PeerDescriptionChange = 0
|
||||
PeerDescriptionChange_PEER_REMOVE PeerDescriptionChange = 1
|
||||
PeerDescriptionChange_PEER_UPDATE PeerDescriptionChange = 2
|
||||
)
|
||||
|
||||
// Enum value maps for PeerDescriptionChange.
|
||||
var (
|
||||
PeerDescriptionChange_name = map[int32]string{
|
||||
0: "PEER_ADD",
|
||||
1: "PEER_REMOVE",
|
||||
2: "PEER_UPDATE",
|
||||
}
|
||||
PeerDescriptionChange_value = map[string]int32{
|
||||
"PEER_ADD": 0,
|
||||
"PEER_REMOVE": 1,
|
||||
"PEER_UPDATE": 2,
|
||||
}
|
||||
)
|
||||
|
||||
func (x PeerDescriptionChange) Enum() *PeerDescriptionChange {
|
||||
p := new(PeerDescriptionChange)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x PeerDescriptionChange) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (PeerDescriptionChange) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_feat_pdisc_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (PeerDescriptionChange) Type() protoreflect.EnumType {
|
||||
return &file_feat_pdisc_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x PeerDescriptionChange) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PeerDescriptionChange.Descriptor instead.
|
||||
func (PeerDescriptionChange) EnumDescriptor() ([]byte, []int) {
|
||||
return file_feat_pdisc_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// A PeerDescription is an announcement of a peer which is distributed to
|
||||
type PeerDescription struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Change PeerDescriptionChange `protobuf:"varint,1,opt,name=change,proto3,enum=wice.pdisc.PeerDescriptionChange" json:"change,omitempty"`
|
||||
// Hostname of the node
|
||||
Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"`
|
||||
// Public WireGuard Curve25519 key
|
||||
PublicKey []byte `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
// A new public WireGuard Curve25519 key
|
||||
// Only valid for change == PEER_UPDATE
|
||||
PublicKeyNew []byte `protobuf:"bytes,4,opt,name=public_key_new,json=publicKeyNew,proto3" json:"public_key_new,omitempty"`
|
||||
// List of allowed IPs
|
||||
AllowedIps []string `protobuf:"bytes,5,rep,name=allowed_ips,json=allowedIps,proto3" json:"allowed_ips,omitempty"`
|
||||
// wice build information
|
||||
BuildInfo *proto.BuildInfo `protobuf:"bytes,6,opt,name=build_info,json=buildInfo,proto3" json:"build_info,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PeerDescription) Reset() {
|
||||
*x = PeerDescription{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_feat_pdisc_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PeerDescription) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PeerDescription) ProtoMessage() {}
|
||||
|
||||
func (x *PeerDescription) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_feat_pdisc_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PeerDescription.ProtoReflect.Descriptor instead.
|
||||
func (*PeerDescription) Descriptor() ([]byte, []int) {
|
||||
return file_feat_pdisc_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PeerDescription) GetChange() PeerDescriptionChange {
|
||||
if x != nil {
|
||||
return x.Change
|
||||
}
|
||||
return PeerDescriptionChange_PEER_ADD
|
||||
}
|
||||
|
||||
func (x *PeerDescription) GetHostname() string {
|
||||
if x != nil {
|
||||
return x.Hostname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PeerDescription) GetPublicKey() []byte {
|
||||
if x != nil {
|
||||
return x.PublicKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PeerDescription) GetPublicKeyNew() []byte {
|
||||
if x != nil {
|
||||
return x.PublicKeyNew
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PeerDescription) GetAllowedIps() []string {
|
||||
if x != nil {
|
||||
return x.AllowedIps
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PeerDescription) GetBuildInfo() *proto.BuildInfo {
|
||||
if x != nil {
|
||||
return x.BuildInfo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_feat_pdisc_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_feat_pdisc_proto_rawDesc = []byte{
|
||||
0x0a, 0x10, 0x66, 0x65, 0x61, 0x74, 0x2f, 0x70, 0x64, 0x69, 0x73, 0x63, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x12, 0x0a, 0x77, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x64, 0x69, 0x73, 0x63, 0x1a, 0x0c,
|
||||
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfe, 0x01, 0x0a,
|
||||
0x0f, 0x50, 0x65, 0x65, 0x72, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x39, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
|
||||
0x32, 0x21, 0x2e, 0x77, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x64, 0x69, 0x73, 0x63, 0x2e, 0x50, 0x65,
|
||||
0x65, 0x72, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x68, 0x61,
|
||||
0x6e, 0x67, 0x65, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68,
|
||||
0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68,
|
||||
0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||
0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
|
||||
0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6e, 0x65, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c,
|
||||
0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4e, 0x65, 0x77, 0x12, 0x1f, 0x0a, 0x0b,
|
||||
0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x12, 0x2e, 0x0a,
|
||||
0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x0f, 0x2e, 0x77, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x2a, 0x47, 0x0a,
|
||||
0x15, 0x50, 0x65, 0x65, 0x72, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x45, 0x45, 0x52, 0x5f, 0x41,
|
||||
0x44, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x45, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x4d,
|
||||
0x4f, 0x56, 0x45, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x45, 0x45, 0x52, 0x5f, 0x55, 0x50,
|
||||
0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x42, 0x24, 0x5a, 0x22, 0x72, 0x69, 0x61, 0x73, 0x63, 0x2e,
|
||||
0x65, 0x75, 0x2f, 0x77, 0x69, 0x63, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2f, 0x66, 0x65, 0x61, 0x74, 0x2f, 0x70, 0x64, 0x69, 0x73, 0x63, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_feat_pdisc_proto_rawDescOnce sync.Once
|
||||
file_feat_pdisc_proto_rawDescData = file_feat_pdisc_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_feat_pdisc_proto_rawDescGZIP() []byte {
|
||||
file_feat_pdisc_proto_rawDescOnce.Do(func() {
|
||||
file_feat_pdisc_proto_rawDescData = protoimpl.X.CompressGZIP(file_feat_pdisc_proto_rawDescData)
|
||||
})
|
||||
return file_feat_pdisc_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_feat_pdisc_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_feat_pdisc_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_feat_pdisc_proto_goTypes = []interface{}{
|
||||
(PeerDescriptionChange)(0), // 0: wice.pdisc.PeerDescriptionChange
|
||||
(*PeerDescription)(nil), // 1: wice.pdisc.PeerDescription
|
||||
(*proto.BuildInfo)(nil), // 2: wice.BuildInfo
|
||||
}
|
||||
var file_feat_pdisc_proto_depIdxs = []int32{
|
||||
0, // 0: wice.pdisc.PeerDescription.change:type_name -> wice.pdisc.PeerDescriptionChange
|
||||
2, // 1: wice.pdisc.PeerDescription.build_info:type_name -> wice.BuildInfo
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_feat_pdisc_proto_init() }
|
||||
func file_feat_pdisc_proto_init() {
|
||||
if File_feat_pdisc_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_feat_pdisc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PeerDescription); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_feat_pdisc_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_feat_pdisc_proto_goTypes,
|
||||
DependencyIndexes: file_feat_pdisc_proto_depIdxs,
|
||||
EnumInfos: file_feat_pdisc_proto_enumTypes,
|
||||
MessageInfos: file_feat_pdisc_proto_msgTypes,
|
||||
}.Build()
|
||||
File_feat_pdisc_proto = out.File
|
||||
file_feat_pdisc_proto_rawDesc = nil
|
||||
file_feat_pdisc_proto_goTypes = nil
|
||||
file_feat_pdisc_proto_depIdxs = nil
|
||||
}
|
||||
@@ -5,7 +5,7 @@ package proto
|
||||
//go:generate protoc --proto_path=../../proto --go_out=. --go_opt=paths=import,module=riasc.eu/wice/pkg/proto core/peer.proto core/interface.proto
|
||||
//go:generate protoc --proto_path=../../proto --go_out=. --go_opt=paths=import,module=riasc.eu/wice/pkg/proto signaling/signaling.proto
|
||||
//go:generate protoc --proto_path=../../proto --go_out=. --go_opt=paths=import,module=riasc.eu/wice/pkg/proto rpc/daemon.proto rpc/epdisc.proto rpc/event.proto rpc/signaling.proto rpc/watcher.proto
|
||||
//go:generate protoc --proto_path=../../proto --go_out=. --go_opt=paths=import,module=riasc.eu/wice/pkg/proto feat/epdisc.proto feat/epdisc_candidate.proto
|
||||
//go:generate protoc --proto_path=../../proto --go_out=. --go_opt=paths=import,module=riasc.eu/wice/pkg/proto feat/epdisc.proto feat/epdisc_candidate.proto feat/pdisc.proto
|
||||
|
||||
//go:generate protoc --proto_path=../../proto --go-grpc_out=. --go-grpc_opt=paths=import,module=riasc.eu/wice/pkg/proto rpc/daemon.proto rpc/epdisc.proto rpc/signaling.proto rpc/watcher.proto
|
||||
//go:generate protoc --proto_path=../../proto --go-grpc_out=. --go-grpc_opt=paths=import,module=riasc.eu/wice/pkg/proto signaling/signaling.proto
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
@@ -77,3 +78,13 @@ func MapSlice[T any](s []T, cb func(T) T) []T {
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func StringSlice[T any](s []T) []string {
|
||||
n := []string{}
|
||||
|
||||
for _, t := range s {
|
||||
n = append(n, fmt.Sprintf("%v", t))
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
@@ -86,6 +86,10 @@ func New(client *wgctrl.Client, interval time.Duration, filter *regexp.Regexp) (
|
||||
}
|
||||
|
||||
func (w *Watcher) Close() error {
|
||||
if err := w.Sync(); err != nil {
|
||||
return fmt.Errorf("final sync failed")
|
||||
}
|
||||
|
||||
close(w.stop)
|
||||
|
||||
return nil
|
||||
@@ -222,3 +226,13 @@ func (w *Watcher) Peer(intf string, pk *crypto.Key) *core.Peer {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Watcher) PeerByKey(pk *crypto.Key) *core.Peer {
|
||||
for _, i := range w.Interfaces {
|
||||
if p, ok := i.Peers[*pk]; ok {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -112,7 +112,9 @@ var _ = Describe("watcher", func() {
|
||||
sk, err := crypto.GenerateKey()
|
||||
Expect(err).To(Succeed())
|
||||
|
||||
err = i.AddPeer(sk.PublicKey())
|
||||
err = i.AddPeer(&wgtypes.PeerConfig{
|
||||
PublicKey: wgtypes.Key(sk.PublicKey()),
|
||||
})
|
||||
Expect(err).To(Succeed())
|
||||
|
||||
Eventually(func(g Gomega) {
|
||||
|
||||
33
proto/feat/pdisc.proto
Normal file
33
proto/feat/pdisc.proto
Normal file
@@ -0,0 +1,33 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package wice.pdisc;
|
||||
option go_package = "riasc.eu/wice/pkg/proto/feat/pdisc";
|
||||
|
||||
import "common.proto";
|
||||
|
||||
enum PeerDescriptionChange {
|
||||
PEER_ADD = 0;
|
||||
PEER_REMOVE = 1;
|
||||
PEER_UPDATE = 2;
|
||||
}
|
||||
|
||||
// A PeerDescription is an announcement of a peer which is distributed to
|
||||
message PeerDescription {
|
||||
PeerDescriptionChange change = 1;
|
||||
|
||||
// Hostname of the node
|
||||
string hostname = 2;
|
||||
|
||||
// Public WireGuard Curve25519 key
|
||||
bytes public_key = 3;
|
||||
|
||||
// A new public WireGuard Curve25519 key
|
||||
// Only valid for change == PEER_UPDATE
|
||||
bytes public_key_new = 4;
|
||||
|
||||
// List of allowed IPs
|
||||
repeated string allowed_ips = 5;
|
||||
|
||||
// wice build information
|
||||
BuildInfo build_info = 6;
|
||||
}
|
||||
Reference in New Issue
Block a user