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
124bc03e
Commit
124bc03e
authored
Jan 03, 2020
by
ginuerzh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tap: fix frame routing
parent
bde4217c
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
103 additions
and
24 deletions
+103
-24
go.mod
go.mod
+1
-0
go.sum
go.sum
+2
-0
tuntap.go
tuntap.go
+94
-23
tuntap_linux.go
tuntap_linux.go
+6
-1
No files found.
go.mod
View file @
124bc03e
...
...
@@ -33,6 +33,7 @@ require (
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735
github.com/shadowsocks/go-shadowsocks2 v0.0.11
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba
github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
...
...
go.sum
View file @
124bc03e
...
...
@@ -69,6 +69,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/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/songgao/packets v0.0.0-20160404182456-549a10cd4091 h1:1zN6ImoqhSJhN8hGXFaJlSC8msLmIbX8bFqOfWLKw0w=
github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091/go.mod h1:N20Z5Y8oye9a7HmytmZ+tr8Q2vlP0tAHP13kTHzwvQY=
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=
...
...
tuntap.go
View file @
124bc03e
package
gost
import
(
"bytes"
"errors"
"io"
"net"
...
...
@@ -10,6 +11,7 @@ import (
"github.com/go-log/log"
"github.com/shadowsocks/go-shadowsocks2/core"
"github.com/songgao/packets/ethernet"
"github.com/songgao/water"
"github.com/songgao/water/waterutil"
"golang.org/x/net/ipv4"
...
...
@@ -283,6 +285,20 @@ func (l *tunListener) Close() error {
return
nil
}
var
mEtherTypes
=
map
[
ethernet
.
Ethertype
]
string
{
ethernet
.
IPv4
:
"ip"
,
ethernet
.
ARP
:
"arp"
,
ethernet
.
RARP
:
"rarp"
,
ethernet
.
IPv6
:
"ip6"
,
}
func
etherType
(
et
ethernet
.
Ethertype
)
string
{
if
s
,
ok
:=
mEtherTypes
[
et
];
ok
{
return
s
}
return
"unknown"
}
type
TapConfig
struct
{
Name
string
Addr
string
...
...
@@ -290,10 +306,17 @@ type TapConfig struct {
Routes
[]
string
}
type
tapRouteKey
[
6
]
byte
func
hwAddrToTapRouteKey
(
addr
net
.
HardwareAddr
)
(
key
tapRouteKey
)
{
copy
(
key
[
:
],
addr
)
return
}
type
tapHandler
struct
{
raddr
string
options
*
HandlerOptions
i
pNet
*
net
.
IPNet
i
fce
*
net
.
Interface
routes
sync
.
Map
}
...
...
@@ -336,7 +359,10 @@ func (h *tapHandler) Handle(conn net.Conn) {
}
defer
tc
.
Close
()
log
.
Logf
(
"[tap] %s - %s: tap creation successful"
,
tc
.
LocalAddr
(),
conn
.
LocalAddr
())
addrs
,
_
:=
h
.
ifce
.
Addrs
()
log
.
Logf
(
"[tap] %s - %s: name: %s, mac: %s, mtu: %d, addr: %s"
,
tc
.
LocalAddr
(),
conn
.
LocalAddr
(),
h
.
ifce
.
Name
,
h
.
ifce
.
HardwareAddr
,
h
.
ifce
.
MTU
,
addrs
)
var
raddr
net
.
Addr
if
h
.
raddr
!=
""
{
...
...
@@ -361,7 +387,7 @@ func (h *tapHandler) Handle(conn net.Conn) {
}
func
(
h
*
tapHandler
)
createTap
()
(
conn
net
.
Conn
,
err
error
)
{
conn
,
h
.
i
pNet
,
err
=
createTap
(
h
.
options
.
TapConfig
)
conn
,
h
.
i
fce
,
err
=
createTap
(
h
.
options
.
TapConfig
)
return
}
...
...
@@ -379,22 +405,36 @@ func (h *tapHandler) transportTap(tap net.Conn, conn net.PacketConn, raddr net.A
return
err
}
macSrc
:=
waterutil
.
MACSource
(
b
[
:
n
])
macDst
:=
waterutil
.
MACDestination
(
b
[
:
n
])
frame
:=
ethernet
.
Frame
(
b
[
:
n
])
addr
:=
raddr
if
v
,
ok
:=
h
.
routes
.
Load
(
macDst
.
String
());
ok
{
addr
=
v
.
(
net
.
Addr
)
if
Debug
{
log
.
Logf
(
"[tap] %s -> %s %s %d"
,
frame
.
Source
(),
frame
.
Destination
(),
etherType
(
frame
.
Ethertype
()),
n
)
}
if
addr
==
nil
{
log
.
Logf
(
"[tap] %s: no route for %s -> %s %d %d"
,
tap
.
LocalAddr
(),
macSrc
,
macDst
,
n
,
waterutil
.
MACEthertype
(
b
[
:
n
]))
// client side delivers frame directly.
if
raddr
!=
nil
{
_
,
err
:=
conn
.
WriteTo
(
b
[
:
n
],
raddr
)
return
err
}
// server side broadcast.
if
waterutil
.
IsBroadcast
(
frame
.
Destination
())
{
h
.
routes
.
Range
(
func
(
k
,
v
interface
{})
bool
{
conn
.
WriteTo
(
b
[
:
n
],
v
.
(
net
.
Addr
))
return
true
})
return
nil
}
if
Debug
{
log
.
Logf
(
"[tap] %s >>> %s: %s -> %s %d %d"
,
tap
.
LocalAddr
(),
addr
,
macSrc
,
macDst
,
n
,
waterutil
.
MACEthertype
(
b
[
:
n
]))
var
addr
net
.
Addr
if
v
,
ok
:=
h
.
routes
.
Load
(
hwAddrToTapRouteKey
(
frame
.
Destination
()));
ok
{
addr
=
v
.
(
net
.
Addr
)
}
if
addr
==
nil
{
log
.
Logf
(
"[tap] no route for %s -> %s %s %d"
,
frame
.
Source
(),
frame
.
Destination
(),
etherType
(
frame
.
Ethertype
()),
n
)
return
nil
}
if
_
,
err
:=
conn
.
WriteTo
(
b
[
:
n
],
addr
);
err
!=
nil
{
...
...
@@ -421,22 +461,53 @@ func (h *tapHandler) transportTap(tap net.Conn, conn net.PacketConn, raddr net.A
return
err
}
macSrc
:=
waterutil
.
MACSource
(
b
[
:
n
])
macDst
:=
waterutil
.
MACDestination
(
b
[
:
n
])
frame
:=
ethernet
.
Frame
(
b
[
:
n
])
// ignore the frame send by myself
if
bytes
.
Equal
(
frame
.
Source
(),
h
.
ifce
.
HardwareAddr
)
{
log
.
Logf
(
"[tap] %s -> %s %s %d ignored"
,
frame
.
Source
(),
frame
.
Destination
(),
etherType
(
frame
.
Ethertype
()),
n
)
return
nil
}
if
Debug
{
log
.
Logf
(
"[tap] %s
<<< %s: %s -> %s %d
%d"
,
tap
.
LocalAddr
(),
addr
,
macSrc
,
macDst
,
n
,
waterutil
.
MACEthertype
(
b
[
:
n
])
)
log
.
Logf
(
"[tap] %s
-> %s %s
%d"
,
frame
.
Source
(),
frame
.
Destination
(),
etherType
(
frame
.
Ethertype
()),
n
)
}
if
actual
,
loaded
:=
h
.
routes
.
LoadOrStore
(
macSrc
.
String
(),
addr
);
loaded
{
// client side, deliver frame to tap device.
if
raddr
!=
nil
{
_
,
err
:=
tap
.
Write
(
b
[
:
n
])
return
err
}
// server side, record route.
rkey
:=
hwAddrToTapRouteKey
(
frame
.
Source
())
if
actual
,
loaded
:=
h
.
routes
.
LoadOrStore
(
rkey
,
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
)
log
.
Logf
(
"[tap] update route: %s -> %s (old %s)"
,
frame
.
Source
()
,
addr
,
actual
.
(
net
.
Addr
))
h
.
routes
.
Store
(
rkey
,
addr
)
}
}
else
{
log
.
Logf
(
"[tap] %s: new route: %s -> %s"
,
tap
.
LocalAddr
(),
macSrc
,
addr
)
log
.
Logf
(
"[tap] new route: %s -> %s"
,
frame
.
Source
(),
addr
)
}
if
waterutil
.
IsBroadcast
(
frame
.
Destination
())
{
h
.
routes
.
Range
(
func
(
k
,
v
interface
{})
bool
{
if
k
.
(
tapRouteKey
)
!=
hwAddrToTapRouteKey
(
frame
.
Source
())
{
conn
.
WriteTo
(
b
[
:
n
],
v
.
(
net
.
Addr
))
}
return
true
})
}
if
v
,
ok
:=
h
.
routes
.
Load
(
hwAddrToTapRouteKey
(
frame
.
Destination
()));
ok
{
log
.
Logf
(
"[tap] find route: %s -> %s"
,
frame
.
Destination
(),
v
)
_
,
err
:=
conn
.
WriteTo
(
b
[
:
n
],
v
.
(
net
.
Addr
))
return
err
}
if
_
,
err
:=
tap
.
Write
(
b
[
:
n
]);
err
!=
nil
{
...
...
tuntap_linux.go
View file @
124bc03e
...
...
@@ -68,7 +68,7 @@ func createTun(cfg TunConfig) (conn net.Conn, ipNet *net.IPNet, err error) {
return
}
func
createTap
(
cfg
TapConfig
)
(
conn
net
.
Conn
,
i
pNet
*
net
.
IPNet
,
err
error
)
{
func
createTap
(
cfg
TapConfig
)
(
conn
net
.
Conn
,
i
tf
*
net
.
Interface
,
err
error
)
{
ip
,
ipNet
,
err
:=
net
.
ParseCIDR
(
cfg
.
Addr
)
if
err
!=
nil
{
return
...
...
@@ -119,6 +119,11 @@ func createTap(cfg TapConfig) (conn net.Conn, ipNet *net.IPNet, err error) {
return
}
itf
,
err
=
net
.
InterfaceByName
(
ifce
.
Name
())
if
err
!=
nil
{
return
}
conn
=
&
tunTapConn
{
ifce
:
ifce
,
addr
:
&
net
.
IPAddr
{
IP
:
ip
},
...
...
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