Compare commits

...

3 Commits

Author SHA1 Message Date
世界
8cc5351bb3 auto-redirect: Move initialize to start 2025-02-06 08:44:55 +08:00
世界
d093b82064 auto-redirect: Fetch interfaces 2025-01-07 19:01:54 +08:00
世界
aa9d9c6296 Improve add windows route 2024-12-29 21:19:14 +08:00
3 changed files with 49 additions and 28 deletions

View File

@@ -44,7 +44,7 @@ type autoRedirect struct {
}
func NewAutoRedirect(options AutoRedirectOptions) (AutoRedirect, error) {
r := &autoRedirect{
return &autoRedirect{
tunOptions: options.TunOptions,
ctx: options.Context,
handler: options.Handler,
@@ -56,7 +56,10 @@ func NewAutoRedirect(options AutoRedirectOptions) (AutoRedirect, error) {
customRedirectPortFunc: options.CustomRedirectPort,
routeAddressSet: options.RouteAddressSet,
routeExcludeAddressSet: options.RouteExcludeAddressSet,
}
}, nil
}
func (r *autoRedirect) Start() error {
var err error
if runtime.GOOS == "android" {
r.enableIPv4 = true
@@ -74,7 +77,7 @@ func NewAutoRedirect(options AutoRedirectOptions) (AutoRedirect, error) {
}
}
if err != nil {
return nil, E.Extend(E.Cause(err, "root permission is required for auto redirect"), os.Getenv("PATH"))
return E.Extend(E.Cause(err, "root permission is required for auto redirect"), os.Getenv("PATH"))
}
}
} else {
@@ -90,7 +93,7 @@ func NewAutoRedirect(options AutoRedirectOptions) (AutoRedirect, error) {
if !r.useNFTables {
r.iptablesPath, err = exec.LookPath("iptables")
if err != nil {
return nil, E.Cause(err, "iptables is required")
return E.Cause(err, "iptables is required")
}
}
}
@@ -100,7 +103,7 @@ func NewAutoRedirect(options AutoRedirectOptions) (AutoRedirect, error) {
r.ip6tablesPath, err = exec.LookPath("ip6tables")
if err != nil {
if !r.enableIPv4 {
return nil, E.Cause(err, "ip6tables is required")
return E.Cause(err, "ip6tables is required")
} else {
r.enableIPv6 = false
r.logger.Error("device has no ip6tables nat support: ", err)
@@ -109,10 +112,6 @@ func NewAutoRedirect(options AutoRedirectOptions) (AutoRedirect, error) {
}
}
}
return r, nil
}
func (r *autoRedirect) Start() error {
if r.customRedirectPortFunc != nil {
r.customRedirectPort = r.customRedirectPortFunc()
}
@@ -132,7 +131,6 @@ func (r *autoRedirect) Start() error {
}
r.redirectServer = server
}
var err error
if r.useNFTables {
r.cleanupNFTables()
err = r.setupNFTables()

View File

@@ -32,6 +32,10 @@ func (r *autoRedirect) setupNFTables() error {
return err
}
err = r.interfaceFinder.Update()
if err != nil {
return err
}
r.localAddresses = common.FlatMap(r.interfaceFinder.Interfaces(), func(it control.Interface) []netip.Prefix {
return common.Filter(it.Addresses, func(prefix netip.Prefix) bool {
return it.Name == "lo" || prefix.Addr().IsGlobalUnicast()

View File

@@ -172,15 +172,9 @@ func (t *NativeTun) Start() error {
if err != nil {
return err
}
for _, routeRange := range routeRanges {
if routeRange.Addr().Is4() {
err = luid.AddRoute(routeRange, gateway4, 0)
} else {
err = luid.AddRoute(routeRange, gateway6, 0)
}
if err != nil {
return err
}
err = addRouteList(luid, routeRanges, gateway4, gateway6, 0)
if err != nil {
return err
}
err = windnsapi.FlushResolverCache()
if err != nil {
@@ -560,15 +554,9 @@ func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error {
if err != nil {
return err
}
for _, routeRange := range routeRanges {
if routeRange.Addr().Is4() {
err = luid.AddRoute(routeRange, gateway4, 0)
} else {
err = luid.AddRoute(routeRange, gateway6, 0)
}
if err != nil {
return err
}
err = addRouteList(luid, routeRanges, gateway4, gateway6, 0)
if err != nil {
return err
}
err = windnsapi.FlushResolverCache()
if err != nil {
@@ -577,6 +565,37 @@ func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error {
return nil
}
func addRouteList(luid winipcfg.LUID, destinations []netip.Prefix, gateway4 netip.Addr, gateway6 netip.Addr, metric uint32) error {
row := winipcfg.MibIPforwardRow2{}
row.Init()
row.InterfaceLUID = luid
row.Metric = metric
nextHop4 := row.NextHop
nextHop6 := row.NextHop
if gateway4.IsValid() {
nextHop4.SetAddr(gateway4)
}
if gateway6.IsValid() {
nextHop6.SetAddr(gateway6)
}
for _, destination := range destinations {
err := row.DestinationPrefix.SetPrefix(destination)
if err != nil {
return err
}
if destination.Addr().Is4() {
row.NextHop = nextHop4
} else {
row.NextHop = nextHop6
}
err = row.Create()
if err != nil {
return err
}
}
return nil
}
func generateGUIDByDeviceName(name string) *windows.GUID {
hash := md5.New()
hash.Write([]byte("wintun"))