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
aef1c86b
Commit
aef1c86b
authored
Jan 06, 2017
by
rui.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
#62 fix UDP port forwarding
parent
62d92d95
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
199 additions
and
245 deletions
+199
-245
forward.go
forward.go
+190
-147
gost.go
gost.go
+2
-0
server.go
server.go
+6
-1
socks.go
socks.go
+1
-97
No files found.
forward.go
View file @
aef1c86b
...
@@ -62,206 +62,249 @@ func (s *TcpForwardServer) handleTcpForward(conn net.Conn, raddr net.Addr) {
...
@@ -62,206 +62,249 @@ func (s *TcpForwardServer) handleTcpForward(conn net.Conn, raddr net.Addr) {
glog
.
V
(
LINFO
)
.
Infof
(
"[tcp] %s >-< %s"
,
conn
.
RemoteAddr
(),
raddr
)
glog
.
V
(
LINFO
)
.
Infof
(
"[tcp] %s >-< %s"
,
conn
.
RemoteAddr
(),
raddr
)
}
}
type
UdpForwardServer
struct
{
type
packet
struct
{
Base
*
ProxyServer
srcAddr
*
net
.
UDPAddr
// src address
dstAddr
*
net
.
UDPAddr
// dest address
data
[]
byte
}
}
func
NewUdpForwardServer
(
base
*
ProxyServer
)
*
UdpForwardServer
{
type
cnode
struct
{
return
&
UdpForwardServer
{
Base
:
base
}
chain
*
ProxyChain
conn
net
.
Conn
srcAddr
,
dstAddr
*
net
.
UDPAddr
rChan
,
wChan
chan
*
packet
err
error
ttl
time
.
Duration
}
}
func
(
s
*
UdpForwardServer
)
ListenAndServe
()
error
{
func
(
node
*
cnode
)
getUDPTunnel
()
(
net
.
Conn
,
error
)
{
laddr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
s
.
Base
.
Node
.
Addr
)
conn
,
err
:=
node
.
chain
.
GetConn
(
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
raddr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
s
.
Base
.
Node
.
Remote
)
conn
.
SetWriteDeadline
(
time
.
Now
()
.
Add
(
WriteTimeout
))
if
err
!=
nil
{
if
err
=
gosocks5
.
NewRequest
(
CmdUdpTun
,
nil
)
.
Write
(
conn
);
err
!=
nil
{
return
err
conn
.
Close
()
return
nil
,
err
}
}
conn
.
SetWriteDeadline
(
time
.
Time
{})
conn
,
err
:=
net
.
ListenUDP
(
"udp"
,
laddr
)
conn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
ReadTimeout
))
reply
,
err
:=
gosocks5
.
ReadReply
(
conn
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
laddr
,
raddr
,
err
)
conn
.
Close
(
)
return
err
return
nil
,
err
}
}
defer
conn
.
Close
(
)
conn
.
SetReadDeadline
(
time
.
Time
{}
)
if
len
(
s
.
Base
.
Chain
.
nodes
)
==
0
{
if
reply
.
Rep
!=
gosocks5
.
Succeeded
{
for
{
conn
.
Close
()
b
:=
make
([]
byte
,
MediumBufferSize
)
return
nil
,
errors
.
New
(
"UDP tunnel failure"
)
n
,
addr
,
err
:=
conn
.
ReadFromUDP
(
b
)
}
return
conn
,
nil
}
func
(
node
*
cnode
)
run
()
{
if
len
(
node
.
chain
.
Nodes
())
==
0
{
lconn
,
err
:=
net
.
ListenUDP
(
"udp"
,
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
laddr
,
ra
ddr
,
err
)
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
node
.
srcAddr
,
node
.
dstA
ddr
,
err
)
continue
return
}
}
go
func
()
{
node
.
conn
=
lconn
s
.
handleUdpForwardLocal
(
conn
,
addr
,
raddr
,
b
[
:
n
])
}
else
{
}()
tc
,
err
:=
node
.
getUDPTunnel
()
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp-tun] %s -> %s : %s"
,
node
.
srcAddr
,
node
.
dstAddr
,
err
)
return
}
}
node
.
conn
=
tc
}
}
rChan
,
wChan
:=
make
(
chan
*
gosocks5
.
UDPDatagram
,
32
),
make
(
chan
*
gosocks5
.
UDPDatagram
,
32
)
defer
node
.
conn
.
Close
()
timer
:=
time
.
NewTimer
(
node
.
ttl
)
errChan
:=
make
(
chan
error
,
2
)
go
func
()
{
go
func
()
{
for
{
for
{
switch
c
:=
node
.
conn
.
(
type
)
{
case
*
net
.
UDPConn
:
b
:=
make
([]
byte
,
MediumBufferSize
)
b
:=
make
([]
byte
,
MediumBufferSize
)
n
,
addr
,
err
:=
conn
.
ReadFromUDP
(
b
)
n
,
addr
,
err
:=
c
.
ReadFromUDP
(
b
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
laddr
,
raddr
,
err
)
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
node
.
srcAddr
,
node
.
dstAddr
,
err
)
node
.
err
=
err
errChan
<-
err
return
return
}
}
timer
.
Reset
(
node
.
ttl
)
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp] %s <<< %s : length %d"
,
node
.
srcAddr
,
addr
,
n
)
if
node
.
dstAddr
.
String
()
!=
addr
.
String
()
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : dst-addr mismatch (%s)"
,
node
.
srcAddr
,
node
.
dstAddr
,
addr
)
break
}
select
{
select
{
case
rChan
<-
gosocks5
.
NewUDPDatagram
(
gosocks5
.
NewUDPHeader
(
uint16
(
n
),
0
,
ToSocksAddr
(
addr
)),
b
[
:
n
])
:
// swap srcAddr with dstAddr
case
node
.
rChan
<-
&
packet
{
srcAddr
:
node
.
dstAddr
,
dstAddr
:
node
.
srcAddr
,
data
:
b
[
:
n
]}
:
case
<-
time
.
After
(
time
.
Second
*
3
)
:
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
node
.
srcAddr
,
node
.
dstAddr
,
"recv queue is full, discard"
)
}
default
:
default
:
// glog.V(LWARNING).Infof("[udp-connect] %s -> %s : rbuf is full", laddr, raddr)
dgram
,
err
:=
gosocks5
.
ReadUDPDatagram
(
c
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp-tun] %s <- %s : %s"
,
node
.
srcAddr
,
node
.
dstAddr
,
err
)
node
.
err
=
err
errChan
<-
err
return
}
timer
.
Reset
(
node
.
ttl
)
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp-tun] %s <<< %s : length %d"
,
node
.
srcAddr
,
dgram
.
Header
.
Addr
.
String
(),
len
(
dgram
.
Data
))
if
dgram
.
Header
.
Addr
.
String
()
!=
node
.
dstAddr
.
String
()
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp-tun] %s <- %s : dst-addr mismatch (%s)"
,
node
.
srcAddr
,
node
.
dstAddr
,
dgram
.
Header
.
Addr
)
break
}
select
{
// swap srcAddr with dstAddr
case
node
.
rChan
<-
&
packet
{
srcAddr
:
node
.
dstAddr
,
dstAddr
:
node
.
srcAddr
,
data
:
dgram
.
Data
}
:
case
<-
time
.
After
(
time
.
Second
*
3
)
:
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp-tun] %s <- %s : %s"
,
node
.
srcAddr
,
node
.
dstAddr
,
"recv queue is full, discard"
)
}
}
}
}
}
}()
}()
go
func
()
{
go
func
()
{
for
{
for
pkt
:=
range
node
.
wChan
{
dgram
:=
<-
wChan
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp] %s >>> %s : length %d"
,
pkt
.
srcAddr
,
pkt
.
dstAddr
,
len
(
pkt
.
data
))
addr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
dgram
.
Header
.
Addr
.
String
())
timer
.
Reset
(
node
.
ttl
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
laddr
,
raddr
,
err
)
switch
c
:=
node
.
conn
.
(
type
)
{
continue
// drop silently
case
*
net
.
UDPConn
:
if
_
,
err
:=
c
.
WriteToUDP
(
pkt
.
data
,
pkt
.
dstAddr
);
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
pkt
.
srcAddr
,
pkt
.
dstAddr
,
err
)
node
.
err
=
err
errChan
<-
err
return
}
}
if
_
,
err
=
conn
.
WriteToUDP
(
dgram
.
Data
,
addr
);
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
laddr
,
raddr
,
err
)
default
:
dgram
:=
gosocks5
.
NewUDPDatagram
(
gosocks5
.
NewUDPHeader
(
uint16
(
len
(
pkt
.
data
)),
0
,
ToSocksAddr
(
pkt
.
dstAddr
)),
pkt
.
data
)
if
err
:=
dgram
.
Write
(
c
);
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp-tun] %s -> %s : %s"
,
pkt
.
srcAddr
,
pkt
.
dstAddr
,
err
)
node
.
err
=
err
errChan
<-
err
return
return
}
}
}
}
}
}()
}()
for
{
select
{
s
.
handleUdpForwardTunnel
(
laddr
,
raddr
,
rChan
,
wChan
)
case
<-
errChan
:
case
<-
timer
.
C
:
}
}
}
}
func
(
s
*
UdpForwardServer
)
handleUdpForwardLocal
(
conn
*
net
.
UDPConn
,
laddr
,
raddr
*
net
.
UDPAddr
,
data
[]
byte
)
{
type
UdpForwardServer
struct
{
lconn
,
err
:=
net
.
ListenUDP
(
"udp"
,
nil
)
Base
*
ProxyServer
if
err
!=
nil
{
TTL
int
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
laddr
,
raddr
,
err
)
}
return
}
defer
lconn
.
Close
()
if
_
,
err
:=
lconn
.
WriteToUDP
(
data
,
raddr
);
err
!=
nil
{
func
NewUdpForwardServer
(
base
*
ProxyServer
,
ttl
int
)
*
UdpForwardServer
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
laddr
,
raddr
,
err
)
return
&
UdpForwardServer
{
Base
:
base
,
TTL
:
ttl
}
return
}
}
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp] %s >>> %s length %d"
,
laddr
,
raddr
,
len
(
data
))
b
:=
make
([]
byte
,
MediumBufferSize
)
func
(
s
*
UdpForwardServer
)
ListenAndServe
()
error
{
lconn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
ReadTimeout
))
laddr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
s
.
Base
.
Node
.
Addr
)
n
,
addr
,
err
:=
lconn
.
ReadFromUDP
(
b
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
laddr
,
raddr
,
err
)
return
err
return
}
}
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp] %s <<< %s length %d"
,
laddr
,
addr
,
n
)
if
_
,
err
:=
conn
.
WriteToUDP
(
b
[
:
n
],
laddr
);
err
!=
nil
{
raddr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
s
.
Base
.
Node
.
Remote
)
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
laddr
,
raddr
,
err
)
if
err
!=
nil
{
return
err
}
}
return
}
func
(
s
*
UdpForwardServer
)
handleUdpForwardTunnel
(
laddr
,
raddr
*
net
.
UDPAddr
,
rChan
,
wChan
chan
*
gosocks5
.
UDPDatagram
)
{
conn
,
err
:=
net
.
ListenUDP
(
"udp"
,
laddr
)
var
cc
net
.
Conn
if
err
!=
nil
{
var
err
error
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
laddr
,
raddr
,
err
)
retry
:=
0
return
err
}
defer
conn
.
Close
()
rChan
,
wChan
:=
make
(
chan
*
packet
,
128
),
make
(
chan
*
packet
,
128
)
// start send queue
go
func
(
ch
chan
<-
*
packet
)
{
for
{
for
{
cc
,
err
=
s
.
prepareUdpConnectTunnel
(
raddr
)
b
:=
make
([]
byte
,
MediumBufferSize
)
n
,
addr
,
err
:=
conn
.
ReadFromUDP
(
b
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
laddr
,
raddr
,
err
)
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
laddr
,
raddr
,
err
)
time
.
Sleep
((
1
<<
uint
(
retry
))
*
time
.
Second
)
if
retry
<
5
{
retry
++
}
continue
continue
}
}
break
}
defer
cc
.
Close
()
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s <-> %s"
,
laddr
,
raddr
)
rExit
:=
make
(
chan
interface
{})
errc
:=
make
(
chan
error
,
2
)
go
func
()
{
for
{
select
{
select
{
case
dgram
:=
<-
rChan
:
case
ch
<-
&
packet
{
srcAddr
:
addr
,
dstAddr
:
raddr
,
data
:
b
[
:
n
]}
:
if
err
:=
dgram
.
Write
(
cc
);
err
!=
nil
{
case
<-
time
.
After
(
time
.
Second
*
3
)
:
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
laddr
,
raddr
,
err
)
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
addr
,
raddr
,
"send queue is full, discard"
)
errc
<-
err
return
}
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp-tun] %s >>> %s length: %d"
,
laddr
,
raddr
,
len
(
dgram
.
Data
))
case
<-
rExit
:
// glog.V(LDEBUG).Infof("[udp-connect] %s -> %s : exited", laddr, raddr)
return
}
}
}
}
}()
}(
wChan
)
go
func
()
{
// start recv queue
for
{
go
func
(
ch
<-
chan
*
packet
)
{
dgram
,
err
:=
gosocks5
.
ReadUDPDatagram
(
cc
)
for
pkt
:=
range
ch
{
if
err
!=
nil
{
if
_
,
err
:=
conn
.
WriteToUDP
(
pkt
.
data
,
pkt
.
dstAddr
);
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
laddr
,
raddr
,
err
)
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
pkt
.
dstAddr
,
pkt
.
srcAddr
,
err
)
close
(
rExit
)
errc
<-
err
return
return
}
}
select
{
case
wChan
<-
dgram
:
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp-tun] %s <<< %s length: %d"
,
laddr
,
raddr
,
len
(
dgram
.
Data
))
default
:
}
}
}
}()
}(
rChan
)
select
{
// mapping client to node
case
<-
errc
:
m
:=
make
(
map
[
string
]
*
cnode
)
//log.Println("w exit", err)
}
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s >-< %s"
,
laddr
,
raddr
)
}
func
(
s
*
UdpForwardServer
)
prepareUdpConnectTunnel
(
addr
net
.
Addr
)
(
net
.
Conn
,
error
)
{
// start dispatcher
conn
,
err
:=
s
.
Base
.
Chain
.
GetConn
()
for
pkt
:=
range
wChan
{
if
err
!=
nil
{
// clear obsolete nodes
return
nil
,
err
for
k
,
node
:=
range
m
{
if
node
!=
nil
&&
node
.
err
!=
nil
{
close
(
node
.
wChan
)
delete
(
m
,
k
)
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] clear node %s"
,
k
)
}
}
conn
.
SetWriteDeadline
(
time
.
Now
()
.
Add
(
WriteTimeout
))
if
err
=
gosocks5
.
NewRequest
(
CmdUdpConnect
,
ToSocksAddr
(
addr
))
.
Write
(
conn
);
err
!=
nil
{
conn
.
Close
()
return
nil
,
err
}
}
conn
.
SetWriteDeadline
(
time
.
Time
{})
conn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
ReadTimeout
))
node
,
ok
:=
m
[
pkt
.
srcAddr
.
String
()]
reply
,
err
:=
gosocks5
.
ReadReply
(
conn
)
if
!
ok
{
if
err
!=
nil
{
node
=
&
cnode
{
conn
.
Close
()
chain
:
s
.
Base
.
Chain
,
return
nil
,
err
srcAddr
:
pkt
.
srcAddr
,
dstAddr
:
pkt
.
dstAddr
,
rChan
:
rChan
,
wChan
:
make
(
chan
*
packet
,
32
),
ttl
:
time
.
Duration
(
s
.
TTL
)
*
time
.
Second
,
}
m
[
pkt
.
srcAddr
.
String
()]
=
node
go
node
.
run
()
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp] %s -> %s : new client (%d)"
,
pkt
.
srcAddr
,
pkt
.
dstAddr
,
len
(
m
))
}
}
conn
.
SetReadDeadline
(
time
.
Time
{})
if
reply
.
Rep
!=
gosocks5
.
Succeeded
{
select
{
conn
.
Close
()
case
node
.
wChan
<-
pkt
:
return
nil
,
errors
.
New
(
"failure"
)
case
<-
time
.
After
(
time
.
Second
*
3
)
:
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
pkt
.
srcAddr
,
pkt
.
dstAddr
,
"node send queue is full, discard"
)
}
}
}
return
conn
,
nil
return
nil
}
}
type
RTcpForwardServer
struct
{
type
RTcpForwardServer
struct
{
...
...
gost.go
View file @
aef1c86b
...
@@ -28,6 +28,8 @@ var (
...
@@ -28,6 +28,8 @@ var (
DialTimeout
=
30
*
time
.
Second
DialTimeout
=
30
*
time
.
Second
ReadTimeout
=
90
*
time
.
Second
ReadTimeout
=
90
*
time
.
Second
WriteTimeout
=
90
*
time
.
Second
WriteTimeout
=
90
*
time
.
Second
DefaultTTL
=
60
// default udp node TTL in second for udp port forwarding
)
)
var
(
var
(
...
...
server.go
View file @
aef1c86b
...
@@ -9,6 +9,7 @@ import (
...
@@ -9,6 +9,7 @@ import (
"io"
"io"
"net"
"net"
"net/http"
"net/http"
"strconv"
)
)
type
ProxyServer
struct
{
type
ProxyServer
struct
{
...
@@ -75,7 +76,11 @@ func (s *ProxyServer) Serve() error {
...
@@ -75,7 +76,11 @@ func (s *ProxyServer) Serve() error {
case
"tcp"
:
// Local TCP port forwarding
case
"tcp"
:
// Local TCP port forwarding
return
NewTcpForwardServer
(
s
)
.
ListenAndServe
()
return
NewTcpForwardServer
(
s
)
.
ListenAndServe
()
case
"udp"
:
// Local UDP port forwarding
case
"udp"
:
// Local UDP port forwarding
return
NewUdpForwardServer
(
s
)
.
ListenAndServe
()
ttl
,
_
:=
strconv
.
Atoi
(
s
.
Node
.
Get
(
"ttl"
))
if
ttl
<=
0
{
ttl
=
DefaultTTL
}
return
NewUdpForwardServer
(
s
,
ttl
)
.
ListenAndServe
()
case
"rtcp"
:
// Remote TCP port forwarding
case
"rtcp"
:
// Remote TCP port forwarding
return
NewRTcpForwardServer
(
s
)
.
Serve
()
return
NewRTcpForwardServer
(
s
)
.
Serve
()
case
"rudp"
:
// Remote UDP port forwarding
case
"rudp"
:
// Remote UDP port forwarding
...
...
socks.go
View file @
aef1c86b
...
@@ -21,7 +21,6 @@ const (
...
@@ -21,7 +21,6 @@ const (
)
)
const
(
const
(
CmdUdpConnect
uint8
=
0xF1
// extended method for udp local port forwarding
CmdUdpTun
uint8
=
0xF3
// extended method for udp over tcp
CmdUdpTun
uint8
=
0xF3
// extended method for udp over tcp
)
)
...
@@ -190,10 +189,6 @@ func (s *Socks5Server) HandleRequest(req *gosocks5.Request) {
...
@@ -190,10 +189,6 @@ func (s *Socks5Server) HandleRequest(req *gosocks5.Request) {
glog
.
V
(
LINFO
)
.
Infof
(
"[socks5-bind] %s - %s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
)
glog
.
V
(
LINFO
)
.
Infof
(
"[socks5-bind] %s - %s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
)
s
.
handleBind
(
req
)
s
.
handleBind
(
req
)
case
CmdUdpConnect
:
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s - %s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
)
s
.
handleUDPConnect
(
req
)
case
gosocks5
.
CmdUdp
:
case
gosocks5
.
CmdUdp
:
glog
.
V
(
LINFO
)
.
Infof
(
"[socks5-udp] %s - %s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
)
glog
.
V
(
LINFO
)
.
Infof
(
"[socks5-udp] %s - %s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
)
s
.
handleUDPRelay
(
req
)
s
.
handleUDPRelay
(
req
)
...
@@ -257,38 +252,6 @@ func (s *Socks5Server) handleBind(req *gosocks5.Request) {
...
@@ -257,38 +252,6 @@ func (s *Socks5Server) handleBind(req *gosocks5.Request) {
glog
.
V
(
LINFO
)
.
Infof
(
"[socks5-bind] %s >-< %s"
,
s
.
conn
.
RemoteAddr
(),
cc
.
RemoteAddr
())
glog
.
V
(
LINFO
)
.
Infof
(
"[socks5-bind] %s >-< %s"
,
s
.
conn
.
RemoteAddr
(),
cc
.
RemoteAddr
())
}
}
func
(
s
*
Socks5Server
)
handleUDPConnect
(
req
*
gosocks5
.
Request
)
{
cc
,
err
:=
s
.
Base
.
Chain
.
GetConn
()
// connection error
if
err
!=
nil
&&
err
!=
ErrEmptyChain
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
,
err
)
reply
:=
gosocks5
.
NewReply
(
gosocks5
.
Failure
,
nil
)
reply
.
Write
(
s
.
conn
)
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp] %s <- %s
\n
%s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
,
reply
)
return
}
// serve udp connect
if
err
==
ErrEmptyChain
{
s
.
udpConnect
(
req
.
Addr
.
String
())
return
}
defer
cc
.
Close
()
// forward request
if
err
:=
req
.
Write
(
cc
);
err
!=
nil
{
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s -> %s : %s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
,
err
)
gosocks5
.
NewReply
(
gosocks5
.
Failure
,
nil
)
.
Write
(
s
.
conn
)
return
}
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s <-> %s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
)
s
.
Base
.
transport
(
s
.
conn
,
cc
)
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s >-< %s"
,
s
.
conn
.
RemoteAddr
(),
req
.
Addr
)
}
func
(
s
*
Socks5Server
)
handleUDPRelay
(
req
*
gosocks5
.
Request
)
{
func
(
s
*
Socks5Server
)
handleUDPRelay
(
req
*
gosocks5
.
Request
)
{
bindAddr
,
_
:=
net
.
ResolveUDPAddr
(
"udp"
,
req
.
Addr
.
String
())
bindAddr
,
_
:=
net
.
ResolveUDPAddr
(
"udp"
,
req
.
Addr
.
String
())
relay
,
err
:=
net
.
ListenUDP
(
"udp"
,
bindAddr
)
// udp associate, strict mode: if the port already in use, it will return error
relay
,
err
:=
net
.
ListenUDP
(
"udp"
,
bindAddr
)
// udp associate, strict mode: if the port already in use, it will return error
...
@@ -506,65 +469,6 @@ func (s *Socks5Server) bindOn(addr string) {
...
@@ -506,65 +469,6 @@ func (s *Socks5Server) bindOn(addr string) {
}
}
}
}
func
(
s
*
Socks5Server
)
udpConnect
(
addr
string
)
{
raddr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
addr
)
if
err
!=
nil
{
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s -> %s : %s"
,
s
.
conn
.
RemoteAddr
(),
addr
,
err
)
gosocks5
.
NewReply
(
gosocks5
.
Failure
,
nil
)
.
Write
(
s
.
conn
)
return
}
if
err
:=
gosocks5
.
NewReply
(
gosocks5
.
Succeeded
,
nil
)
.
Write
(
s
.
conn
);
err
!=
nil
{
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s <- %s : %s"
,
s
.
conn
.
RemoteAddr
(),
addr
,
err
)
return
}
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s <-> %s"
,
s
.
conn
.
RemoteAddr
(),
raddr
)
defer
glog
.
V
(
LINFO
)
.
Infof
(
"[udp] %s >-< %s"
,
s
.
conn
.
RemoteAddr
(),
raddr
)
for
{
dgram
,
err
:=
gosocks5
.
ReadUDPDatagram
(
s
.
conn
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
s
.
conn
.
RemoteAddr
(),
addr
,
err
)
return
}
go
func
()
{
b
:=
make
([]
byte
,
LargeBufferSize
)
relay
,
err
:=
net
.
DialUDP
(
"udp"
,
nil
,
raddr
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
s
.
conn
.
RemoteAddr
(),
raddr
,
err
)
return
}
defer
relay
.
Close
()
if
_
,
err
:=
relay
.
Write
(
dgram
.
Data
);
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s -> %s : %s"
,
s
.
conn
.
RemoteAddr
(),
raddr
,
err
)
return
}
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp-tun] %s >>> %s length: %d"
,
s
.
conn
.
RemoteAddr
(),
raddr
,
len
(
dgram
.
Data
))
relay
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
time
.
Second
*
60
))
n
,
err
:=
relay
.
Read
(
b
)
if
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
s
.
conn
.
RemoteAddr
(),
raddr
,
err
)
return
}
relay
.
SetReadDeadline
(
time
.
Time
{})
glog
.
V
(
LDEBUG
)
.
Infof
(
"[udp-tun] %s <<< %s length: %d"
,
s
.
conn
.
RemoteAddr
(),
raddr
,
n
)
s
.
conn
.
SetWriteDeadline
(
time
.
Now
()
.
Add
(
time
.
Second
*
90
))
if
err
:=
gosocks5
.
NewUDPDatagram
(
gosocks5
.
NewUDPHeader
(
uint16
(
n
),
0
,
dgram
.
Header
.
Addr
),
b
[
:
n
])
.
Write
(
s
.
conn
);
err
!=
nil
{
glog
.
V
(
LWARNING
)
.
Infof
(
"[udp] %s <- %s : %s"
,
s
.
conn
.
RemoteAddr
(),
raddr
,
err
)
return
}
s
.
conn
.
SetWriteDeadline
(
time
.
Time
{})
}()
}
}
func
(
s
*
Socks5Server
)
transportUDP
(
relay
,
peer
*
net
.
UDPConn
)
(
err
error
)
{
func
(
s
*
Socks5Server
)
transportUDP
(
relay
,
peer
*
net
.
UDPConn
)
(
err
error
)
{
errc
:=
make
(
chan
error
,
2
)
errc
:=
make
(
chan
error
,
2
)
...
...
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