mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2026-10-20 00:17:34 +00:00
105 lines
2.1 KiB
Go
105 lines
2.1 KiB
Go
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
|
|
}
|