/
tcp.go
78 lines (66 loc) · 1.67 KB
/
tcp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package socks
import (
"fmt"
"io"
"net"
"sync"
"golang.org/x/net/proxy"
"github.com/tahirmahm123/go-tun2socks/common/dns"
"github.com/tahirmahm123/go-tun2socks/common/log"
"github.com/tahirmahm123/go-tun2socks/core"
)
type tcpHandler struct {
sync.Mutex
proxyHost string
proxyPort uint16
fakeDns dns.FakeDns
}
func NewTCPHandler(proxyHost string, proxyPort uint16, fakeDns dns.FakeDns) core.TCPConnHandler {
return &tcpHandler{
proxyHost: proxyHost,
proxyPort: proxyPort,
fakeDns: 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 (h *tcpHandler) Handle(conn net.Conn, target net.Addr) error {
dialer, err := proxy.SOCKS5("tcp", core.ParseTCPAddr(h.proxyHost, h.proxyPort).String(), nil, nil)
if err != nil {
return err
}
// Replace with a domain name if target address IP is a fake IP.
host, port, err := net.SplitHostPort(target.String())
if err != nil {
log.Errorf("error when split host port %v", err)
}
var targetHost string = host
if h.fakeDns != nil {
if ip := net.ParseIP(host); ip != nil {
if h.fakeDns.IsFakeIP(ip) {
targetHost = h.fakeDns.QueryDomain(ip)
}
}
}
dest := fmt.Sprintf("%s:%s", targetHost, port)
c, err := dialer.Dial(target.Network(), dest)
if err != nil {
return err
}
go h.handleInput(conn, c)
go h.handleOutput(conn, c)
log.Infof("new proxy connection for target: %s:%s", target.Network(), fmt.Sprintf("%s:%s", targetHost, port))
return nil
}