mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-12-23 16:55:40 +00:00
commit
c9dc9507de
@ -48,19 +48,21 @@ func (c *cryptokey) init(tun *TunAdapter) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
c.tun.log.Debugln("Configuring CKR...")
|
||||||
if err := c.configure(); err != nil {
|
if err := c.configure(); err != nil {
|
||||||
c.tun.log.Errorln("CKR configuration failed:", err)
|
c.tun.log.Errorln("CKR configuration failed:", err)
|
||||||
|
} else {
|
||||||
|
c.tun.log.Debugln("CKR configured")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the CKR routes - this must only ever be called from the router
|
// Configure the CKR routes - this must only ever be called from the router
|
||||||
// goroutine, e.g. through router.doAdmin
|
// goroutine, e.g. through router.doAdmin
|
||||||
func (c *cryptokey) configure() error {
|
func (c *cryptokey) configure() error {
|
||||||
c.tun.config.Mutex.RLock()
|
current, _ := c.tun.config.Get()
|
||||||
defer c.tun.config.Mutex.RUnlock()
|
|
||||||
|
|
||||||
// Set enabled/disabled state
|
// Set enabled/disabled state
|
||||||
c.setEnabled(c.tun.config.Current.TunnelRouting.Enable)
|
c.setEnabled(current.TunnelRouting.Enable)
|
||||||
|
|
||||||
// Clear out existing routes
|
// Clear out existing routes
|
||||||
c.mutexroutes.Lock()
|
c.mutexroutes.Lock()
|
||||||
@ -69,14 +71,14 @@ func (c *cryptokey) configure() error {
|
|||||||
c.mutexroutes.Unlock()
|
c.mutexroutes.Unlock()
|
||||||
|
|
||||||
// Add IPv6 routes
|
// Add IPv6 routes
|
||||||
for ipv6, pubkey := range c.tun.config.Current.TunnelRouting.IPv6Destinations {
|
for ipv6, pubkey := range current.TunnelRouting.IPv6Destinations {
|
||||||
if err := c.addRoute(ipv6, pubkey); err != nil {
|
if err := c.addRoute(ipv6, pubkey); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add IPv4 routes
|
// Add IPv4 routes
|
||||||
for ipv4, pubkey := range c.tun.config.Current.TunnelRouting.IPv4Destinations {
|
for ipv4, pubkey := range current.TunnelRouting.IPv4Destinations {
|
||||||
if err := c.addRoute(ipv4, pubkey); err != nil {
|
if err := c.addRoute(ipv4, pubkey); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -90,7 +92,7 @@ func (c *cryptokey) configure() error {
|
|||||||
|
|
||||||
// Add IPv6 sources
|
// Add IPv6 sources
|
||||||
c.ipv6sources = make([]net.IPNet, 0)
|
c.ipv6sources = make([]net.IPNet, 0)
|
||||||
for _, source := range c.tun.config.Current.TunnelRouting.IPv6Sources {
|
for _, source := range current.TunnelRouting.IPv6Sources {
|
||||||
if err := c.addSourceSubnet(source); err != nil {
|
if err := c.addSourceSubnet(source); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -98,7 +100,7 @@ func (c *cryptokey) configure() error {
|
|||||||
|
|
||||||
// Add IPv4 sources
|
// Add IPv4 sources
|
||||||
c.ipv4sources = make([]net.IPNet, 0)
|
c.ipv4sources = make([]net.IPNet, 0)
|
||||||
for _, source := range c.tun.config.Current.TunnelRouting.IPv4Sources {
|
for _, source := range current.TunnelRouting.IPv4Sources {
|
||||||
if err := c.addSourceSubnet(source); err != nil {
|
if err := c.addSourceSubnet(source); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
@ -21,19 +22,18 @@ import (
|
|||||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||||
)
|
)
|
||||||
|
|
||||||
type macAddress [6]byte
|
|
||||||
|
|
||||||
const len_ETHER = 14
|
const len_ETHER = 14
|
||||||
|
|
||||||
type ICMPv6 struct {
|
type ICMPv6 struct {
|
||||||
tun *TunAdapter
|
tun *TunAdapter
|
||||||
mylladdr net.IP
|
mylladdr net.IP
|
||||||
mymac macAddress
|
mymac net.HardwareAddr
|
||||||
peermacs map[address.Address]neighbor
|
peermacs map[address.Address]neighbor
|
||||||
|
peermacsmutex sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type neighbor struct {
|
type neighbor struct {
|
||||||
mac macAddress
|
mac net.HardwareAddr
|
||||||
learned bool
|
learned bool
|
||||||
lastadvertisement time.Time
|
lastadvertisement time.Time
|
||||||
lastsolicitation time.Time
|
lastsolicitation time.Time
|
||||||
@ -61,10 +61,12 @@ func ipv6Header_Marshal(h *ipv6.Header) ([]byte, error) {
|
|||||||
// addresses.
|
// addresses.
|
||||||
func (i *ICMPv6) Init(t *TunAdapter) {
|
func (i *ICMPv6) Init(t *TunAdapter) {
|
||||||
i.tun = t
|
i.tun = t
|
||||||
|
i.peermacsmutex.Lock()
|
||||||
i.peermacs = make(map[address.Address]neighbor)
|
i.peermacs = make(map[address.Address]neighbor)
|
||||||
|
i.peermacsmutex.Unlock()
|
||||||
|
|
||||||
// Our MAC address and link-local address
|
// Our MAC address and link-local address
|
||||||
i.mymac = macAddress{
|
i.mymac = net.HardwareAddr{
|
||||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x02}
|
0x02, 0x00, 0x00, 0x00, 0x00, 0x02}
|
||||||
i.mylladdr = net.IP{
|
i.mylladdr = net.IP{
|
||||||
0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@ -181,16 +183,30 @@ func (i *ICMPv6) UnmarshalPacket(datain []byte, datamac *[]byte) ([]byte, error)
|
|||||||
if datamac != nil {
|
if datamac != nil {
|
||||||
var addr address.Address
|
var addr address.Address
|
||||||
var target address.Address
|
var target address.Address
|
||||||
var mac macAddress
|
mac := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
copy(addr[:], ipv6Header.Src[:])
|
copy(addr[:], ipv6Header.Src[:])
|
||||||
copy(target[:], datain[48:64])
|
copy(target[:], datain[48:64])
|
||||||
copy(mac[:], (*datamac)[:])
|
copy(mac[:], (*datamac)[:])
|
||||||
// fmt.Printf("Learning peer MAC %x for %x\n", mac, target)
|
i.peermacsmutex.Lock()
|
||||||
neighbor := i.peermacs[target]
|
neighbor := i.peermacs[target]
|
||||||
neighbor.mac = mac
|
neighbor.mac = mac
|
||||||
neighbor.learned = true
|
neighbor.learned = true
|
||||||
neighbor.lastadvertisement = time.Now()
|
neighbor.lastadvertisement = time.Now()
|
||||||
i.peermacs[target] = neighbor
|
i.peermacs[target] = neighbor
|
||||||
|
i.peermacsmutex.Unlock()
|
||||||
|
i.tun.log.Debugln("Learned peer MAC", mac.String(), "for", net.IP(target[:]).String())
|
||||||
|
/*
|
||||||
|
i.tun.log.Debugln("Peer MAC table:")
|
||||||
|
i.peermacsmutex.RLock()
|
||||||
|
for t, n := range i.peermacs {
|
||||||
|
if n.learned {
|
||||||
|
i.tun.log.Debugln("- Target", net.IP(t[:]).String(), "has MAC", n.mac.String())
|
||||||
|
} else {
|
||||||
|
i.tun.log.Debugln("- Target", net.IP(t[:]).String(), "is not learned yet")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i.peermacsmutex.RUnlock()
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
return nil, errors.New("No response needed")
|
return nil, errors.New("No response needed")
|
||||||
}
|
}
|
||||||
@ -201,7 +217,7 @@ func (i *ICMPv6) UnmarshalPacket(datain []byte, datamac *[]byte) ([]byte, error)
|
|||||||
// Creates an ICMPv6 packet based on the given icmp.MessageBody and other
|
// Creates an ICMPv6 packet based on the given icmp.MessageBody and other
|
||||||
// parameters, complete with ethernet and IP headers, which can be written
|
// parameters, complete with ethernet and IP headers, which can be written
|
||||||
// directly to a TAP adapter.
|
// directly to a TAP adapter.
|
||||||
func (i *ICMPv6) CreateICMPv6L2(dstmac macAddress, dst net.IP, src net.IP, mtype ipv6.ICMPType, mcode int, mbody icmp.MessageBody) ([]byte, error) {
|
func (i *ICMPv6) CreateICMPv6L2(dstmac net.HardwareAddr, dst net.IP, src net.IP, mtype ipv6.ICMPType, mcode int, mbody icmp.MessageBody) ([]byte, error) {
|
||||||
// Pass through to CreateICMPv6
|
// Pass through to CreateICMPv6
|
||||||
ipv6packet, err := CreateICMPv6(dst, src, mtype, mcode, mbody)
|
ipv6packet, err := CreateICMPv6(dst, src, mtype, mcode, mbody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -264,13 +280,54 @@ func CreateICMPv6(dst net.IP, src net.IP, mtype ipv6.ICMPType, mcode int, mbody
|
|||||||
return responsePacket, nil
|
return responsePacket, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ICMPv6) CreateNDPL2(dst address.Address) ([]byte, error) {
|
func (i *ICMPv6) Solicit(addr address.Address) {
|
||||||
|
retries := 5
|
||||||
|
for retries > 0 {
|
||||||
|
retries--
|
||||||
|
i.peermacsmutex.RLock()
|
||||||
|
if n, ok := i.peermacs[addr]; ok && n.learned {
|
||||||
|
i.tun.log.Debugln("MAC learned for", net.IP(addr[:]).String())
|
||||||
|
i.peermacsmutex.RUnlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i.peermacsmutex.RUnlock()
|
||||||
|
i.tun.log.Debugln("Sending neighbor solicitation for", net.IP(addr[:]).String())
|
||||||
|
i.peermacsmutex.Lock()
|
||||||
|
if n, ok := i.peermacs[addr]; !ok {
|
||||||
|
i.peermacs[addr] = neighbor{
|
||||||
|
lastsolicitation: time.Now(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
n.lastsolicitation = time.Now()
|
||||||
|
}
|
||||||
|
i.peermacsmutex.Unlock()
|
||||||
|
request, err := i.createNDPL2(addr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if _, err := i.tun.iface.Write(request); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
i.tun.log.Debugln("Sent neighbor solicitation for", net.IP(addr[:]).String())
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ICMPv6) getNeighbor(addr address.Address) (neighbor, bool) {
|
||||||
|
i.peermacsmutex.RLock()
|
||||||
|
defer i.peermacsmutex.RUnlock()
|
||||||
|
|
||||||
|
n, ok := i.peermacs[addr]
|
||||||
|
return n, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ICMPv6) createNDPL2(dst address.Address) ([]byte, error) {
|
||||||
// Create the ND payload
|
// Create the ND payload
|
||||||
var payload [28]byte
|
var payload [28]byte
|
||||||
copy(payload[:4], []byte{0x00, 0x00, 0x00, 0x00})
|
copy(payload[:4], []byte{0x00, 0x00, 0x00, 0x00}) // Flags
|
||||||
copy(payload[4:20], dst[:])
|
copy(payload[4:20], dst[:]) // Destination
|
||||||
copy(payload[20:22], []byte{0x01, 0x01})
|
copy(payload[20:22], []byte{0x01, 0x01}) // Type & length
|
||||||
copy(payload[22:28], i.mymac[:6])
|
copy(payload[22:28], i.mymac[:6]) // Link layer address
|
||||||
|
|
||||||
// Create the ICMPv6 solicited-node address
|
// Create the ICMPv6 solicited-node address
|
||||||
var dstaddr address.Address
|
var dstaddr address.Address
|
||||||
@ -281,7 +338,7 @@ func (i *ICMPv6) CreateNDPL2(dst address.Address) ([]byte, error) {
|
|||||||
copy(dstaddr[13:], dst[13:16])
|
copy(dstaddr[13:], dst[13:16])
|
||||||
|
|
||||||
// Create the multicast MAC
|
// Create the multicast MAC
|
||||||
var dstmac macAddress
|
dstmac := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
copy(dstmac[:2], []byte{0x33, 0x33})
|
copy(dstmac[:2], []byte{0x33, 0x33})
|
||||||
copy(dstmac[2:6], dstaddr[12:16])
|
copy(dstmac[2:6], dstaddr[12:16])
|
||||||
|
|
||||||
@ -293,9 +350,6 @@ func (i *ICMPv6) CreateNDPL2(dst address.Address) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
neighbor := i.peermacs[dstaddr]
|
|
||||||
neighbor.lastsolicitation = time.Now()
|
|
||||||
i.peermacs[dstaddr] = neighbor
|
|
||||||
|
|
||||||
return requestPacket, nil
|
return requestPacket, nil
|
||||||
}
|
}
|
||||||
@ -319,10 +373,10 @@ func (i *ICMPv6) HandleNDP(in []byte) ([]byte, error) {
|
|||||||
|
|
||||||
// Create our NDP message body response
|
// Create our NDP message body response
|
||||||
body := make([]byte, 28)
|
body := make([]byte, 28)
|
||||||
binary.BigEndian.PutUint32(body[:4], uint32(0x20000000))
|
binary.BigEndian.PutUint32(body[:4], uint32(0x40000000)) // Flags
|
||||||
copy(body[4:20], in[8:24]) // Target address
|
copy(body[4:20], in[8:24]) // Target address
|
||||||
body[20] = uint8(2)
|
body[20] = uint8(2) // Type: Target link-layer address
|
||||||
body[21] = uint8(1)
|
body[21] = uint8(1) // Length: 1x address (8 bytes)
|
||||||
copy(body[22:28], i.mymac[:6])
|
copy(body[22:28], i.mymac[:6])
|
||||||
|
|
||||||
// Send it back
|
// Send it back
|
||||||
|
@ -3,6 +3,7 @@ package tuntap
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/songgao/packets/ethernet"
|
"github.com/songgao/packets/ethernet"
|
||||||
@ -40,22 +41,13 @@ func (tun *TunAdapter) writer() error {
|
|||||||
return errors.New("Invalid address family")
|
return errors.New("Invalid address family")
|
||||||
}
|
}
|
||||||
sendndp := func(dstAddr address.Address) {
|
sendndp := func(dstAddr address.Address) {
|
||||||
neigh, known := tun.icmpv6.peermacs[dstAddr]
|
neigh, known := tun.icmpv6.getNeighbor(dstAddr)
|
||||||
known = known && (time.Since(neigh.lastsolicitation).Seconds() < 30)
|
known = known && (time.Since(neigh.lastsolicitation).Seconds() < 30)
|
||||||
if !known {
|
if !known {
|
||||||
request, err := tun.icmpv6.CreateNDPL2(dstAddr)
|
tun.icmpv6.Solicit(dstAddr)
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if _, err := tun.iface.Write(request); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
tun.icmpv6.peermacs[dstAddr] = neighbor{
|
|
||||||
lastsolicitation: time.Now(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
peermac := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
var peermac macAddress
|
|
||||||
var peerknown bool
|
var peerknown bool
|
||||||
if b[0]&0xf0 == 0x40 {
|
if b[0]&0xf0 == 0x40 {
|
||||||
dstAddr = tun.addr
|
dstAddr = tun.addr
|
||||||
@ -64,15 +56,20 @@ func (tun *TunAdapter) writer() error {
|
|||||||
dstAddr = tun.addr
|
dstAddr = tun.addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if neighbor, ok := tun.icmpv6.peermacs[dstAddr]; ok && neighbor.learned {
|
if neighbor, ok := tun.icmpv6.getNeighbor(dstAddr); ok && neighbor.learned {
|
||||||
|
// If we've learned the MAC of a 300::/7 address, for example, or a CKR
|
||||||
|
// address, use the MAC address of that
|
||||||
peermac = neighbor.mac
|
peermac = neighbor.mac
|
||||||
peerknown = true
|
peerknown = true
|
||||||
} else if neighbor, ok := tun.icmpv6.peermacs[tun.addr]; ok && neighbor.learned {
|
} else if neighbor, ok := tun.icmpv6.getNeighbor(tun.addr); ok && neighbor.learned {
|
||||||
|
// Otherwise send directly to the MAC address of the host if that's
|
||||||
|
// known instead
|
||||||
peermac = neighbor.mac
|
peermac = neighbor.mac
|
||||||
peerknown = true
|
peerknown = true
|
||||||
sendndp(dstAddr)
|
|
||||||
} else {
|
} else {
|
||||||
|
// Nothing has been discovered, try to discover the destination
|
||||||
sendndp(tun.addr)
|
sendndp(tun.addr)
|
||||||
|
|
||||||
}
|
}
|
||||||
if peerknown {
|
if peerknown {
|
||||||
var proto ethernet.Ethertype
|
var proto ethernet.Ethertype
|
||||||
@ -92,6 +89,8 @@ func (tun *TunAdapter) writer() error {
|
|||||||
copy(frame[tun_ETHER_HEADER_LENGTH:], b[:n])
|
copy(frame[tun_ETHER_HEADER_LENGTH:], b[:n])
|
||||||
n += tun_ETHER_HEADER_LENGTH
|
n += tun_ETHER_HEADER_LENGTH
|
||||||
w, err = tun.iface.Write(frame[:n])
|
w, err = tun.iface.Write(frame[:n])
|
||||||
|
} else {
|
||||||
|
tun.log.Errorln("TUN/TAP iface write error: no peer MAC known for", net.IP(dstAddr[:]).String(), "- dropping packet")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
w, err = tun.iface.Write(b[:n])
|
w, err = tun.iface.Write(b[:n])
|
||||||
@ -184,7 +183,7 @@ func (tun *TunAdapter) reader() error {
|
|||||||
// Unknown address length or protocol, so drop the packet and ignore it
|
// Unknown address length or protocol, so drop the packet and ignore it
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !tun.ckr.isValidSource(srcAddr, addrlen) {
|
if tun.ckr.isEnabled() && !tun.ckr.isValidSource(srcAddr, addrlen) {
|
||||||
// The packet had a source address that doesn't belong to us or our
|
// The packet had a source address that doesn't belong to us or our
|
||||||
// configured crypto-key routing source subnets
|
// configured crypto-key routing source subnets
|
||||||
continue
|
continue
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gologme/log"
|
"github.com/gologme/log"
|
||||||
"github.com/yggdrasil-network/water"
|
"github.com/yggdrasil-network/water"
|
||||||
@ -120,13 +119,12 @@ func (tun *TunAdapter) Init(config *config.NodeState, log *log.Logger, listener
|
|||||||
// Start the setup process for the TUN/TAP adapter. If successful, starts the
|
// Start the setup process for the TUN/TAP adapter. If successful, starts the
|
||||||
// read/write goroutines to handle packets on that interface.
|
// read/write goroutines to handle packets on that interface.
|
||||||
func (tun *TunAdapter) Start() error {
|
func (tun *TunAdapter) Start() error {
|
||||||
tun.config.Mutex.RLock()
|
current, _ := tun.config.Get()
|
||||||
defer tun.config.Mutex.RUnlock()
|
|
||||||
if tun.config == nil || tun.listener == nil || tun.dialer == nil {
|
if tun.config == nil || tun.listener == nil || tun.dialer == nil {
|
||||||
return errors.New("No configuration available to TUN/TAP")
|
return errors.New("No configuration available to TUN/TAP")
|
||||||
}
|
}
|
||||||
var boxPub crypto.BoxPubKey
|
var boxPub crypto.BoxPubKey
|
||||||
boxPubHex, err := hex.DecodeString(tun.config.Current.EncryptionPublicKey)
|
boxPubHex, err := hex.DecodeString(current.EncryptionPublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -134,9 +132,9 @@ func (tun *TunAdapter) Start() error {
|
|||||||
nodeID := crypto.GetNodeID(&boxPub)
|
nodeID := crypto.GetNodeID(&boxPub)
|
||||||
tun.addr = *address.AddrForNodeID(nodeID)
|
tun.addr = *address.AddrForNodeID(nodeID)
|
||||||
tun.subnet = *address.SubnetForNodeID(nodeID)
|
tun.subnet = *address.SubnetForNodeID(nodeID)
|
||||||
tun.mtu = tun.config.Current.IfMTU
|
tun.mtu = current.IfMTU
|
||||||
ifname := tun.config.Current.IfName
|
ifname := current.IfName
|
||||||
iftapmode := tun.config.Current.IfTAPMode
|
iftapmode := current.IfTAPMode
|
||||||
addr := fmt.Sprintf("%s/%d", net.IP(tun.addr[:]).String(), 8*len(address.GetPrefix())-1)
|
addr := fmt.Sprintf("%s/%d", net.IP(tun.addr[:]).String(), 8*len(address.GetPrefix())-1)
|
||||||
if ifname != "none" {
|
if ifname != "none" {
|
||||||
if err := tun.setup(ifname, iftapmode, addr, tun.mtu); err != nil {
|
if err := tun.setup(ifname, iftapmode, addr, tun.mtu); err != nil {
|
||||||
@ -152,21 +150,6 @@ func (tun *TunAdapter) Start() error {
|
|||||||
tun.send = make(chan []byte, 32) // TODO: is this a sensible value?
|
tun.send = make(chan []byte, 32) // TODO: is this a sensible value?
|
||||||
tun.reconfigure = make(chan chan error)
|
tun.reconfigure = make(chan chan error)
|
||||||
tun.mutex.Unlock()
|
tun.mutex.Unlock()
|
||||||
if iftapmode {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
if _, ok := tun.icmpv6.peermacs[tun.addr]; ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
request, err := tun.icmpv6.CreateNDPL2(tun.addr)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
tun.send <- request
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
e := <-tun.reconfigure
|
e := <-tun.reconfigure
|
||||||
@ -177,6 +160,9 @@ func (tun *TunAdapter) Start() error {
|
|||||||
go tun.reader()
|
go tun.reader()
|
||||||
go tun.writer()
|
go tun.writer()
|
||||||
tun.icmpv6.Init(tun)
|
tun.icmpv6.Init(tun)
|
||||||
|
if iftapmode {
|
||||||
|
go tun.icmpv6.Solicit(tun.addr)
|
||||||
|
}
|
||||||
tun.ckr.init(tun)
|
tun.ckr.init(tun)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -31,18 +31,18 @@ func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int
|
|||||||
}
|
}
|
||||||
// Disable/enable the interface to resets its configuration (invalidating iface)
|
// Disable/enable the interface to resets its configuration (invalidating iface)
|
||||||
cmd := exec.Command("netsh", "interface", "set", "interface", iface.Name(), "admin=DISABLED")
|
cmd := exec.Command("netsh", "interface", "set", "interface", iface.Name(), "admin=DISABLED")
|
||||||
tun.log.Printf("netsh command: %v", strings.Join(cmd.Args, " "))
|
tun.log.Debugln("netsh command:", strings.Join(cmd.Args, " "))
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.log.Errorf("Windows netsh failed: %v.", err)
|
tun.log.Errorln("Windows netsh failed:", err)
|
||||||
tun.log.Traceln(string(output))
|
tun.log.Traceln(string(output))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cmd = exec.Command("netsh", "interface", "set", "interface", iface.Name(), "admin=ENABLED")
|
cmd = exec.Command("netsh", "interface", "set", "interface", iface.Name(), "admin=ENABLED")
|
||||||
tun.log.Printf("netsh command: %v", strings.Join(cmd.Args, " "))
|
tun.log.Debugln("netsh command:", strings.Join(cmd.Args, " "))
|
||||||
output, err = cmd.CombinedOutput()
|
output, err = cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.log.Errorf("Windows netsh failed: %v.", err)
|
tun.log.Errorln("Windows netsh failed:", err)
|
||||||
tun.log.Traceln(string(output))
|
tun.log.Traceln(string(output))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -71,10 +71,10 @@ func (tun *TunAdapter) setupMTU(mtu int) error {
|
|||||||
fmt.Sprintf("interface=%s", tun.iface.Name()),
|
fmt.Sprintf("interface=%s", tun.iface.Name()),
|
||||||
fmt.Sprintf("mtu=%d", mtu),
|
fmt.Sprintf("mtu=%d", mtu),
|
||||||
"store=active")
|
"store=active")
|
||||||
tun.log.Debugln("netsh command: %v", strings.Join(cmd.Args, " "))
|
tun.log.Debugln("netsh command:", strings.Join(cmd.Args, " "))
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.log.Errorf("Windows netsh failed: %v.", err)
|
tun.log.Errorln("Windows netsh failed:", err)
|
||||||
tun.log.Traceln(string(output))
|
tun.log.Traceln(string(output))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -88,10 +88,10 @@ func (tun *TunAdapter) setupAddress(addr string) error {
|
|||||||
fmt.Sprintf("interface=%s", tun.iface.Name()),
|
fmt.Sprintf("interface=%s", tun.iface.Name()),
|
||||||
fmt.Sprintf("addr=%s", addr),
|
fmt.Sprintf("addr=%s", addr),
|
||||||
"store=active")
|
"store=active")
|
||||||
tun.log.Debugln("netsh command: %v", strings.Join(cmd.Args, " "))
|
tun.log.Debugln("netsh command:", strings.Join(cmd.Args, " "))
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.log.Errorf("Windows netsh failed: %v.", err)
|
tun.log.Errorln("Windows netsh failed:", err)
|
||||||
tun.log.Traceln(string(output))
|
tun.log.Traceln(string(output))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user