Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
G
gost
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
gost
Commits
302767f6
Commit
302767f6
authored
Mar 27, 2015
by
rui.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
be75c8e1
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
559 additions
and
127 deletions
+559
-127
client.go
client.go
+250
-0
gost.go
gost.go
+6
-109
main.go
main.go
+24
-7
server.go
server.go
+150
-0
socks5.go
socks5.go
+0
-11
util.go
util.go
+129
-0
No files found.
client.go
0 → 100644
View file @
302767f6
package
main
import
(
"bufio"
"bytes"
"github.com/ginuerzh/gosocks5"
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
"io"
"log"
"net"
"net/http"
"strconv"
"strings"
)
func
listenAndServe
(
addr
string
,
handler
func
(
net
.
Conn
))
error
{
laddr
,
err
:=
net
.
ResolveTCPAddr
(
"tcp"
,
addr
)
if
err
!=
nil
{
return
err
}
ln
,
err
:=
net
.
ListenTCP
(
"tcp"
,
laddr
)
if
err
!=
nil
{
return
err
}
defer
ln
.
Close
()
for
{
conn
,
err
:=
ln
.
AcceptTCP
()
if
err
!=
nil
{
log
.
Println
(
"accept:"
,
err
)
continue
}
//log.Println("accept", conn.RemoteAddr())
go
handler
(
conn
)
}
}
func
handshake
(
conn
net
.
Conn
,
methods
...
uint8
)
(
method
uint8
,
err
error
)
{
nm
:=
len
(
methods
)
if
nm
==
0
{
nm
=
1
}
b
:=
make
([]
byte
,
2
+
nm
)
b
[
0
]
=
Ver5
b
[
1
]
=
uint8
(
nm
)
copy
(
b
[
2
:
],
methods
)
if
_
,
err
=
conn
.
Write
(
b
);
err
!=
nil
{
return
}
if
_
,
err
=
io
.
ReadFull
(
conn
,
b
[
:
2
]);
err
!=
nil
{
return
}
if
b
[
0
]
!=
Ver5
{
err
=
gosocks5
.
ErrBadVersion
}
method
=
b
[
1
]
return
}
func
cliHandle
(
conn
net
.
Conn
)
{
defer
conn
.
Close
()
sconn
,
err
:=
Connect
(
Saddr
,
Proxy
)
if
err
!=
nil
{
return
}
defer
sconn
.
Close
()
method
,
err
:=
handshake
(
sconn
,
MethodAES256
,
gosocks5
.
MethodNoAuth
)
if
err
!=
nil
||
method
==
gosocks5
.
MethodNoAcceptable
{
return
}
if
method
==
MethodAES256
{
cipher
,
_
:=
shadowsocks
.
NewCipher
(
Cipher
,
Password
)
sconn
=
shadowsocks
.
NewConn
(
sconn
,
cipher
)
}
b
:=
make
([]
byte
,
8192
)
n
,
err
:=
io
.
ReadAtLeast
(
conn
,
b
,
2
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
if
b
[
0
]
==
gosocks5
.
Ver5
{
length
:=
2
+
int
(
b
[
1
])
if
n
<
length
{
if
_
,
err
:=
io
.
ReadFull
(
conn
,
b
[
n
:
length
]);
err
!=
nil
{
return
}
}
if
err
:=
gosocks5
.
WriteMethod
(
gosocks5
.
MethodNoAuth
,
conn
);
err
!=
nil
{
return
}
handleSocks5
(
conn
,
sconn
)
return
}
for
{
if
bytes
.
HasSuffix
(
b
[
:
n
],
[]
byte
(
"
\r\n\r\n
"
))
{
break
}
nn
,
err
:=
conn
.
Read
(
b
[
n
:
])
if
err
!=
nil
{
return
}
n
+=
nn
}
req
,
err
:=
http
.
ReadRequest
(
bufio
.
NewReader
(
bytes
.
NewReader
(
b
[
:
n
])))
if
err
!=
nil
{
return
}
handleHttp
(
req
,
conn
,
sconn
)
}
func
handleSocks5
(
conn
net
.
Conn
,
sconn
net
.
Conn
)
{
req
,
err
:=
gosocks5
.
ReadRequest
(
conn
)
if
err
!=
nil
{
return
}
switch
req
.
Cmd
{
case
gosocks5
.
CmdConnect
,
gosocks5
.
CmdBind
:
if
err
:=
req
.
Write
(
sconn
);
err
!=
nil
{
return
}
Transport
(
conn
,
sconn
)
case
gosocks5
.
CmdUdp
:
if
err
:=
req
.
Write
(
sconn
);
err
!=
nil
{
return
}
rep
,
err
:=
gosocks5
.
ReadReply
(
sconn
)
if
err
!=
nil
||
rep
.
Rep
!=
gosocks5
.
Succeeded
{
return
}
uconn
,
err
:=
net
.
ListenUDP
(
"udp"
,
nil
)
if
err
!=
nil
{
log
.
Println
(
err
)
gosocks5
.
NewReply
(
Failure
,
nil
)
.
Write
(
conn
)
return
}
defer
uconn
.
Close
()
addr
:=
ToSocksAddr
(
uconn
.
LocalAddr
())
addr
.
Host
,
_
,
_
=
net
.
SplitHostPort
(
conn
.
LocalAddr
()
.
String
())
log
.
Println
(
"udp:"
,
addr
)
rep
=
gosocks5
.
NewReply
(
Succeeded
,
addr
)
if
err
:=
rep
.
Write
(
conn
);
err
!=
nil
{
log
.
Println
(
err
)
return
}
addr
.
Port
=
req
.
Addr
.
Port
raddr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
addr
.
String
())
if
err
!=
nil
{
return
}
cliTunnelUDP
(
raddr
,
uconn
,
conn
)
}
}
func
cliTunnelUDP
(
raddr
net
.
Addr
,
uconn
*
net
.
UDPConn
,
conn
net
.
Conn
)
{
go
func
()
{
udp
,
err
:=
gosocks5
.
ReadUDPDatagram
(
uconn
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
udp
.
Header
.
Rsv
=
uint16
(
len
(
udp
.
Data
))
if
err
:=
udp
.
Write
(
conn
);
err
!=
nil
{
log
.
Println
(
err
)
return
}
}()
for
{
udp
,
err
:=
gosocks5
.
ReadUDPDatagram
(
conn
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
udp
.
Header
.
Rsv
=
0
buf
:=
&
bytes
.
Buffer
{}
udp
.
Write
(
buf
)
if
_
,
err
:=
uconn
.
WriteTo
(
buf
.
Bytes
(),
raddr
);
err
!=
nil
{
log
.
Println
(
err
)
return
}
}
}
func
handleHttp
(
req
*
http
.
Request
,
conn
net
.
Conn
,
sconn
net
.
Conn
)
{
var
host
string
var
port
uint16
s
:=
strings
.
Split
(
req
.
Host
,
":"
)
host
=
s
[
0
]
port
=
80
if
len
(
s
)
==
2
{
n
,
_
:=
strconv
.
ParseUint
(
s
[
1
],
10
,
16
)
port
=
uint16
(
n
)
}
addr
:=
&
gosocks5
.
Addr
{
Type
:
gosocks5
.
AddrDomain
,
Host
:
host
,
Port
:
port
,
}
r
:=
gosocks5
.
NewRequest
(
gosocks5
.
CmdConnect
,
addr
)
if
err
:=
r
.
Write
(
sconn
);
err
!=
nil
{
return
}
rep
,
err
:=
gosocks5
.
ReadReply
(
sconn
)
if
err
!=
nil
||
rep
.
Rep
!=
gosocks5
.
Succeeded
{
conn
.
Write
([]
byte
(
"HTTP/1.1 503 Service unavailable
\r\n
"
+
"Proxy-Agent: gost/1.0
\r\n\r\n
"
))
return
}
if
req
.
Method
==
"CONNECT"
{
if
_
,
err
=
conn
.
Write
(
[]
byte
(
"HTTP/1.1 200 Connection established
\r\n
"
+
"Proxy-Agent: gost/2.0
\r\n\r\n
"
));
err
!=
nil
{
return
}
}
else
{
if
err
:=
req
.
Write
(
sconn
);
err
!=
nil
{
return
}
}
if
err
:=
Transport
(
conn
,
sconn
);
err
!=
nil
{
log
.
Println
(
err
)
}
}
gost.go
View file @
302767f6
...
@@ -4,7 +4,7 @@ import (
...
@@ -4,7 +4,7 @@ import (
"bufio"
"bufio"
"bytes"
"bytes"
//"crypto/tls"
//"crypto/tls"
"errors"
//
"errors"
"io"
"io"
//"io/ioutil"
//"io/ioutil"
"log"
"log"
...
@@ -16,7 +16,7 @@ import (
...
@@ -16,7 +16,7 @@ import (
"encoding/binary"
"encoding/binary"
"fmt"
"fmt"
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
"net/url"
//
"net/url"
"time"
"time"
)
)
...
@@ -90,8 +90,8 @@ func (g *Gost) cli(conn net.Conn) {
...
@@ -90,8 +90,8 @@ func (g *Gost) cli(conn net.Conn) {
b
:=
make
([]
byte
,
8192
)
b
:=
make
([]
byte
,
8192
)
b
[
0
]
=
5
b
[
0
]
=
5
b
[
1
]
=
1
b
[
1
]
=
1
if
gost
.
Cipher
{
if
len
(
Cipher
)
>
0
{
b
[
2
]
=
0x88
b
[
2
]
=
MethodAES256
}
}
if
_
,
err
:=
sconn
.
Write
(
b
[
:
3
]);
err
!=
nil
{
if
_
,
err
:=
sconn
.
Write
(
b
[
:
3
]);
err
!=
nil
{
...
@@ -107,7 +107,7 @@ func (g *Gost) cli(conn net.Conn) {
...
@@ -107,7 +107,7 @@ func (g *Gost) cli(conn net.Conn) {
}
}
lg
.
Logln
(
"<<<|"
,
b
[
:
n
])
lg
.
Logln
(
"<<<|"
,
b
[
:
n
])
if
b
[
1
]
==
0x88
{
if
b
[
1
]
==
MethodAES256
{
cipher
,
_
:=
shadowsocks
.
NewCipher
(
"aes-256-cfb"
,
"gost"
)
cipher
,
_
:=
shadowsocks
.
NewCipher
(
"aes-256-cfb"
,
"gost"
)
sconn
=
shadowsocks
.
NewConn
(
sconn
,
cipher
)
sconn
=
shadowsocks
.
NewConn
(
sconn
,
cipher
)
}
}
...
@@ -174,7 +174,7 @@ func (g *Gost) srv(conn net.Conn) {
...
@@ -174,7 +174,7 @@ func (g *Gost) srv(conn net.Conn) {
}
}
lg
.
Logln
(
"|<<<"
,
[]
byte
{
5
,
method
})
lg
.
Logln
(
"|<<<"
,
[]
byte
{
5
,
method
})
if
method
==
0x88
{
if
method
==
MethodAES256
{
cipher
,
_
:=
shadowsocks
.
NewCipher
(
"aes-256-cfb"
,
"gost"
)
cipher
,
_
:=
shadowsocks
.
NewCipher
(
"aes-256-cfb"
,
"gost"
)
conn
=
shadowsocks
.
NewConn
(
conn
,
cipher
)
conn
=
shadowsocks
.
NewConn
(
conn
,
cipher
)
}
}
...
@@ -610,109 +610,6 @@ func shadowTransfer(conn, sconn net.Conn, lg *BufferedLog) {
...
@@ -610,109 +610,6 @@ func shadowTransfer(conn, sconn net.Conn, lg *BufferedLog) {
}
}
}
}
func
Connect
(
addr
,
proxy
string
)
(
net
.
Conn
,
error
)
{
if
len
(
proxy
)
==
0
{
taddr
,
err
:=
net
.
ResolveTCPAddr
(
"tcp"
,
addr
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
nil
,
err
}
return
net
.
DialTCP
(
"tcp"
,
nil
,
taddr
)
}
paddr
,
err
:=
net
.
ResolveTCPAddr
(
"tcp"
,
proxy
)
if
err
!=
nil
{
return
nil
,
err
}
pconn
,
err
:=
net
.
DialTCP
(
"tcp"
,
nil
,
paddr
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
nil
,
err
}
header
:=
http
.
Header
{}
header
.
Set
(
"Proxy-Connection"
,
"keep-alive"
)
req
:=
&
http
.
Request
{
Method
:
"CONNECT"
,
URL
:
&
url
.
URL
{
Host
:
addr
},
Host
:
addr
,
Header
:
header
,
}
if
err
:=
req
.
Write
(
pconn
);
err
!=
nil
{
log
.
Println
(
err
)
pconn
.
Close
()
return
nil
,
err
}
resp
,
err
:=
http
.
ReadResponse
(
bufio
.
NewReader
(
pconn
),
req
)
if
err
!=
nil
{
log
.
Println
(
err
)
pconn
.
Close
()
return
nil
,
err
}
if
resp
.
StatusCode
!=
http
.
StatusOK
{
pconn
.
Close
()
return
nil
,
errors
.
New
(
resp
.
Status
)
}
return
pconn
,
nil
}
func
Copy
(
dst
io
.
Writer
,
src
io
.
Reader
)
(
written
int64
,
err
error
)
{
buf
:=
make
([]
byte
,
32
*
1024
)
for
{
nr
,
er
:=
src
.
Read
(
buf
)
//log.Println("cp r", nr, er)
if
nr
>
0
{
nw
,
ew
:=
dst
.
Write
(
buf
[
:
nr
])
//log.Println("cp w", nw, ew)
if
nw
>
0
{
written
+=
int64
(
nw
)
}
if
ew
!=
nil
{
err
=
ew
break
}
/*
if nr != nw {
err = io.ErrShortWrite
break
}
*/
}
if
er
==
io
.
EOF
{
break
}
if
er
!=
nil
{
err
=
er
break
}
}
return
}
func
Pipe
(
src
io
.
Reader
,
dst
io
.
Writer
,
c
chan
<-
error
)
{
_
,
err
:=
Copy
(
dst
,
src
)
c
<-
err
}
func
Transport
(
conn
,
conn2
net
.
Conn
)
(
err
error
)
{
rChan
:=
make
(
chan
error
,
1
)
wChan
:=
make
(
chan
error
,
1
)
go
Pipe
(
conn
,
conn2
,
wChan
)
go
Pipe
(
conn2
,
conn
,
rChan
)
select
{
case
err
=
<-
wChan
:
//log.Println("w exit", err)
case
err
=
<-
rChan
:
//log.Println("r exit", err)
}
return
}
func
getRequest
(
conn
net
.
Conn
)
(
addrType
uint8
,
addr
string
,
port
uint16
,
extra
[]
byte
,
err
error
)
{
func
getRequest
(
conn
net
.
Conn
)
(
addrType
uint8
,
addr
string
,
port
uint16
,
extra
[]
byte
,
err
error
)
{
const
(
const
(
idType
=
0
// address type index
idType
=
0
// address type index
...
...
main.go
View file @
302767f6
...
@@ -3,17 +3,23 @@ package main
...
@@ -3,17 +3,23 @@ package main
import
(
import
(
"flag"
"flag"
"github.com/ginuerzh/gosocks5"
"log"
"log"
)
)
var
gost
Gost
var
(
Laddr
,
Saddr
,
Proxy
string
Shadows
bool
Cipher
,
Password
string
)
func
init
()
{
func
init
()
{
flag
.
StringVar
(
&
gost
.
Proxy
,
"P"
,
""
,
"proxy for forward"
)
flag
.
StringVar
(
&
Proxy
,
"P"
,
""
,
"proxy for forward"
)
flag
.
StringVar
(
&
gost
.
Saddr
,
"S"
,
""
,
"the server that connecting to"
)
flag
.
StringVar
(
&
Saddr
,
"S"
,
""
,
"the server that connecting to"
)
flag
.
StringVar
(
&
gost
.
Laddr
,
"L"
,
":8080"
,
"listen address"
)
flag
.
StringVar
(
&
Laddr
,
"L"
,
":8080"
,
"listen address"
)
flag
.
BoolVar
(
&
gost
.
Cipher
,
"cipher"
,
true
,
"cipher transfer data"
)
flag
.
StringVar
(
&
Cipher
,
"cipher"
,
"rc4-md5"
,
"cipher method"
)
flag
.
BoolVar
(
&
gost
.
Shadows
,
"ss"
,
false
,
"shadowsocks compatible"
)
flag
.
StringVar
(
&
Password
,
"password"
,
"20150327"
,
"cipher password"
)
flag
.
BoolVar
(
&
Shadows
,
"ss"
,
false
,
"shadowsocks compatible"
)
flag
.
BoolVar
(
&
Debug
,
"d"
,
false
,
"debug option"
)
flag
.
BoolVar
(
&
Debug
,
"d"
,
false
,
"debug option"
)
flag
.
Parse
()
flag
.
Parse
()
...
@@ -21,5 +27,16 @@ func init() {
...
@@ -21,5 +27,16 @@ func init() {
}
}
func
main
()
{
func
main
()
{
log
.
Fatal
(
gost
.
Run
())
//log.Fatal(gost.Run())
if
len
(
Saddr
)
==
0
{
srv
:=
&
gosocks5
.
Server
{
Addr
:
Laddr
,
SelectMethod
:
selectMethod
,
Handle
:
srvHandle
,
}
log
.
Fatal
(
srv
.
ListenAndServe
())
return
}
log
.
Fatal
(
listenAndServe
(
Laddr
,
cliHandle
))
}
}
server.go
0 → 100644
View file @
302767f6
package
main
import
(
"github.com/ginuerzh/gosocks5"
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
"net"
//"strconv"
"log"
)
const
(
MethodAES256
uint8
=
0x88
)
func
selectMethod
(
methods
...
uint8
)
uint8
{
for
_
,
method
:=
range
methods
{
if
method
==
MethodAES256
{
return
method
}
}
return
gosocks5
.
MethodNoAcceptable
}
func
srvHandle
(
conn
net
.
Conn
,
method
uint8
)
{
defer
conn
.
Close
()
if
method
==
gosocks5
.
MethodNoAcceptable
{
return
}
if
method
==
MethodAES256
{
cipher
,
_
:=
shadowsocks
.
NewCipher
(
Cipher
,
Password
)
conn
=
shadowsocks
.
NewConn
(
conn
,
cipher
)
}
req
,
err
:=
gosocks5
.
ReadRequest
(
conn
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
switch
req
.
Cmd
{
case
gosocks5
.
CmdConnect
:
log
.
Println
(
"connect"
,
req
.
Addr
.
String
())
tconn
,
err
:=
Connect
(
req
.
Addr
.
String
(),
Proxy
)
if
err
!=
nil
{
gosocks5
.
NewReply
(
gosocks5
.
HostUnreachable
,
nil
)
.
Write
(
conn
)
return
}
defer
tconn
.
Close
()
rep
:=
gosocks5
.
NewReply
(
gosocks5
.
Succeeded
,
nil
)
if
err
:=
rep
.
Write
(
conn
);
err
!=
nil
{
return
}
if
err
:=
Transport
(
conn
,
tconn
);
err
!=
nil
{
log
.
Println
(
err
)
}
case
gosocks5
.
CmdBind
:
l
,
err
:=
net
.
ListenTCP
(
"tcp"
,
nil
)
if
err
!=
nil
{
gosocks5
.
NewReply
(
gosocks5
.
Failure
,
nil
)
.
Write
(
conn
)
return
}
addr
:=
ToSocksAddr
(
l
.
Addr
())
addr
.
Host
,
_
,
_
=
net
.
SplitHostPort
(
conn
.
LocalAddr
()
.
String
())
log
.
Println
(
"bind:"
,
addr
)
rep
:=
gosocks5
.
NewReply
(
gosocks5
.
Succeeded
,
addr
)
if
err
:=
rep
.
Write
(
conn
);
err
!=
nil
{
return
}
tconn
,
err
:=
l
.
AcceptTCP
()
if
err
!=
nil
{
log
.
Println
(
"accept:"
,
err
)
gosocks5
.
NewReply
(
gosocks5
.
Failure
,
nil
)
.
Write
(
conn
)
return
}
defer
tconn
.
Close
()
l
.
Close
()
addr
=
ToSocksAddr
(
tconn
.
RemoteAddr
())
rep
=
gosocks5
.
NewReply
(
gosocks5
.
Succeeded
,
addr
)
if
err
:=
rep
.
Write
(
conn
);
err
!=
nil
{
log
.
Println
(
err
)
return
}
if
err
:=
Transport
(
conn
,
tconn
);
err
!=
nil
{
log
.
Println
(
err
)
}
case
gosocks5
.
CmdUdp
:
uconn
,
err
:=
net
.
ListenUDP
(
"udp"
,
nil
)
if
err
!=
nil
{
log
.
Println
(
err
)
gosocks5
.
NewReply
(
Failure
,
nil
)
.
Write
(
conn
)
return
}
defer
uconn
.
Close
()
addr
:=
ToSocksAddr
(
uconn
.
LocalAddr
())
addr
.
Host
,
_
,
_
=
net
.
SplitHostPort
(
conn
.
LocalAddr
()
.
String
())
log
.
Println
(
"udp:"
,
addr
)
rep
:=
gosocks5
.
NewReply
(
Succeeded
,
addr
)
if
err
:=
rep
.
Write
(
conn
);
err
!=
nil
{
log
.
Println
(
err
)
return
}
srvTunnelUDP
(
conn
,
uconn
)
}
}
func
srvTunnelUDP
(
conn
net
.
Conn
,
uconn
*
net
.
UDPConn
)
{
go
func
()
{
b
:=
make
([]
byte
,
65535
)
n
,
addr
,
err
:=
uconn
.
ReadFromUDP
(
b
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
udp
:=
gosocks5
.
NewUDPDatagram
(
gosocks5
.
NewUDPHeader
(
uint16
(
n
),
0
,
ToSocksAddr
(
addr
)),
b
[
:
n
])
if
err
:=
udp
.
Write
(
conn
);
err
!=
nil
{
log
.
Println
(
err
)
return
}
}()
for
{
ud
,
err
:=
gosocks5
.
ReadUDPDatagram
(
conn
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
}
addr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
ud
.
Header
.
Addr
.
String
())
if
err
!=
nil
{
log
.
Println
(
err
)
continue
// drop silently
}
if
_
,
err
:=
uconn
.
WriteToUDP
(
ud
.
Data
,
addr
);
err
!=
nil
{
log
.
Println
(
err
)
return
}
}
}
socks5.go
View file @
302767f6
...
@@ -52,17 +52,6 @@ var (
...
@@ -52,17 +52,6 @@ var (
ErrBadFormat
=
errors
.
New
(
"Bad format"
)
ErrBadFormat
=
errors
.
New
(
"Bad format"
)
ErrBadAddrType
=
errors
.
New
(
"Bad address type"
)
ErrBadAddrType
=
errors
.
New
(
"Bad address type"
)
ErrShortBuffer
=
errors
.
New
(
"Short buffer"
)
ErrShortBuffer
=
errors
.
New
(
"Short buffer"
)
cmdErrMap
=
map
[
uint8
]
error
{
Failure
:
errors
.
New
(
"General SOCKS server failure"
),
NotAllowed
:
errors
.
New
(
"Connection not allowed by ruleset"
),
NetUnreachable
:
errors
.
New
(
"Network unreachable"
),
HostUnreachable
:
errors
.
New
(
"Host unreachable"
),
ConnRefused
:
errors
.
New
(
"Connection refused"
),
TTLExpired
:
errors
.
New
(
"TTL expired"
),
CmdUnsupported
:
errors
.
New
(
"Command not supported"
),
AddrUnsupported
:
errors
.
New
(
"Address type not supported"
),
}
)
)
/*
/*
...
...
util.go
0 → 100644
View file @
302767f6
package
main
import
(
"bufio"
//"bytes"
"errors"
"github.com/ginuerzh/gosocks5"
"io"
"log"
"net"
"net/http"
"net/url"
"strconv"
)
func
ToSocksAddr
(
addr
net
.
Addr
)
*
gosocks5
.
Addr
{
host
,
port
,
_
:=
net
.
SplitHostPort
(
addr
.
String
())
p
,
_
:=
strconv
.
Atoi
(
port
)
return
&
gosocks5
.
Addr
{
Type
:
AddrIPv4
,
Host
:
host
,
Port
:
uint16
(
p
),
}
}
func
Connect
(
addr
,
proxy
string
)
(
net
.
Conn
,
error
)
{
if
len
(
proxy
)
==
0
{
taddr
,
err
:=
net
.
ResolveTCPAddr
(
"tcp"
,
addr
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
nil
,
err
}
return
net
.
DialTCP
(
"tcp"
,
nil
,
taddr
)
}
paddr
,
err
:=
net
.
ResolveTCPAddr
(
"tcp"
,
proxy
)
if
err
!=
nil
{
return
nil
,
err
}
pconn
,
err
:=
net
.
DialTCP
(
"tcp"
,
nil
,
paddr
)
if
err
!=
nil
{
log
.
Println
(
err
)
return
nil
,
err
}
header
:=
http
.
Header
{}
header
.
Set
(
"Proxy-Connection"
,
"keep-alive"
)
req
:=
&
http
.
Request
{
Method
:
"CONNECT"
,
URL
:
&
url
.
URL
{
Host
:
addr
},
Host
:
addr
,
Header
:
header
,
}
if
err
:=
req
.
Write
(
pconn
);
err
!=
nil
{
log
.
Println
(
err
)
pconn
.
Close
()
return
nil
,
err
}
resp
,
err
:=
http
.
ReadResponse
(
bufio
.
NewReader
(
pconn
),
req
)
if
err
!=
nil
{
log
.
Println
(
err
)
pconn
.
Close
()
return
nil
,
err
}
if
resp
.
StatusCode
!=
http
.
StatusOK
{
pconn
.
Close
()
return
nil
,
errors
.
New
(
resp
.
Status
)
}
return
pconn
,
nil
}
// based on io.Copy
func
Copy
(
dst
io
.
Writer
,
src
io
.
Reader
)
(
written
int64
,
err
error
)
{
buf
:=
make
([]
byte
,
32
*
1024
)
for
{
nr
,
er
:=
src
.
Read
(
buf
)
//log.Println("cp r", nr, er)
if
nr
>
0
{
nw
,
ew
:=
dst
.
Write
(
buf
[
:
nr
])
//log.Println("cp w", nw, ew)
if
nw
>
0
{
written
+=
int64
(
nw
)
}
if
ew
!=
nil
{
err
=
ew
break
}
/*
if nr != nw {
err = io.ErrShortWrite
break
}
*/
}
if
er
==
io
.
EOF
{
break
}
if
er
!=
nil
{
err
=
er
break
}
}
return
}
func
Pipe
(
src
io
.
Reader
,
dst
io
.
Writer
,
c
chan
<-
error
)
{
_
,
err
:=
Copy
(
dst
,
src
)
c
<-
err
}
func
Transport
(
conn
,
conn2
net
.
Conn
)
(
err
error
)
{
rChan
:=
make
(
chan
error
,
1
)
wChan
:=
make
(
chan
error
,
1
)
go
Pipe
(
conn
,
conn2
,
wChan
)
go
Pipe
(
conn2
,
conn
,
rChan
)
select
{
case
err
=
<-
wChan
:
//log.Println("w exit", err)
case
err
=
<-
rChan
:
//log.Println("r exit", err)
}
return
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment