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
bde4217c
Commit
bde4217c
authored
Jan 01, 2020
by
ginuerzh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add support for tap device
parent
355847fa
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
493 additions
and
39 deletions
+493
-39
cmd/gost/route.go
cmd/gost/route.go
+10
-0
handler.go
handler.go
+8
-0
node.go
node.go
+2
-2
tuntap.go
tuntap.go
+259
-26
tuntap_darwin.go
tuntap_darwin.go
+7
-3
tuntap_linux.go
tuntap_linux.go
+62
-4
tuntap_unix.go
tuntap_unix.go
+102
-0
tuntap_windows.go
tuntap_windows.go
+43
-4
No files found.
cmd/gost/route.go
View file @
bde4217c
...
...
@@ -396,6 +396,8 @@ func (r *route) GenRouters() ([]router, error) {
ln
,
err
=
gost
.
ObfsHTTPListener
(
node
.
Addr
)
case
"tun"
:
ln
,
err
=
gost
.
TunListener
(
node
.
Addr
)
case
"tap"
:
ln
,
err
=
gost
.
TapListener
(
node
.
Addr
)
default
:
ln
,
err
=
gost
.
TCPListener
(
node
.
Addr
)
}
...
...
@@ -441,6 +443,14 @@ func (r *route) GenRouters() ([]router, error) {
Routes
:
strings
.
Split
(
node
.
Get
(
"route"
),
","
),
}
handler
=
gost
.
TunHandler
(
node
.
Remote
,
gost
.
TunConfigHandlerOption
(
cfg
))
case
"tap"
:
cfg
:=
gost
.
TapConfig
{
Name
:
node
.
Get
(
"name"
),
Addr
:
node
.
Get
(
"net"
),
MTU
:
node
.
GetInt
(
"mtu"
),
Routes
:
strings
.
Split
(
node
.
Get
(
"route"
),
","
),
}
handler
=
gost
.
TapHandler
(
node
.
Remote
,
gost
.
TapConfigHandlerOption
(
cfg
))
default
:
// start from 2.5, if remote is not empty, then we assume that it is a forward tunnel.
if
node
.
Remote
!=
""
{
...
...
handler.go
View file @
bde4217c
...
...
@@ -41,6 +41,7 @@ type HandlerOptions struct {
Host
string
IPs
[]
string
TunConfig
TunConfig
TapConfig
TapConfig
}
// HandlerOption allows a common way to set handler options.
...
...
@@ -203,6 +204,13 @@ func TunConfigHandlerOption(cfg TunConfig) HandlerOption {
}
}
// TapConfigHandlerOption sets the config for tap device.
func
TapConfigHandlerOption
(
cfg
TapConfig
)
HandlerOption
{
return
func
(
opts
*
HandlerOptions
)
{
opts
.
TapConfig
=
cfg
}
}
type
autoHandler
struct
{
options
*
HandlerOptions
}
...
...
node.go
View file @
bde4217c
...
...
@@ -82,7 +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
"rtcp"
,
"rudp"
:
// rtcp and rudp are for remote port forwarding
case
"ohttp"
:
// obfs-http
case
"tun"
:
//tun
device
case
"tun"
,
"tap"
:
// tun/tap
device
default
:
node
.
Transport
=
"tcp"
}
...
...
@@ -94,7 +94,7 @@ func ParseNode(s string) (node Node, err error) {
case
"tcp"
,
"udp"
,
"rtcp"
,
"rudp"
:
// port forwarding
case
"direct"
,
"remote"
,
"forward"
:
// forwarding
case
"redirect"
:
// TCP transparent proxy
case
"tun"
:
// tun
device
case
"tun"
,
"tap"
:
// tun/tap
device
default
:
node
.
Protocol
=
""
}
...
...
tun.go
→
tun
tap
.go
View file @
bde4217c
...
...
@@ -11,6 +11,7 @@ import (
"github.com/go-log/log"
"github.com/shadowsocks/go-shadowsocks2/core"
"github.com/songgao/water"
"github.com/songgao/water/waterutil"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
)
...
...
@@ -227,58 +228,253 @@ func (h *tunHandler) transportTun(tun net.Conn, conn net.PacketConn, raddr net.A
return
err
}
type
tunConn
struct
{
ifce
*
water
.
Interface
addr
net
.
Addr
type
tunListener
struct
{
addr
net
.
Addr
conns
chan
net
.
Conn
closed
chan
struct
{}
}
func
(
c
*
tunConn
)
Read
(
b
[]
byte
)
(
n
int
,
err
error
)
{
return
c
.
ifce
.
Read
(
b
)
// 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
}
threads
:=
1
ln
:=
&
tunListener
{
addr
:
laddr
,
conns
:
make
(
chan
net
.
Conn
,
threads
),
closed
:
make
(
chan
struct
{}),
}
for
i
:=
0
;
i
<
threads
;
i
++
{
conn
,
err
:=
net
.
ListenUDP
(
"udp"
,
laddr
)
if
err
!=
nil
{
return
nil
,
err
}
ln
.
conns
<-
conn
}
return
ln
,
nil
}
func
(
c
*
tunConn
)
Write
(
b
[]
byte
)
(
n
int
,
err
error
)
{
return
c
.
ifce
.
Write
(
b
)
func
(
l
*
tunListener
)
Accept
()
(
net
.
Conn
,
error
)
{
select
{
case
conn
:=
<-
l
.
conns
:
return
conn
,
nil
case
<-
l
.
closed
:
}
return
nil
,
errors
.
New
(
"accept on closed listener"
)
}
func
(
c
*
tunConn
)
Close
()
(
err
error
)
{
return
c
.
ifce
.
Close
()
func
(
l
*
tunListener
)
Addr
()
net
.
Addr
{
return
l
.
addr
}
func
(
c
*
tunConn
)
LocalAddr
()
net
.
Addr
{
return
c
.
addr
func
(
l
*
tunListener
)
Close
()
error
{
select
{
case
<-
l
.
closed
:
return
errors
.
New
(
"listener has been closed"
)
default
:
close
(
l
.
closed
)
}
return
nil
}
func
(
c
*
tunConn
)
RemoteAddr
()
net
.
Addr
{
return
&
net
.
IPAddr
{}
type
TapConfig
struct
{
Name
string
Addr
string
MTU
int
Routes
[]
string
}
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"
)}
type
tapHandler
struct
{
raddr
string
options
*
HandlerOptions
ipNet
*
net
.
IPNet
routes
sync
.
Map
}
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"
)}
// TapHandler creates a handler for tap tunnel.
func
TapHandler
(
raddr
string
,
opts
...
HandlerOption
)
Handler
{
h
:=
&
tapHandler
{
raddr
:
raddr
,
options
:
&
HandlerOptions
{},
}
for
_
,
opt
:=
range
opts
{
opt
(
h
.
options
)
}
return
h
}
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"
)}
func
(
h
*
tapHandler
)
Init
(
options
...
HandlerOption
)
{
if
h
.
options
==
nil
{
h
.
options
=
&
HandlerOptions
{}
}
for
_
,
opt
:=
range
options
{
opt
(
h
.
options
)
}
}
type
tunListener
struct
{
func
(
h
*
tapHandler
)
Handle
(
conn
net
.
Conn
)
{
defer
os
.
Exit
(
0
)
defer
conn
.
Close
()
uc
,
ok
:=
conn
.
(
net
.
PacketConn
)
if
!
ok
{
log
.
Log
(
"[tap] wrong connection type, must be PacketConn"
)
return
}
tc
,
err
:=
h
.
createTap
()
if
err
!=
nil
{
log
.
Logf
(
"[tap] %s create tap: %v"
,
conn
.
LocalAddr
(),
err
)
return
}
defer
tc
.
Close
()
log
.
Logf
(
"[tap] %s - %s: tap 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
(
"[tap] %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
(
"[tap] %s - %s cipher: %v"
,
tc
.
LocalAddr
(),
conn
.
LocalAddr
(),
err
)
return
}
uc
=
cipher
.
PacketConn
(
uc
)
}
h
.
transportTap
(
tc
,
uc
,
raddr
)
}
func
(
h
*
tapHandler
)
createTap
()
(
conn
net
.
Conn
,
err
error
)
{
conn
,
h
.
ipNet
,
err
=
createTap
(
h
.
options
.
TapConfig
)
return
}
func
(
h
*
tapHandler
)
transportTap
(
tap
net
.
Conn
,
conn
net
.
PacketConn
,
raddr
net
.
Addr
)
error
{
errc
:=
make
(
chan
error
,
1
)
go
func
()
{
for
{
err
:=
func
()
error
{
b
:=
sPool
.
Get
()
.
([]
byte
)
defer
sPool
.
Put
(
b
)
n
,
err
:=
tap
.
Read
(
b
)
if
err
!=
nil
{
return
err
}
macSrc
:=
waterutil
.
MACSource
(
b
[
:
n
])
macDst
:=
waterutil
.
MACDestination
(
b
[
:
n
])
addr
:=
raddr
if
v
,
ok
:=
h
.
routes
.
Load
(
macDst
.
String
());
ok
{
addr
=
v
.
(
net
.
Addr
)
}
if
addr
==
nil
{
log
.
Logf
(
"[tap] %s: no route for %s -> %s %d %d"
,
tap
.
LocalAddr
(),
macSrc
,
macDst
,
n
,
waterutil
.
MACEthertype
(
b
[
:
n
]))
return
nil
}
if
Debug
{
log
.
Logf
(
"[tap] %s >>> %s: %s -> %s %d %d"
,
tap
.
LocalAddr
(),
addr
,
macSrc
,
macDst
,
n
,
waterutil
.
MACEthertype
(
b
[
:
n
]))
}
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
}
macSrc
:=
waterutil
.
MACSource
(
b
[
:
n
])
macDst
:=
waterutil
.
MACDestination
(
b
[
:
n
])
if
Debug
{
log
.
Logf
(
"[tap] %s <<< %s: %s -> %s %d %d"
,
tap
.
LocalAddr
(),
addr
,
macSrc
,
macDst
,
n
,
waterutil
.
MACEthertype
(
b
[
:
n
]))
}
if
actual
,
loaded
:=
h
.
routes
.
LoadOrStore
(
macSrc
.
String
(),
addr
);
loaded
{
if
actual
.
(
net
.
Addr
)
.
String
()
!=
addr
.
String
()
{
log
.
Logf
(
"[tap] %s <- %s: update route: %s -> %s (old %s)"
,
tap
.
LocalAddr
(),
addr
,
macSrc
,
addr
,
actual
.
(
net
.
Addr
))
h
.
routes
.
Store
(
macSrc
.
String
(),
addr
)
}
}
else
{
log
.
Logf
(
"[tap] %s: new route: %s -> %s"
,
tap
.
LocalAddr
(),
macSrc
,
addr
)
}
if
_
,
err
:=
tap
.
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
(
"[tap] %s - %s: %v"
,
tap
.
LocalAddr
(),
conn
.
LocalAddr
(),
err
)
return
err
}
type
tapListener
struct
{
addr
net
.
Addr
conns
chan
net
.
Conn
closed
chan
struct
{}
}
// T
unListener creates a listener for tun
tunnel.
func
T
un
Listener
(
addr
string
)
(
Listener
,
error
)
{
// T
apListener creates a listener for tap
tunnel.
func
T
ap
Listener
(
addr
string
)
(
Listener
,
error
)
{
laddr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
addr
)
if
err
!=
nil
{
return
nil
,
err
}
threads
:=
1
ln
:=
&
t
un
Listener
{
ln
:=
&
t
ap
Listener
{
addr
:
laddr
,
conns
:
make
(
chan
net
.
Conn
,
threads
),
closed
:
make
(
chan
struct
{}),
...
...
@@ -295,7 +491,7 @@ func TunListener(addr string) (Listener, error) {
return
ln
,
nil
}
func
(
l
*
t
un
Listener
)
Accept
()
(
net
.
Conn
,
error
)
{
func
(
l
*
t
ap
Listener
)
Accept
()
(
net
.
Conn
,
error
)
{
select
{
case
conn
:=
<-
l
.
conns
:
return
conn
,
nil
...
...
@@ -305,11 +501,11 @@ func (l *tunListener) Accept() (net.Conn, error) {
return
nil
,
errors
.
New
(
"accept on closed listener"
)
}
func
(
l
*
t
un
Listener
)
Addr
()
net
.
Addr
{
func
(
l
*
t
ap
Listener
)
Addr
()
net
.
Addr
{
return
l
.
addr
}
func
(
l
*
t
un
Listener
)
Close
()
error
{
func
(
l
*
t
ap
Listener
)
Close
()
error
{
select
{
case
<-
l
.
closed
:
return
errors
.
New
(
"listener has been closed"
)
...
...
@@ -318,3 +514,40 @@ func (l *tunListener) Close() error {
}
return
nil
}
type
tunTapConn
struct
{
ifce
*
water
.
Interface
addr
net
.
Addr
}
func
(
c
*
tunTapConn
)
Read
(
b
[]
byte
)
(
n
int
,
err
error
)
{
return
c
.
ifce
.
Read
(
b
)
}
func
(
c
*
tunTapConn
)
Write
(
b
[]
byte
)
(
n
int
,
err
error
)
{
return
c
.
ifce
.
Write
(
b
)
}
func
(
c
*
tunTapConn
)
Close
()
(
err
error
)
{
return
c
.
ifce
.
Close
()
}
func
(
c
*
tunTapConn
)
LocalAddr
()
net
.
Addr
{
return
c
.
addr
}
func
(
c
*
tunTapConn
)
RemoteAddr
()
net
.
Addr
{
return
&
net
.
IPAddr
{}
}
func
(
c
*
tunTapConn
)
SetDeadline
(
t
time
.
Time
)
error
{
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"tuntap"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
}
func
(
c
*
tunTapConn
)
SetReadDeadline
(
t
time
.
Time
)
error
{
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"tuntap"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
}
func
(
c
*
tunTapConn
)
SetWriteDeadline
(
t
time
.
Time
)
error
{
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"tuntap"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
}
tun
_unix
.go
→
tun
tap_darwin
.go
View file @
bde4217c
// +build !linux,!windows
package
gost
import
(
"errors"
"fmt"
"net"
"os/exec"
...
...
@@ -42,13 +41,18 @@ func createTun(cfg TunConfig) (conn net.Conn, ipNet *net.IPNet, err error) {
return
}
conn
=
&
tunConn
{
conn
=
&
tun
Tap
Conn
{
ifce
:
ifce
,
addr
:
&
net
.
IPAddr
{
IP
:
ip
},
}
return
}
func
createTap
(
cfg
TapConfig
)
(
conn
net
.
Conn
,
ipNet
*
net
.
IPNet
,
err
error
)
{
err
=
errors
.
New
(
"tap is not supported on darwin"
)
return
}
func
addRoutes
(
ifName
string
,
routes
...
string
)
error
{
for
_
,
route
:=
range
routes
{
if
route
==
""
{
...
...
tun_linux.go
→
tun
tap
_linux.go
View file @
bde4217c
...
...
@@ -57,24 +57,82 @@ func createTun(cfg TunConfig) (conn net.Conn, ipNet *net.IPNet, err error) {
return
}
if
err
=
addRoutes
(
ifce
.
Name
(),
cfg
.
Routes
...
);
err
!=
nil
{
if
err
=
addRoutes
(
"tun"
,
ifce
.
Name
(),
cfg
.
Routes
...
);
err
!=
nil
{
return
}
conn
=
&
tunConn
{
conn
=
&
tun
Tap
Conn
{
ifce
:
ifce
,
addr
:
&
net
.
IPAddr
{
IP
:
ip
},
}
return
}
func
addRoutes
(
ifName
string
,
routes
...
string
)
error
{
func
createTap
(
cfg
TapConfig
)
(
conn
net
.
Conn
,
ipNet
*
net
.
IPNet
,
err
error
)
{
ip
,
ipNet
,
err
:=
net
.
ParseCIDR
(
cfg
.
Addr
)
if
err
!=
nil
{
return
}
ifce
,
err
:=
water
.
New
(
water
.
Config
{
DeviceType
:
water
.
TAP
,
PlatformSpecificParams
:
water
.
PlatformSpecificParams
{
Name
:
cfg
.
Name
,
},
})
if
err
!=
nil
{
return
}
link
,
err
:=
tenus
.
NewLinkFrom
(
ifce
.
Name
())
if
err
!=
nil
{
return
}
mtu
:=
cfg
.
MTU
if
mtu
<=
0
{
mtu
=
DefaultMTU
}
cmd
:=
fmt
.
Sprintf
(
"ip link set dev %s mtu %d"
,
ifce
.
Name
(),
mtu
)
log
.
Log
(
"[tap]"
,
cmd
)
if
er
:=
link
.
SetLinkMTU
(
mtu
);
er
!=
nil
{
err
=
fmt
.
Errorf
(
"%s: %v"
,
cmd
,
er
)
return
}
cmd
=
fmt
.
Sprintf
(
"ip address add %s dev %s"
,
cfg
.
Addr
,
ifce
.
Name
())
log
.
Log
(
"[tap]"
,
cmd
)
if
er
:=
link
.
SetLinkIp
(
ip
,
ipNet
);
er
!=
nil
{
err
=
fmt
.
Errorf
(
"%s: %v"
,
cmd
,
er
)
return
}
cmd
=
fmt
.
Sprintf
(
"ip link set dev %s up"
,
ifce
.
Name
())
log
.
Log
(
"[tap]"
,
cmd
)
if
er
:=
link
.
SetLinkUp
();
er
!=
nil
{
err
=
fmt
.
Errorf
(
"%s: %v"
,
cmd
,
er
)
return
}
if
err
=
addRoutes
(
"tap"
,
ifce
.
Name
(),
cfg
.
Routes
...
);
err
!=
nil
{
return
}
conn
=
&
tunTapConn
{
ifce
:
ifce
,
addr
:
&
net
.
IPAddr
{
IP
:
ip
},
}
return
}
func
addRoutes
(
ifType
,
ifName
string
,
routes
...
string
)
error
{
for
_
,
route
:=
range
routes
{
if
route
==
""
{
continue
}
cmd
:=
fmt
.
Sprintf
(
"ip route add %s dev %s"
,
route
,
ifName
)
log
.
Log
(
"[tun]"
,
cmd
)
log
.
Log
f
(
"[%s] %s"
,
ifType
,
cmd
)
if
err
:=
netlink
.
AddRoute
(
route
,
""
,
""
,
ifName
);
err
!=
nil
{
return
fmt
.
Errorf
(
"%s: %v"
,
cmd
,
err
)
}
...
...
tuntap_unix.go
0 → 100644
View file @
bde4217c
// +build !linux,!windows,!darwin
package
gost
import
(
"fmt"
"net"
"os/exec"
"strings"
"github.com/go-log/log"
"github.com/songgao/water"
)
func
createTun
(
cfg
TunConfig
)
(
conn
net
.
Conn
,
ipNet
*
net
.
IPNet
,
err
error
)
{
ip
,
ipNet
,
err
:=
net
.
ParseCIDR
(
cfg
.
Addr
)
if
err
!=
nil
{
return
}
ifce
,
err
:=
water
.
New
(
water
.
Config
{
DeviceType
:
water
.
TUN
,
})
if
err
!=
nil
{
return
}
mtu
:=
cfg
.
MTU
if
mtu
<=
0
{
mtu
=
DefaultMTU
}
cmd
:=
fmt
.
Sprintf
(
"ifconfig %s inet %s mtu %d up"
,
ifce
.
Name
(),
cfg
.
Addr
,
mtu
)
log
.
Log
(
"[tun]"
,
cmd
)
args
:=
strings
.
Split
(
cmd
,
" "
)
if
er
:=
exec
.
Command
(
args
[
0
],
args
[
1
:
]
...
)
.
Run
();
er
!=
nil
{
err
=
fmt
.
Errorf
(
"%s: %v"
,
cmd
,
er
)
return
}
if
err
=
addRoutes
(
"tun"
,
ifce
.
Name
(),
cfg
.
Routes
...
);
err
!=
nil
{
return
}
conn
=
&
tunTapConn
{
ifce
:
ifce
,
addr
:
&
net
.
IPAddr
{
IP
:
ip
},
}
return
}
func
createTap
(
cfg
TapConfig
)
(
conn
net
.
Conn
,
ipNet
*
net
.
IPNet
,
err
error
)
{
ip
,
ipNet
,
err
:=
net
.
ParseCIDR
(
cfg
.
Addr
)
if
err
!=
nil
{
return
}
ifce
,
err
:=
water
.
New
(
water
.
Config
{
DeviceType
:
water
.
TAP
,
})
if
err
!=
nil
{
return
}
mtu
:=
cfg
.
MTU
if
mtu
<=
0
{
mtu
=
DefaultMTU
}
cmd
:=
fmt
.
Sprintf
(
"ifconfig %s inet %s mtu %d up"
,
ifce
.
Name
(),
cfg
.
Addr
,
mtu
)
log
.
Log
(
"[tap]"
,
cmd
)
args
:=
strings
.
Split
(
cmd
,
" "
)
if
er
:=
exec
.
Command
(
args
[
0
],
args
[
1
:
]
...
)
.
Run
();
er
!=
nil
{
err
=
fmt
.
Errorf
(
"%s: %v"
,
cmd
,
er
)
return
}
if
err
=
addRoutes
(
"tap"
,
ifce
.
Name
(),
cfg
.
Routes
...
);
err
!=
nil
{
return
}
conn
=
&
tunTapConn
{
ifce
:
ifce
,
addr
:
&
net
.
IPAddr
{
IP
:
ip
},
}
return
}
func
addRoutes
(
ifType
,
ifName
string
,
routes
...
string
)
error
{
for
_
,
route
:=
range
routes
{
if
route
==
""
{
continue
}
cmd
:=
fmt
.
Sprintf
(
"route add -net %s -interface %s"
,
route
,
ifName
)
log
.
Logf
(
"[%s] %s"
,
ifType
,
cmd
)
args
:=
strings
.
Split
(
cmd
,
" "
)
if
er
:=
exec
.
Command
(
args
[
0
],
args
[
1
:
]
...
)
.
Run
();
er
!=
nil
{
return
fmt
.
Errorf
(
"%s: %v"
,
cmd
,
er
)
}
}
return
nil
}
tun_windows.go
→
tun
tap
_windows.go
View file @
bde4217c
...
...
@@ -38,18 +38,57 @@ func createTun(cfg TunConfig) (conn net.Conn, ipNet *net.IPNet, err error) {
return
}
if
err
=
addRoutes
(
ifce
.
Name
(),
cfg
.
Routes
...
);
err
!=
nil
{
if
err
=
addRoutes
(
"tun"
,
ifce
.
Name
(),
cfg
.
Routes
...
);
err
!=
nil
{
return
}
conn
=
&
tunConn
{
conn
=
&
tun
Tap
Conn
{
ifce
:
ifce
,
addr
:
&
net
.
IPAddr
{
IP
:
ip
},
}
return
}
func
addRoutes
(
ifName
string
,
routes
...
string
)
error
{
func
createTap
(
cfg
TapConfig
)
(
conn
net
.
Conn
,
ipNet
*
net
.
IPNet
,
err
error
)
{
ip
,
ipNet
,
err
:=
net
.
ParseCIDR
(
cfg
.
Addr
)
if
err
!=
nil
{
return
}
ifce
,
err
:=
water
.
New
(
water
.
Config
{
DeviceType
:
water
.
TAP
,
PlatformSpecificParams
:
water
.
PlatformSpecificParams
{
ComponentID
:
"tap0901"
,
InterfaceName
:
cfg
.
Name
,
Network
:
cfg
.
Addr
,
},
})
if
err
!=
nil
{
return
}
cmd
:=
fmt
.
Sprintf
(
"netsh interface ip set address name=%s "
+
"source=static addr=%s mask=%s gateway=none"
,
ifce
.
Name
(),
ip
.
String
(),
ipMask
(
ipNet
.
Mask
))
log
.
Log
(
"[tap]"
,
cmd
)
args
:=
strings
.
Split
(
cmd
,
" "
)
if
er
:=
exec
.
Command
(
args
[
0
],
args
[
1
:
]
...
)
.
Run
();
er
!=
nil
{
err
=
fmt
.
Errorf
(
"%s: %v"
,
cmd
,
er
)
return
}
if
err
=
addRoutes
(
"tap"
,
ifce
.
Name
(),
cfg
.
Routes
...
);
err
!=
nil
{
return
}
conn
=
&
tunTapConn
{
ifce
:
ifce
,
addr
:
&
net
.
IPAddr
{
IP
:
ip
},
}
return
}
func
addRoutes
(
ifType
,
ifName
string
,
routes
...
string
)
error
{
for
_
,
route
:=
range
routes
{
if
route
==
""
{
continue
...
...
@@ -59,7 +98,7 @@ func addRoutes(ifName string, routes ...string) error {
cmd
:=
fmt
.
Sprintf
(
"netsh interface ip add route prefix=%s interface=%s store=active"
,
route
,
ifName
)
log
.
Log
(
"[tun]"
,
cmd
)
log
.
Log
f
(
"[%s] %s"
,
ifType
,
cmd
)
args
:=
strings
.
Split
(
cmd
,
" "
)
if
er
:=
exec
.
Command
(
args
[
0
],
args
[
1
:
]
...
)
.
Run
();
er
!=
nil
{
return
fmt
.
Errorf
(
"%s: %v"
,
cmd
,
er
)
...
...
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