sing-box/common/srs/ip_set.go

82 lines
1.6 KiB
Go
Raw Normal View History

2023-12-01 05:24:12 +00:00
package srs
import (
"encoding/binary"
"net/netip"
2024-06-24 01:49:15 +00:00
"os"
2023-12-01 05:24:12 +00:00
"unsafe"
2024-06-24 01:49:15 +00:00
"github.com/sagernet/sing/common"
M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/common/varbin"
2023-12-01 05:24:12 +00:00
"go4.org/netipx"
)
type myIPSet struct {
rr []myIPRange
}
type myIPRange struct {
from netip.Addr
to netip.Addr
}
2024-06-24 01:49:15 +00:00
type myIPRangeData struct {
From []byte
To []byte
}
func readIPSet(reader varbin.Reader) (*netipx.IPSet, error) {
version, err := reader.ReadByte()
2023-12-01 05:24:12 +00:00
if err != nil {
return nil, err
}
2024-06-24 01:49:15 +00:00
if version != 1 {
return nil, os.ErrInvalid
}
// WTF why using uint64 here
2023-12-01 05:24:12 +00:00
var length uint64
err = binary.Read(reader, binary.BigEndian, &length)
if err != nil {
return nil, err
}
2024-06-24 01:49:15 +00:00
ranges := make([]myIPRangeData, length)
err = varbin.Read(reader, binary.BigEndian, &ranges)
if err != nil {
return nil, err
}
2023-12-01 05:24:12 +00:00
mySet := &myIPSet{
2024-06-24 01:49:15 +00:00
rr: make([]myIPRange, len(ranges)),
2023-12-01 05:24:12 +00:00
}
2024-06-24 01:49:15 +00:00
for i, rangeData := range ranges {
mySet.rr[i].from = M.AddrFromIP(rangeData.From)
mySet.rr[i].to = M.AddrFromIP(rangeData.To)
2023-12-01 05:24:12 +00:00
}
return (*netipx.IPSet)(unsafe.Pointer(mySet)), nil
}
2024-06-24 01:49:15 +00:00
func writeIPSet(writer varbin.Writer, set *netipx.IPSet) error {
err := writer.WriteByte(1)
2023-12-01 05:24:12 +00:00
if err != nil {
return err
}
2024-06-24 01:49:15 +00:00
dataList := common.Map((*myIPSet)(unsafe.Pointer(set)).rr, func(rr myIPRange) myIPRangeData {
return myIPRangeData{
From: rr.from.AsSlice(),
To: rr.to.AsSlice(),
}
})
err = binary.Write(writer, binary.BigEndian, uint64(len(dataList)))
2023-12-01 05:24:12 +00:00
if err != nil {
return err
}
2024-06-24 01:49:15 +00:00
for _, data := range dataList {
err = varbin.Write(writer, binary.BigEndian, data)
2023-12-01 05:24:12 +00:00
if err != nil {
return err
}
}
return nil
}