mirror of
https://github.com/fumiama/WireGold.git
synced 2026-06-08 17:40:26 +08:00
108 lines
2.2 KiB
Go
108 lines
2.2 KiB
Go
package wg
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
|
|
base14 "github.com/fumiama/go-base16384"
|
|
curve "github.com/fumiama/go-x25519"
|
|
|
|
"github.com/fumiama/WireGold/config"
|
|
"github.com/fumiama/WireGold/gold/link"
|
|
"github.com/fumiama/WireGold/helper"
|
|
"github.com/fumiama/WireGold/lower"
|
|
)
|
|
|
|
const suffix32 = "㴄"
|
|
|
|
type WG struct {
|
|
c *config.Config
|
|
key [32]byte
|
|
PublicKey string
|
|
nic *lower.NIC
|
|
me link.Me
|
|
}
|
|
|
|
func NewWireGold(c *config.Config) (wg WG, err error) {
|
|
wg.c = c
|
|
|
|
var k []byte
|
|
k, err = base14.UTF82utf16be(helper.StringToBytes(c.PrivateKey + suffix32))
|
|
if err != nil {
|
|
return
|
|
}
|
|
n := copy(wg.key[:], base14.Decode(k))
|
|
if n != 32 {
|
|
err = errors.New("private key length is not 32")
|
|
return
|
|
}
|
|
|
|
cur := curve.Get(wg.key[:])
|
|
pubk, err := base14.UTF16be2utf8(base14.Encode((*cur.Public())[:]))
|
|
if err != nil {
|
|
return
|
|
}
|
|
wg.PublicKey = helper.BytesToString(pubk[:57])
|
|
|
|
return
|
|
}
|
|
|
|
func (wg *WG) Start(srcport, destport, mtu uint16) {
|
|
wg.init(srcport, destport, mtu)
|
|
wg.nic.Up()
|
|
go wg.nic.Start(&wg.me)
|
|
}
|
|
|
|
func (wg *WG) Run(srcport, destport, mtu uint16) {
|
|
wg.init(srcport, destport, mtu)
|
|
wg.nic.Up()
|
|
wg.nic.Start(&wg.me)
|
|
}
|
|
|
|
func (wg *WG) Stop() {
|
|
wg.nic.Stop()
|
|
wg.nic.Down()
|
|
wg.nic.Destroy()
|
|
}
|
|
|
|
func (wg *WG) init(srcport, destport, mtu uint16) {
|
|
cidrsmap := make(map[string]bool, 32)
|
|
_, mysubnet, err := net.ParseCIDR(wg.c.SubNet)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
for _, p := range wg.c.Peers {
|
|
for _, ip := range p.AllowedIPs {
|
|
ipnet, _, err := net.ParseCIDR(ip)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if !mysubnet.Contains(ipnet) {
|
|
cidrsmap[ip] = true
|
|
}
|
|
}
|
|
}
|
|
cidrs := make([]string, len(cidrsmap))
|
|
i := 0
|
|
for k := range cidrsmap {
|
|
cidrs[i] = k
|
|
i++
|
|
}
|
|
|
|
wg.nic = lower.NewNIC(wg.c.IP, wg.c.SubNet, cidrs...)
|
|
wg.me = link.NewMe(&wg.key, wg.c.IP+"/32", wg.c.EndPoint, true, srcport, destport, mtu)
|
|
|
|
for _, peer := range wg.c.Peers {
|
|
var peerkey [32]byte
|
|
k, err := base14.UTF82utf16be(helper.StringToBytes(peer.PublicKey + suffix32))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
n := copy(peerkey[:], base14.Decode(k))
|
|
if n != 32 {
|
|
panic("peer public key length is not 32")
|
|
}
|
|
wg.me.AddPeer(peer.IP, &peerkey, peer.EndPoint, peer.AllowedIPs, peer.KeepAliveSeconds, peer.AllowTrans, true)
|
|
}
|
|
}
|