MagiTrickle/group.go

115 lines
2.1 KiB
Go
Raw Normal View History

2024-08-27 03:07:58 +03:00
package main
2024-08-30 04:30:33 +03:00
import (
"fmt"
2024-08-30 05:27:52 +03:00
"net"
2024-09-04 08:14:09 +03:00
"os"
2024-08-30 05:27:52 +03:00
"time"
2024-08-30 04:30:33 +03:00
"kvas2-go/models"
"kvas2-go/pkg/ip-helper"
"github.com/vishvananda/netlink"
2024-08-30 04:30:33 +03:00
)
2024-08-27 03:07:58 +03:00
2024-08-30 04:09:28 +03:00
type GroupOptions struct {
Enabled bool
ipRule *netlink.Rule
2024-08-30 04:09:28 +03:00
}
2024-08-27 03:07:58 +03:00
type Group struct {
*models.Group
2024-08-30 04:40:46 +03:00
ipsetName string
options GroupOptions
2024-08-27 03:07:58 +03:00
}
2024-08-30 04:30:33 +03:00
2024-08-30 05:27:52 +03:00
func (g *Group) HandleIPv4(names []string, address net.IP, ttl time.Duration) error {
if !g.options.Enabled {
return nil
}
2024-09-04 08:14:09 +03:00
ttlSeconds := uint32(ttl.Seconds())
2024-08-30 05:27:52 +03:00
DomainSearch:
for _, domain := range g.Domains {
if !domain.IsEnabled() {
continue
}
for _, name := range names {
if domain.IsMatch(name) {
2024-09-04 08:14:09 +03:00
err := netlink.IpsetAdd(g.ipsetName, &netlink.IPSetEntry{
IP: address,
Timeout: &ttlSeconds,
Replace: true,
})
2024-08-30 05:27:52 +03:00
if err != nil {
2024-09-04 09:15:03 +03:00
return fmt.Errorf("failed to assign address: %w", err)
2024-08-30 05:27:52 +03:00
}
break DomainSearch
}
}
}
return nil
}
2024-08-30 04:30:33 +03:00
func (g *Group) Enable() error {
if g.options.Enabled {
return nil
}
var err error
rule := netlink.NewRule()
rule.Mark, err = ipHelper.GetUnusedFwMark(1)
2024-08-30 04:30:33 +03:00
if err != nil {
return fmt.Errorf("error while getting free fwmark: %w", err)
}
rule.Table, err = ipHelper.GetUnusedTable(1)
2024-08-30 04:30:33 +03:00
if err != nil {
return fmt.Errorf("error while getting free table: %w", err)
}
err = netlink.RuleAdd(rule)
2024-08-30 04:30:33 +03:00
if err != nil {
return fmt.Errorf("error while adding rule: %w", err)
2024-08-30 04:30:33 +03:00
}
g.options.ipRule = rule
2024-08-30 04:30:33 +03:00
2024-09-04 08:14:09 +03:00
defaultTimeout := uint32(300)
err = netlink.IpsetDestroy(g.ipsetName)
if err != nil && !os.IsNotExist(err) {
2024-08-30 04:40:46 +03:00
return fmt.Errorf("failed to destroy ipset: %w", err)
}
2024-09-04 08:14:09 +03:00
err = netlink.IpsetCreate(g.ipsetName, "hash:ip", netlink.IpsetCreateOptions{
Timeout: &defaultTimeout,
})
2024-08-30 04:40:46 +03:00
if err != nil {
return fmt.Errorf("failed to create ipset: %w", err)
}
2024-08-30 04:30:33 +03:00
g.options.Enabled = true
return nil
}
func (g *Group) Disable() error {
if !g.options.Enabled {
return nil
}
err := netlink.RuleDel(g.options.ipRule)
2024-08-30 04:30:33 +03:00
if err != nil {
return fmt.Errorf("error while deleting rule: %w", err)
2024-08-30 04:30:33 +03:00
}
2024-09-04 08:14:09 +03:00
err = netlink.IpsetDestroy(g.ipsetName)
if err != nil && !os.IsNotExist(err) {
2024-08-30 04:40:46 +03:00
return fmt.Errorf("failed to destroy ipset: %w", err)
}
2024-08-30 04:30:33 +03:00
g.options.Enabled = false
g.options.ipRule = nil
2024-08-30 04:30:33 +03:00
return nil
}