mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	start migrating the TunAdapter to the actor model
This commit is contained in:
		
							parent
							
								
									502f2937a9
								
							
						
					
					
						commit
						aaf34c6304
					
				
					 3 changed files with 267 additions and 250 deletions
				
			
		| 
						 | 
					@ -113,8 +113,7 @@ func (s *tunConn) _read(bs []byte) (err error) {
 | 
				
			||||||
		util.PutBytes(bs)
 | 
							util.PutBytes(bs)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// FIXME this send can block if the tuntap isn't running, which isn't really safe...
 | 
						s.tun.writer.writeFrom(s, bs)
 | 
				
			||||||
	s.tun.send <- bs
 | 
					 | 
				
			||||||
	s.stillAlive()
 | 
						s.stillAlive()
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -208,7 +207,7 @@ func (s *tunConn) _write(bs []byte) (err error) {
 | 
				
			||||||
					Data: bs[:900],
 | 
										Data: bs[:900],
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				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 {
 | 
				
			||||||
					s.tun.send <- packet
 | 
										s.tun.writer.writeFrom(s, packet)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if e.Closed() {
 | 
									if e.Closed() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,48 +9,60 @@ import (
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/address"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/address"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/util"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/Arceliar/phony"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tun *TunAdapter) writer() error {
 | 
					type tunWriter struct {
 | 
				
			||||||
	var w int
 | 
						phony.Inbox
 | 
				
			||||||
 | 
						tun *TunAdapter
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *tunWriter) writeFrom(from phony.Actor, b []byte) {
 | 
				
			||||||
 | 
						w.RecvFrom(from, func() {
 | 
				
			||||||
 | 
							w._write(b)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// write is pretty loose with the memory safety rules, e.g. it assumes it can read w.tun.iface.IsTap() safely
 | 
				
			||||||
 | 
					func (w *tunWriter) _write(b []byte) {
 | 
				
			||||||
 | 
						var written int
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		b := <-tun.send
 | 
					 | 
				
			||||||
	n := len(b)
 | 
						n := len(b)
 | 
				
			||||||
	if n == 0 {
 | 
						if n == 0 {
 | 
				
			||||||
			continue
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		if tun.iface.IsTAP() {
 | 
						if w.tun.iface.IsTAP() {
 | 
				
			||||||
		sendndp := func(dstAddr address.Address) {
 | 
							sendndp := func(dstAddr address.Address) {
 | 
				
			||||||
				neigh, known := tun.icmpv6.getNeighbor(dstAddr)
 | 
								neigh, known := w.tun.icmpv6.getNeighbor(dstAddr)
 | 
				
			||||||
			known = known && (time.Since(neigh.lastsolicitation).Seconds() < 30)
 | 
								known = known && (time.Since(neigh.lastsolicitation).Seconds() < 30)
 | 
				
			||||||
			if !known {
 | 
								if !known {
 | 
				
			||||||
					tun.icmpv6.Solicit(dstAddr)
 | 
									w.tun.icmpv6.Solicit(dstAddr)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		peermac := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 | 
							peermac := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 | 
				
			||||||
		var dstAddr address.Address
 | 
							var dstAddr address.Address
 | 
				
			||||||
		var peerknown bool
 | 
							var peerknown bool
 | 
				
			||||||
		if b[0]&0xf0 == 0x40 {
 | 
							if b[0]&0xf0 == 0x40 {
 | 
				
			||||||
				dstAddr = tun.addr
 | 
								dstAddr = w.tun.addr
 | 
				
			||||||
		} else if b[0]&0xf0 == 0x60 {
 | 
							} else if b[0]&0xf0 == 0x60 {
 | 
				
			||||||
				if !bytes.Equal(tun.addr[:16], dstAddr[:16]) && !bytes.Equal(tun.subnet[:8], dstAddr[:8]) {
 | 
								if !bytes.Equal(w.tun.addr[:16], dstAddr[:16]) && !bytes.Equal(w.tun.subnet[:8], dstAddr[:8]) {
 | 
				
			||||||
					dstAddr = tun.addr
 | 
									dstAddr = w.tun.addr
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			if neighbor, ok := tun.icmpv6.getNeighbor(dstAddr); ok && neighbor.learned {
 | 
							if neighbor, ok := w.tun.icmpv6.getNeighbor(dstAddr); ok && neighbor.learned {
 | 
				
			||||||
			// If we've learned the MAC of a 300::/7 address, for example, or a CKR
 | 
								// If we've learned the MAC of a 300::/7 address, for example, or a CKR
 | 
				
			||||||
			// address, use the MAC address of that
 | 
								// address, use the MAC address of that
 | 
				
			||||||
			peermac = neighbor.mac
 | 
								peermac = neighbor.mac
 | 
				
			||||||
			peerknown = true
 | 
								peerknown = true
 | 
				
			||||||
			} else if neighbor, ok := tun.icmpv6.getNeighbor(tun.addr); ok && neighbor.learned {
 | 
							} else if neighbor, ok := w.tun.icmpv6.getNeighbor(w.tun.addr); ok && neighbor.learned {
 | 
				
			||||||
			// Otherwise send directly to the MAC address of the host if that's
 | 
								// Otherwise send directly to the MAC address of the host if that's
 | 
				
			||||||
			// known instead
 | 
								// known instead
 | 
				
			||||||
			peermac = neighbor.mac
 | 
								peermac = neighbor.mac
 | 
				
			||||||
			peerknown = true
 | 
								peerknown = true
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			// Nothing has been discovered, try to discover the destination
 | 
								// Nothing has been discovered, try to discover the destination
 | 
				
			||||||
				sendndp(tun.addr)
 | 
								sendndp(w.tun.addr)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if peerknown {
 | 
							if peerknown {
 | 
				
			||||||
			var proto ethernet.Ethertype
 | 
								var proto ethernet.Ethertype
 | 
				
			||||||
| 
						 | 
					@ -63,38 +75,67 @@ func (tun *TunAdapter) writer() error {
 | 
				
			||||||
			var frame ethernet.Frame
 | 
								var frame ethernet.Frame
 | 
				
			||||||
			frame.Prepare(
 | 
								frame.Prepare(
 | 
				
			||||||
				peermac[:6],            // Destination MAC address
 | 
									peermac[:6],            // Destination MAC address
 | 
				
			||||||
					tun.icmpv6.mymac[:6], // Source MAC address
 | 
									w.tun.icmpv6.mymac[:6], // Source MAC address
 | 
				
			||||||
				ethernet.NotTagged,     // VLAN tagging
 | 
									ethernet.NotTagged,     // VLAN tagging
 | 
				
			||||||
				proto,                  // Ethertype
 | 
									proto,                  // Ethertype
 | 
				
			||||||
				len(b))                 // Payload length
 | 
									len(b))                 // Payload length
 | 
				
			||||||
			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])
 | 
								written, err = w.tun.iface.Write(frame[:n])
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
				tun.log.Errorln("TUN/TAP iface write error: no peer MAC known for", net.IP(dstAddr[:]).String(), "- dropping packet")
 | 
								w.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])
 | 
							written, err = w.tun.iface.Write(b[:n])
 | 
				
			||||||
		util.PutBytes(b)
 | 
							util.PutBytes(b)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
			if !tun.isOpen {
 | 
							w.tun.mutex.Lock()
 | 
				
			||||||
				return err
 | 
							open := w.tun.isOpen
 | 
				
			||||||
 | 
							w.tun.mutex.Unlock()
 | 
				
			||||||
 | 
							if !open {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			tun.log.Errorln("TUN/TAP iface write error:", err)
 | 
							w.tun.log.Errorln("TUN/TAP iface write error:", err)
 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if w != n {
 | 
					 | 
				
			||||||
			tun.log.Errorln("TUN/TAP iface write mismatch:", w, "bytes written vs", n, "bytes given")
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if written != n {
 | 
				
			||||||
 | 
							w.tun.log.Errorln("TUN/TAP iface write mismatch:", written, "bytes written vs", n, "bytes given")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Run in a separate goroutine by the reader
 | 
					type tunReader struct {
 | 
				
			||||||
// Does all of the per-packet ICMP checks, passes packets to the right Conn worker
 | 
						phony.Inbox
 | 
				
			||||||
func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
 | 
						tun *TunAdapter
 | 
				
			||||||
	for recvd := range ch {
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *tunReader) _read() {
 | 
				
			||||||
 | 
						// Get a slice to store the packet in
 | 
				
			||||||
 | 
						recvd := util.ResizeBytes(util.GetBytes(), 65535+tun_ETHER_HEADER_LENGTH)
 | 
				
			||||||
 | 
						// Wait for a packet to be delivered to us through the TUN/TAP adapter
 | 
				
			||||||
 | 
						n, err := r.tun.iface.Read(recvd)
 | 
				
			||||||
 | 
						if n == 0 {
 | 
				
			||||||
 | 
							util.PutBytes(recvd)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							r.tun.handlePacketFrom(r, recvd[:n], err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							// Now read again
 | 
				
			||||||
 | 
							r.RecvFrom(nil, r._read)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (tun *TunAdapter) handlePacketFrom(from phony.Actor, packet []byte, err error) {
 | 
				
			||||||
 | 
						tun.RecvFrom(from, func() {
 | 
				
			||||||
 | 
							tun._handlePacket(packet, err)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// does the work of reading a packet and sending it to the correct tunConn
 | 
				
			||||||
 | 
					func (tun *TunAdapter) _handlePacket(recvd []byte, err error) {
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							tun.log.Errorln("TUN/TAP iface read error:", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// If it's a TAP adapter, update the buffer slice so that we no longer
 | 
						// If it's a TAP adapter, update the buffer slice so that we no longer
 | 
				
			||||||
	// include the ethernet headers
 | 
						// include the ethernet headers
 | 
				
			||||||
	offset := 0
 | 
						offset := 0
 | 
				
			||||||
| 
						 | 
					@ -103,7 +144,7 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
 | 
				
			||||||
		offset = tun_ETHER_HEADER_LENGTH
 | 
							offset = tun_ETHER_HEADER_LENGTH
 | 
				
			||||||
		// Check first of all that we can go beyond the ethernet headers
 | 
							// Check first of all that we can go beyond the ethernet headers
 | 
				
			||||||
		if len(recvd) <= offset {
 | 
							if len(recvd) <= offset {
 | 
				
			||||||
				continue
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Offset the buffer from now on so that we can ignore ethernet frames if
 | 
						// Offset the buffer from now on so that we can ignore ethernet frames if
 | 
				
			||||||
| 
						 | 
					@ -117,7 +158,7 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
 | 
				
			||||||
		if err := tun.icmpv6.ParsePacket(recvd); err == nil {
 | 
							if err := tun.icmpv6.ParsePacket(recvd); err == nil {
 | 
				
			||||||
			// We acted on the packet in the ICMPv6 module so don't forward or do
 | 
								// We acted on the packet in the ICMPv6 module so don't forward or do
 | 
				
			||||||
			// anything else with it
 | 
								// anything else with it
 | 
				
			||||||
				continue
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if offset != 0 {
 | 
						if offset != 0 {
 | 
				
			||||||
| 
						 | 
					@ -136,11 +177,11 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
 | 
				
			||||||
	if bs[0]&0xf0 == 0x60 {
 | 
						if bs[0]&0xf0 == 0x60 {
 | 
				
			||||||
		// Check if we have a fully-sized IPv6 header
 | 
							// Check if we have a fully-sized IPv6 header
 | 
				
			||||||
		if len(bs) < 40 {
 | 
							if len(bs) < 40 {
 | 
				
			||||||
				continue
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Check the packet size
 | 
							// Check the packet size
 | 
				
			||||||
		if n-tun_IPv6_HEADER_LENGTH != 256*int(bs[4])+int(bs[5]) {
 | 
							if n-tun_IPv6_HEADER_LENGTH != 256*int(bs[4])+int(bs[5]) {
 | 
				
			||||||
				continue
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// IPv6 address
 | 
							// IPv6 address
 | 
				
			||||||
		addrlen = 16
 | 
							addrlen = 16
 | 
				
			||||||
| 
						 | 
					@ -149,11 +190,11 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
 | 
				
			||||||
	} else if bs[0]&0xf0 == 0x40 {
 | 
						} else if bs[0]&0xf0 == 0x40 {
 | 
				
			||||||
		// Check if we have a fully-sized IPv4 header
 | 
							// Check if we have a fully-sized IPv4 header
 | 
				
			||||||
		if len(bs) < 20 {
 | 
							if len(bs) < 20 {
 | 
				
			||||||
				continue
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Check the packet size
 | 
							// Check the packet size
 | 
				
			||||||
		if n != 256*int(bs[2])+int(bs[3]) {
 | 
							if n != 256*int(bs[2])+int(bs[3]) {
 | 
				
			||||||
				continue
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// IPv4 address
 | 
							// IPv4 address
 | 
				
			||||||
		addrlen = 4
 | 
							addrlen = 4
 | 
				
			||||||
| 
						 | 
					@ -161,7 +202,7 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// Unknown address length or protocol, so drop the packet and ignore it
 | 
							// Unknown address length or protocol, so drop the packet and ignore it
 | 
				
			||||||
		tun.log.Traceln("Unknown packet type, dropping")
 | 
							tun.log.Traceln("Unknown packet type, dropping")
 | 
				
			||||||
			continue
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if tun.ckr.isEnabled() {
 | 
						if tun.ckr.isEnabled() {
 | 
				
			||||||
		if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) {
 | 
							if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) {
 | 
				
			||||||
| 
						 | 
					@ -176,7 +217,7 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) {
 | 
						if addrlen != 16 || (!dstAddr.IsValid() && !dstSnet.IsValid()) {
 | 
				
			||||||
		// Couldn't find this node's ygg IP
 | 
							// Couldn't find this node's ygg IP
 | 
				
			||||||
			continue
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Do we have an active connection for this node address?
 | 
						// Do we have an active connection for this node address?
 | 
				
			||||||
	var dstNodeID, dstNodeIDMask *crypto.NodeID
 | 
						var dstNodeID, dstNodeIDMask *crypto.NodeID
 | 
				
			||||||
| 
						 | 
					@ -237,36 +278,10 @@ func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
		// While the dial is going on we can't do much else
 | 
							// While the dial is going on we can't do much else
 | 
				
			||||||
			// continuing this iteration - skip to the next one
 | 
							return
 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// If we have a connection now, try writing to it
 | 
						// If we have a connection now, try writing to it
 | 
				
			||||||
	if isIn && session != nil {
 | 
						if isIn && session != nil {
 | 
				
			||||||
			<-session.SyncExec(func() { session._write(bs) })
 | 
							session.RecvFrom(tun, func() { session._write(bs) })
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (tun *TunAdapter) reader() error {
 | 
					 | 
				
			||||||
	toWorker := make(chan []byte, 32)
 | 
					 | 
				
			||||||
	defer close(toWorker)
 | 
					 | 
				
			||||||
	go tun.readerPacketHandler(toWorker)
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		// Get a slice to store the packet in
 | 
					 | 
				
			||||||
		recvd := util.ResizeBytes(util.GetBytes(), 65535+tun_ETHER_HEADER_LENGTH)
 | 
					 | 
				
			||||||
		// Wait for a packet to be delivered to us through the TUN/TAP adapter
 | 
					 | 
				
			||||||
		n, err := tun.iface.Read(recvd)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			if !tun.isOpen {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			panic(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if n == 0 {
 | 
					 | 
				
			||||||
			util.PutBytes(recvd)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Send the packet to the worker
 | 
					 | 
				
			||||||
		toWorker <- recvd[:n]
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@ import (
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/Arceliar/phony"
 | 
				
			||||||
	"github.com/gologme/log"
 | 
						"github.com/gologme/log"
 | 
				
			||||||
	"github.com/yggdrasil-network/water"
 | 
						"github.com/yggdrasil-network/water"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +34,8 @@ const tun_ETHER_HEADER_LENGTH = 14
 | 
				
			||||||
// you should pass this object to the yggdrasil.SetRouterAdapter() function
 | 
					// you should pass this object to the yggdrasil.SetRouterAdapter() function
 | 
				
			||||||
// before calling yggdrasil.Start().
 | 
					// before calling yggdrasil.Start().
 | 
				
			||||||
type TunAdapter struct {
 | 
					type TunAdapter struct {
 | 
				
			||||||
 | 
						writer       tunWriter
 | 
				
			||||||
 | 
						reader       tunReader
 | 
				
			||||||
	config       *config.NodeState
 | 
						config       *config.NodeState
 | 
				
			||||||
	log          *log.Logger
 | 
						log          *log.Logger
 | 
				
			||||||
	reconfigure  chan chan error
 | 
						reconfigure  chan chan error
 | 
				
			||||||
| 
						 | 
					@ -44,7 +47,7 @@ type TunAdapter struct {
 | 
				
			||||||
	icmpv6       ICMPv6
 | 
						icmpv6       ICMPv6
 | 
				
			||||||
	mtu          int
 | 
						mtu          int
 | 
				
			||||||
	iface        *water.Interface
 | 
						iface        *water.Interface
 | 
				
			||||||
	send         chan []byte
 | 
						phony.Inbox               // Currently only used for _handlePacket from the reader, TODO: all the stuff that currently needs a mutex below
 | 
				
			||||||
	mutex        sync.RWMutex // Protects the below
 | 
						mutex        sync.RWMutex // Protects the below
 | 
				
			||||||
	addrToConn   map[address.Address]*tunConn
 | 
						addrToConn   map[address.Address]*tunConn
 | 
				
			||||||
	subnetToConn map[address.Subnet]*tunConn
 | 
						subnetToConn map[address.Subnet]*tunConn
 | 
				
			||||||
| 
						 | 
					@ -114,6 +117,8 @@ func (tun *TunAdapter) Init(config *config.NodeState, log *log.Logger, listener
 | 
				
			||||||
	tun.addrToConn = make(map[address.Address]*tunConn)
 | 
						tun.addrToConn = make(map[address.Address]*tunConn)
 | 
				
			||||||
	tun.subnetToConn = make(map[address.Subnet]*tunConn)
 | 
						tun.subnetToConn = make(map[address.Subnet]*tunConn)
 | 
				
			||||||
	tun.dials = make(map[crypto.NodeID][][]byte)
 | 
						tun.dials = make(map[crypto.NodeID][][]byte)
 | 
				
			||||||
 | 
						tun.writer.tun = tun
 | 
				
			||||||
 | 
						tun.reader.tun = tun
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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
 | 
				
			||||||
| 
						 | 
					@ -147,7 +152,6 @@ func (tun *TunAdapter) Start() error {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	tun.mutex.Lock()
 | 
						tun.mutex.Lock()
 | 
				
			||||||
	tun.isOpen = true
 | 
						tun.isOpen = true
 | 
				
			||||||
	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()
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
| 
						 | 
					@ -157,8 +161,7 @@ func (tun *TunAdapter) Start() error {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	go tun.handler()
 | 
						go tun.handler()
 | 
				
			||||||
	go tun.reader()
 | 
						tun.reader.RecvFrom(nil, tun.reader._read) // Start the reader
 | 
				
			||||||
	go tun.writer()
 | 
					 | 
				
			||||||
	tun.icmpv6.Init(tun)
 | 
						tun.icmpv6.Init(tun)
 | 
				
			||||||
	if iftapmode {
 | 
						if iftapmode {
 | 
				
			||||||
		go tun.icmpv6.Solicit(tun.addr)
 | 
							go tun.icmpv6.Solicit(tun.addr)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue