mirror of
				https://github.com/xjasonlyu/tun2socks.git
				synced 2025-10-31 03:56:30 +08:00 
			
		
		
		
	remove ss & v2ray handler
This commit is contained in:
		| @@ -1,39 +0,0 @@ | |||||||
| // +build shadowsocks |  | ||||||
|  |  | ||||||
| package main |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"flag" |  | ||||||
| 	"net" |  | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	sscore "github.com/shadowsocks/go-shadowsocks2/core" |  | ||||||
|  |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/common/log" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/core" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/proxy/shadowsocks" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func init() { |  | ||||||
| 	args.addFlag(fProxyServer) |  | ||||||
| 	args.addFlag(fUdpTimeout) |  | ||||||
|  |  | ||||||
| 	args.ProxyCipher = flag.String("proxyCipher", "AEAD_CHACHA20_POLY1305", "Cipher used for Shadowsocks proxy, available ciphers: "+strings.Join(sscore.ListCipher(), " ")) |  | ||||||
| 	args.ProxyPassword = flag.String("proxyPassword", "", "Password used for Shadowsocks proxy") |  | ||||||
|  |  | ||||||
| 	registerHandlerCreator("shadowsocks", func() { |  | ||||||
| 		// Verify proxy server address. |  | ||||||
| 		proxyAddr, err := net.ResolveTCPAddr("tcp", *args.ProxyServer) |  | ||||||
| 		if err != nil { |  | ||||||
| 			log.Fatalf("invalid proxy server address: %v", err) |  | ||||||
| 		} |  | ||||||
| 		proxyHost := proxyAddr.IP.String() |  | ||||||
| 		proxyPort := uint16(proxyAddr.Port) |  | ||||||
|  |  | ||||||
| 		if *args.ProxyCipher == "" || *args.ProxyPassword == "" { |  | ||||||
| 			log.Fatalf("invalid cipher or password") |  | ||||||
| 		} |  | ||||||
| 		core.RegisterTCPConnHandler(shadowsocks.NewTCPHandler(core.ParseTCPAddr(proxyHost, proxyPort).String(), *args.ProxyCipher, *args.ProxyPassword, fakeDns)) |  | ||||||
| 		core.RegisterUDPConnHandler(shadowsocks.NewUDPHandler(core.ParseUDPAddr(proxyHost, proxyPort).String(), *args.ProxyCipher, *args.ProxyPassword, *args.UdpTimeout, dnsCache, fakeDns)) |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| @@ -1,59 +0,0 @@ | |||||||
| // +build v2ray |  | ||||||
|  |  | ||||||
| package main |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"flag" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	vcore "v2ray.com/core" |  | ||||||
| 	vproxyman "v2ray.com/core/app/proxyman" |  | ||||||
| 	vbytespool "v2ray.com/core/common/bytespool" |  | ||||||
|  |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/common/log" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/core" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/proxy/v2ray" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func init() { |  | ||||||
| 	args.addFlag(fUdpTimeout) |  | ||||||
|  |  | ||||||
| 	args.VConfig = flag.String("vconfig", "config.json", "Config file for v2ray, in JSON format, and note that routing in v2ray could not violate routes in the routing table") |  | ||||||
| 	args.SniffingType = flag.String("sniffingType", "http,tls", "Enable domain sniffing for specific kind of traffic in v2ray") |  | ||||||
|  |  | ||||||
| 	registerHandlerCreator("v2ray", func() { |  | ||||||
| 		core.SetBufferPool(vbytespool.GetPool(core.BufSize)) |  | ||||||
|  |  | ||||||
| 		configBytes, err := ioutil.ReadFile(*args.VConfig) |  | ||||||
| 		if err != nil { |  | ||||||
| 			log.Fatalf("invalid vconfig file") |  | ||||||
| 		} |  | ||||||
| 		var validSniffings []string |  | ||||||
| 		sniffings := strings.Split(*args.SniffingType, ",") |  | ||||||
| 		for _, s := range sniffings { |  | ||||||
| 			if s == "http" || s == "tls" { |  | ||||||
| 				validSniffings = append(validSniffings, s) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		v, err := vcore.StartInstance("json", configBytes) |  | ||||||
| 		if err != nil { |  | ||||||
| 			log.Fatalf("start V instance failed: %v", err) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		sniffingConfig := &vproxyman.SniffingConfig{ |  | ||||||
| 			Enabled:             true, |  | ||||||
| 			DestinationOverride: validSniffings, |  | ||||||
| 		} |  | ||||||
| 		if len(validSniffings) == 0 { |  | ||||||
| 			sniffingConfig.Enabled = false |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		ctx := vproxyman.ContextWithSniffingConfig(context.Background(), sniffingConfig) |  | ||||||
|  |  | ||||||
| 		core.RegisterTCPConnHandler(v2ray.NewTCPHandler(ctx, v)) |  | ||||||
| 		core.RegisterUDPConnHandler(v2ray.NewUDPHandler(ctx, v, *args.UdpTimeout)) |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| @@ -1,85 +0,0 @@ | |||||||
| package shadowsocks |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"net" |  | ||||||
| 	"strconv" |  | ||||||
|  |  | ||||||
| 	sscore "github.com/shadowsocks/go-shadowsocks2/core" |  | ||||||
| 	sssocks "github.com/shadowsocks/go-shadowsocks2/socks" |  | ||||||
|  |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/common/dns" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/common/log" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/core" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type tcpHandler struct { |  | ||||||
| 	cipher  sscore.Cipher |  | ||||||
| 	server  string |  | ||||||
| 	fakeDns dns.FakeDns |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *tcpHandler) handleInput(conn net.Conn, input io.ReadCloser) { |  | ||||||
| 	defer func() { |  | ||||||
| 		conn.Close() |  | ||||||
| 		input.Close() |  | ||||||
| 	}() |  | ||||||
| 	io.Copy(conn, input) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *tcpHandler) handleOutput(conn net.Conn, output io.WriteCloser) { |  | ||||||
| 	defer func() { |  | ||||||
| 		conn.Close() |  | ||||||
| 		output.Close() |  | ||||||
| 	}() |  | ||||||
| 	io.Copy(output, conn) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewTCPHandler(server, cipher, password string, fakeDns dns.FakeDns) core.TCPConnHandler { |  | ||||||
| 	ciph, err := sscore.PickCipher(cipher, []byte{}, password) |  | ||||||
| 	if err != nil { |  | ||||||
| 		log.Errorf("failed to pick a cipher: %v", err) |  | ||||||
| 	} |  | ||||||
| 	return &tcpHandler{ |  | ||||||
| 		cipher:  ciph, |  | ||||||
| 		server:  server, |  | ||||||
| 		fakeDns: fakeDns, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *tcpHandler) Handle(conn net.Conn, target *net.TCPAddr) error { |  | ||||||
| 	if target == nil { |  | ||||||
| 		log.Fatalf("unexpected nil target") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Connect the relay server. |  | ||||||
| 	rc, err := net.Dial("tcp", h.server) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return errors.New(fmt.Sprintf("dial remote server failed: %v", err)) |  | ||||||
| 	} |  | ||||||
| 	rc = h.cipher.StreamConn(rc) |  | ||||||
|  |  | ||||||
| 	// Replace with a domain name if target address IP is a fake IP. |  | ||||||
| 	var targetHost string |  | ||||||
| 	if h.fakeDns != nil && h.fakeDns.IsFakeIP(target.IP) { |  | ||||||
| 		targetHost = h.fakeDns.QueryDomain(target.IP) |  | ||||||
| 	} else { |  | ||||||
| 		targetHost = target.IP.String() |  | ||||||
| 	} |  | ||||||
| 	dest := net.JoinHostPort(targetHost, strconv.Itoa(target.Port)) |  | ||||||
|  |  | ||||||
| 	// Write target address. |  | ||||||
| 	tgt := sssocks.ParseAddr(dest) |  | ||||||
| 	_, err = rc.Write(tgt) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("send target address failed: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	go h.handleInput(conn, rc) |  | ||||||
| 	go h.handleOutput(conn, rc) |  | ||||||
|  |  | ||||||
| 	log.Infof("new proxy connection for target: %s:%s", target.Network(), dest) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| @@ -1,172 +0,0 @@ | |||||||
| package shadowsocks |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"net" |  | ||||||
| 	"strconv" |  | ||||||
| 	"sync" |  | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	sscore "github.com/shadowsocks/go-shadowsocks2/core" |  | ||||||
| 	sssocks "github.com/shadowsocks/go-shadowsocks2/socks" |  | ||||||
|  |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/common/dns" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/common/log" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/core" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type udpHandler struct { |  | ||||||
| 	sync.Mutex |  | ||||||
|  |  | ||||||
| 	cipher     sscore.Cipher |  | ||||||
| 	remoteAddr net.Addr |  | ||||||
| 	conns      map[core.UDPConn]net.PacketConn |  | ||||||
| 	dnsCache   dns.DnsCache |  | ||||||
| 	fakeDns    dns.FakeDns |  | ||||||
| 	timeout    time.Duration |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewUDPHandler(server, cipher, password string, timeout time.Duration, dnsCache dns.DnsCache, fakeDns dns.FakeDns) core.UDPConnHandler { |  | ||||||
| 	ciph, err := sscore.PickCipher(cipher, []byte{}, password) |  | ||||||
| 	if err != nil { |  | ||||||
| 		log.Errorf("failed to pick a cipher: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	remoteAddr, err := net.ResolveUDPAddr("udp", server) |  | ||||||
| 	if err != nil { |  | ||||||
| 		log.Errorf("failed to resolve udp address: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return &udpHandler{ |  | ||||||
| 		cipher:     ciph, |  | ||||||
| 		remoteAddr: remoteAddr, |  | ||||||
| 		conns:      make(map[core.UDPConn]net.PacketConn, 16), |  | ||||||
| 		dnsCache:   dnsCache, |  | ||||||
| 		fakeDns:    fakeDns, |  | ||||||
| 		timeout:    timeout, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *udpHandler) fetchUDPInput(conn core.UDPConn, input net.PacketConn) { |  | ||||||
| 	buf := core.NewBytes(core.BufSize) |  | ||||||
|  |  | ||||||
| 	defer func() { |  | ||||||
| 		h.Close(conn) |  | ||||||
| 		core.FreeBytes(buf) |  | ||||||
| 	}() |  | ||||||
|  |  | ||||||
| 	for { |  | ||||||
| 		input.SetDeadline(time.Now().Add(h.timeout)) |  | ||||||
| 		n, _, err := input.ReadFrom(buf) |  | ||||||
| 		if err != nil { |  | ||||||
| 			// log.Printf("read remote failed: %v", err) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		addr := sssocks.SplitAddr(buf[:]) |  | ||||||
| 		resolvedAddr, err := net.ResolveUDPAddr("udp", addr.String()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		_, err = conn.WriteFrom(buf[int(len(addr)):n], resolvedAddr) |  | ||||||
| 		if err != nil { |  | ||||||
| 			log.Warnf("write local failed: %v", err) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if h.dnsCache != nil { |  | ||||||
| 			_, port, err := net.SplitHostPort(addr.String()) |  | ||||||
| 			if err != nil { |  | ||||||
| 				panic("impossible error") |  | ||||||
| 			} |  | ||||||
| 			if port == strconv.Itoa(dns.CommonDnsPort) { |  | ||||||
| 				h.dnsCache.Store(buf[int(len(addr)):n]) |  | ||||||
| 				return // DNS response |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *udpHandler) Connect(conn core.UDPConn, target *net.UDPAddr) error { |  | ||||||
| 	pc, err := net.ListenPacket("udp", "") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	pc = h.cipher.PacketConn(pc) |  | ||||||
|  |  | ||||||
| 	h.Lock() |  | ||||||
| 	h.conns[conn] = pc |  | ||||||
| 	h.Unlock() |  | ||||||
| 	go h.fetchUDPInput(conn, pc) |  | ||||||
| 	if target != nil { |  | ||||||
| 		log.Infof("new proxy connection for target: %s:%s", target.Network(), target.String()) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *udpHandler) ReceiveTo(conn core.UDPConn, data []byte, addr *net.UDPAddr) error { |  | ||||||
| 	h.Lock() |  | ||||||
| 	pc, ok1 := h.conns[conn] |  | ||||||
| 	h.Unlock() |  | ||||||
|  |  | ||||||
| 	if addr.Port == dns.CommonDnsPort { |  | ||||||
| 		if h.fakeDns != nil { |  | ||||||
| 			resp, err := h.fakeDns.GenerateFakeResponse(data) |  | ||||||
| 			if err == nil { |  | ||||||
| 				_, err = conn.WriteFrom(resp, addr) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return errors.New(fmt.Sprintf("write dns answer failed: %v", err)) |  | ||||||
| 				} |  | ||||||
| 				h.Close(conn) |  | ||||||
| 				return nil |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if h.dnsCache != nil { |  | ||||||
| 			if answer := h.dnsCache.Query(data); answer != nil { |  | ||||||
| 				_, err := conn.WriteFrom(answer, addr) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return errors.New(fmt.Sprintf("cache dns answer failed: %v", err)) |  | ||||||
| 				} |  | ||||||
| 				h.Close(conn) |  | ||||||
| 				return nil |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if ok1 { |  | ||||||
| 		// Replace with a domain name if target address IP is a fake IP. |  | ||||||
| 		var targetHost string |  | ||||||
| 		if h.fakeDns != nil && h.fakeDns.IsFakeIP(addr.IP) { |  | ||||||
| 			targetHost = h.fakeDns.QueryDomain(addr.IP) |  | ||||||
| 		} else { |  | ||||||
| 			targetHost = addr.IP.String() |  | ||||||
| 		} |  | ||||||
| 		dest := net.JoinHostPort(targetHost, strconv.Itoa(addr.Port)) |  | ||||||
|  |  | ||||||
| 		buf := append([]byte{0, 0, 0}, sssocks.ParseAddr(dest)...) |  | ||||||
| 		buf = append(buf, data[:]...) |  | ||||||
| 		_, err := pc.WriteTo(buf[3:], h.remoteAddr) |  | ||||||
| 		if err != nil { |  | ||||||
| 			h.Close(conn) |  | ||||||
| 			return errors.New(fmt.Sprintf("write remote failed: %v", err)) |  | ||||||
| 		} |  | ||||||
| 		return nil |  | ||||||
| 	} else { |  | ||||||
| 		h.Close(conn) |  | ||||||
| 		return errors.New(fmt.Sprintf("proxy connection %v->%v does not exists", conn.LocalAddr(), addr)) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *udpHandler) Close(conn core.UDPConn) { |  | ||||||
| 	conn.Close() |  | ||||||
|  |  | ||||||
| 	h.Lock() |  | ||||||
| 	defer h.Unlock() |  | ||||||
|  |  | ||||||
| 	if pc, ok := h.conns[conn]; ok { |  | ||||||
| 		pc.Close() |  | ||||||
| 		delete(h.conns, conn) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -1,61 +0,0 @@ | |||||||
| package v2ray |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	// The following are necessary as they register handlers in their init functions. |  | ||||||
|  |  | ||||||
| 	// Required features. Can't remove unless there is replacements. |  | ||||||
| 	_ "v2ray.com/core/app/dispatcher" |  | ||||||
| 	_ "v2ray.com/core/app/proxyman/inbound" |  | ||||||
| 	_ "v2ray.com/core/app/proxyman/outbound" |  | ||||||
|  |  | ||||||
| 	// Default commander and all its services. This is an optional feature. |  | ||||||
| 	// _ "v2ray.com/core/app/commander" |  | ||||||
| 	// _ "v2ray.com/core/app/log/command" |  | ||||||
| 	// _ "v2ray.com/core/app/proxyman/command" |  | ||||||
| 	// _ "v2ray.com/core/app/stats/command" |  | ||||||
|  |  | ||||||
| 	// Other optional features. |  | ||||||
| 	_ "v2ray.com/core/app/dns" |  | ||||||
| 	_ "v2ray.com/core/app/log" |  | ||||||
| 	_ "v2ray.com/core/app/policy" |  | ||||||
| 	_ "v2ray.com/core/app/router" |  | ||||||
| 	_ "v2ray.com/core/app/stats" |  | ||||||
|  |  | ||||||
| 	// Inbound and outbound proxies. |  | ||||||
| 	_ "v2ray.com/core/proxy/blackhole" |  | ||||||
| 	_ "v2ray.com/core/proxy/dokodemo" |  | ||||||
| 	_ "v2ray.com/core/proxy/freedom" |  | ||||||
| 	_ "v2ray.com/core/proxy/http" |  | ||||||
| 	_ "v2ray.com/core/proxy/mtproto" |  | ||||||
| 	_ "v2ray.com/core/proxy/shadowsocks" |  | ||||||
| 	_ "v2ray.com/core/proxy/socks" |  | ||||||
| 	_ "v2ray.com/core/proxy/vmess/inbound" |  | ||||||
| 	_ "v2ray.com/core/proxy/vmess/outbound" |  | ||||||
|  |  | ||||||
| 	// Transports |  | ||||||
| 	_ "v2ray.com/core/transport/internet/domainsocket" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/http" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/kcp" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/quic" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/tcp" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/tls" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/udp" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/websocket" |  | ||||||
|  |  | ||||||
| 	// Transport headers |  | ||||||
| 	_ "v2ray.com/core/transport/internet/headers/http" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/headers/noop" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/headers/srtp" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/headers/tls" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/headers/utp" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/headers/wechat" |  | ||||||
| 	_ "v2ray.com/core/transport/internet/headers/wireguard" |  | ||||||
|  |  | ||||||
| 	// JSON config support. Choose only one from the two below. |  | ||||||
| 	// The following line loads JSON from v2ctl |  | ||||||
| 	// _ "v2ray.com/core/main/json" |  | ||||||
| 	// The following line loads JSON internally |  | ||||||
| 	_ "v2ray.com/core/main/jsonem" |  | ||||||
| 	// Load config from file or http(s) |  | ||||||
| 	// _ "v2ray.com/core/main/confloader/external" |  | ||||||
| ) |  | ||||||
| @@ -1,14 +0,0 @@ | |||||||
| // +build !ios,!android |  | ||||||
|  |  | ||||||
| package v2ray |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	_ "v2ray.com/core/app/commander" |  | ||||||
| 	_ "v2ray.com/core/app/log/command" |  | ||||||
| 	_ "v2ray.com/core/app/proxyman/command" |  | ||||||
| 	_ "v2ray.com/core/app/stats/command" |  | ||||||
|  |  | ||||||
| 	_ "v2ray.com/core/app/reverse" |  | ||||||
|  |  | ||||||
| 	_ "v2ray.com/core/transport/internet/domainsocket" |  | ||||||
| ) |  | ||||||
| @@ -1,58 +0,0 @@ | |||||||
| package v2ray |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"net" |  | ||||||
|  |  | ||||||
| 	vcore "v2ray.com/core" |  | ||||||
| 	vnet "v2ray.com/core/common/net" |  | ||||||
| 	vsession "v2ray.com/core/common/session" |  | ||||||
|  |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/common/log" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/core" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type tcpHandler struct { |  | ||||||
| 	ctx context.Context |  | ||||||
| 	v   *vcore.Instance |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *tcpHandler) handleInput(conn net.Conn, input io.ReadCloser) { |  | ||||||
| 	defer func() { |  | ||||||
| 		conn.Close() |  | ||||||
| 		input.Close() |  | ||||||
| 	}() |  | ||||||
| 	io.Copy(conn, input) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *tcpHandler) handleOutput(conn net.Conn, output io.WriteCloser) { |  | ||||||
| 	defer func() { |  | ||||||
| 		conn.Close() |  | ||||||
| 		output.Close() |  | ||||||
| 	}() |  | ||||||
| 	io.Copy(output, conn) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewTCPHandler(ctx context.Context, instance *vcore.Instance) core.TCPConnHandler { |  | ||||||
| 	return &tcpHandler{ |  | ||||||
| 		ctx: ctx, |  | ||||||
| 		v:   instance, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *tcpHandler) Handle(conn net.Conn, target *net.TCPAddr) error { |  | ||||||
| 	dest := vnet.DestinationFromAddr(target) |  | ||||||
| 	sid := vsession.NewID() |  | ||||||
| 	ctx := vsession.ContextWithID(h.ctx, sid) |  | ||||||
| 	c, err := vcore.Dial(ctx, h.v, dest) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return errors.New(fmt.Sprintf("dial V proxy connection failed: %v", err)) |  | ||||||
| 	} |  | ||||||
| 	go h.handleInput(conn, c) |  | ||||||
| 	go h.handleOutput(conn, c) |  | ||||||
| 	log.Infof("new proxy connection for target: %s:%s", target.Network(), target.String()) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| @@ -1,138 +0,0 @@ | |||||||
| package v2ray |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"context" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"net" |  | ||||||
| 	"sync" |  | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	vcore "v2ray.com/core" |  | ||||||
| 	vsession "v2ray.com/core/common/session" |  | ||||||
| 	vsignal "v2ray.com/core/common/signal" |  | ||||||
| 	vtask "v2ray.com/core/common/task" |  | ||||||
|  |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/common/log" |  | ||||||
| 	"github.com/xjasonlyu/tun2socks/core" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type udpConnEntry struct { |  | ||||||
| 	conn net.PacketConn |  | ||||||
|  |  | ||||||
| 	// `ReadFrom` method of PacketConn given by V2Ray |  | ||||||
| 	// won't return the correct remote address, we treat |  | ||||||
| 	// all data receive from V2Ray are coming from the |  | ||||||
| 	// same remote host, i.e. the `target` that passed |  | ||||||
| 	// to `Connect`. |  | ||||||
| 	target *net.UDPAddr |  | ||||||
|  |  | ||||||
| 	updater vsignal.ActivityUpdater |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type udpHandler struct { |  | ||||||
| 	sync.Mutex |  | ||||||
|  |  | ||||||
| 	ctx     context.Context |  | ||||||
| 	v       *vcore.Instance |  | ||||||
| 	conns   map[core.UDPConn]*udpConnEntry |  | ||||||
| 	timeout time.Duration // Maybe override by V2Ray local policies for some conns. |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *udpHandler) fetchInput(conn core.UDPConn) { |  | ||||||
| 	h.Lock() |  | ||||||
| 	c, ok := h.conns[conn] |  | ||||||
| 	h.Unlock() |  | ||||||
| 	if !ok { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	buf := core.NewBytes(core.BufSize) |  | ||||||
| 	defer core.FreeBytes(buf) |  | ||||||
|  |  | ||||||
| 	for { |  | ||||||
| 		n, _, err := c.conn.ReadFrom(buf) |  | ||||||
| 		if err != nil && n <= 0 { |  | ||||||
| 			h.Close(conn) |  | ||||||
| 			conn.Close() |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		c.updater.Update() |  | ||||||
| 		_, err = conn.WriteFrom(buf[:n], c.target) |  | ||||||
| 		if err != nil { |  | ||||||
| 			h.Close(conn) |  | ||||||
| 			conn.Close() |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewUDPHandler(ctx context.Context, instance *vcore.Instance, timeout time.Duration) core.UDPConnHandler { |  | ||||||
| 	return &udpHandler{ |  | ||||||
| 		ctx:     ctx, |  | ||||||
| 		v:       instance, |  | ||||||
| 		conns:   make(map[core.UDPConn]*udpConnEntry, 16), |  | ||||||
| 		timeout: timeout, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *udpHandler) Connect(conn core.UDPConn, target *net.UDPAddr) error { |  | ||||||
| 	if target == nil { |  | ||||||
| 		return errors.New("nil target is not allowed") |  | ||||||
| 	} |  | ||||||
| 	sid := vsession.NewID() |  | ||||||
| 	ctx := vsession.ContextWithID(h.ctx, sid) |  | ||||||
| 	ctx, cancel := context.WithCancel(ctx) |  | ||||||
| 	pc, err := vcore.DialUDP(ctx, h.v) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return errors.New(fmt.Sprintf("dial V proxy connection failed: %v", err)) |  | ||||||
| 	} |  | ||||||
| 	timer := vsignal.CancelAfterInactivity(ctx, cancel, h.timeout) |  | ||||||
| 	h.Lock() |  | ||||||
| 	h.conns[conn] = &udpConnEntry{ |  | ||||||
| 		conn:    pc, |  | ||||||
| 		target:  target, |  | ||||||
| 		updater: timer, |  | ||||||
| 	} |  | ||||||
| 	h.Unlock() |  | ||||||
| 	fetchTask := func() error { |  | ||||||
| 		h.fetchInput(conn) |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	go func() { |  | ||||||
| 		if err := vtask.Run(ctx, fetchTask); err != nil { |  | ||||||
| 			pc.Close() |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
| 	log.Infof("new proxy connection for target: %s:%s", target.Network(), target.String()) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *udpHandler) ReceiveTo(conn core.UDPConn, data []byte, addr *net.UDPAddr) error { |  | ||||||
| 	h.Lock() |  | ||||||
| 	c, ok := h.conns[conn] |  | ||||||
| 	h.Unlock() |  | ||||||
|  |  | ||||||
| 	if ok { |  | ||||||
| 		_, err := c.conn.WriteTo(data, addr) |  | ||||||
| 		c.updater.Update() |  | ||||||
| 		if err != nil { |  | ||||||
| 			h.Close(conn) |  | ||||||
| 			return errors.New(fmt.Sprintf("write remote failed: %v", err)) |  | ||||||
| 		} |  | ||||||
| 		return nil |  | ||||||
| 	} else { |  | ||||||
| 		h.Close(conn) |  | ||||||
| 		return errors.New(fmt.Sprintf("proxy connection %v->%v does not exists", conn.LocalAddr(), c.target)) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *udpHandler) Close(conn core.UDPConn) { |  | ||||||
| 	h.Lock() |  | ||||||
| 	defer h.Unlock() |  | ||||||
|  |  | ||||||
| 	if c, found := h.conns[conn]; found { |  | ||||||
| 		c.conn.Close() |  | ||||||
| 	} |  | ||||||
| 	delete(h.conns, conn) |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user
	 Jason
					Jason