142 lines
2.7 KiB
Go
142 lines
2.7 KiB
Go
package vpn
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/netip"
|
|
"time"
|
|
|
|
"git.jasinco.work/wgcl/internal/logger"
|
|
"git.jasinco.work/wgcl/internal/wg"
|
|
protovpn "git.jasinco.work/wgcl/proto/out"
|
|
"github.com/gin-gonic/gin"
|
|
"google.golang.org/protobuf/encoding/protojson"
|
|
)
|
|
|
|
var wgctrl *wg.WG
|
|
var sync_cancel context.CancelFunc
|
|
|
|
func SyncWGStat(ctx context.Context) {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
default:
|
|
wgctrl.SyncStatus()
|
|
logger.Logger.Info("sync wg status")
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
}
|
|
}
|
|
|
|
func StartWG() {
|
|
var err error
|
|
baseip4 := netip.AddrFrom4([4]byte{172, 16, 0, 1})
|
|
pool := wg.IPPool_Init(baseip4, 26)
|
|
|
|
wgctrl, err = wg.WG_init("wg0", wg.NewKey(), 51823, pool)
|
|
if err != nil {
|
|
logger.Logger.Warn(err.Error())
|
|
logger.Logger.Fatal("Failed init wgctrl")
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
sync_cancel = cancel
|
|
go SyncWGStat(ctx)
|
|
}
|
|
|
|
func StopWG() {
|
|
logger.Logger.Info("Stopping WG")
|
|
sync_cancel()
|
|
wgctrl.Deinit()
|
|
}
|
|
|
|
func GETPeers(c *gin.Context) {
|
|
resp := wgctrl.GetPeersJson()
|
|
resp_json, err := protojson.Marshal(resp)
|
|
if err != nil {
|
|
c.Status(500)
|
|
return
|
|
}
|
|
c.Data(200, "application/json", resp_json)
|
|
}
|
|
func NewPeer(c *gin.Context) {
|
|
req := &protovpn.PeerReq{}
|
|
req_json, err := io.ReadAll(c.Request.Body)
|
|
if err != nil {
|
|
c.Status(400)
|
|
return
|
|
}
|
|
if protojson.Unmarshal(req_json, req) != nil {
|
|
c.Status(400)
|
|
return
|
|
}
|
|
wgctrl.WriteTxStart()
|
|
defer wgctrl.WriteTxEnd()
|
|
|
|
var ip4 *netip.Addr
|
|
if req.HasIp4() {
|
|
_ip4, err := netip.ParseAddr(req.GetIp4())
|
|
ip4 = &_ip4
|
|
if err != nil {
|
|
c.Status(400)
|
|
return
|
|
}
|
|
} else {
|
|
_ip4, err := wgctrl.IP4Pool.Next()
|
|
if err != nil {
|
|
logger.Logger.Warn("ip pool exhausted")
|
|
c.Status(500)
|
|
return
|
|
}
|
|
ip4 = &_ip4
|
|
}
|
|
peer := wg.WGPeer_init(req.GetName(), wg.NewKey(), *ip4)
|
|
wgctrl.AddPeer(peer)
|
|
wgctrl.IP4Pool.Lease(*ip4)
|
|
wgctrl.Apply()
|
|
|
|
c.Status(200)
|
|
}
|
|
|
|
func SearchPeer(c *gin.Context) {
|
|
if pubkey := c.Query("pubkey"); len(pubkey) > 0 {
|
|
p, err := wgctrl.SearchPeerPubkey(pubkey)
|
|
if p == nil {
|
|
if err != nil {
|
|
logger.Logger.Warn(err.Error())
|
|
}
|
|
c.Status(400)
|
|
return
|
|
}
|
|
b, err := protojson.Marshal(p.ToPeerStatus())
|
|
if err != nil {
|
|
logger.Logger.Warn(err.Error())
|
|
}
|
|
c.Data(200, "application/json", b)
|
|
} else {
|
|
c.Status(400)
|
|
}
|
|
}
|
|
|
|
func DeletePeer(c *gin.Context) {
|
|
if pubkey := c.Query("pubkey"); len(pubkey) > 0 {
|
|
p, err := wgctrl.SearchPeerPubkey(pubkey)
|
|
if p == nil {
|
|
if err != nil {
|
|
logger.Logger.Warn(err.Error())
|
|
}
|
|
c.Status(400)
|
|
return
|
|
}
|
|
wgctrl.WriteTxStart()
|
|
defer wgctrl.WriteTxEnd()
|
|
p.Disable()
|
|
if err = wgctrl.Apply(); err != nil {
|
|
logger.Logger.Warn("Can't apply disable peer")
|
|
}
|
|
wgctrl.RemovePeer(p)
|
|
c.Status(200)
|
|
} else {
|
|
c.Status(400)
|
|
}
|
|
}
|