diff --git a/cmd/tun2socks/main_shadowsocks.go b/cmd/tun2socks/main_shadowsocks.go deleted file mode 100644 index 53142de..0000000 --- a/cmd/tun2socks/main_shadowsocks.go +++ /dev/null @@ -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)) - }) -} diff --git a/cmd/tun2socks/main_v2ray.go b/cmd/tun2socks/main_v2ray.go deleted file mode 100644 index 99ff946..0000000 --- a/cmd/tun2socks/main_v2ray.go +++ /dev/null @@ -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)) - }) -} diff --git a/proxy/shadowsocks/tcp.go b/proxy/shadowsocks/tcp.go deleted file mode 100644 index cc3a0bb..0000000 --- a/proxy/shadowsocks/tcp.go +++ /dev/null @@ -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 -} diff --git a/proxy/shadowsocks/udp.go b/proxy/shadowsocks/udp.go deleted file mode 100644 index 9872ea5..0000000 --- a/proxy/shadowsocks/udp.go +++ /dev/null @@ -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) - } -} diff --git a/proxy/v2ray/features.go b/proxy/v2ray/features.go deleted file mode 100644 index d86c35c..0000000 --- a/proxy/v2ray/features.go +++ /dev/null @@ -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" -) diff --git a/proxy/v2ray/features_other.go b/proxy/v2ray/features_other.go deleted file mode 100644 index f92818d..0000000 --- a/proxy/v2ray/features_other.go +++ /dev/null @@ -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" -) diff --git a/proxy/v2ray/tcp.go b/proxy/v2ray/tcp.go deleted file mode 100644 index 2cf7d85..0000000 --- a/proxy/v2ray/tcp.go +++ /dev/null @@ -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 -} diff --git a/proxy/v2ray/udp.go b/proxy/v2ray/udp.go deleted file mode 100644 index 1a46943..0000000 --- a/proxy/v2ray/udp.go +++ /dev/null @@ -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) -}