mirror of
https://github.com/KusakabeShi/EtherGuard-VPN.git
synced 2024-11-25 00:33:08 +01:00
LinuxTap, not test yet
This commit is contained in:
parent
26ba4dbe94
commit
d717d35f64
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
@ -10,7 +10,8 @@
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}",
|
||||
"args":["-config","example_config/p2p_mode/n1.yaml","-mode","edge"/*,"-example"*/],
|
||||
"env": {"CGO_CFLAGS":"-I/usr/include/memif"},
|
||||
"args":["-config","example_config/static_mode/n1.yaml","-mode","edge"/*,"-example"*/],
|
||||
}
|
||||
]
|
||||
}
|
@ -5,15 +5,16 @@ import (
|
||||
)
|
||||
|
||||
type EdgeConfig struct {
|
||||
Interface InterfaceConf
|
||||
NodeID Vertex
|
||||
NodeName string
|
||||
PrivKey string
|
||||
ListenPort int
|
||||
LogLevel LoggerInfo
|
||||
DynamicRoute DynamicRouteInfo
|
||||
NextHopTable NextHopTable
|
||||
Peers []PeerInfo
|
||||
Interface InterfaceConf
|
||||
NodeID Vertex
|
||||
NodeName string
|
||||
PrivKey string
|
||||
ListenPort int
|
||||
LogLevel LoggerInfo
|
||||
DynamicRoute DynamicRouteInfo
|
||||
NextHopTable NextHopTable
|
||||
ResetConnInterval float64
|
||||
Peers []PeerInfo
|
||||
}
|
||||
|
||||
type SuperConfig struct {
|
||||
@ -28,15 +29,15 @@ type SuperConfig struct {
|
||||
}
|
||||
|
||||
type InterfaceConf struct {
|
||||
Itype string
|
||||
Name string
|
||||
VPPIfaceID uint32
|
||||
VPPBridgeID uint32
|
||||
MacAddr string
|
||||
MTU int
|
||||
RecvAddr string
|
||||
SendAddr string
|
||||
DevFriendly bool
|
||||
Itype string
|
||||
Name string
|
||||
VPPIfaceID uint32
|
||||
VPPBridgeID uint32
|
||||
MacAddrPrefix string
|
||||
MTU int
|
||||
RecvAddr string
|
||||
SendAddr string
|
||||
L2HeaderMode string
|
||||
}
|
||||
|
||||
type PeerInfo struct {
|
||||
|
@ -7,6 +7,7 @@ package device
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@ -69,9 +70,12 @@ type Device struct {
|
||||
Peer_state [32]byte
|
||||
}
|
||||
event_tryendpoint chan struct{}
|
||||
ResetConnInterval float64
|
||||
|
||||
EdgeConfigPath string
|
||||
EdgeConfig *config.EdgeConfig
|
||||
EdgeConfigPath string
|
||||
EdgeConfig *config.EdgeConfig
|
||||
SuperConfigPath string
|
||||
SuperConfig *config.SuperConfig
|
||||
|
||||
Event_server_register chan path.RegisterMsg
|
||||
Event_server_pong chan path.PongMsg
|
||||
@ -304,7 +308,7 @@ func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewDevice(tapDevice tap.Device, id config.Vertex, bind conn.Bind, logger *Logger, graph *path.IG, IsSuperNode bool, theconfigpath string, econfig *config.EdgeConfig, sconfig *config.SuperConfig, superevents *path.SUPER_Events) *Device {
|
||||
func NewDevice(tapDevice tap.Device, id config.Vertex, bind conn.Bind, logger *Logger, graph *path.IG, IsSuperNode bool, configpath string, econfig *config.EdgeConfig, sconfig *config.SuperConfig, superevents *path.SUPER_Events) *Device {
|
||||
device := new(Device)
|
||||
device.state.state = uint32(deviceStateDown)
|
||||
device.closed = make(chan struct{})
|
||||
@ -333,9 +337,11 @@ func NewDevice(tapDevice tap.Device, id config.Vertex, bind conn.Bind, logger *L
|
||||
device.Event_server_NhTable_changed = superevents.Event_server_NhTable_changed
|
||||
device.LogTransit = sconfig.LogLevel.LogTransit
|
||||
device.LogControl = sconfig.LogLevel.LogControl
|
||||
device.SuperConfig = sconfig
|
||||
device.SuperConfigPath = configpath
|
||||
go device.RoutineRecalculateNhTable()
|
||||
} else {
|
||||
device.EdgeConfigPath = theconfigpath
|
||||
device.EdgeConfigPath = configpath
|
||||
device.EdgeConfig = econfig
|
||||
device.DRoute = econfig.DynamicRoute
|
||||
device.DupData = *fixed_time_cache.NewCache(path.S2TD(econfig.DynamicRoute.DupCheckTimeout), false, path.S2TD(60))
|
||||
@ -343,11 +349,13 @@ func NewDevice(tapDevice tap.Device, id config.Vertex, bind conn.Bind, logger *L
|
||||
device.Event_save_config = make(chan struct{}, 1<<5)
|
||||
device.LogTransit = econfig.LogLevel.LogTransit
|
||||
device.LogControl = econfig.LogLevel.LogControl
|
||||
device.ResetConnInterval = device.EdgeConfig.ResetConnInterval
|
||||
go device.RoutineSetEndpoint()
|
||||
go device.RoutineRegister()
|
||||
go device.RoutineSendPing()
|
||||
go device.RoutineRecalculateNhTable()
|
||||
go device.RoutineSpreadAllMyNeighbor()
|
||||
go device.RoutineResetConn()
|
||||
}
|
||||
// create queues
|
||||
|
||||
@ -374,6 +382,29 @@ func NewDevice(tapDevice tap.Device, id config.Vertex, bind conn.Bind, logger *L
|
||||
return device
|
||||
}
|
||||
|
||||
func (device *Device) LookupPeerIDAtConfig(pk NoisePublicKey) (ID config.Vertex, err error) {
|
||||
var peerlist []config.PeerInfo
|
||||
if device.IsSuperNode {
|
||||
if device.SuperConfig == nil {
|
||||
return 0, errors.New("Superconfig is nil")
|
||||
}
|
||||
peerlist = device.SuperConfig.Peers
|
||||
} else {
|
||||
if device.EdgeConfig == nil {
|
||||
return 0, errors.New("EdgeConfig is nil")
|
||||
}
|
||||
peerlist = device.EdgeConfig.Peers
|
||||
}
|
||||
|
||||
pkstr := PubKey2Str(pk)
|
||||
for _, peerinfo := range peerlist {
|
||||
if peerinfo.PubKey == pkstr {
|
||||
return peerinfo.NodeID, nil
|
||||
}
|
||||
}
|
||||
return 0, errors.New("Peer not found in the config file.")
|
||||
}
|
||||
|
||||
func (device *Device) LookupPeer(pk NoisePublicKey) *Peer {
|
||||
device.peers.RLock()
|
||||
defer device.peers.RUnlock()
|
||||
|
@ -36,6 +36,8 @@ type Peer struct {
|
||||
|
||||
ID config.Vertex
|
||||
AskedForNeighbor bool
|
||||
StaticConn bool //if true, this peer will not write to config file when roaming, and the endpoint will be reset periodically
|
||||
ConnURL string
|
||||
|
||||
// These fields are accessed with atomic operations, which must be
|
||||
// 64-bit aligned even on 32-bit platforms. Go guarantees that an
|
||||
@ -330,15 +332,16 @@ func (device *Device) SaveToConfig(peer *Peer, endpoint conn.Endpoint) {
|
||||
if device.IsSuperNode { //Can't in super mode
|
||||
return
|
||||
}
|
||||
if peer.StaticConn == true { //static conn do not write new endpoint to config
|
||||
return
|
||||
}
|
||||
if !device.DRoute.P2P.UseP2P { //Must in p2p mode
|
||||
return
|
||||
}
|
||||
if peer.endpoint != nil && peer.endpoint.DstIP().Equal(endpoint.DstIP()) { //endpoint changed
|
||||
return
|
||||
}
|
||||
if peer.LastPingReceived.Add(path.S2TD(device.DRoute.P2P.PeerAliveTimeout)).After(time.Now()) { //Peer alives
|
||||
return
|
||||
}
|
||||
|
||||
url := endpoint.DstToString()
|
||||
foundInFile := false
|
||||
pubkeystr := PubKey2Str(peer.handshake.remoteStatic)
|
||||
|
@ -548,7 +548,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||
goto skip
|
||||
}
|
||||
src_macaddr := tap.GetSrcMacAddr(elem.packet[path.EgHeaderLen:])
|
||||
if !tap.IsBoardCast(src_macaddr) {
|
||||
if !tap.IsNotUnicast(src_macaddr) {
|
||||
device.l2fib.Store(src_macaddr, src_nodeID) // Write to l2fib table
|
||||
}
|
||||
_, err = device.tap.device.Write(elem.buffer[:MessageTransportOffsetContent+len(elem.packet)], MessageTransportOffsetContent+path.EgHeaderLen)
|
||||
|
@ -142,7 +142,7 @@ func (device *Device) process_received(msg_type path.Usage, peer *Peer, body []b
|
||||
}
|
||||
case path.BoardcastPeer:
|
||||
if content, err := path.ParseBoardcastPeerMsg(body); err == nil {
|
||||
return device.process_BoardcastPeerMsg(content)
|
||||
return device.process_BoardcastPeerMsg(peer, content)
|
||||
}
|
||||
default:
|
||||
err = errors.New("Not a valid msg_type")
|
||||
@ -245,7 +245,6 @@ func (device *Device) process_pong(peer *Peer, content path.PongMsg) error {
|
||||
header.SetPacketLength(uint16(len(body)))
|
||||
copy(buf[path.EgHeaderLen:], body)
|
||||
device.SendPacket(peer, buf, MessageTransportOffsetContent)
|
||||
peer.AskedForNeighbor = true
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -434,12 +433,35 @@ func (device *Device) RoutineSpreadAllMyNeighbor() {
|
||||
}
|
||||
for {
|
||||
device.process_RequestPeerMsg(path.QueryPeerMsg{
|
||||
Request_ID: 0,
|
||||
Request_ID: uint32(path.Boardcast),
|
||||
})
|
||||
time.Sleep(path.S2TD(device.DRoute.P2P.SendPeerInterval))
|
||||
}
|
||||
}
|
||||
|
||||
func (device *Device) RoutineResetConn() {
|
||||
if device.ResetConnInterval <= 0.01 {
|
||||
return
|
||||
}
|
||||
for {
|
||||
for _, peer := range device.peers.keyMap {
|
||||
if peer.StaticConn {
|
||||
continue
|
||||
}
|
||||
if peer.ConnURL == "" {
|
||||
continue
|
||||
}
|
||||
endpoint, err := device.Bind().ParseEndpoint(peer.ConnURL)
|
||||
if err != nil {
|
||||
device.log.Errorf("Failed to bind "+peer.ConnURL, err)
|
||||
continue
|
||||
}
|
||||
peer.SetEndpointFromPacket(endpoint)
|
||||
}
|
||||
time.Sleep(time.Duration(device.ResetConnInterval))
|
||||
}
|
||||
}
|
||||
|
||||
func (device *Device) GeneratePingPacket(src_nodeID config.Vertex) ([]byte, error) {
|
||||
body, err := path.GetByte(&path.PingMsg{
|
||||
Src_nodeID: src_nodeID,
|
||||
@ -531,9 +553,12 @@ func (device *Device) process_RequestPeerMsg(content path.QueryPeerMsg) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (device *Device) process_BoardcastPeerMsg(content path.BoardcastPeerMsg) error {
|
||||
func (device *Device) process_BoardcastPeerMsg(peer *Peer, content path.BoardcastPeerMsg) error {
|
||||
if device.DRoute.P2P.UseP2P {
|
||||
var sk NoisePublicKey
|
||||
if content.Request_ID == uint32(device.ID) {
|
||||
peer.AskedForNeighbor = true
|
||||
}
|
||||
if bytes.Equal(content.PubKey[:], device.staticIdentity.publicKey[:]) {
|
||||
return nil
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ func (device *Device) RoutineReadFromTUN() {
|
||||
dst_nodeID := EgBody.GetDst()
|
||||
dstMacAddr := tap.GetDstMacAddr(elem.packet[path.EgHeaderLen:])
|
||||
// lookup peer
|
||||
if tap.IsBoardCast(dstMacAddr) {
|
||||
if tap.IsNotUnicast(dstMacAddr) {
|
||||
dst_nodeID = path.Boardcast
|
||||
} else if val, ok := device.l2fib.Load(dstMacAddr); !ok { //Lookup failed
|
||||
dst_nodeID = path.Boardcast
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
@ -19,7 +18,6 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
"github.com/KusakabeSi/EtherGuardVPN/ipc"
|
||||
)
|
||||
|
||||
@ -268,8 +266,6 @@ func (device *Device) handlePublicKeyLine(peer *ipcSetPeer, value string) error
|
||||
if err != nil {
|
||||
return ipcErrorf(ipc.IpcErrorInvalid, "failed to get peer by public key: %w", err)
|
||||
}
|
||||
h := crc32.NewIEEE()
|
||||
h.Write(publicKey[:])
|
||||
|
||||
// Ignore peer with the same public key as this device.
|
||||
device.staticIdentity.RLock()
|
||||
@ -284,7 +280,11 @@ func (device *Device) handlePublicKeyLine(peer *ipcSetPeer, value string) error
|
||||
|
||||
peer.created = peer.Peer == nil
|
||||
if peer.created {
|
||||
peer.Peer, err = device.NewPeer(publicKey, config.Vertex(h.Sum32()))
|
||||
id, err := device.LookupPeerIDAtConfig(publicKey)
|
||||
if err != nil {
|
||||
return errors.New("Create new peer by UAPI is not implemented")
|
||||
}
|
||||
peer.Peer, err = device.NewPeer(publicKey, id)
|
||||
if err != nil {
|
||||
return ipcErrorf(ipc.IpcErrorInvalid, "failed to create new peer: %w", err)
|
||||
}
|
||||
|
@ -1,18 +1,19 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 1
|
||||
name: tap1
|
||||
macaddr: AA:BB:CC:DD:EE:01
|
||||
vppifaceid: 1
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4001
|
||||
sendaddr: 127.0.0.1:5001
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 1
|
||||
nodename: Node01
|
||||
privkey: aABzjKhWdkFfQ29ZuijtMp1h1TNJe66SDCwvfmvQznw=
|
||||
listenport: 3001
|
||||
loglevel:
|
||||
loglevel: normal`
|
||||
loglevel: normal
|
||||
logtransit: true
|
||||
logcontrol: true
|
||||
dynamicroute:
|
||||
@ -23,9 +24,9 @@ dynamicroute:
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 2
|
||||
pubkey: csT+hco4Jpa7btMeC9subHk2ZqzxcljcBk/57V0cSEk=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 2
|
||||
name: tap2
|
||||
macaddr: AA:BB:CC:DD:EE:02
|
||||
vppifaceid: 2
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4002
|
||||
sendaddr: 127.0.0.1:5002
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 2
|
||||
nodename: Node02
|
||||
privkey: UNZMzPX5fG/8yGC8edVj/ksF9N6ARRqdq7fqE/PD7ls=
|
||||
@ -23,9 +24,9 @@ dynamicroute:
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 1
|
||||
pubkey: CooSkIP7/wiC7Rh83UYnB2yPkJijkNFmhtorHtyYlzY=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 3
|
||||
name: tap3
|
||||
macaddr: AA:BB:CC:DD:EE:03
|
||||
vppifaceid: 3
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4003
|
||||
sendaddr: 127.0.0.1:5003
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 3
|
||||
nodename: Node03
|
||||
privkey: gJy35nbsd8FuuxyWHjsefN+U+oM7RkuIB1EanNLSVHg=
|
||||
@ -23,9 +24,9 @@ dynamicroute:
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 2
|
||||
pubkey: csT+hco4Jpa7btMeC9subHk2ZqzxcljcBk/57V0cSEk=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 4
|
||||
name: tap4
|
||||
macaddr: AA:BB:CC:DD:EE:04
|
||||
vppifaceid: 4
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4004
|
||||
sendaddr: 127.0.0.1:5004
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 4
|
||||
nodename: Node04
|
||||
privkey: wAdLgCk0SHiO11/aUf9944focD1BUCH5b6Pe+cRHHXQ=
|
||||
@ -23,9 +24,9 @@ dynamicroute:
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 2
|
||||
pubkey: csT+hco4Jpa7btMeC9subHk2ZqzxcljcBk/57V0cSEk=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 5
|
||||
name: tap5
|
||||
macaddr: AA:BB:CC:DD:EE:05
|
||||
vppifaceid: 5
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4005
|
||||
sendaddr: 127.0.0.1:5005
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 5
|
||||
nodename: Node05
|
||||
privkey: gLmzeCbmN/hjiE+ehNXL9IxuG9hhWIYv2s16/DOW6FE=
|
||||
@ -23,9 +24,9 @@ dynamicroute:
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 3
|
||||
pubkey: 0meQ0pQCAkLZdpfyMqggpnk0k3UKG2M8jfIMlQjTRWs=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 6
|
||||
name: tap6
|
||||
macaddr: AA:BB:CC:DD:EE:03
|
||||
vppifaceid: 6
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4006
|
||||
sendaddr: 127.0.0.1:5006
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 6
|
||||
nodename: Node06
|
||||
privkey: IIX5F6oWZUS2dlhxWFJ7TxdJtDCr5jzeuhxUB6YM7Us=
|
||||
@ -23,9 +24,9 @@ dynamicroute:
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 4
|
||||
pubkey: 2EfY85KF1S+3dZ3A55eZcyi0QU+sOzOyuADtJs2U2Ww=
|
||||
|
@ -1,31 +1,32 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 1
|
||||
name: tap1
|
||||
macaddr: AA:BB:CC:DD:EE:01
|
||||
vppifaceid: 1
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4001
|
||||
sendaddr: 127.0.0.1:5001
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 1
|
||||
nodename: Node01
|
||||
privkey: aABzjKhWdkFfQ29ZuijtMp1h1TNJe66SDCwvfmvQznw=
|
||||
listenport: 3001
|
||||
loglevel:
|
||||
loglevel: normal`
|
||||
loglevel: normal
|
||||
logtransit: true
|
||||
logcontrol: true
|
||||
dynamicroute:
|
||||
sendpinginterval: 20
|
||||
dupchecktimeout: 40
|
||||
conntimeout: 30
|
||||
savenewpeers: true
|
||||
savenewpeers: false
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 2
|
||||
pubkey: csT+hco4Jpa7btMeC9subHk2ZqzxcljcBk/57V0cSEk=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 2
|
||||
name: tap2
|
||||
macaddr: AA:BB:CC:DD:EE:02
|
||||
vppifaceid: 2
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4002
|
||||
sendaddr: 127.0.0.1:5002
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 2
|
||||
nodename: Node02
|
||||
privkey: UNZMzPX5fG/8yGC8edVj/ksF9N6ARRqdq7fqE/PD7ls=
|
||||
@ -19,13 +20,13 @@ dynamicroute:
|
||||
sendpinginterval: 20
|
||||
dupchecktimeout: 40
|
||||
conntimeout: 30
|
||||
savenewpeers: true
|
||||
savenewpeers: false
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 1
|
||||
pubkey: CooSkIP7/wiC7Rh83UYnB2yPkJijkNFmhtorHtyYlzY=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 3
|
||||
name: tap3
|
||||
macaddr: AA:BB:CC:DD:EE:03
|
||||
vppifaceid: 3
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4003
|
||||
sendaddr: 127.0.0.1:5003
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 3
|
||||
nodename: Node03
|
||||
privkey: gJy35nbsd8FuuxyWHjsefN+U+oM7RkuIB1EanNLSVHg=
|
||||
@ -19,13 +20,13 @@ dynamicroute:
|
||||
sendpinginterval: 20
|
||||
dupchecktimeout: 40
|
||||
conntimeout: 30
|
||||
savenewpeers: true
|
||||
savenewpeers: false
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 2
|
||||
pubkey: csT+hco4Jpa7btMeC9subHk2ZqzxcljcBk/57V0cSEk=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 4
|
||||
name: tap4
|
||||
macaddr: AA:BB:CC:DD:EE:04
|
||||
vppifaceid: 4
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4004
|
||||
sendaddr: 127.0.0.1:5004
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 4
|
||||
nodename: Node04
|
||||
privkey: wAdLgCk0SHiO11/aUf9944focD1BUCH5b6Pe+cRHHXQ=
|
||||
@ -19,13 +20,13 @@ dynamicroute:
|
||||
sendpinginterval: 20
|
||||
dupchecktimeout: 40
|
||||
conntimeout: 30
|
||||
savenewpeers: true
|
||||
savenewpeers: false
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 2
|
||||
pubkey: csT+hco4Jpa7btMeC9subHk2ZqzxcljcBk/57V0cSEk=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 5
|
||||
name: tap5
|
||||
macaddr: AA:BB:CC:DD:EE:05
|
||||
vppifaceid: 5
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4005
|
||||
sendaddr: 127.0.0.1:5005
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 5
|
||||
nodename: Node05
|
||||
privkey: gLmzeCbmN/hjiE+ehNXL9IxuG9hhWIYv2s16/DOW6FE=
|
||||
@ -19,13 +20,13 @@ dynamicroute:
|
||||
sendpinginterval: 20
|
||||
dupchecktimeout: 40
|
||||
conntimeout: 30
|
||||
savenewpeers: true
|
||||
savenewpeers: false
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 3
|
||||
pubkey: 0meQ0pQCAkLZdpfyMqggpnk0k3UKG2M8jfIMlQjTRWs=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 6
|
||||
name: tap6
|
||||
macaddr: AA:BB:CC:DD:EE:03
|
||||
vppifaceid: 6
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4006
|
||||
sendaddr: 127.0.0.1:5006
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 6
|
||||
nodename: Node06
|
||||
privkey: IIX5F6oWZUS2dlhxWFJ7TxdJtDCr5jzeuhxUB6YM7Us=
|
||||
@ -19,13 +20,13 @@ dynamicroute:
|
||||
sendpinginterval: 20
|
||||
dupchecktimeout: 40
|
||||
conntimeout: 30
|
||||
savenewpeers: true
|
||||
savenewpeers: false
|
||||
supernode:
|
||||
usesupernode: false
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
p2p:
|
||||
@ -93,6 +94,7 @@ nexthoptable:
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
resetconninterval: 86400
|
||||
peers:
|
||||
- nodeid: 4
|
||||
pubkey: 2EfY85KF1S+3dZ3A55eZcyi0QU+sOzOyuADtJs2U2Ww=
|
||||
|
@ -1,12 +1,13 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 1
|
||||
name: tap1
|
||||
macaddr: AA:BB:CC:DD:EE:FF
|
||||
vppifaceid: 1
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4001
|
||||
sendaddr: 127.0.0.1:5001
|
||||
devfriendly: true
|
||||
l2headermode: kbdbg
|
||||
nodeid: 1
|
||||
nodename: Node01
|
||||
privkey: 6GyDagZKhbm5WNqMiRHhkf43RlbMJ34IieTlIuvfJ1M=
|
||||
@ -24,7 +25,7 @@ dynamicroute:
|
||||
usesupernode: true
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:2999'
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
@ -57,4 +58,5 @@ dynamicroute:
|
||||
- time.euro.apple.com
|
||||
- time.windows.com
|
||||
nexthoptable: {}
|
||||
resetconninterval: 86400
|
||||
peers: []
|
@ -1,14 +1,15 @@
|
||||
interface:
|
||||
itype: stdio
|
||||
ifaceid: 2
|
||||
name: tap2
|
||||
macaddr: AA:BB:CC:DD:EE:FF
|
||||
vppifaceid: 2
|
||||
vppbridgeid: 0
|
||||
macaddrprefix: AA:BB:CC:DD:EE
|
||||
mtu: 1400
|
||||
recvaddr: 127.0.0.1:4002
|
||||
sendaddr: 127.0.0.1:5002
|
||||
devfriendly: true
|
||||
nodeid: 2
|
||||
nodename: Node02
|
||||
l2headermode: kbdbg
|
||||
nodeid: 1
|
||||
nodename: Node01
|
||||
privkey: OH8BsVUU2Rqzeu9B2J5GPG8PUmxWfX8uVvNFZKhVF3o=
|
||||
listenport: 3002
|
||||
loglevel:
|
||||
@ -24,7 +25,7 @@ dynamicroute:
|
||||
usesupernode: true
|
||||
connurlv4: 127.0.0.1:3000
|
||||
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
connurlv6: '[::1]:2999'
|
||||
connurlv6: '[::1]:3000'
|
||||
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
apiurl: http://127.0.0.1:3000/api
|
||||
supernodeinfotimeout: 40
|
||||
@ -57,4 +58,5 @@ dynamicroute:
|
||||
- time.euro.apple.com
|
||||
- time.windows.com
|
||||
nexthoptable: {}
|
||||
resetconninterval: 86400
|
||||
peers: []
|
@ -2,14 +2,14 @@ nodename: NodeSuper
|
||||
privkeyv4: mL5IW0GuqbjgDeOJuPHBU2iJzBPNKhaNEXbIGwwYWWk=
|
||||
privkeyv6: +EdOKIoBp/EvIusHDsvXhV1RJYbyN3Qr8nxlz35wl3I=
|
||||
listenport: 3000
|
||||
repushconfiginterval: 10
|
||||
loglevel:
|
||||
loglevel: normal
|
||||
logtransit: true
|
||||
logcontrol: true
|
||||
repushconfiginterval: 30
|
||||
graphrecalculatesetting:
|
||||
jittertolerance: 20
|
||||
jittertolerancemultiplier: 1.1
|
||||
jittertolerance: 5
|
||||
jittertolerancemultiplier: 1.01
|
||||
nodereporttimeout: 40
|
||||
recalculatecooldown: 5
|
||||
peers:
|
||||
|
15
main.go
15
main.go
@ -25,8 +25,8 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
ENV_WP_UAPI_FD = "WP_UAPI_FD"
|
||||
ENV_WP_UAPI_DIR = "WP_UAPI_DIR"
|
||||
ENV_EG_UAPI_FD = "EG_UAPI_FD"
|
||||
ENV_EG_UAPI_DIR = "EG_UAPI_DIR"
|
||||
)
|
||||
|
||||
func printUsage() {
|
||||
@ -62,20 +62,25 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
uapiDir := os.Getenv(ENV_WP_UAPI_DIR)
|
||||
uapiDir := os.Getenv(ENV_EG_UAPI_DIR)
|
||||
if uapiDir != "" {
|
||||
ipc.SetsocketDirectory(uapiDir)
|
||||
}
|
||||
|
||||
var err error
|
||||
switch *mode {
|
||||
case "edge":
|
||||
Edge(*tconfig, !*nouapi, *printExample)
|
||||
err = Edge(*tconfig, !*nouapi, *printExample)
|
||||
case "super":
|
||||
Super(*tconfig, !*nouapi, *printExample)
|
||||
err = Super(*tconfig, !*nouapi, *printExample)
|
||||
case "path":
|
||||
path.Solve()
|
||||
default:
|
||||
flag.Usage()
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error :%v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
36
main_edge.go
36
main_edge.go
@ -29,13 +29,13 @@ func printExampleEdgeConf() {
|
||||
tconfig := config.EdgeConfig{
|
||||
Interface: config.InterfaceConf{
|
||||
Itype: "stdio",
|
||||
VPPIfaceID: 5,
|
||||
VPPIfaceID: 5,
|
||||
Name: "tap1",
|
||||
MacAddr: "AA:BB:CC:DD:EE:FF",
|
||||
MacAddrPrefix: "AA:BB:CC:DD:EE:FF",
|
||||
MTU: 1400,
|
||||
RecvAddr: "127.0.0.1:4001",
|
||||
SendAddr: "127.0.0.1:5001",
|
||||
DevFriendly: true,
|
||||
L2HeaderMode: "nochg",
|
||||
},
|
||||
NodeID: 1,
|
||||
NodeName: "Node01",
|
||||
@ -44,6 +44,7 @@ func printExampleEdgeConf() {
|
||||
LogLevel: config.LoggerInfo{
|
||||
LogLevel: "normal",
|
||||
LogTransit: true,
|
||||
LogControl: true,
|
||||
},
|
||||
DynamicRoute: config.DynamicRouteInfo{
|
||||
SendPingInterval: 20,
|
||||
@ -53,9 +54,9 @@ func printExampleEdgeConf() {
|
||||
SuperNode: config.SuperInfo{
|
||||
UseSuperNode: true,
|
||||
ConnURLV4: "127.0.0.1:3000",
|
||||
PubKeyV4: "j8i4dY1i7CUqd/ftaCSfCWosnURiztM+ExI7QRezU2Y=",
|
||||
PubKeyV4: "LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=",
|
||||
ConnURLV6: "[::1]:3000",
|
||||
PubKeyV6: "cCcPlZw0hVkPSi15G+jpJpKE3TdCVEtO1nSiaedukGw=",
|
||||
PubKeyV6: "HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=",
|
||||
APIUrl: "http://127.0.0.1:3000/api",
|
||||
SuperNodeInfoTimeout: 40,
|
||||
},
|
||||
@ -90,7 +91,8 @@ func printExampleEdgeConf() {
|
||||
"time.windows.com"},
|
||||
},
|
||||
},
|
||||
NextHopTable: config.NextHopTable{},
|
||||
NextHopTable: config.NextHopTable{},
|
||||
ResetConnInterval: 86400,
|
||||
Peers: []config.PeerInfo{
|
||||
{
|
||||
NodeID: 2,
|
||||
@ -165,13 +167,17 @@ func Edge(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
case "dummy":
|
||||
thetap, err = tap.CreateDummyTAP()
|
||||
case "stdio":
|
||||
thetap, err = tap.CreateStdIOTAP(tconfig.Interface.Name, tconfig.Interface.DevFriendly)
|
||||
tconfig.Interface.VPPIfaceID = uint32(tconfig.NodeID)
|
||||
thetap, err = tap.CreateStdIOTAP(tconfig.Interface)
|
||||
case "udpsock":
|
||||
{
|
||||
lis, _ := net.ResolveUDPAddr("udp", tconfig.Interface.RecvAddr)
|
||||
sen, _ := net.ResolveUDPAddr("udp", tconfig.Interface.SendAddr)
|
||||
thetap, err = tap.CreateUDPSockTAP(tconfig.Interface.Name, lis, sen, tconfig.Interface.DevFriendly)
|
||||
}
|
||||
tconfig.Interface.VPPIfaceID = uint32(tconfig.NodeID)
|
||||
lis, _ := net.ResolveUDPAddr("udp", tconfig.Interface.RecvAddr)
|
||||
sen, _ := net.ResolveUDPAddr("udp", tconfig.Interface.SendAddr)
|
||||
thetap, err = tap.CreateUDPSockTAP(tconfig.Interface, lis, sen)
|
||||
case "vpp":
|
||||
thetap, err = tap.CreateVppTAP(tconfig.Interface, tconfig.LogLevel.LogLevel)
|
||||
default:
|
||||
return errors.New("Unknow interface type:" + tconfig.Interface.Itype)
|
||||
}
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to create TAP device: %v", err)
|
||||
@ -206,6 +212,8 @@ func Edge(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
logger.Errorf("Failed to set endpoint %v: %w", peerconf.EndPoint, err)
|
||||
return err
|
||||
}
|
||||
peer.StaticConn = peerconf.Static
|
||||
peer.ConnURL = peerconf.EndPoint
|
||||
peer.SetEndpointFromPacket(endpoint)
|
||||
}
|
||||
}
|
||||
@ -222,6 +230,8 @@ func Edge(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
peer.StaticConn = false
|
||||
peer.ConnURL = tconfig.DynamicRoute.SuperNode.ConnURLV4
|
||||
peer.SetEndpointFromPacket(endpoint)
|
||||
}
|
||||
if tconfig.DynamicRoute.SuperNode.ConnURLV6 != "" {
|
||||
@ -235,6 +245,8 @@ func Edge(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
peer.StaticConn = false
|
||||
peer.ConnURL = tconfig.DynamicRoute.SuperNode.ConnURLV6
|
||||
peer.SetEndpointFromPacket(endpoint)
|
||||
}
|
||||
}
|
||||
|
@ -34,13 +34,15 @@ import (
|
||||
func printExampleSuperConf() {
|
||||
sconfig := config.SuperConfig{
|
||||
NodeName: "NodeSuper",
|
||||
PrivKeyV4: "SM8pGjT0r8njy1/7ffN4wMwF7nnJ8UYSjGRWpCqo3ng=",
|
||||
PrivKeyV6: "SM8pGjT0r8njy1/7ffN4wMwF7nnJ8UYSjGRWpCqo3ng=",
|
||||
PrivKeyV4: "mL5IW0GuqbjgDeOJuPHBU2iJzBPNKhaNEXbIGwwYWWk=",
|
||||
PrivKeyV6: "+EdOKIoBp/EvIusHDsvXhV1RJYbyN3Qr8nxlz35wl3I=",
|
||||
ListenPort: 3000,
|
||||
LogLevel: config.LoggerInfo{
|
||||
LogLevel: "normal",
|
||||
LogTransit: true,
|
||||
LogControl: true,
|
||||
},
|
||||
RePushConfigInterval: 30,
|
||||
Peers: []config.PeerInfo{
|
||||
{
|
||||
NodeID: 2,
|
||||
@ -50,8 +52,8 @@ func printExampleSuperConf() {
|
||||
},
|
||||
},
|
||||
GraphRecalculateSetting: config.GraphRecalculateSetting{
|
||||
JitterTolerance: 20,
|
||||
JitterToleranceMultiplier: 1.1,
|
||||
JitterTolerance: 5,
|
||||
JitterToleranceMultiplier: 1.01,
|
||||
NodeReportTimeout: 40,
|
||||
RecalculateCoolDown: 5,
|
||||
},
|
||||
@ -70,8 +72,7 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
var sconfig config.SuperConfig
|
||||
err = readYaml(configPath, &sconfig)
|
||||
if err != nil {
|
||||
fmt.Printf("Error read config: %s :", configPath)
|
||||
fmt.Print(err)
|
||||
fmt.Printf("Error read config: %v\n", configPath)
|
||||
return err
|
||||
}
|
||||
interfaceName := sconfig.NodeName
|
||||
@ -107,21 +108,29 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
|
||||
thetap, _ := tap.CreateDummyTAP()
|
||||
http_graph = path.NewGraph(3, true, sconfig.GraphRecalculateSetting)
|
||||
http_device4 = device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(true, false), logger4, http_graph, true, "", nil, &sconfig, &super_chains)
|
||||
http_device6 = device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(false, true), logger6, http_graph, true, "", nil, &sconfig, &super_chains)
|
||||
http_device4 = device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(true, false), logger4, http_graph, true, configPath, nil, &sconfig, &super_chains)
|
||||
http_device6 = device.NewDevice(thetap, path.SuperNodeMessage, conn.NewCustomBind(false, true), logger6, http_graph, true, configPath, nil, &sconfig, &super_chains)
|
||||
defer http_device4.Close()
|
||||
defer http_device6.Close()
|
||||
var sk [32]byte
|
||||
sk_slice, _ := base64.StdEncoding.DecodeString(sconfig.PrivKeyV4)
|
||||
sk_slice, err := base64.StdEncoding.DecodeString(sconfig.PrivKeyV4)
|
||||
if err != nil {
|
||||
fmt.Printf("Can't decode base64:%v\n", sconfig.PrivKeyV4)
|
||||
return err
|
||||
}
|
||||
copy(sk[:], sk_slice)
|
||||
http_device4.SetPrivateKey(sk)
|
||||
sk_slice, _ = base64.StdEncoding.DecodeString(sconfig.PrivKeyV6)
|
||||
sk_slice, err = base64.StdEncoding.DecodeString(sconfig.PrivKeyV6)
|
||||
if err != nil {
|
||||
fmt.Printf("Can't decode base64:%v\n", sconfig.PrivKeyV6)
|
||||
return err
|
||||
}
|
||||
copy(sk[:], sk_slice)
|
||||
http_device6.SetPrivateKey(sk)
|
||||
http_device4.IpcSet("fwmark=0\n")
|
||||
http_device6.IpcSet("fwmark=0\n")
|
||||
http_device4.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n")
|
||||
http_device6.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort-1) + "\n")
|
||||
http_device6.IpcSet("listen_port=" + strconv.Itoa(sconfig.ListenPort) + "\n")
|
||||
http_device4.IpcSet("replace_peers=true\n")
|
||||
http_device6.IpcSet("replace_peers=true\n")
|
||||
|
||||
@ -143,8 +152,20 @@ func Super(configPath string, useUAPI bool, printExample bool) (err error) {
|
||||
PSKey: peerconf.PSKey,
|
||||
Connurl: make(map[string]bool),
|
||||
}
|
||||
peer4, _ := http_device4.NewPeer(pk, peerconf.NodeID)
|
||||
peer6, _ := http_device6.NewPeer(pk, peerconf.NodeID)
|
||||
peer4, err := http_device4.NewPeer(pk, peerconf.NodeID)
|
||||
if err != nil {
|
||||
fmt.Printf("Error create peer id %v\n", peerconf.NodeID)
|
||||
return err
|
||||
}
|
||||
peer4.StaticConn = true
|
||||
peer4.ConnURL = peerconf.EndPoint
|
||||
peer6, err := http_device6.NewPeer(pk, peerconf.NodeID)
|
||||
if err != nil {
|
||||
fmt.Printf("Error create peer id %v\n", peerconf.NodeID)
|
||||
return err
|
||||
}
|
||||
peer6.StaticConn = true
|
||||
peer6.ConnURL = peerconf.EndPoint
|
||||
if peerconf.PSKey != "" {
|
||||
var psk device.NoisePresharedKey
|
||||
psk_slice, err := base64.StdEncoding.DecodeString(peerconf.PSKey)
|
||||
@ -306,7 +327,7 @@ func PushUpdate() {
|
||||
|
||||
func startUAPI(interfaceName string, logger *device.Logger, the_device *device.Device, errs chan error) (net.Listener, error) {
|
||||
fileUAPI, err := func() (*os.File, error) {
|
||||
uapiFdStr := os.Getenv(ENV_WP_UAPI_FD)
|
||||
uapiFdStr := os.Getenv(ENV_EG_UAPI_FD)
|
||||
if uapiFdStr == "" {
|
||||
return ipc.UAPIOpen(interfaceName)
|
||||
}
|
||||
@ -317,10 +338,14 @@ func startUAPI(interfaceName string, logger *device.Logger, the_device *device.D
|
||||
}
|
||||
return os.NewFile(uintptr(fd), ""), nil
|
||||
}()
|
||||
if err != nil {
|
||||
fmt.Printf("Error create UAPI socket \n")
|
||||
return nil, err
|
||||
}
|
||||
uapi, err := ipc.UAPIListen(interfaceName, fileUAPI)
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to listen on uapi socket: %v", err)
|
||||
os.Exit(ExitSetupFailed)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
25
path/path.go
25
path/path.go
@ -79,22 +79,29 @@ func NewGraph(num_node int, IsSuperMode bool, theconfig config.GraphRecalculateS
|
||||
return &g
|
||||
}
|
||||
|
||||
func (g *IG) GetWeightType(x float64) float64 {
|
||||
func (g *IG) GetWeightType(x float64) (y float64) {
|
||||
x = math.Abs(x)
|
||||
y := x
|
||||
if g.JitterTolerance > 1 && g.JitterToleranceMultiplier > 0.001 {
|
||||
r := g.JitterTolerance
|
||||
m := g.JitterToleranceMultiplier
|
||||
y = math.Pow(math.Ceil(math.Pow(x/m, 1/r)), r) * m
|
||||
y = x
|
||||
if g.JitterTolerance > 0.001 && g.JitterToleranceMultiplier > 1 {
|
||||
t := g.JitterTolerance
|
||||
r := g.JitterToleranceMultiplier
|
||||
y = math.Pow(math.Ceil(math.Pow(x/t, 1/r)), r) * t
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
func (g *IG) ShouldUpdate(u config.Vertex, v config.Vertex, newval float64) bool {
|
||||
oldval := g.Weight(u, v) * 1000
|
||||
newval *= 1000
|
||||
oldval := math.Abs(g.Weight(u, v) * 1000)
|
||||
newval = math.Abs(newval * 1000)
|
||||
if g.IsSuperMode {
|
||||
return (oldval-newval)*(oldval*g.JitterToleranceMultiplier) >= g.JitterTolerance
|
||||
if g.JitterTolerance > 0.001 && g.JitterToleranceMultiplier >= 1 {
|
||||
diff := math.Abs(newval - oldval)
|
||||
x := math.Max(oldval, newval)
|
||||
t := g.JitterTolerance
|
||||
r := g.JitterToleranceMultiplier
|
||||
return diff > t+x*(r-1) // https://www.desmos.com/calculator/raoti16r5n
|
||||
}
|
||||
return oldval == newval
|
||||
} else {
|
||||
return g.GetWeightType(oldval) == g.GetWeightType(newval)
|
||||
}
|
||||
|
48
tap/tap.go
48
tap/tap.go
@ -6,7 +6,10 @@
|
||||
package tap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Event int
|
||||
@ -22,13 +25,44 @@ func GetSrcMacAddr(packet []byte) (srcMacAddr MacAddress) {
|
||||
return
|
||||
}
|
||||
|
||||
func IsBoardCast(mac_in MacAddress) bool {
|
||||
if bytes.Equal(mac_in[:], []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}) {
|
||||
return true
|
||||
} else if bytes.Equal(mac_in[0:2], []byte{0x33, 0x33}) {
|
||||
return true
|
||||
func GetMacAddr(prefix string, uid uint32) (mac MacAddress, err error) {
|
||||
macprefix, _, err := prefixStr2prefix(prefix)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return false
|
||||
idbuf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(idbuf, uid)
|
||||
copy(mac[2:], idbuf)
|
||||
copy(mac[:], macprefix)
|
||||
if IsNotUnicast(mac) {
|
||||
err = errors.New("ERROR: MAC address can only set to unicast address")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func prefixStr2prefix(prefix string) ([]uint8, uint32, error) {
|
||||
hexStrs := strings.Split(strings.ToLower(prefix), ":")
|
||||
retprefix := make([]uint8, len(hexStrs))
|
||||
maxID := uint32(1)<<((6-len(hexStrs))*8) - 1
|
||||
if len(hexStrs) < 2 || len(hexStrs) > 6 {
|
||||
return []uint8{}, 0, errors.New("Macaddr prefix length must between 2 and 6, " + prefix + " is " + strconv.Itoa(len(hexStrs)))
|
||||
}
|
||||
for index, hexstr := range hexStrs {
|
||||
value, err := strconv.ParseInt(hexstr, 16, 16)
|
||||
if err != nil {
|
||||
return []uint8{}, 0, err
|
||||
}
|
||||
retprefix[index] = uint8(value)
|
||||
}
|
||||
return retprefix, maxID, nil
|
||||
}
|
||||
|
||||
func IsNotUnicast(mac_in MacAddress) bool {
|
||||
if mac_in[0]&1 == 0 { // Is unicast
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
|
529
tap/tap_linux.go
Normal file
529
tap/tap_linux.go
Normal file
@ -0,0 +1,529 @@
|
||||
/* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved.
|
||||
*/
|
||||
|
||||
package tap
|
||||
|
||||
/* Implementation of the TUN device interface for linux
|
||||
*/
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
"github.com/KusakabeSi/EtherGuardVPN/rwcancel"
|
||||
)
|
||||
|
||||
const (
|
||||
cloneDevicePath = "/dev/net/tun"
|
||||
ifReqSize = unix.IFNAMSIZ + 64
|
||||
)
|
||||
|
||||
type NativeTap struct {
|
||||
tapFile *os.File
|
||||
index int32 // if index
|
||||
errors chan error // async error handling
|
||||
events chan Event // device related events
|
||||
nopi bool // the device was passed IFF_NO_PI
|
||||
netlinkSock int
|
||||
netlinkCancel *rwcancel.RWCancel
|
||||
hackListenerClosed sync.Mutex
|
||||
statusListenersShutdown chan struct{}
|
||||
|
||||
closeOnce sync.Once
|
||||
|
||||
nameOnce sync.Once // guards calling initNameCache, which sets following fields
|
||||
nameCache string // name of interface
|
||||
nameErr error
|
||||
}
|
||||
|
||||
func (tap *NativeTap) File() *os.File {
|
||||
return tap.tapFile
|
||||
}
|
||||
|
||||
func (tap *NativeTap) routineHackListener() {
|
||||
defer tap.hackListenerClosed.Unlock()
|
||||
/* This is needed for the detection to work across network namespaces
|
||||
* If you are reading this and know a better method, please get in touch.
|
||||
*/
|
||||
last := 0
|
||||
const (
|
||||
up = 1
|
||||
down = 2
|
||||
)
|
||||
for {
|
||||
sysconn, err := tap.tapFile.SyscallConn()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err2 := sysconn.Control(func(fd uintptr) {
|
||||
_, err = unix.Write(int(fd), nil)
|
||||
})
|
||||
if err2 != nil {
|
||||
return
|
||||
}
|
||||
switch err {
|
||||
case unix.EINVAL:
|
||||
if last != up {
|
||||
// If the tunnel is up, it reports that write() is
|
||||
// allowed but we provided invalid data.
|
||||
tap.events <- EventUp
|
||||
last = up
|
||||
}
|
||||
case unix.EIO:
|
||||
if last != down {
|
||||
// If the tunnel is down, it reports that no I/O
|
||||
// is possible, without checking our provided data.
|
||||
tap.events <- EventDown
|
||||
last = down
|
||||
}
|
||||
default:
|
||||
return
|
||||
}
|
||||
select {
|
||||
case <-time.After(time.Second):
|
||||
// nothing
|
||||
case <-tap.statusListenersShutdown:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createNetlinkSocket() (int, error) {
|
||||
sock, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, unix.NETLINK_ROUTE)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
saddr := &unix.SockaddrNetlink{
|
||||
Family: unix.AF_NETLINK,
|
||||
Groups: unix.RTMGRP_LINK | unix.RTMGRP_IPV4_IFADDR | unix.RTMGRP_IPV6_IFADDR,
|
||||
}
|
||||
err = unix.Bind(sock, saddr)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return sock, nil
|
||||
}
|
||||
|
||||
func (tap *NativeTap) routineNetlinkListener() {
|
||||
defer func() {
|
||||
unix.Close(tap.netlinkSock)
|
||||
tap.hackListenerClosed.Lock()
|
||||
close(tap.events)
|
||||
tap.netlinkCancel.Close()
|
||||
}()
|
||||
|
||||
for msg := make([]byte, 1<<16); ; {
|
||||
var err error
|
||||
var msgn int
|
||||
for {
|
||||
msgn, _, _, _, err = unix.Recvmsg(tap.netlinkSock, msg[:], nil, 0)
|
||||
if err == nil || !rwcancel.RetryAfterError(err) {
|
||||
break
|
||||
}
|
||||
if !tap.netlinkCancel.ReadyRead() {
|
||||
tap.errors <- fmt.Errorf("netlink socket closed: %w", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
tap.errors <- fmt.Errorf("failed to receive netlink message: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-tap.statusListenersShutdown:
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
wasEverUp := false
|
||||
for remain := msg[:msgn]; len(remain) >= unix.SizeofNlMsghdr; {
|
||||
|
||||
hdr := *(*unix.NlMsghdr)(unsafe.Pointer(&remain[0]))
|
||||
|
||||
if int(hdr.Len) > len(remain) {
|
||||
break
|
||||
}
|
||||
|
||||
switch hdr.Type {
|
||||
case unix.NLMSG_DONE:
|
||||
remain = []byte{}
|
||||
|
||||
case unix.RTM_NEWLINK:
|
||||
info := *(*unix.IfInfomsg)(unsafe.Pointer(&remain[unix.SizeofNlMsghdr]))
|
||||
remain = remain[hdr.Len:]
|
||||
|
||||
if info.Index != tap.index {
|
||||
// not our interface
|
||||
continue
|
||||
}
|
||||
|
||||
if info.Flags&unix.IFF_RUNNING != 0 {
|
||||
tap.events <- EventUp
|
||||
wasEverUp = true
|
||||
}
|
||||
|
||||
if info.Flags&unix.IFF_RUNNING == 0 {
|
||||
// Don't emit EventDown before we've ever emitted EventUp.
|
||||
// This avoids a startup race with HackListener, which
|
||||
// might detect Up before we have finished reporting Down.
|
||||
if wasEverUp {
|
||||
tap.events <- EventDown
|
||||
}
|
||||
}
|
||||
|
||||
tap.events <- EventMTUUpdate
|
||||
|
||||
default:
|
||||
remain = remain[hdr.Len:]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (tap *NativeTap) setMacAddr(mac MacAddress) (err error) {
|
||||
fd, err := unix.Socket(
|
||||
unix.AF_INET,
|
||||
unix.SOCK_DGRAM,
|
||||
0,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer unix.Close(fd)
|
||||
var ifr [ifReqSize]byte
|
||||
name, err := tap.Name()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
/*
|
||||
ifreq = struct.pack('16sH6B8x', self.name, AF_UNIX, *macbytes)
|
||||
fcntl.ioctl(sockfd, SIOCSIFHWADDR, ifreq)
|
||||
*/
|
||||
copy(ifr[:16], name)
|
||||
binary.BigEndian.PutUint16(ifr[16:18], unix.AF_UNIX)
|
||||
copy(ifr[18:24], mac[:])
|
||||
copy(ifr[24:32], make([]byte, 8))
|
||||
_, _, err = unix.Syscall(
|
||||
unix.SYS_IOCTL,
|
||||
uintptr(fd),
|
||||
uintptr(unix.SIOCSIFHWADDR),
|
||||
uintptr(unsafe.Pointer(&ifr[0])),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
func getIFIndex(name string) (int32, error) {
|
||||
fd, err := unix.Socket(
|
||||
unix.AF_INET,
|
||||
unix.SOCK_DGRAM,
|
||||
0,
|
||||
)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
defer unix.Close(fd)
|
||||
|
||||
var ifr [ifReqSize]byte
|
||||
copy(ifr[:], name)
|
||||
_, _, errno := unix.Syscall(
|
||||
unix.SYS_IOCTL,
|
||||
uintptr(fd),
|
||||
uintptr(unix.SIOCGIFINDEX),
|
||||
uintptr(unsafe.Pointer(&ifr[0])),
|
||||
)
|
||||
|
||||
if errno != 0 {
|
||||
return 0, errno
|
||||
}
|
||||
|
||||
return *(*int32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])), nil
|
||||
}
|
||||
|
||||
func (tap *NativeTap) setMTU(n int) error {
|
||||
name, err := tap.Name()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// open datagram socket
|
||||
fd, err := unix.Socket(
|
||||
unix.AF_INET,
|
||||
unix.SOCK_DGRAM,
|
||||
0,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer unix.Close(fd)
|
||||
|
||||
// do ioctl call
|
||||
var ifr [ifReqSize]byte
|
||||
copy(ifr[:], name)
|
||||
*(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = uint32(n)
|
||||
_, _, errno := unix.Syscall(
|
||||
unix.SYS_IOCTL,
|
||||
uintptr(fd),
|
||||
uintptr(unix.SIOCSIFMTU),
|
||||
uintptr(unsafe.Pointer(&ifr[0])),
|
||||
)
|
||||
|
||||
if errno != 0 {
|
||||
return fmt.Errorf("failed to set MTU of TUN device: %w", errno)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tap *NativeTap) MTU() (int, error) {
|
||||
name, err := tap.Name()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// open datagram socket
|
||||
fd, err := unix.Socket(
|
||||
unix.AF_INET,
|
||||
unix.SOCK_DGRAM,
|
||||
0,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
defer unix.Close(fd)
|
||||
|
||||
// do ioctl call
|
||||
|
||||
var ifr [ifReqSize]byte
|
||||
copy(ifr[:], name)
|
||||
_, _, errno := unix.Syscall(
|
||||
unix.SYS_IOCTL,
|
||||
uintptr(fd),
|
||||
uintptr(unix.SIOCGIFMTU),
|
||||
uintptr(unsafe.Pointer(&ifr[0])),
|
||||
)
|
||||
if errno != 0 {
|
||||
return 0, fmt.Errorf("failed to get MTU of TUN device: %w", errno)
|
||||
}
|
||||
|
||||
return int(*(*int32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ]))), nil
|
||||
}
|
||||
|
||||
func (tap *NativeTap) Name() (string, error) {
|
||||
tap.nameOnce.Do(tap.initNameCache)
|
||||
return tap.nameCache, tap.nameErr
|
||||
}
|
||||
|
||||
func (tap *NativeTap) initNameCache() {
|
||||
tap.nameCache, tap.nameErr = tap.nameSlow()
|
||||
}
|
||||
|
||||
func (tap *NativeTap) nameSlow() (string, error) {
|
||||
sysconn, err := tap.tapFile.SyscallConn()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var ifr [ifReqSize]byte
|
||||
var errno syscall.Errno
|
||||
err = sysconn.Control(func(fd uintptr) {
|
||||
_, _, errno = unix.Syscall(
|
||||
unix.SYS_IOCTL,
|
||||
fd,
|
||||
uintptr(unix.TUNGETIFF),
|
||||
uintptr(unsafe.Pointer(&ifr[0])),
|
||||
)
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get name of TUN device: %w", err)
|
||||
}
|
||||
if errno != 0 {
|
||||
return "", fmt.Errorf("failed to get name of TUN device: %w", errno)
|
||||
}
|
||||
name := ifr[:]
|
||||
if i := bytes.IndexByte(name, 0); i != -1 {
|
||||
name = name[:i]
|
||||
}
|
||||
return string(name), nil
|
||||
}
|
||||
|
||||
func (tap *NativeTap) Write(buf []byte, offset int) (int, error) {
|
||||
buf = buf[offset:]
|
||||
n, err := tap.tapFile.Write(buf)
|
||||
if errors.Is(err, syscall.EBADFD) {
|
||||
err = os.ErrClosed
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (tap *NativeTap) Flush() error {
|
||||
// TODO: can flushing be implemented by buffering and using sendmmsg?
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tap *NativeTap) Read(buf []byte, offset int) (n int, err error) {
|
||||
select {
|
||||
case err = <-tap.errors:
|
||||
default:
|
||||
n, err = tap.tapFile.Read(buf[offset:])
|
||||
if errors.Is(err, syscall.EBADFD) {
|
||||
err = os.ErrClosed
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (tap *NativeTap) Events() chan Event {
|
||||
return tap.events
|
||||
}
|
||||
|
||||
func (tap *NativeTap) Close() error {
|
||||
var err1, err2 error
|
||||
tap.closeOnce.Do(func() {
|
||||
if tap.statusListenersShutdown != nil {
|
||||
close(tap.statusListenersShutdown)
|
||||
if tap.netlinkCancel != nil {
|
||||
err1 = tap.netlinkCancel.Cancel()
|
||||
}
|
||||
} else if tap.events != nil {
|
||||
close(tap.events)
|
||||
}
|
||||
err2 = tap.tapFile.Close()
|
||||
})
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
return err2
|
||||
}
|
||||
|
||||
func CreateTAP(iconfig config.InterfaceConf) (Device, error) {
|
||||
nfd, err := unix.Open(cloneDevicePath, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("CreateTAP(%q) failed; %s does not exist", iconfig.Name, cloneDevicePath)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ifr [ifReqSize]byte
|
||||
var flags uint16 = unix.IFF_TAP | unix.IFF_NO_PI // (disabled for TUN status hack)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR: Failed parse mac address:", iconfig.MacAddrPrefix)
|
||||
return nil, err
|
||||
}
|
||||
nameBytes := []byte(iconfig.Name)
|
||||
if len(nameBytes) >= unix.IFNAMSIZ {
|
||||
return nil, fmt.Errorf("interface name too long: %w", unix.ENAMETOOLONG)
|
||||
}
|
||||
copy(ifr[:], nameBytes)
|
||||
*(*uint16)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = flags
|
||||
|
||||
_, _, errno := unix.Syscall(
|
||||
unix.SYS_IOCTL,
|
||||
uintptr(nfd),
|
||||
uintptr(unix.TUNSETIFF),
|
||||
uintptr(unsafe.Pointer(&ifr[0])),
|
||||
)
|
||||
if errno != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
err = unix.SetNonblock(nfd, true)
|
||||
|
||||
// Note that the above -- open,ioctl,nonblock -- must happen prior to handing it to netpoll as below this line.
|
||||
|
||||
fd := os.NewFile(uintptr(nfd), cloneDevicePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return CreateTAPFromFile(fd, iconfig)
|
||||
}
|
||||
|
||||
func CreateTAPFromFile(file *os.File, iconfig config.InterfaceConf) (Device, error) {
|
||||
tap := &NativeTap{
|
||||
tapFile: file,
|
||||
events: make(chan Event, 5),
|
||||
errors: make(chan error, 5),
|
||||
statusListenersShutdown: make(chan struct{}),
|
||||
nopi: false,
|
||||
}
|
||||
|
||||
name, err := tap.Name()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// start event listener
|
||||
|
||||
tap.index, err = getIFIndex(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tap.netlinkSock, err = createNetlinkSocket()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tap.netlinkCancel, err = rwcancel.NewRWCancel(tap.netlinkSock)
|
||||
if err != nil {
|
||||
unix.Close(tap.netlinkSock)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tap.hackListenerClosed.Lock()
|
||||
go tap.routineNetlinkListener()
|
||||
go tap.routineHackListener() // cross namespace
|
||||
|
||||
err = tap.setMTU(iconfig.MTU)
|
||||
if err != nil {
|
||||
unix.Close(tap.netlinkSock)
|
||||
return nil, err
|
||||
}
|
||||
IfMacAddr, err := GetMacAddr(iconfig.MacAddrPrefix, iconfig.VPPIfaceID)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR: Failed parse mac address:", iconfig.MacAddrPrefix)
|
||||
return nil, err
|
||||
}
|
||||
err = tap.setMacAddr(IfMacAddr)
|
||||
if err != nil {
|
||||
unix.Close(tap.netlinkSock)
|
||||
return nil, err
|
||||
}
|
||||
return tap, nil
|
||||
}
|
||||
|
||||
func CreateUnmonitoredTUNFromFD(fd int) (Device, string, error) {
|
||||
err := unix.SetNonblock(fd, true)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
file := os.NewFile(uintptr(fd), "/dev/tap")
|
||||
tap := &NativeTap{
|
||||
tapFile: file,
|
||||
events: make(chan Event, 5),
|
||||
errors: make(chan error, 5),
|
||||
nopi: true,
|
||||
}
|
||||
name, err := tap.Name()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return tap, name, nil
|
||||
}
|
@ -3,42 +3,71 @@ package tap
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
)
|
||||
|
||||
type L2MODE uint8
|
||||
|
||||
const (
|
||||
NoChange L2MODE = iota
|
||||
KeyboardDebug //Register to server
|
||||
BoardcastAndNodeID
|
||||
)
|
||||
|
||||
func GetL2Mode(mode string) L2MODE {
|
||||
switch mode {
|
||||
case "nochg":
|
||||
return NoChange
|
||||
case "kbdbg":
|
||||
return KeyboardDebug
|
||||
case "noL2":
|
||||
return BoardcastAndNodeID
|
||||
}
|
||||
return NoChange
|
||||
}
|
||||
|
||||
type StdIOTap struct {
|
||||
name string
|
||||
mtu int
|
||||
HumanFriendly bool
|
||||
events chan Event
|
||||
name string
|
||||
mtu int
|
||||
macaddr MacAddress
|
||||
L2mode L2MODE
|
||||
events chan Event
|
||||
}
|
||||
|
||||
func Charform2mac(b byte) MacAddress {
|
||||
if b == 'b' {
|
||||
return MacAddress{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
||||
}
|
||||
return MacAddress{0xff, 0xff, 0xff, 0xff, 0xff, b - 48}
|
||||
return MacAddress{0x00, 0x11, 0xff, 0xff, 0xff, b - 48}
|
||||
}
|
||||
func Mac2charForm(m []byte) byte {
|
||||
var M MacAddress
|
||||
copy(M[:], m)
|
||||
if IsBoardCast(M) {
|
||||
if IsNotUnicast(M) {
|
||||
return 'b'
|
||||
}
|
||||
return m[5] + 48
|
||||
}
|
||||
|
||||
// New creates and returns a new TUN interface for the application.
|
||||
func CreateStdIOTAP(interfaceName string, HumanFriendly bool) (tapdev Device, err error) {
|
||||
func CreateStdIOTAP(iconfig config.InterfaceConf) (tapdev Device, err error) {
|
||||
// Setup TUN Config
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
macaddr, err := GetMacAddr(iconfig.MacAddrPrefix, iconfig.VPPIfaceID)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR: Failed parse mac address:", iconfig.MacAddrPrefix)
|
||||
return nil, err
|
||||
}
|
||||
tapdev = &StdIOTap{
|
||||
name: interfaceName,
|
||||
mtu: 1500,
|
||||
HumanFriendly: HumanFriendly,
|
||||
events: make(chan Event, 1<<5),
|
||||
name: iconfig.Name,
|
||||
mtu: 1500,
|
||||
macaddr: macaddr,
|
||||
L2mode: GetL2Mode(iconfig.L2HeaderMode),
|
||||
events: make(chan Event, 1<<5),
|
||||
}
|
||||
tapdev.Events() <- EventUp
|
||||
return
|
||||
@ -48,7 +77,8 @@ func CreateStdIOTAP(interfaceName string, HumanFriendly bool) (tapdev Device, er
|
||||
// Packet on the interface.
|
||||
|
||||
func (tap *StdIOTap) Read(buf []byte, offset int) (int, error) {
|
||||
if tap.HumanFriendly {
|
||||
switch tap.L2mode {
|
||||
case KeyboardDebug:
|
||||
size, err := os.Stdin.Read(buf[offset+10:])
|
||||
packet := buf[offset:]
|
||||
src := Charform2mac(packet[11])
|
||||
@ -56,22 +86,36 @@ func (tap *StdIOTap) Read(buf []byte, offset int) (int, error) {
|
||||
copy(packet[0:6], dst[:])
|
||||
copy(packet[6:12], src[:])
|
||||
return size - 2 + 12, err
|
||||
} else {
|
||||
case BoardcastAndNodeID:
|
||||
size, err := os.Stdin.Read(buf[offset+12:])
|
||||
packet := buf[offset:]
|
||||
src := tap.macaddr
|
||||
dst := Charform2mac('b')
|
||||
copy(packet[0:6], dst[:])
|
||||
copy(packet[6:12], src[:])
|
||||
return size + 12, err
|
||||
default:
|
||||
size, err := os.Stdin.Read(buf[offset:])
|
||||
return size, err
|
||||
}
|
||||
} // read a packet from the device (without any additional headers)
|
||||
func (tap *StdIOTap) Write(buf []byte, offset int) (size int, err error) {
|
||||
packet := buf[offset:]
|
||||
if tap.HumanFriendly {
|
||||
switch tap.L2mode {
|
||||
case KeyboardDebug:
|
||||
src := Mac2charForm(packet[6:12])
|
||||
dst := Mac2charForm(packet[0:6])
|
||||
packet[10] = dst
|
||||
packet[11] = src
|
||||
packet = packet[10:]
|
||||
size, err = os.Stdout.Write(packet[10:])
|
||||
return
|
||||
case BoardcastAndNodeID:
|
||||
size, err = os.Stdout.Write(packet[12:])
|
||||
return
|
||||
default:
|
||||
size, err = os.Stdout.Write(packet)
|
||||
return
|
||||
}
|
||||
size, err = os.Stdout.Write(packet)
|
||||
return
|
||||
} // writes a packet to the device (without any additional headers)
|
||||
func (tap *StdIOTap) Flush() error {
|
||||
return nil
|
||||
|
@ -3,32 +3,41 @@ package tap
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/KusakabeSi/EtherGuardVPN/config"
|
||||
)
|
||||
|
||||
type UdpSockTap struct {
|
||||
name string
|
||||
mtu int
|
||||
recv *net.UDPConn
|
||||
send *net.UDPAddr
|
||||
HumanFriendly bool
|
||||
events chan Event
|
||||
name string
|
||||
mtu int
|
||||
recv *net.UDPConn
|
||||
send *net.UDPAddr
|
||||
L2mode L2MODE
|
||||
macaddr MacAddress
|
||||
events chan Event
|
||||
}
|
||||
|
||||
// New creates and returns a new TUN interface for the application.
|
||||
func CreateUDPSockTAP(interfaceName string, listenAddr *net.UDPAddr, sendAddr *net.UDPAddr, HumanFriendly bool) (tapdev Device, err error) {
|
||||
func CreateUDPSockTAP(iconfig config.InterfaceConf, listenAddr *net.UDPAddr, sendAddr *net.UDPAddr) (tapdev Device, err error) {
|
||||
// Setup TUN Config
|
||||
|
||||
listener, err := net.ListenUDP("udp", listenAddr)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
macaddr, err := GetMacAddr(iconfig.MacAddrPrefix, iconfig.VPPIfaceID)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR: Failed parse mac address:", iconfig.MacAddrPrefix)
|
||||
return nil, err
|
||||
}
|
||||
tapdev = &UdpSockTap{
|
||||
name: interfaceName,
|
||||
mtu: 1500,
|
||||
recv: listener,
|
||||
send: sendAddr,
|
||||
HumanFriendly: HumanFriendly,
|
||||
events: make(chan Event, 1<<5),
|
||||
name: iconfig.Name,
|
||||
mtu: 1500,
|
||||
recv: listener,
|
||||
send: sendAddr,
|
||||
macaddr: macaddr,
|
||||
L2mode: GetL2Mode(iconfig.L2HeaderMode),
|
||||
events: make(chan Event, 1<<5),
|
||||
}
|
||||
tapdev.Events() <- EventUp
|
||||
return
|
||||
@ -38,15 +47,24 @@ func CreateUDPSockTAP(interfaceName string, listenAddr *net.UDPAddr, sendAddr *n
|
||||
// Packet on the interface.
|
||||
|
||||
func (tap *UdpSockTap) Read(buf []byte, offset int) (int, error) {
|
||||
if tap.HumanFriendly {
|
||||
switch tap.L2mode {
|
||||
case KeyboardDebug:
|
||||
size, _, err := tap.recv.ReadFromUDP(buf[offset+10:])
|
||||
packet := buf[offset:]
|
||||
src := Charform2mac(packet[11])
|
||||
dst := Charform2mac(packet[10])
|
||||
copy(packet[0:6], dst[:])
|
||||
copy(packet[6:12], src[:])
|
||||
return size - 2 + 12, err
|
||||
} else {
|
||||
return size + 10, err
|
||||
case BoardcastAndNodeID:
|
||||
size, _, err := tap.recv.ReadFromUDP(buf[offset+12:])
|
||||
packet := buf[offset:]
|
||||
src := tap.macaddr
|
||||
dst := Charform2mac('b')
|
||||
copy(packet[0:6], dst[:])
|
||||
copy(packet[6:12], src[:])
|
||||
return size + 12, err
|
||||
default:
|
||||
size, _, err := tap.recv.ReadFromUDP(buf[offset:])
|
||||
return size, err
|
||||
}
|
||||
@ -54,16 +72,21 @@ func (tap *UdpSockTap) Read(buf []byte, offset int) (int, error) {
|
||||
} // read a packet from the device (without any additional headers)
|
||||
func (tap *UdpSockTap) Write(buf []byte, offset int) (size int, err error) {
|
||||
packet := buf[offset:]
|
||||
if tap.HumanFriendly {
|
||||
switch tap.L2mode {
|
||||
case KeyboardDebug:
|
||||
src := Mac2charForm(packet[6:12])
|
||||
dst := Mac2charForm(packet[0:6])
|
||||
packet[10] = dst
|
||||
packet[11] = src
|
||||
size, err = tap.recv.WriteToUDP(packet[10:], tap.send)
|
||||
return
|
||||
case BoardcastAndNodeID:
|
||||
size, err = tap.recv.WriteToUDP(packet[12:], tap.send)
|
||||
return
|
||||
default:
|
||||
size, err = tap.recv.WriteToUDP(packet, tap.send)
|
||||
return
|
||||
}
|
||||
size, err = tap.recv.WriteToUDP(packet, tap.send)
|
||||
return
|
||||
} // writes a packet to the device (without any additional headers)
|
||||
func (tap *UdpSockTap) Flush() error {
|
||||
return nil
|
||||
|
@ -2,6 +2,7 @@ package tap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -58,7 +59,7 @@ type VppTap struct {
|
||||
}
|
||||
|
||||
// New creates and returns a new TUN interface for the application.
|
||||
func CreateVppTAP(interfaceName string, iconfig config.InterfaceConf, loglevel string) (tapdev Device, err error) {
|
||||
func CreateVppTAP(iconfig config.InterfaceConf, loglevel string) (tapdev Device, err error) {
|
||||
// Setup TUN Config
|
||||
// Set logger
|
||||
log := logger.New()
|
||||
@ -75,10 +76,20 @@ func CreateVppTAP(interfaceName string, iconfig config.InterfaceConf, loglevel s
|
||||
return logger.ErrorLevel
|
||||
}()
|
||||
libmemif.SetLogger(log)
|
||||
if os.Getenv(ENV_VPP_MEMIF_SOCKET_DIR) != "" {
|
||||
vppMemifSocketDir = os.Getenv(ENV_VPP_MEMIF_SOCKET_DIR)
|
||||
}
|
||||
if os.Getenv(ENV_VPP_SOCKET_PATH) != "" {
|
||||
vppApiSocketPath = os.Getenv(ENV_VPP_SOCKET_PATH)
|
||||
}
|
||||
if err := os.MkdirAll(vppMemifSocketDir, 0755); err != nil {
|
||||
log.Fatalln("ERROR: Failed to create VPP memif socket folder " + vppMemifSocketDir)
|
||||
return nil, err
|
||||
}
|
||||
// connect to VPP
|
||||
conn, err := govpp.Connect(vppApiSocketPath)
|
||||
if err != nil {
|
||||
log.Fatalln("ERROR: connecting to VPP failed:", err)
|
||||
log.Fatalln("ERROR: Connecting to VPP failed:", err)
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Disconnect()
|
||||
@ -105,18 +116,19 @@ func CreateVppTAP(interfaceName string, iconfig config.InterfaceConf, loglevel s
|
||||
l2service := l2.NewServiceClient(conn)
|
||||
interfacservice := interfaces.NewServiceClient(conn)
|
||||
|
||||
vppIfMacAddr, err := ethernet_types.ParseMacAddress(iconfig.MacAddr)
|
||||
IfMacAddr, err := GetMacAddr(iconfig.MacAddrPrefix, iconfig.VPPIfaceID)
|
||||
if err != nil {
|
||||
log.Fatalln("ERROR: Failed parse mac address:", iconfig.MacAddr)
|
||||
log.Fatalln("ERROR: Failed parse mac address:", iconfig.MacAddrPrefix)
|
||||
return nil, err
|
||||
}
|
||||
vppIfMacAddr := ethernet_types.MacAddress(IfMacAddr)
|
||||
|
||||
tap := &VppTap{
|
||||
name: iconfig.Name,
|
||||
mtu: iconfig.MTU,
|
||||
ifuid: iconfig.VPPIfaceID,
|
||||
SwIfIndex: 0,
|
||||
memifSockPath: vppMemifSocketDir + "/" + iconfig.Name,
|
||||
memifSockPath: path.Join(vppMemifSocketDir, iconfig.Name+".sock"),
|
||||
secret: config.RandomStr(16, iconfig.Name),
|
||||
logger: log,
|
||||
errors: make(chan error, 1<<5),
|
||||
|
Loading…
Reference in New Issue
Block a user