mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	mostly finish migration of IP stuff to core, tuntap is still responsible for ICMP PacketTooBig
This commit is contained in:
		
							parent
							
								
									1147ee1934
								
							
						
					
					
						commit
						816356ea65
					
				
					 7 changed files with 114 additions and 185 deletions
				
			
		| 
						 | 
					@ -222,3 +222,28 @@ func (c *Core) RemovePeer(addr string, sintf string) error {
 | 
				
			||||||
func (c *Core) CallPeer(u *url.URL, sintf string) error {
 | 
					func (c *Core) CallPeer(u *url.URL, sintf string) error {
 | 
				
			||||||
	return c.links.call(u, sintf)
 | 
						return c.links.call(u, sintf)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Core) PublicKey() ed25519.PublicKey {
 | 
				
			||||||
 | 
						return c.public
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Core) MaxMTU() uint64 {
 | 
				
			||||||
 | 
						return c.store.maxSessionMTU()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Implement io.ReadWriteCloser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Core) Read(p []byte) (n int, err error) {
 | 
				
			||||||
 | 
						n, err = c.store.readPC(p)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Core) Write(p []byte) (n int, err error) {
 | 
				
			||||||
 | 
						n, err = c.store.writePC(p)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Core) Close() error {
 | 
				
			||||||
 | 
						c.Stop()
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ import (
 | 
				
			||||||
	"crypto/ed25519"
 | 
						"crypto/ed25519"
 | 
				
			||||||
	"encoding/hex"
 | 
						"encoding/hex"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
| 
						 | 
					@ -25,13 +26,13 @@ type Core struct {
 | 
				
			||||||
	// We're going to keep our own copy of the provided config - that way we can
 | 
						// We're going to keep our own copy of the provided config - that way we can
 | 
				
			||||||
	// guarantee that it will be covered by the mutex
 | 
						// guarantee that it will be covered by the mutex
 | 
				
			||||||
	phony.Inbox
 | 
						phony.Inbox
 | 
				
			||||||
	pc *iw.PacketConn
 | 
						pc           *iw.PacketConn
 | 
				
			||||||
	config       *config.NodeConfig // Config
 | 
						config       *config.NodeConfig // Config
 | 
				
			||||||
	secret       ed25519.PrivateKey
 | 
						secret       ed25519.PrivateKey
 | 
				
			||||||
	public       ed25519.PublicKey
 | 
						public       ed25519.PublicKey
 | 
				
			||||||
	links        links
 | 
						links        links
 | 
				
			||||||
	proto     protoHandler
 | 
						proto        protoHandler
 | 
				
			||||||
	store       keyStore
 | 
						store        keyStore
 | 
				
			||||||
	log          *log.Logger
 | 
						log          *log.Logger
 | 
				
			||||||
	addPeerTimer *time.Timer
 | 
						addPeerTimer *time.Timer
 | 
				
			||||||
	ctx          context.Context
 | 
						ctx          context.Context
 | 
				
			||||||
| 
						 | 
					@ -43,13 +44,13 @@ func (c *Core) _init() error {
 | 
				
			||||||
	//  Init sets up structs
 | 
						//  Init sets up structs
 | 
				
			||||||
	//  Start launches goroutines that depend on structs being set up
 | 
						//  Start launches goroutines that depend on structs being set up
 | 
				
			||||||
	// This is pretty much required to completely avoid race conditions
 | 
						// This is pretty much required to completely avoid race conditions
 | 
				
			||||||
 | 
						c.config.RLock()
 | 
				
			||||||
 | 
						defer c.config.RUnlock()
 | 
				
			||||||
	if c.log == nil {
 | 
						if c.log == nil {
 | 
				
			||||||
		c.log = log.New(ioutil.Discard, "", 0)
 | 
							c.log = log.New(ioutil.Discard, "", 0)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.config.RLock()
 | 
					 | 
				
			||||||
	sigPriv, err := hex.DecodeString(c.config.PrivateKey)
 | 
						sigPriv, err := hex.DecodeString(c.config.PrivateKey)
 | 
				
			||||||
	c.config.RUnlock()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -65,6 +66,9 @@ func (c *Core) _init() error {
 | 
				
			||||||
	c.ctx, c.ctxCancel = context.WithCancel(context.Background())
 | 
						c.ctx, c.ctxCancel = context.WithCancel(context.Background())
 | 
				
			||||||
	c.store.init(c)
 | 
						c.store.init(c)
 | 
				
			||||||
	c.proto.init(c)
 | 
						c.proto.init(c)
 | 
				
			||||||
 | 
						if err := c.proto.nodeinfo.setNodeInfo(c.config.NodeInfo, c.config.NodeInfoPrivacy); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("setNodeInfo: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -177,20 +181,3 @@ func (c *Core) _stop() {
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	c.log.Infoln("Stopped")
 | 
						c.log.Infoln("Stopped")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// Implement io.ReadWriteCloser
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Core) Read(p []byte) (n int, err error) {
 | 
					 | 
				
			||||||
  n, err = c.store.readPC(p)
 | 
					 | 
				
			||||||
  return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Core) Write(p []byte) (n int, err error) {
 | 
					 | 
				
			||||||
  n, err = c.store.writePC(p)
 | 
					 | 
				
			||||||
  return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *Core) Close() error {
 | 
					 | 
				
			||||||
  c.Stop()
 | 
					 | 
				
			||||||
  return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ const keyStoreTimeout = 2 * time.Minute
 | 
				
			||||||
type keyArray [ed25519.PublicKeySize]byte
 | 
					type keyArray [ed25519.PublicKeySize]byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type keyStore struct {
 | 
					type keyStore struct {
 | 
				
			||||||
	core    *Core
 | 
						core         *Core
 | 
				
			||||||
	address      address.Address
 | 
						address      address.Address
 | 
				
			||||||
	subnet       address.Subnet
 | 
						subnet       address.Subnet
 | 
				
			||||||
	mutex        sync.Mutex
 | 
						mutex        sync.Mutex
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,6 @@ type keyStore struct {
 | 
				
			||||||
	addrBuffer   map[address.Address]*buffer
 | 
						addrBuffer   map[address.Address]*buffer
 | 
				
			||||||
	subnetToInfo map[address.Subnet]*keyInfo
 | 
						subnetToInfo map[address.Subnet]*keyInfo
 | 
				
			||||||
	subnetBuffer map[address.Subnet]*buffer
 | 
						subnetBuffer map[address.Subnet]*buffer
 | 
				
			||||||
	buf []byte // scratch space to prefix with typeSessionTraffic before sending
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type keyInfo struct {
 | 
					type keyInfo struct {
 | 
				
			||||||
| 
						 | 
					@ -45,7 +44,10 @@ func (k *keyStore) init(core *Core) {
 | 
				
			||||||
	k.core = core
 | 
						k.core = core
 | 
				
			||||||
	k.address = *address.AddrForKey(k.core.public)
 | 
						k.address = *address.AddrForKey(k.core.public)
 | 
				
			||||||
	k.subnet = *address.SubnetForKey(k.core.public)
 | 
						k.subnet = *address.SubnetForKey(k.core.public)
 | 
				
			||||||
	k.core.pc.SetOutOfBandHandler(k.oobHandler)
 | 
						if err := k.core.pc.SetOutOfBandHandler(k.oobHandler); err != nil {
 | 
				
			||||||
 | 
							err = fmt.Errorf("tun.core.SetOutOfBandHander: %w", err)
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	k.keyToInfo = make(map[keyArray]*keyInfo)
 | 
						k.keyToInfo = make(map[keyArray]*keyInfo)
 | 
				
			||||||
	k.addrToInfo = make(map[address.Address]*keyInfo)
 | 
						k.addrToInfo = make(map[address.Address]*keyInfo)
 | 
				
			||||||
	k.addrBuffer = make(map[address.Address]*buffer)
 | 
						k.addrBuffer = make(map[address.Address]*buffer)
 | 
				
			||||||
| 
						 | 
					@ -204,38 +206,39 @@ func (k *keyStore) maxSessionMTU() uint64 {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (k *keyStore) readPC(p []byte) (int, error) {
 | 
					func (k *keyStore) readPC(p []byte) (int, error) {
 | 
				
			||||||
    for {
 | 
						buf := make([]byte, k.core.pc.MTU(), 65535)
 | 
				
			||||||
      bs := p
 | 
						for {
 | 
				
			||||||
      n, from, err := k.core.pc.ReadFrom(bs)
 | 
							bs := buf
 | 
				
			||||||
		  if err != nil {
 | 
							n, from, err := k.core.pc.ReadFrom(bs)
 | 
				
			||||||
			  return n, err
 | 
							if err != nil {
 | 
				
			||||||
		  }
 | 
								return n, err
 | 
				
			||||||
		  if n == 0 {
 | 
							}
 | 
				
			||||||
			  continue
 | 
							if n == 0 {
 | 
				
			||||||
		  }
 | 
								continue
 | 
				
			||||||
		  switch bs[0] {
 | 
							}
 | 
				
			||||||
		  case typeSessionTraffic:
 | 
							switch bs[0] {
 | 
				
			||||||
			  // This is what we want to handle here
 | 
							case typeSessionTraffic:
 | 
				
			||||||
		  case typeSessionProto:
 | 
								// This is what we want to handle here
 | 
				
			||||||
			  var key keyArray
 | 
							case typeSessionProto:
 | 
				
			||||||
			  copy(key[:], from.(iwt.Addr))
 | 
								var key keyArray
 | 
				
			||||||
			  data := append([]byte(nil), bs[1:n]...)
 | 
								copy(key[:], from.(iwt.Addr))
 | 
				
			||||||
			  k.core.proto.handleProto(nil, key, data)
 | 
								data := append([]byte(nil), bs[1:n]...)
 | 
				
			||||||
			  continue
 | 
								k.core.proto.handleProto(nil, key, data)
 | 
				
			||||||
		  default:
 | 
								continue
 | 
				
			||||||
			  continue
 | 
							default:
 | 
				
			||||||
		  }
 | 
								continue
 | 
				
			||||||
		  bs = bs[1:n]
 | 
							}
 | 
				
			||||||
		  if len(bs) == 0 {
 | 
							bs = bs[1:n]
 | 
				
			||||||
			  continue
 | 
							if len(bs) == 0 {
 | 
				
			||||||
		  }
 | 
								continue
 | 
				
			||||||
		  if bs[0]&0xf0 != 0x60 {
 | 
							}
 | 
				
			||||||
			  continue // not IPv6
 | 
							if bs[0]&0xf0 != 0x60 {
 | 
				
			||||||
		  }
 | 
								continue // not IPv6
 | 
				
			||||||
		  if len(bs) < 40 {
 | 
							}
 | 
				
			||||||
			  continue
 | 
							if len(bs) < 40 {
 | 
				
			||||||
		  }
 | 
								continue
 | 
				
			||||||
		  /* TODO ICMP packet too big
 | 
							}
 | 
				
			||||||
 | 
							/* TODO? ICMP packet too big, for now tuntap sends this when needed
 | 
				
			||||||
		  if len(bs) > int(tun.MTU()) {
 | 
							  if len(bs) > int(tun.MTU()) {
 | 
				
			||||||
			  ptb := &icmp.PacketTooBig{
 | 
								  ptb := &icmp.PacketTooBig{
 | 
				
			||||||
				  MTU:  int(tun.mtu),
 | 
									  MTU:  int(tun.mtu),
 | 
				
			||||||
| 
						 | 
					@ -246,32 +249,32 @@ func (k *keyStore) readPC(p []byte) (int, error) {
 | 
				
			||||||
			  }
 | 
								  }
 | 
				
			||||||
			  continue
 | 
								  continue
 | 
				
			||||||
		  }
 | 
							  }
 | 
				
			||||||
		  */
 | 
							*/
 | 
				
			||||||
		  var srcAddr, dstAddr address.Address
 | 
							var srcAddr, dstAddr address.Address
 | 
				
			||||||
		  var srcSubnet, dstSubnet address.Subnet
 | 
							var srcSubnet, dstSubnet address.Subnet
 | 
				
			||||||
		  copy(srcAddr[:], bs[8:])
 | 
							copy(srcAddr[:], bs[8:])
 | 
				
			||||||
		  copy(dstAddr[:], bs[24:])
 | 
							copy(dstAddr[:], bs[24:])
 | 
				
			||||||
		  copy(srcSubnet[:], bs[8:])
 | 
							copy(srcSubnet[:], bs[8:])
 | 
				
			||||||
		  copy(dstSubnet[:], bs[24:])
 | 
							copy(dstSubnet[:], bs[24:])
 | 
				
			||||||
		  if dstAddr != k.address && dstSubnet != k.subnet {
 | 
							if dstAddr != k.address && dstSubnet != k.subnet {
 | 
				
			||||||
			  continue // bad local address/subnet
 | 
								continue // bad local address/subnet
 | 
				
			||||||
		  }
 | 
					 | 
				
			||||||
		  info := k.update(ed25519.PublicKey(from.(iwt.Addr)))
 | 
					 | 
				
			||||||
		  if srcAddr != info.address && srcSubnet != info.subnet {
 | 
					 | 
				
			||||||
			  continue // bad remote address/subnet
 | 
					 | 
				
			||||||
		  }
 | 
					 | 
				
			||||||
		  n = copy(p, bs)
 | 
					 | 
				
			||||||
		  return n, nil
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							info := k.update(ed25519.PublicKey(from.(iwt.Addr)))
 | 
				
			||||||
 | 
							if srcAddr != info.address && srcSubnet != info.subnet {
 | 
				
			||||||
 | 
								continue // bad remote address/subnet
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							n = copy(p, bs)
 | 
				
			||||||
 | 
							return n, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (k *keyStore) writePC(bs []byte) (int, error) {
 | 
					func (k *keyStore) writePC(bs []byte) (int, error) {
 | 
				
			||||||
  if bs[0]&0xf0 != 0x60 {
 | 
						if bs[0]&0xf0 != 0x60 {
 | 
				
			||||||
		return 0, errors.New("not an IPv6 packet") // not IPv6
 | 
							return 0, errors.New("not an IPv6 packet") // not IPv6
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(bs) < 40 {
 | 
						if len(bs) < 40 {
 | 
				
			||||||
	  strErr := fmt.Sprint("undersized IPv6 packet, length:", len(bs))
 | 
							strErr := fmt.Sprint("undersized IPv6 packet, length:", len(bs))
 | 
				
			||||||
	  return 0, errors.New(strErr)
 | 
							return 0, errors.New(strErr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var srcAddr, dstAddr address.Address
 | 
						var srcAddr, dstAddr address.Address
 | 
				
			||||||
	var srcSubnet, dstSubnet address.Subnet
 | 
						var srcSubnet, dstSubnet address.Subnet
 | 
				
			||||||
| 
						 | 
					@ -280,16 +283,17 @@ func (k *keyStore) writePC(bs []byte) (int, error) {
 | 
				
			||||||
	copy(srcSubnet[:], bs[8:])
 | 
						copy(srcSubnet[:], bs[8:])
 | 
				
			||||||
	copy(dstSubnet[:], bs[24:])
 | 
						copy(dstSubnet[:], bs[24:])
 | 
				
			||||||
	if srcAddr != k.address && srcSubnet != k.subnet {
 | 
						if srcAddr != k.address && srcSubnet != k.subnet {
 | 
				
			||||||
    return 0, errors.New("wrong source address")
 | 
							return 0, errors.New("wrong source address")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	k.buf = append(k.buf[:0], typeSessionTraffic)
 | 
						buf := make([]byte, 1+len(bs), 65535)
 | 
				
			||||||
	k.buf = append(k.buf, bs...)
 | 
						buf[0] = typeSessionTraffic
 | 
				
			||||||
 | 
						copy(buf[1:], bs)
 | 
				
			||||||
	if dstAddr.IsValid() {
 | 
						if dstAddr.IsValid() {
 | 
				
			||||||
		k.sendToAddress(dstAddr, k.buf)
 | 
							k.sendToAddress(dstAddr, buf)
 | 
				
			||||||
	} else if dstSubnet.IsValid() {
 | 
						} else if dstSubnet.IsValid() {
 | 
				
			||||||
		k.sendToSubnet(dstSubnet, k.buf)
 | 
							k.sendToSubnet(dstSubnet, buf)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
    return 0, errors.New("invalid destination address")
 | 
							return 0, errors.New("invalid destination address")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return len(bs), nil
 | 
						return len(bs), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,7 @@ type reqInfo struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type protoHandler struct {
 | 
					type protoHandler struct {
 | 
				
			||||||
	phony.Inbox
 | 
						phony.Inbox
 | 
				
			||||||
	core    *Core
 | 
						core     *Core
 | 
				
			||||||
	nodeinfo nodeinfo
 | 
						nodeinfo nodeinfo
 | 
				
			||||||
	sreqs    map[keyArray]*reqInfo
 | 
						sreqs    map[keyArray]*reqInfo
 | 
				
			||||||
	preqs    map[keyArray]*reqInfo
 | 
						preqs    map[keyArray]*reqInfo
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,8 +34,8 @@ func (t *TunAdapter) SetupAdminHandlers(a *admin.AdminSocket) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return res, nil
 | 
							return res, nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	_ = a.AddHandler("getNodeInfo", []string{"key"}, t.proto.nodeinfo.nodeInfoAdminHandler)
 | 
						//_ = a.AddHandler("getNodeInfo", []string{"key"}, t.proto.nodeinfo.nodeInfoAdminHandler)
 | 
				
			||||||
	_ = a.AddHandler("debug_remoteGetSelf", []string{"key"}, t.proto.getSelfHandler)
 | 
						//_ = a.AddHandler("debug_remoteGetSelf", []string{"key"}, t.proto.getSelfHandler)
 | 
				
			||||||
	_ = a.AddHandler("debug_remoteGetPeers", []string{"key"}, t.proto.getPeersHandler)
 | 
						//_ = a.AddHandler("debug_remoteGetPeers", []string{"key"}, t.proto.getPeersHandler)
 | 
				
			||||||
	_ = a.AddHandler("debug_remoteGetDHT", []string{"key"}, t.proto.getDHTHandler)
 | 
						//_ = a.AddHandler("debug_remoteGetDHT", []string{"key"}, t.proto.getDHTHandler)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,20 +1,8 @@
 | 
				
			||||||
package tuntap
 | 
					package tuntap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"crypto/ed25519"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/address"
 | 
					 | 
				
			||||||
	"golang.org/x/net/icmp"
 | 
						"golang.org/x/net/icmp"
 | 
				
			||||||
	"golang.org/x/net/ipv6"
 | 
						"golang.org/x/net/ipv6"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	//"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
 | 
					 | 
				
			||||||
	//"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//"golang.org/x/net/icmp"
 | 
					 | 
				
			||||||
	//"golang.org/x/net/ipv6"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	iwt "github.com/Arceliar/ironwood/types"
 | 
					 | 
				
			||||||
	//"github.com/Arceliar/phony"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const TUN_OFFSET_BYTES = 4
 | 
					const TUN_OFFSET_BYTES = 4
 | 
				
			||||||
| 
						 | 
					@ -34,28 +22,8 @@ func (tun *TunAdapter) read() {
 | 
				
			||||||
		begin := TUN_OFFSET_BYTES
 | 
							begin := TUN_OFFSET_BYTES
 | 
				
			||||||
		end := begin + n
 | 
							end := begin + n
 | 
				
			||||||
		bs := buf[begin:end]
 | 
							bs := buf[begin:end]
 | 
				
			||||||
		if bs[0]&0xf0 != 0x60 {
 | 
							if _, err := tun.core.Write(bs); err != nil {
 | 
				
			||||||
			continue // not IPv6
 | 
								tun.log.Errorln("Unable to send packet:", err)
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(bs) < 40 {
 | 
					 | 
				
			||||||
			tun.log.Traceln("TUN iface read undersized ipv6 packet, length:", len(bs))
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		var srcAddr, dstAddr address.Address
 | 
					 | 
				
			||||||
		var srcSubnet, dstSubnet address.Subnet
 | 
					 | 
				
			||||||
		copy(srcAddr[:], bs[8:])
 | 
					 | 
				
			||||||
		copy(dstAddr[:], bs[24:])
 | 
					 | 
				
			||||||
		copy(srcSubnet[:], bs[8:])
 | 
					 | 
				
			||||||
		copy(dstSubnet[:], bs[24:])
 | 
					 | 
				
			||||||
		if srcAddr != tun.addr && srcSubnet != tun.subnet {
 | 
					 | 
				
			||||||
			continue // Wrong source address
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		bs = buf[begin-1 : end]
 | 
					 | 
				
			||||||
		bs[0] = typeSessionTraffic
 | 
					 | 
				
			||||||
		if dstAddr.IsValid() {
 | 
					 | 
				
			||||||
			tun.store.sendToAddress(dstAddr, bs)
 | 
					 | 
				
			||||||
		} else if dstSubnet.IsValid() {
 | 
					 | 
				
			||||||
			tun.store.sendToSubnet(dstSubnet, bs)
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -63,63 +31,23 @@ func (tun *TunAdapter) read() {
 | 
				
			||||||
func (tun *TunAdapter) write() {
 | 
					func (tun *TunAdapter) write() {
 | 
				
			||||||
	var buf [TUN_OFFSET_BYTES + 65535]byte
 | 
						var buf [TUN_OFFSET_BYTES + 65535]byte
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		bs := buf[TUN_OFFSET_BYTES-1:]
 | 
							bs := buf[TUN_OFFSET_BYTES:]
 | 
				
			||||||
		n, from, err := tun.core.ReadFrom(bs)
 | 
							n, err := tun.core.Read(bs)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								tun.log.Errorln("Exiting tun writer due to core read error:", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if n == 0 {
 | 
							if n > int(tun.MTU()) {
 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		switch bs[0] {
 | 
					 | 
				
			||||||
		case typeSessionTraffic:
 | 
					 | 
				
			||||||
			// This is what we want to handle here
 | 
					 | 
				
			||||||
			if !tun.isEnabled {
 | 
					 | 
				
			||||||
				continue // Drop traffic if the tun is disabled
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		case typeSessionProto:
 | 
					 | 
				
			||||||
			var key keyArray
 | 
					 | 
				
			||||||
			copy(key[:], from.(iwt.Addr))
 | 
					 | 
				
			||||||
			data := append([]byte(nil), bs[1:n]...)
 | 
					 | 
				
			||||||
			tun.proto.handleProto(nil, key, data)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		bs = bs[1:n]
 | 
					 | 
				
			||||||
		if len(bs) == 0 {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if bs[0]&0xf0 != 0x60 {
 | 
					 | 
				
			||||||
			continue // not IPv6
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(bs) < 40 {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(bs) > int(tun.MTU()) {
 | 
					 | 
				
			||||||
			ptb := &icmp.PacketTooBig{
 | 
								ptb := &icmp.PacketTooBig{
 | 
				
			||||||
				MTU:  int(tun.mtu),
 | 
									MTU:  int(tun.mtu),
 | 
				
			||||||
				Data: bs[:40],
 | 
									Data: bs[:40],
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if packet, err := CreateICMPv6(bs[8:24], bs[24:40], ipv6.ICMPTypePacketTooBig, 0, ptb); err == nil {
 | 
								if packet, err := CreateICMPv6(bs[8:24], bs[24:40], ipv6.ICMPTypePacketTooBig, 0, ptb); err == nil {
 | 
				
			||||||
				_, _ = tun.core.WriteTo(packet, from)
 | 
									_, _ = tun.core.Write(packet)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var srcAddr, dstAddr address.Address
 | 
							bs = buf[:TUN_OFFSET_BYTES+n]
 | 
				
			||||||
		var srcSubnet, dstSubnet address.Subnet
 | 
					 | 
				
			||||||
		copy(srcAddr[:], bs[8:])
 | 
					 | 
				
			||||||
		copy(dstAddr[:], bs[24:])
 | 
					 | 
				
			||||||
		copy(srcSubnet[:], bs[8:])
 | 
					 | 
				
			||||||
		copy(dstSubnet[:], bs[24:])
 | 
					 | 
				
			||||||
		if dstAddr != tun.addr && dstSubnet != tun.subnet {
 | 
					 | 
				
			||||||
			continue // bad local address/subnet
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		info := tun.store.update(ed25519.PublicKey(from.(iwt.Addr)))
 | 
					 | 
				
			||||||
		if srcAddr != info.address && srcSubnet != info.subnet {
 | 
					 | 
				
			||||||
			continue // bad remote address/subnet
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		bs = buf[:TUN_OFFSET_BYTES+len(bs)]
 | 
					 | 
				
			||||||
		if _, err = tun.iface.Write(bs, TUN_OFFSET_BYTES); err != nil {
 | 
							if _, err = tun.iface.Write(bs, TUN_OFFSET_BYTES); err != nil {
 | 
				
			||||||
			tun.Act(nil, func() {
 | 
								tun.Act(nil, func() {
 | 
				
			||||||
				if !tun.isOpen {
 | 
									if !tun.isOpen {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,6 @@ package tuntap
 | 
				
			||||||
// TODO: Don't block in reader on writes that are pending searches
 | 
					// TODO: Don't block in reader on writes that are pending searches
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"crypto/ed25519"
 | 
					 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
| 
						 | 
					@ -34,7 +33,6 @@ type MTU uint16
 | 
				
			||||||
// calling yggdrasil.Start().
 | 
					// calling yggdrasil.Start().
 | 
				
			||||||
type TunAdapter struct {
 | 
					type TunAdapter struct {
 | 
				
			||||||
	core        *core.Core
 | 
						core        *core.Core
 | 
				
			||||||
	store       keyStore
 | 
					 | 
				
			||||||
	config      *config.NodeConfig
 | 
						config      *config.NodeConfig
 | 
				
			||||||
	log         *log.Logger
 | 
						log         *log.Logger
 | 
				
			||||||
	addr        address.Address
 | 
						addr        address.Address
 | 
				
			||||||
| 
						 | 
					@ -45,7 +43,6 @@ type TunAdapter struct {
 | 
				
			||||||
	//mutex        sync.RWMutex // Protects the below
 | 
						//mutex        sync.RWMutex // Protects the below
 | 
				
			||||||
	isOpen    bool
 | 
						isOpen    bool
 | 
				
			||||||
	isEnabled bool // Used by the writer to drop sessionTraffic if not enabled
 | 
						isEnabled bool // Used by the writer to drop sessionTraffic if not enabled
 | 
				
			||||||
	proto     protoHandler
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gets the maximum supported MTU for the platform based on the defaults in
 | 
					// Gets the maximum supported MTU for the platform based on the defaults in
 | 
				
			||||||
| 
						 | 
					@ -98,18 +95,8 @@ func MaximumMTU() uint64 {
 | 
				
			||||||
// the Yggdrasil core before this point and it must not be in use elsewhere.
 | 
					// the Yggdrasil core before this point and it must not be in use elsewhere.
 | 
				
			||||||
func (tun *TunAdapter) Init(core *core.Core, config *config.NodeConfig, log *log.Logger, options interface{}) error {
 | 
					func (tun *TunAdapter) Init(core *core.Core, config *config.NodeConfig, log *log.Logger, options interface{}) error {
 | 
				
			||||||
	tun.core = core
 | 
						tun.core = core
 | 
				
			||||||
	tun.store.init(tun)
 | 
					 | 
				
			||||||
	tun.config = config
 | 
						tun.config = config
 | 
				
			||||||
	tun.log = log
 | 
						tun.log = log
 | 
				
			||||||
	tun.proto.init(tun)
 | 
					 | 
				
			||||||
	tun.config.RLock()
 | 
					 | 
				
			||||||
	if err := tun.proto.nodeinfo.setNodeInfo(tun.config.NodeInfo, tun.config.NodeInfoPrivacy); err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("tun.proto.nodeinfo.setNodeInfo: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	tun.config.RUnlock()
 | 
					 | 
				
			||||||
	if err := tun.core.SetOutOfBandHandler(tun.oobHandler); err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("tun.core.SetOutOfBandHander: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,8 +119,7 @@ func (tun *TunAdapter) _start() error {
 | 
				
			||||||
	if tun.config == nil {
 | 
						if tun.config == nil {
 | 
				
			||||||
		return errors.New("no configuration available to TUN")
 | 
							return errors.New("no configuration available to TUN")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sk := tun.core.PrivateKey()
 | 
						pk := tun.core.PublicKey()
 | 
				
			||||||
	pk := sk.Public().(ed25519.PublicKey)
 | 
					 | 
				
			||||||
	tun.addr = *address.AddrForKey(pk)
 | 
						tun.addr = *address.AddrForKey(pk)
 | 
				
			||||||
	tun.subnet = *address.SubnetForKey(pk)
 | 
						tun.subnet = *address.SubnetForKey(pk)
 | 
				
			||||||
	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)
 | 
				
			||||||
| 
						 | 
					@ -144,8 +130,8 @@ func (tun *TunAdapter) _start() error {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mtu := tun.config.IfMTU
 | 
						mtu := tun.config.IfMTU
 | 
				
			||||||
	if tun.maxSessionMTU() < mtu {
 | 
						if tun.core.MaxMTU() < mtu {
 | 
				
			||||||
		mtu = tun.maxSessionMTU()
 | 
							mtu = tun.core.MaxMTU()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := tun.setup(tun.config.IfName, addr, mtu); err != nil {
 | 
						if err := tun.setup(tun.config.IfName, addr, mtu); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
| 
						 | 
					@ -188,4 +174,3 @@ func (tun *TunAdapter) _stop() error {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue