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
b11ce8a7
Commit
b11ce8a7
authored
Dec 26, 2019
by
ginuerzh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add tun device support (#420)
parent
54147689
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
368 additions
and
11 deletions
+368
-11
cmd/gost/route.go
cmd/gost/route.go
+9
-0
go.mod
go.mod
+1
-0
go.sum
go.sum
+2
-0
gost.go
gost.go
+5
-3
handler.go
handler.go
+8
-0
node.go
node.go
+2
-0
server.go
server.go
+0
-8
tun.go
tun.go
+341
-0
No files found.
cmd/gost/route.go
View file @
b11ce8a7
...
@@ -372,6 +372,8 @@ func (r *route) GenRouters() ([]router, error) {
...
@@ -372,6 +372,8 @@ func (r *route) GenRouters() ([]router, error) {
ln
,
err
=
gost
.
Obfs4Listener
(
node
.
Addr
)
ln
,
err
=
gost
.
Obfs4Listener
(
node
.
Addr
)
case
"ohttp"
:
case
"ohttp"
:
ln
,
err
=
gost
.
ObfsHTTPListener
(
node
.
Addr
)
ln
,
err
=
gost
.
ObfsHTTPListener
(
node
.
Addr
)
case
"tun"
:
ln
,
err
=
gost
.
TunListener
(
node
.
Addr
)
default
:
default
:
ln
,
err
=
gost
.
TCPListener
(
node
.
Addr
)
ln
,
err
=
gost
.
TCPListener
(
node
.
Addr
)
}
}
...
@@ -409,6 +411,13 @@ func (r *route) GenRouters() ([]router, error) {
...
@@ -409,6 +411,13 @@ func (r *route) GenRouters() ([]router, error) {
handler
=
gost
.
ShadowUDPdHandler
()
handler
=
gost
.
ShadowUDPdHandler
()
case
"sni"
:
case
"sni"
:
handler
=
gost
.
SNIHandler
()
handler
=
gost
.
SNIHandler
()
case
"tun"
:
cfg
:=
gost
.
TunConfig
{
Name
:
node
.
Get
(
"name"
),
Addr
:
node
.
Get
(
"net"
),
MTU
:
node
.
GetInt
(
"mtu"
),
}
handler
=
gost
.
TunHandler
(
node
.
Remote
,
gost
.
TunConfigHandlerOption
(
cfg
))
default
:
default
:
// start from 2.5, if remote is not empty, then we assume that it is a forward tunnel.
// start from 2.5, if remote is not empty, then we assume that it is a forward tunnel.
if
node
.
Remote
!=
""
{
if
node
.
Remote
!=
""
{
...
...
go.mod
View file @
b11ce8a7
...
@@ -31,6 +31,7 @@ require (
...
@@ -31,6 +31,7 @@ require (
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735
github.com/shadowsocks/go-shadowsocks2 v0.0.11
github.com/shadowsocks/go-shadowsocks2 v0.0.11
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
github.com/tjfoc/gmsm v1.0.1 // indirect
github.com/tjfoc/gmsm v1.0.1 // indirect
...
...
go.sum
View file @
b11ce8a7
...
@@ -65,6 +65,8 @@ github.com/shadowsocks/go-shadowsocks2 v0.0.11 h1:dXloqEhYnZV40jblWTK8kWeC0Eb+dg
...
@@ -65,6 +65,8 @@ github.com/shadowsocks/go-shadowsocks2 v0.0.11 h1:dXloqEhYnZV40jblWTK8kWeC0Eb+dg
github.com/shadowsocks/go-shadowsocks2 v0.0.11/go.mod h1:R+KWaoIwRRhnpw6XV+dZil0XHi64Hc1D7hXUyXTjUzQ=
github.com/shadowsocks/go-shadowsocks2 v0.0.11/go.mod h1:R+KWaoIwRRhnpw6XV+dZil0XHi64Hc1D7hXUyXTjUzQ=
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba h1:tJgNXb3S+RkB4kNPi6N5OmEWe3m+Y3Qs6LUMiNDAONM=
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba h1:tJgNXb3S+RkB4kNPi6N5OmEWe3m+Y3Qs6LUMiNDAONM=
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba/go.mod h1:mttDPaeLm87u74HMrP+n2tugXvIKWcwff/cqSX0lehY=
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba/go.mod h1:mttDPaeLm87u74HMrP+n2tugXvIKWcwff/cqSX0lehY=
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b h1:+y4hCMc/WKsDbAPsOQZgBSaSZ26uh2afyaWeVg/3s/c=
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b h1:mnG1fcsIB1d/3vbkBak2MM0u+vhGhlQwpeimUi7QncM=
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b h1:mnG1fcsIB1d/3vbkBak2MM0u+vhGhlQwpeimUi7QncM=
...
...
gost.go
View file @
b11ce8a7
...
@@ -20,14 +20,14 @@ import (
...
@@ -20,14 +20,14 @@ import (
)
)
// Version is the gost version.
// Version is the gost version.
const
Version
=
"2.
8.2
"
const
Version
=
"2.
9.0-dev
"
// Debug is a flag that enables the debug log.
// Debug is a flag that enables the debug log.
var
Debug
bool
var
Debug
bool
var
(
var
(
tinyBufferSize
=
128
tinyBufferSize
=
512
smallBufferSize
=
1
*
1024
// 1
KB small buffer
smallBufferSize
=
2
*
1024
// 2
KB small buffer
mediumBufferSize
=
8
*
1024
// 8KB medium buffer
mediumBufferSize
=
8
*
1024
// 8KB medium buffer
largeBufferSize
=
32
*
1024
// 32KB large buffer
largeBufferSize
=
32
*
1024
// 32KB large buffer
)
)
...
@@ -77,6 +77,8 @@ var (
...
@@ -77,6 +77,8 @@ var (
// DefaultUserAgent is the default HTTP User-Agent header used by HTTP and websocket.
// DefaultUserAgent is the default HTTP User-Agent header used by HTTP and websocket.
DefaultUserAgent
=
"Chrome/78.0.3904.106"
DefaultUserAgent
=
"Chrome/78.0.3904.106"
DefaultMTU
=
1350
// default mtu for tun device
)
)
// SetLogger sets a new logger for internal log system.
// SetLogger sets a new logger for internal log system.
...
...
handler.go
View file @
b11ce8a7
...
@@ -40,6 +40,7 @@ type HandlerOptions struct {
...
@@ -40,6 +40,7 @@ type HandlerOptions struct {
Node
Node
Node
Node
Host
string
Host
string
IPs
[]
string
IPs
[]
string
TunConfig
TunConfig
}
}
// HandlerOption allows a common way to set handler options.
// HandlerOption allows a common way to set handler options.
...
@@ -195,6 +196,13 @@ func IPsHandlerOption(ips []string) HandlerOption {
...
@@ -195,6 +196,13 @@ func IPsHandlerOption(ips []string) HandlerOption {
}
}
}
}
// TunConfigHandlerOption sets the config for tun device.
func
TunConfigHandlerOption
(
cfg
TunConfig
)
HandlerOption
{
return
func
(
opts
*
HandlerOptions
)
{
opts
.
TunConfig
=
cfg
}
}
type
autoHandler
struct
{
type
autoHandler
struct
{
options
*
HandlerOptions
options
*
HandlerOptions
}
}
...
...
node.go
View file @
b11ce8a7
...
@@ -82,6 +82,7 @@ func ParseNode(s string) (node Node, err error) {
...
@@ -82,6 +82,7 @@ func ParseNode(s string) (node Node, err error) {
case
"tcp"
,
"udp"
:
// started from v2.1, tcp and udp are for local port forwarding
case
"tcp"
,
"udp"
:
// started from v2.1, tcp and udp are for local port forwarding
case
"rtcp"
,
"rudp"
:
// rtcp and rudp are for remote port forwarding
case
"rtcp"
,
"rudp"
:
// rtcp and rudp are for remote port forwarding
case
"ohttp"
:
// obfs-http
case
"ohttp"
:
// obfs-http
case
"tun"
:
//tun device
default
:
default
:
node
.
Transport
=
"tcp"
node
.
Transport
=
"tcp"
}
}
...
@@ -93,6 +94,7 @@ func ParseNode(s string) (node Node, err error) {
...
@@ -93,6 +94,7 @@ func ParseNode(s string) (node Node, err error) {
case
"tcp"
,
"udp"
,
"rtcp"
,
"rudp"
:
// port forwarding
case
"tcp"
,
"udp"
,
"rtcp"
,
"rudp"
:
// port forwarding
case
"direct"
,
"remote"
,
"forward"
:
// forwarding
case
"direct"
,
"remote"
,
"forward"
:
// forwarding
case
"redirect"
:
// TCP transparent proxy
case
"redirect"
:
// TCP transparent proxy
case
"tun"
:
// tun device
default
:
default
:
node
.
Protocol
=
""
node
.
Protocol
=
""
}
}
...
...
server.go
View file @
b11ce8a7
...
@@ -81,14 +81,6 @@ func (s *Server) Serve(h Handler, opts ...ServerOption) error {
...
@@ -81,14 +81,6 @@ func (s *Server) Serve(h Handler, opts ...ServerOption) error {
}
}
tempDelay
=
0
tempDelay
=
0
/*
if s.options.Bypass.Contains(conn.RemoteAddr().String()) {
log.Log("[bypass]", conn.RemoteAddr())
conn.Close()
continue
}
*/
go
h
.
Handle
(
conn
)
go
h
.
Handle
(
conn
)
}
}
}
}
...
...
tun.go
0 → 100644
View file @
b11ce8a7
package
gost
import
(
"errors"
"io"
"net"
"os"
"os/exec"
"strconv"
"sync"
"time"
"github.com/go-log/log"
"github.com/shadowsocks/go-shadowsocks2/core"
"github.com/songgao/water"
"golang.org/x/net/ipv4"
)
type
TunConfig
struct
{
Name
string
Addr
string
MTU
int
Routes
[]
string
}
type
tunHandler
struct
{
raddr
string
options
*
HandlerOptions
}
// TunHandler creates a handler for tun tunnel.
func
TunHandler
(
raddr
string
,
opts
...
HandlerOption
)
Handler
{
h
:=
&
tunHandler
{
raddr
:
raddr
,
options
:
&
HandlerOptions
{},
}
for
_
,
opt
:=
range
opts
{
opt
(
h
.
options
)
}
return
h
}
func
(
h
*
tunHandler
)
Init
(
options
...
HandlerOption
)
{
if
h
.
options
==
nil
{
h
.
options
=
&
HandlerOptions
{}
}
for
_
,
opt
:=
range
options
{
opt
(
h
.
options
)
}
}
func
(
h
*
tunHandler
)
Handle
(
conn
net
.
Conn
)
{
defer
os
.
Exit
(
0
)
defer
conn
.
Close
()
uc
,
ok
:=
conn
.
(
net
.
PacketConn
)
if
!
ok
{
log
.
Log
(
"[tun] wrong connection type, must be PacketConn"
)
return
}
tc
,
err
:=
h
.
createTun
()
if
err
!=
nil
{
log
.
Logf
(
"[tun] %s create tun: %v"
,
conn
.
LocalAddr
(),
err
)
return
}
defer
tc
.
Close
()
log
.
Logf
(
"[tun] %s - %s: tun creation successful"
,
tc
.
LocalAddr
(),
conn
.
LocalAddr
())
var
raddr
net
.
Addr
if
h
.
raddr
!=
""
{
raddr
,
err
=
net
.
ResolveUDPAddr
(
"udp"
,
h
.
raddr
)
if
err
!=
nil
{
log
.
Logf
(
"[tun] %s - %s remote addr: %v"
,
tc
.
LocalAddr
(),
conn
.
LocalAddr
(),
err
)
return
}
}
if
len
(
h
.
options
.
Users
)
>
0
&&
h
.
options
.
Users
[
0
]
!=
nil
{
passwd
,
_
:=
h
.
options
.
Users
[
0
]
.
Password
()
cipher
,
err
:=
core
.
PickCipher
(
h
.
options
.
Users
[
0
]
.
Username
(),
nil
,
passwd
)
if
err
!=
nil
{
log
.
Logf
(
"[tun] %s - %s cipher: %v"
,
tc
.
LocalAddr
(),
conn
.
LocalAddr
(),
err
)
return
}
uc
=
cipher
.
PacketConn
(
uc
)
}
h
.
transportTun
(
tc
,
uc
,
raddr
)
}
func
(
h
*
tunHandler
)
createTun
()
(
conn
net
.
Conn
,
err
error
)
{
cfg
:=
h
.
options
.
TunConfig
ip
,
_
,
err
:=
net
.
ParseCIDR
(
cfg
.
Addr
)
if
err
!=
nil
{
return
}
ifce
,
err
:=
water
.
New
(
water
.
Config
{
DeviceType
:
water
.
TUN
,
PlatformSpecificParams
:
water
.
PlatformSpecificParams
{
Name
:
cfg
.
Name
,
},
})
if
err
!=
nil
{
return
}
setup
:=
func
(
args
...
string
)
error
{
cmd
:=
exec
.
Command
(
"/sbin/ip"
,
args
...
)
cmd
.
Stdout
=
os
.
Stdout
cmd
.
Stderr
=
os
.
Stderr
return
cmd
.
Run
()
}
mtu
:=
cfg
.
MTU
if
mtu
<=
0
{
mtu
=
DefaultMTU
}
if
err
=
setup
(
"link"
,
"set"
,
"dev"
,
ifce
.
Name
(),
"mtu"
,
strconv
.
Itoa
(
mtu
));
err
!=
nil
{
return
}
if
err
=
setup
(
"addr"
,
"add"
,
cfg
.
Addr
,
"dev"
,
ifce
.
Name
());
err
!=
nil
{
return
}
if
err
=
setup
(
"link"
,
"set"
,
"dev"
,
ifce
.
Name
(),
"up"
);
err
!=
nil
{
return
}
tc
:=
&
tunConn
{
ifce
:
ifce
,
addr
:
&
net
.
IPAddr
{
IP
:
ip
},
}
return
tc
,
nil
}
func
(
h
*
tunHandler
)
transportTun
(
tun
net
.
Conn
,
conn
net
.
PacketConn
,
raddr
net
.
Addr
)
error
{
var
routes
sync
.
Map
errc
:=
make
(
chan
error
,
1
)
go
func
()
{
for
{
err
:=
func
()
error
{
b
:=
sPool
.
Get
()
.
([]
byte
)
defer
sPool
.
Put
(
b
)
n
,
err
:=
tun
.
Read
(
b
)
if
err
!=
nil
{
return
err
}
header
,
err
:=
ipv4
.
ParseHeader
(
b
[
:
n
])
if
err
!=
nil
{
log
.
Logf
(
"[tun] %s: %v"
,
tun
.
LocalAddr
(),
err
)
return
err
}
if
header
.
Version
!=
ipv4
.
Version
{
log
.
Logf
(
"[tun] %s: v%d ignored, only support ipv4"
,
tun
.
LocalAddr
(),
header
.
Version
)
return
nil
}
addr
:=
raddr
if
v
,
ok
:=
routes
.
Load
(
header
.
Dst
.
String
());
ok
{
addr
=
v
.
(
net
.
Addr
)
}
if
addr
==
nil
{
log
.
Logf
(
"[tun] %s: no address to forward for %s -> %s"
,
tun
.
LocalAddr
(),
header
.
Src
,
header
.
Dst
)
return
nil
}
if
Debug
{
log
.
Logf
(
"[tun] %s >>> %s: %s -> %s %d/%d %x %x %d"
,
tun
.
LocalAddr
(),
addr
,
header
.
Src
,
header
.
Dst
,
header
.
Len
,
header
.
TotalLen
,
header
.
ID
,
header
.
Flags
,
header
.
Protocol
)
}
if
_
,
err
:=
conn
.
WriteTo
(
b
[
:
n
],
addr
);
err
!=
nil
{
return
err
}
return
nil
}()
if
err
!=
nil
{
errc
<-
err
return
}
}
}()
go
func
()
{
for
{
err
:=
func
()
error
{
b
:=
sPool
.
Get
()
.
([]
byte
)
defer
mPool
.
Put
(
b
)
n
,
addr
,
err
:=
conn
.
ReadFrom
(
b
)
if
err
!=
nil
{
return
err
}
header
,
err
:=
ipv4
.
ParseHeader
(
b
[
:
n
])
if
err
!=
nil
{
log
.
Logf
(
"[tun] %s <- %s: %v"
,
tun
.
LocalAddr
(),
addr
,
err
)
return
err
}
if
header
.
Version
!=
ipv4
.
Version
{
log
.
Logf
(
"[tun] %s <- %s: v%d ignored, only support ipv4"
,
tun
.
LocalAddr
(),
addr
,
header
.
Version
)
return
nil
}
if
Debug
{
log
.
Logf
(
"[tun] %s <<< %s: %s -> %s %d/%d %x %x %d"
,
tun
.
LocalAddr
(),
addr
,
header
.
Src
,
header
.
Dst
,
header
.
Len
,
header
.
TotalLen
,
header
.
ID
,
header
.
Flags
,
header
.
Protocol
)
}
if
actual
,
loaded
:=
routes
.
LoadOrStore
(
header
.
Src
.
String
(),
addr
);
loaded
{
if
actual
.
(
net
.
Addr
)
.
String
()
!=
addr
.
String
()
{
log
.
Logf
(
"[tun] %s <- %s: unexpected address mapping %s -> %s(actual %s)"
,
tun
.
LocalAddr
(),
addr
,
header
.
Dst
.
String
(),
addr
,
actual
.
(
net
.
Addr
)
.
String
())
}
}
if
_
,
err
:=
tun
.
Write
(
b
[
:
n
]);
err
!=
nil
{
return
err
}
return
nil
}()
if
err
!=
nil
{
errc
<-
err
return
}
}
}()
err
:=
<-
errc
if
err
!=
nil
&&
err
==
io
.
EOF
{
err
=
nil
}
log
.
Logf
(
"[tun] %s - %s: %v"
,
tun
.
LocalAddr
(),
conn
.
LocalAddr
(),
err
)
return
err
}
type
tunConn
struct
{
ifce
*
water
.
Interface
addr
net
.
Addr
}
func
(
c
*
tunConn
)
Read
(
b
[]
byte
)
(
n
int
,
err
error
)
{
return
c
.
ifce
.
Read
(
b
)
}
func
(
c
*
tunConn
)
Write
(
b
[]
byte
)
(
n
int
,
err
error
)
{
return
c
.
ifce
.
Write
(
b
)
}
func
(
c
*
tunConn
)
Close
()
(
err
error
)
{
return
c
.
ifce
.
Close
()
}
func
(
c
*
tunConn
)
LocalAddr
()
net
.
Addr
{
return
c
.
addr
}
func
(
c
*
tunConn
)
RemoteAddr
()
net
.
Addr
{
return
&
net
.
IPAddr
{}
}
func
(
c
*
tunConn
)
SetDeadline
(
t
time
.
Time
)
error
{
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"tun"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
}
func
(
c
*
tunConn
)
SetReadDeadline
(
t
time
.
Time
)
error
{
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"tun"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
}
func
(
c
*
tunConn
)
SetWriteDeadline
(
t
time
.
Time
)
error
{
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"tun"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
}
type
tunListener
struct
{
conn
*
net
.
UDPConn
accepted
,
closed
chan
struct
{}
}
// TunListener creates a listener for tun tunnel.
func
TunListener
(
addr
string
)
(
Listener
,
error
)
{
laddr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
addr
)
if
err
!=
nil
{
return
nil
,
err
}
conn
,
err
:=
net
.
ListenUDP
(
"udp"
,
laddr
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
tunListener
{
conn
:
conn
,
accepted
:
make
(
chan
struct
{}),
closed
:
make
(
chan
struct
{}),
},
nil
}
func
(
l
*
tunListener
)
Accept
()
(
net
.
Conn
,
error
)
{
select
{
case
<-
l
.
accepted
:
default
:
close
(
l
.
accepted
)
return
l
.
conn
,
nil
}
select
{
case
<-
l
.
closed
:
}
return
nil
,
errors
.
New
(
"accept on closed listener"
)
}
func
(
l
*
tunListener
)
Addr
()
net
.
Addr
{
return
l
.
conn
.
LocalAddr
()
}
func
(
l
*
tunListener
)
Close
()
error
{
select
{
case
<-
l
.
closed
:
return
errors
.
New
(
"listener has been closed"
)
default
:
close
(
l
.
closed
)
}
return
nil
}
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