forked from 3gstudent/Homework-of-Go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
frsocks.go
169 lines (156 loc) · 4.05 KB
/
frsocks.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package main
import (
"flag"
"fmt"
"log"
"os"
"net"
"io"
socks5 "go-socks5"
"yamux"
)
var session *yamux.Session
func createForwardSocks(address string) error {
server, err := socks5.New(&socks5.Config{})
if err != nil {
return err
}
log.Println("Create a socks5 proxy on localhost port",address)
if err := server.ListenAndServe("tcp", "0.0.0.0:"+address); err != nil {
return err
}
return nil
}
func connectForSocks(address string) error {
server, err := socks5.New(&socks5.Config{})
if err != nil {
return err
}
var conn net.Conn
log.Println("Connecting to far end")
conn, err = net.Dial("tcp", address)
if err != nil {
return err
}
log.Println("Starting server")
session, err = yamux.Server(conn, nil)
if err != nil {
return err
}
for {
stream, err := session.Accept()
log.Println("Acceping stream")
if err != nil {
return err
}
log.Println("Passing off to socks5")
go func() {
err = server.ServeConn(stream)
if err != nil {
log.Println(err)
}
}()
}
}
// Catches yamux connecting to us
func listenForSocks(address string) {
log.Println("Listening for the far end")
ln, err := net.Listen("tcp", "0.0.0.0:"+address)
if err != nil {
return
}
for {
conn, err := ln.Accept()
log.Println("Got a client")
if err != nil {
fmt.Fprintf(os.Stderr, "Errors accepting!")
}
// Add connection to yamux
session, err = yamux.Client(conn, nil)
}
}
// Catches clients and connects to yamux
func listenForClients(address string) error {
log.Println("Waiting for clients")
ln, err := net.Listen("tcp", address)
if err != nil {
return err
}
for {
conn, err := ln.Accept()
if err != nil {
return err
}
// TODO dial socks5 through yamux and connect to conn
if session == nil {
conn.Close()
continue
}
log.Println("Got a client")
log.Println("Opening a stream")
stream, err := session.Open()
if err != nil {
return err
}
// connect both of conn and stream
go func() {
log.Println("Starting to copy conn to stream")
io.Copy(conn, stream)
conn.Close()
}()
go func() {
log.Println("Starting to copy stream to conn")
io.Copy(stream, conn)
stream.Close()
log.Println("Done copying stream to conn")
}()
}
}
func main() {
sockstype := flag.String("sockstype", "", "fsocks or rsocks,eg. rsocks")
listen := flag.String("listen", "", "listen port for receiver,eg. 1080")
socks := flag.String("socks", "", "socks address:port,eg. 127.0.0.1:2222")
connect := flag.String("connect", "", "connect address:port,eg. 1.1.1.1:1080")
flag.Usage = func() {
fmt.Println("frsocks - forward and reverse socks5 server/client")
fmt.Println("reference:https://github.com/brimstone/rsocks")
fmt.Println("add forward socks5 mode and some changes to the reference")
fmt.Println("author:3gstudent")
fmt.Println("")
fmt.Println("Usage:")
fmt.Println("Mode1:[Forward Socks5 Mode]")
fmt.Println("1) Create a socks5 proxy on localhost and port 1080.")
fmt.Println("eg.")
fmt.Println("frsocks -sockstype fsocks -listen 1080")
fmt.Println("2) Connect to 127.0.0.1:1080 on the client with any socks5 client.")
fmt.Println("Mode2:[Reverse Socks5 Mode]")
fmt.Println("1) Create a socks redirection on the client.")
fmt.Println("eg.")
fmt.Println("frsocks -sockstype rsocks -listen 1111 -socks 127.0.0.1:2222")
fmt.Println("2) Connect to the client(1.1.1.1:1111)on the transit server.")
fmt.Println("eg.")
fmt.Println("frsocks -sockstype rsocks -connect 1.1.1.1:1111")
fmt.Println("3) Connect to 127.0.0.1:2222 on the client with any socks5 client.")
}
flag.Parse()
if *sockstype == "fsocks" {
log.Println("[Forward Socks5 Mode]")
if *listen != "" {
log.Fatal(createForwardSocks(*listen))
}
}else if *sockstype == "rsocks" {
log.Println("[Reverse Socks5 Mode]")
if *listen != "" {
log.Println("Start to listen for clients")
go listenForSocks(*listen)
log.Fatal(listenForClients(*socks))
}
if *connect != "" {
log.Println("Connect to the far end")
log.Fatal(connectForSocks(*connect))
}
}else{
flag.Usage()
os.Exit(1)
}
}