package engine import ( "fmt" "net" "net/netip" "net/url" "runtime" "strings" "github.com/xjasonlyu/tun2socks/v2/core/device" "github.com/xjasonlyu/tun2socks/v2/core/device/fdbased" "github.com/xjasonlyu/tun2socks/v2/core/device/tun" "github.com/xjasonlyu/tun2socks/v2/proxy" ) func parseRestAPI(s string) (*url.URL, error) { if !strings.Contains(s, "://") { s = fmt.Sprintf("%s://%s", "http", s) } u, err := url.Parse(s) if err != nil { return nil, err } addr, err := net.ResolveTCPAddr("tcp", u.Host) if err != nil { return nil, err } if addr.IP == nil { addr.IP = net.IPv4zero /* default: 0.0.0.0 */ } u.Host = addr.String() switch u.Scheme { case "http": return u, nil default: return nil, fmt.Errorf("unsupported scheme: %s", u.Scheme) } } func parseDevice(s string, mtu uint32) (device.Device, error) { if !strings.Contains(s, "://") { s = fmt.Sprintf("%s://%s", tun.Driver, s) } u, err := url.Parse(s) if err != nil { return nil, err } driver := strings.ToLower(u.Scheme) switch driver { case fdbased.Driver: return parseFD(u, mtu) case tun.Driver: return parseTUN(u, mtu) default: return nil, fmt.Errorf("unsupported driver: %s", driver) } } func parseFD(u *url.URL, mtu uint32) (device.Device, error) { offset := 0 // fd offset in darwin and ios // https://stackoverflow.com/questions/69260852/ios-network-extension-packet-parsing/69487795#69487795 if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { offset = 4 } return fdbased.Open(u.Host, mtu, offset) } func parseProxy(s string) (proxy.Proxy, error) { if !strings.Contains(s, "://") { s = fmt.Sprintf("%s://%s", "socks5" /* default */, s) } u, err := url.Parse(s) if err != nil { return nil, err } return proxy.Parse(u) } func parseMulticastGroups(v []string) ([]netip.Addr, error) { groups := make([]netip.Addr, 0, len(v)) for _, ip := range v { if ip = strings.TrimSpace(ip); ip == "" { continue } addr, err := netip.ParseAddr(ip) if err != nil { return nil, err } if !addr.IsMulticast() { return nil, fmt.Errorf("invalid multicast IP: %s", addr) } groups = append(groups, addr) } return groups, nil }