-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.go
126 lines (102 loc) · 3.17 KB
/
main.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package main
import (
"flag"
"github.com/esrrhs/gohome/common"
"github.com/esrrhs/gohome/loggo"
"github.com/esrrhs/gohome/network"
"io"
"net"
)
func main() {
defer common.CrashLog()
listen := flag.String("l", "", "listen addr")
nolog := flag.Int("nolog", 0, "write log file")
noprint := flag.Int("noprint", 0, "print stdout")
loglevel := flag.String("loglevel", "info", "log level")
user := flag.String("u", "", "username")
password := flag.String("p", "", "password")
flag.Parse()
if *listen == "" {
flag.Usage()
return
}
level := loggo.LEVEL_INFO
if loggo.NameToLevel(*loglevel) >= 0 {
level = loggo.NameToLevel(*loglevel)
}
loggo.Ini(loggo.Config{
Level: level,
Prefix: "socksserver",
MaxDay: 3,
NoLogFile: *nolog > 0,
NoPrint: *noprint > 0,
})
loggo.Info("start...")
tcpaddr, err := net.ResolveTCPAddr("tcp", *listen)
if err != nil {
loggo.Error("listen fail %s", err)
return
}
tcplistenConn, err := net.ListenTCP("tcp", tcpaddr)
if err != nil {
loggo.Error("Error listening for tcp packets: %s", err)
return
}
loggo.Info("listen ok %s", tcpaddr.String())
for {
conn, err := tcplistenConn.AcceptTCP()
if err != nil {
loggo.Info("Error accept tcp %s", err)
continue
}
go process(conn, *user, *password)
}
}
func process(conn *net.TCPConn, user string, password string) {
defer common.CrashLog()
var err error = nil
if err = network.Sock5HandshakeBy(conn, user, password); err != nil {
loggo.Error("socks handshake: %s", err)
conn.Close()
return
}
_, targetAddr, err := network.Sock5GetRequest(conn)
if err != nil {
loggo.Error("error getting request: %s", err)
conn.Close()
return
}
// Sending connection established message immediately to client.
// This some round trip time for creating socks connection with the client.
// But if connection failed, the client will get connection reset error.
_, err = conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x43})
if err != nil {
loggo.Error("send connection confirmation: %s", err)
conn.Close()
return
}
loggo.Info("accept new sock5 conn: %s", targetAddr)
tcpsrcaddr := conn.RemoteAddr().(*net.TCPAddr)
loggo.Info("client accept new direct local tcp %s %s", tcpsrcaddr.String(), targetAddr)
tcpaddrTarget, err := net.ResolveTCPAddr("tcp", targetAddr)
if err != nil {
loggo.Info("direct local tcp ResolveTCPAddr fail: %s %s", targetAddr, err.Error())
return
}
targetconn, err := net.DialTCP("tcp", nil, tcpaddrTarget)
if err != nil {
loggo.Info("direct local tcp DialTCP fail: %s %s", targetAddr, err.Error())
return
}
go transfer(conn, targetconn, conn.RemoteAddr().String(), targetconn.RemoteAddr().String())
go transfer(targetconn, conn, targetconn.RemoteAddr().String(), conn.RemoteAddr().String())
loggo.Info("client accept new direct local tcp ok %s %s", tcpsrcaddr.String(), targetAddr)
}
func transfer(destination io.WriteCloser, source io.ReadCloser, dst string, src string) {
defer common.CrashLog()
defer destination.Close()
defer source.Close()
loggo.Info("client begin transfer from %s -> %s", src, dst)
io.Copy(destination, source)
loggo.Info("client end transfer from %s -> %s", src, dst)
}