Skip to content

Commit

Permalink
Add custom route support (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
XYenon authored Oct 10, 2022
1 parent 1ede22e commit 99492e0
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 39 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ require (
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
github.com/sagernet/sing v0.0.0-20220929000216-9a83e35b7186
golang.org/x/net v0.0.0-20220927171203-f486391704dc
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
golang.org/x/net v0.0.0-20221004154528-8021a29435af
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875
gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c
)

Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ github.com/sagernet/sing v0.0.0-20220929000216-9a83e35b7186 h1:ZDlgH6dTozS3ODaYq
github.com/sagernet/sing v0.0.0-20220929000216-9a83e35b7186/go.mod h1:zvgDYKI+vCAW9RyfyrKTgleI+DOa8lzHMPC7VZo3OL4=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
golang.org/x/net v0.0.0-20220927171203-f486391704dc h1:FxpXZdoBqT8RjqTy6i1E8nXHhW21wK7ptQ/EPIGxzPQ=
golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=
golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 h1:AzgQNqF+FKwyQ5LbVrVqOcuuFB67N47F9+htZYH0wFM=
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c h1:m5lcgWnL3OElQNVyp3qcncItJ2c0sQlSGjYK2+nJTA4=
Expand Down
2 changes: 2 additions & 0 deletions tun.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ type Options struct {
MTU uint32
AutoRoute bool
StrictRoute bool
Inet4RouteAddress []netip.Prefix
Inet6RouteAddress []netip.Prefix
IncludeUID []ranges.Range[uint32]
ExcludeUID []ranges.Range[uint32]
IncludeAndroidUser []int
Expand Down
45 changes: 30 additions & 15 deletions tun_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,27 +241,42 @@ func configure(tunFd int, ifIndex int, name string, options Options) error {
}
if options.AutoRoute {
if len(options.Inet4Address) > 0 {
for _, subnet := range []netip.Prefix{
netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 0, 0, 0}), 8),
netip.PrefixFrom(netip.AddrFrom4([4]byte{2, 0, 0, 0}), 7),
netip.PrefixFrom(netip.AddrFrom4([4]byte{4, 0, 0, 0}), 6),
netip.PrefixFrom(netip.AddrFrom4([4]byte{8, 0, 0, 0}), 5),
netip.PrefixFrom(netip.AddrFrom4([4]byte{16, 0, 0, 0}), 4),
netip.PrefixFrom(netip.AddrFrom4([4]byte{32, 0, 0, 0}), 3),
netip.PrefixFrom(netip.AddrFrom4([4]byte{64, 0, 0, 0}), 2),
netip.PrefixFrom(netip.AddrFrom4([4]byte{128, 0, 0, 0}), 1),
} {
var routes []netip.Prefix
if len(options.Inet4RouteAddress) > 0 {
routes = append(options.Inet4RouteAddress, netip.PrefixFrom(options.Inet4Address[0].Addr().Next(), 32))
} else {
routes = []netip.Prefix{
netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 0, 0, 0}), 8),
netip.PrefixFrom(netip.AddrFrom4([4]byte{2, 0, 0, 0}), 7),
netip.PrefixFrom(netip.AddrFrom4([4]byte{4, 0, 0, 0}), 6),
netip.PrefixFrom(netip.AddrFrom4([4]byte{8, 0, 0, 0}), 5),
netip.PrefixFrom(netip.AddrFrom4([4]byte{16, 0, 0, 0}), 4),
netip.PrefixFrom(netip.AddrFrom4([4]byte{32, 0, 0, 0}), 3),
netip.PrefixFrom(netip.AddrFrom4([4]byte{64, 0, 0, 0}), 2),
netip.PrefixFrom(netip.AddrFrom4([4]byte{128, 0, 0, 0}), 1),
}
}
for _, subnet := range routes {
err = addRoute(subnet, options.Inet4Address[0].Addr())
if err != nil {
return E.Cause(err, "add ipv4 route "+subnet.String())
return E.Cause(err, "add ipv4 route ", subnet)
}
}
}
if len(options.Inet6Address) > 0 {
subnet := netip.PrefixFrom(netip.AddrFrom16([16]byte{32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}), 3)
err = addRoute(subnet, options.Inet6Address[0].Addr())
if err != nil {
return E.Cause(err, "add ipv6 route "+subnet.String())
var routes []netip.Prefix
if len(options.Inet6RouteAddress) > 0 {
routes = append(options.Inet6RouteAddress, netip.PrefixFrom(options.Inet6Address[0].Addr().Next(), 128))
} else {
routes = []netip.Prefix{
netip.PrefixFrom(netip.AddrFrom16([16]byte{32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}), 3),
}
}
for _, subnet := range routes {
err = addRoute(subnet, options.Inet6Address[0].Addr())
if err != nil {
return E.Cause(err, "add ipv6 route ", subnet)
}
}
}
}
Expand Down
50 changes: 38 additions & 12 deletions tun_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,26 +171,52 @@ func (t *NativeTun) routes(tunLink netlink.Link) []netlink.Route {
var routes []netlink.Route
if len(t.options.Inet4Address) > 0 {
if t.options.AutoRoute {
if len(t.options.Inet4RouteAddress) > 0 {
for _, addr := range t.options.Inet4RouteAddress {
routes = append(routes, netlink.Route{
Dst: &net.IPNet{
IP: addr.Addr().AsSlice(),
Mask: net.CIDRMask(addr.Bits(), 32),
},
LinkIndex: tunLink.Attrs().Index,
Table: t.options.TableIndex,
})
}
} else {
routes = append(routes, netlink.Route{
Dst: &net.IPNet{
IP: net.IPv4zero,
Mask: net.CIDRMask(0, 32),
},
LinkIndex: tunLink.Attrs().Index,
Table: t.options.TableIndex,
})
}
}
}
if len(t.options.Inet6Address) > 0 {
if len(t.options.Inet6RouteAddress) > 0 {
for _, addr := range t.options.Inet6RouteAddress {
routes = append(routes, netlink.Route{
Dst: &net.IPNet{
IP: addr.Addr().AsSlice(),
Mask: net.CIDRMask(addr.Bits(), 128),
},
LinkIndex: tunLink.Attrs().Index,
Table: t.options.TableIndex,
})
}
} else {
routes = append(routes, netlink.Route{
Dst: &net.IPNet{
IP: net.IPv4zero,
Mask: net.CIDRMask(0, 32),
IP: net.IPv6zero,
Mask: net.CIDRMask(0, 128),
},
LinkIndex: tunLink.Attrs().Index,
Table: t.options.TableIndex,
})
}
}
if len(t.options.Inet6Address) > 0 {
routes = append(routes, netlink.Route{
Dst: &net.IPNet{
IP: net.IPv6zero,
Mask: net.CIDRMask(0, 128),
},
LinkIndex: tunLink.Attrs().Index,
Table: t.options.TableIndex,
})
}
return routes
}

Expand Down
30 changes: 24 additions & 6 deletions tun_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,33 @@ func (t *NativeTun) configure() error {
}
} else {
if len(t.options.Inet4Address) > 0 {
err := luid.AddRoute(netip.PrefixFrom(netip.IPv4Unspecified(), 0), netip.IPv4Unspecified(), 0)
if err != nil {
return E.Cause(err, "set ipv4 route")
if len(t.options.Inet4RouteAddress) > 0 {
for _, addr := range t.options.Inet4RouteAddress {
err := luid.AddRoute(addr, netip.IPv4Unspecified(), 0)
if err != nil {
return E.Cause(err, "add ipv4 route: ", addr)
}
}
} else {
err := luid.AddRoute(netip.PrefixFrom(netip.IPv4Unspecified(), 0), netip.IPv4Unspecified(), 0)
if err != nil {
return E.Cause(err, "set ipv4 route")
}
}
}
if len(t.options.Inet6Address) > 0 {
err := luid.AddRoute(netip.PrefixFrom(netip.IPv6Unspecified(), 0), netip.IPv6Unspecified(), 0)
if err != nil {
return E.Cause(err, "set ipv6 route")
if len(t.options.Inet6RouteAddress) > 0 {
for _, addr := range t.options.Inet6RouteAddress {
err := luid.AddRoute(addr, netip.IPv6Unspecified(), 0)
if err != nil {
return E.Cause(err, "add ipv6 route: ", addr)
}
}
} else {
err := luid.AddRoute(netip.PrefixFrom(netip.IPv6Unspecified(), 0), netip.IPv6Unspecified(), 0)
if err != nil {
return E.Cause(err, "set ipv6 route")
}
}
}
}
Expand Down

0 comments on commit 99492e0

Please sign in to comment.