mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2026-04-23 00:07:30 +08:00
109 lines
2.2 KiB
Go
109 lines
2.2 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"
|
|
)
|
|
|
|
const (
|
|
defaultDeviceType = "tun"
|
|
defaultProxyType = "socks5"
|
|
)
|
|
|
|
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", defaultDeviceType, 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 ios
|
|
// https://stackoverflow.com/questions/69260852/ios-network-extension-packet-parsing/69487795#69487795
|
|
if 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", defaultProxyType, s)
|
|
}
|
|
|
|
u, err := url.Parse(s)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return proxy.Parse(u)
|
|
}
|
|
|
|
func parseMulticastGroups(s string) (multicastGroups []netip.Addr, _ error) {
|
|
for _, ip := range strings.Split(s, ",") {
|
|
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)
|
|
}
|
|
multicastGroups = append(multicastGroups, addr)
|
|
}
|
|
return
|
|
}
|