mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2025-10-30 11:36:22 +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