github.com/sagernet/sing-box@v1.9.0-rc.20/common/srs/ip_set.go (about) 1 package srs 2 3 import ( 4 "encoding/binary" 5 "io" 6 "net/netip" 7 "unsafe" 8 9 "github.com/sagernet/sing/common/rw" 10 11 "go4.org/netipx" 12 ) 13 14 type myIPSet struct { 15 rr []myIPRange 16 } 17 18 type myIPRange struct { 19 from netip.Addr 20 to netip.Addr 21 } 22 23 func readIPSet(reader io.Reader) (*netipx.IPSet, error) { 24 var version uint8 25 err := binary.Read(reader, binary.BigEndian, &version) 26 if err != nil { 27 return nil, err 28 } 29 var length uint64 30 err = binary.Read(reader, binary.BigEndian, &length) 31 if err != nil { 32 return nil, err 33 } 34 mySet := &myIPSet{ 35 rr: make([]myIPRange, length), 36 } 37 for i := uint64(0); i < length; i++ { 38 var ( 39 fromLen uint64 40 toLen uint64 41 fromAddr netip.Addr 42 toAddr netip.Addr 43 ) 44 fromLen, err = rw.ReadUVariant(reader) 45 if err != nil { 46 return nil, err 47 } 48 fromBytes := make([]byte, fromLen) 49 _, err = io.ReadFull(reader, fromBytes) 50 if err != nil { 51 return nil, err 52 } 53 err = fromAddr.UnmarshalBinary(fromBytes) 54 if err != nil { 55 return nil, err 56 } 57 toLen, err = rw.ReadUVariant(reader) 58 if err != nil { 59 return nil, err 60 } 61 toBytes := make([]byte, toLen) 62 _, err = io.ReadFull(reader, toBytes) 63 if err != nil { 64 return nil, err 65 } 66 err = toAddr.UnmarshalBinary(toBytes) 67 if err != nil { 68 return nil, err 69 } 70 mySet.rr[i] = myIPRange{fromAddr, toAddr} 71 } 72 return (*netipx.IPSet)(unsafe.Pointer(mySet)), nil 73 } 74 75 func writeIPSet(writer io.Writer, set *netipx.IPSet) error { 76 err := binary.Write(writer, binary.BigEndian, uint8(1)) 77 if err != nil { 78 return err 79 } 80 mySet := (*myIPSet)(unsafe.Pointer(set)) 81 err = binary.Write(writer, binary.BigEndian, uint64(len(mySet.rr))) 82 if err != nil { 83 return err 84 } 85 for _, rr := range mySet.rr { 86 var ( 87 fromBinary []byte 88 toBinary []byte 89 ) 90 fromBinary, err = rr.from.MarshalBinary() 91 if err != nil { 92 return err 93 } 94 err = rw.WriteUVariant(writer, uint64(len(fromBinary))) 95 if err != nil { 96 return err 97 } 98 _, err = writer.Write(fromBinary) 99 if err != nil { 100 return err 101 } 102 toBinary, err = rr.to.MarshalBinary() 103 if err != nil { 104 return err 105 } 106 err = rw.WriteUVariant(writer, uint64(len(toBinary))) 107 if err != nil { 108 return err 109 } 110 _, err = writer.Write(toBinary) 111 if err != nil { 112 return err 113 } 114 } 115 return nil 116 }