feat: grace period for new peers as a new evection policy
Signed-off-by: HeshamTB <hishaminv@gmail.com>
This commit is contained in:
parent
8e798706e3
commit
7d1a0cdbdc
@ -180,6 +180,8 @@ func HandleDeletePeer(wg *WGLink) http.HandlerFunc {
|
||||
|
||||
func HandleGetCreatePeer(wg *WGLink) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
reqId := r.Context().Value(CtxReqID).(uuid.UUID)
|
||||
info("Create peer", reqId)
|
||||
newPeer, err := wg.CreateNewPeer()
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
@ -200,8 +202,6 @@ func HandleGetCreatePeer(wg *WGLink) http.HandlerFunc {
|
||||
slog.Error(err.Error())
|
||||
}
|
||||
|
||||
// TODO: Add peer to device
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
15
link.go
15
link.go
@ -20,6 +20,7 @@ type WGLink struct {
|
||||
*netlink.LinkAttrs
|
||||
*wgctrl.Client
|
||||
IPPool
|
||||
meta *PeerMeta
|
||||
Endpoint string // Endpoint for clients to use when connecting to this link. Has no effect.
|
||||
StartedAT time.Time
|
||||
lock *sync.Mutex
|
||||
@ -60,6 +61,7 @@ func InitWGLink(ifName string, privateKey *wgtypes.Key, port int, endpoint strin
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wg.meta = NewPeerMeta()
|
||||
wg.lock = &sync.Mutex{}
|
||||
|
||||
return &wg, netlink.LinkSetUp(&wg)
|
||||
@ -146,6 +148,8 @@ func (wg *WGLink) AddPeer(publicKey string) (*wgtypes.Peer, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wg.meta.AddPeer(pubKey)
|
||||
|
||||
return wg.getPeer(pubKey)
|
||||
}
|
||||
@ -175,6 +179,8 @@ func (wg *WGLink) deletePeer(publickey wgtypes.Key) error {
|
||||
return err
|
||||
}
|
||||
|
||||
wg.meta.DeletePeer(publickey)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -258,7 +264,7 @@ func (wg *WGLink) GetPublicKey() (*wgtypes.Key, error) {
|
||||
type NewPeer struct {
|
||||
Peer wgtypes.Peer // The server as a peer
|
||||
PrivateKey wgtypes.Key
|
||||
Address net.IP
|
||||
Address net.IPNet
|
||||
DNS []net.IP
|
||||
MTU uint
|
||||
|
||||
@ -266,7 +272,7 @@ type NewPeer struct {
|
||||
}
|
||||
|
||||
// Create a new peer. Used for server-side clinet config generation
|
||||
// Peer is not added to the wglink
|
||||
// New peer is added to the wireguard device
|
||||
func (wg *WGLink) CreateNewPeer() (*NewPeer, error) {
|
||||
dev, err := wg.Device(wg.Name)
|
||||
if err != nil {
|
||||
@ -283,19 +289,18 @@ func (wg *WGLink) CreateNewPeer() (*NewPeer, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ip, err := wg.Allocate()
|
||||
wgPeer, err := wg.AddPeer(privKey.PublicKey().String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peer := NewPeer{
|
||||
Address: ip,
|
||||
Address: wgPeer.AllowedIPs[0],
|
||||
DNS: WG_CLIENT_DNS,
|
||||
PrivateKey: privKey,
|
||||
MTU: WG_CLIENT_MTU,
|
||||
Peer: wgtypes.Peer{
|
||||
PublicKey: *serverPubkey,
|
||||
AllowedIPs: []net.IPNet{wg.Network()},
|
||||
},
|
||||
Endpoint: fmt.Sprintf("%s:%d", wg.Endpoint, dev.ListenPort),
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ func monitor(wg *WGLink, log slog.Logger) {
|
||||
for _, peer := range peers {
|
||||
totalRx += peer.ReceiveBytes
|
||||
totalTx += peer.TransmitBytes
|
||||
if !isActive(peer) {
|
||||
if !isActive(peer, wg) {
|
||||
log.Info(
|
||||
fmt.Sprintf("[WGMonitor] Evecting peer %s", peer.PublicKey.String()),
|
||||
)
|
||||
@ -48,8 +48,11 @@ func monitor(wg *WGLink, log slog.Logger) {
|
||||
}
|
||||
}
|
||||
|
||||
func isActive(peer wgtypes.Peer) bool {
|
||||
func isActive(peer wgtypes.Peer, wg *WGLink) bool {
|
||||
if peer.LastHandshakeTime.IsZero() {
|
||||
if time.Since(wg.meta.TimeAdded(peer.PublicKey)) < time.Duration(4 * time.Minute) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
} else if time.Since(peer.LastHandshakeTime.UTC()) < time.Duration(4 * time.Minute) {
|
||||
return true
|
||||
|
54
peer_meta.go
Normal file
54
peer_meta.go
Normal file
@ -0,0 +1,54 @@
|
||||
package hvpnnode3
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
// Contians data about peers
|
||||
type PeerData struct {
|
||||
addedOn time.Time
|
||||
deleted bool
|
||||
}
|
||||
|
||||
// Basic implementaion to track peers based on public keys. Thraed safe.
|
||||
type PeerMeta struct {
|
||||
data map[wgtypes.Key]PeerData
|
||||
rwl *sync.RWMutex
|
||||
}
|
||||
|
||||
func NewPeerMeta() *PeerMeta {
|
||||
meta := new(PeerMeta)
|
||||
meta.data = make(map[wgtypes.Key]PeerData)
|
||||
meta.rwl = new(sync.RWMutex)
|
||||
return meta
|
||||
}
|
||||
|
||||
func (m *PeerMeta) AddPeer(publicKey wgtypes.Key) {
|
||||
m.rwl.Lock()
|
||||
m.data[publicKey] = PeerData{
|
||||
addedOn: time.Now().UTC(),
|
||||
deleted: false,
|
||||
}
|
||||
m.rwl.Unlock()
|
||||
}
|
||||
|
||||
func (m *PeerMeta) DeletePeer(publicKey wgtypes.Key) {
|
||||
m.rwl.Lock()
|
||||
d := m.data[publicKey]
|
||||
d.deleted = true
|
||||
m.rwl.Unlock()
|
||||
}
|
||||
|
||||
func (m *PeerMeta) TimeAdded(publicKey wgtypes.Key) time.Time {
|
||||
m.rwl.RLock()
|
||||
t := m.data[publicKey].addedOn
|
||||
m.rwl.RUnlock()
|
||||
return t
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
[Interface]
|
||||
Address = {{ .Address }}/24
|
||||
Address = {{ .Address }}
|
||||
PrivateKey = {{ .PrivateKey }}
|
||||
DNS = {{$dnss := .DNS}}{{range $index, $element := .DNS}}{{if $index}}, {{end}}{{$element.String}}{{end}}
|
||||
MTU = {{ .MTU }}
|
||||
|
Loading…
Reference in New Issue
Block a user