mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	move some logic from TunAdapter.reader into a new function, TunAdapter.readerPacketHandler
This commit is contained in:
		
							parent
							
								
									38e1503b28
								
							
						
					
					
						commit
						406e143f7f
					
				
					 1 changed files with 178 additions and 173 deletions
				
			
		| 
						 | 
					@ -110,178 +110,10 @@ func (tun *TunAdapter) writer() error {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tun *TunAdapter) reader() error {
 | 
					// Run in a separate goroutine by the reader
 | 
				
			||||||
	recvd := make([]byte, 65535+tun_ETHER_HEADER_LENGTH)
 | 
					// Does all of the per-packet ICMP checks, passes packets to the right Conn worker
 | 
				
			||||||
	toWorker := make(chan []byte, 32)
 | 
					func (tun *TunAdapter) readerPacketHandler(ch chan []byte) {
 | 
				
			||||||
	defer close(toWorker)
 | 
						for recvd := range ch {
 | 
				
			||||||
	go func() {
 | 
					 | 
				
			||||||
		for bs := range toWorker {
 | 
					 | 
				
			||||||
			// If we detect an ICMP packet then hand it to the ICMPv6 module
 | 
					 | 
				
			||||||
			if bs[6] == 58 {
 | 
					 | 
				
			||||||
				// Found an ICMPv6 packet - we need to make sure to give ICMPv6 the full
 | 
					 | 
				
			||||||
				// Ethernet frame rather than just the IPv6 packet as this is needed for
 | 
					 | 
				
			||||||
				// NDP to work correctly
 | 
					 | 
				
			||||||
				if err := tun.icmpv6.ParsePacket(recvd); err == nil {
 | 
					 | 
				
			||||||
					// We acted on the packet in the ICMPv6 module so don't forward or do
 | 
					 | 
				
			||||||
					// anything else with it
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			// From the IP header, work out what our source and destination addresses
 | 
					 | 
				
			||||||
			// and node IDs are. We will need these in order to work out where to send
 | 
					 | 
				
			||||||
			// the packet
 | 
					 | 
				
			||||||
			var srcAddr address.Address
 | 
					 | 
				
			||||||
			var dstAddr address.Address
 | 
					 | 
				
			||||||
			var dstNodeID *crypto.NodeID
 | 
					 | 
				
			||||||
			var dstNodeIDMask *crypto.NodeID
 | 
					 | 
				
			||||||
			var dstSnet address.Subnet
 | 
					 | 
				
			||||||
			var addrlen int
 | 
					 | 
				
			||||||
			n := len(bs)
 | 
					 | 
				
			||||||
			// Check the IP protocol - if it doesn't match then we drop the packet and
 | 
					 | 
				
			||||||
			// do nothing with it
 | 
					 | 
				
			||||||
			if bs[0]&0xf0 == 0x60 {
 | 
					 | 
				
			||||||
				// Check if we have a fully-sized IPv6 header
 | 
					 | 
				
			||||||
				if len(bs) < 40 {
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				// Check the packet size
 | 
					 | 
				
			||||||
				if n-tun_IPv6_HEADER_LENGTH != 256*int(bs[4])+int(bs[5]) {
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				// IPv6 address
 | 
					 | 
				
			||||||
				addrlen = 16
 | 
					 | 
				
			||||||
				copy(srcAddr[:addrlen], bs[8:])
 | 
					 | 
				
			||||||
				copy(dstAddr[:addrlen], bs[24:])
 | 
					 | 
				
			||||||
				copy(dstSnet[:addrlen/2], bs[24:])
 | 
					 | 
				
			||||||
			} else if bs[0]&0xf0 == 0x40 {
 | 
					 | 
				
			||||||
				// Check if we have a fully-sized IPv4 header
 | 
					 | 
				
			||||||
				if len(bs) < 20 {
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				// Check the packet size
 | 
					 | 
				
			||||||
				if n != 256*int(bs[2])+int(bs[3]) {
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				// IPv4 address
 | 
					 | 
				
			||||||
				addrlen = 4
 | 
					 | 
				
			||||||
				copy(srcAddr[:addrlen], bs[12:])
 | 
					 | 
				
			||||||
				copy(dstAddr[:addrlen], bs[16:])
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				// Unknown address length or protocol, so drop the packet and ignore it
 | 
					 | 
				
			||||||
				tun.log.Traceln("Unknown packet type, dropping")
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if tun.ckr.isEnabled() && !tun.ckr.isValidSource(srcAddr, addrlen) {
 | 
					 | 
				
			||||||
				// The packet had a source address that doesn't belong to us or our
 | 
					 | 
				
			||||||
				// configured crypto-key routing source subnets
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if !dstAddr.IsValid() && !dstSnet.IsValid() {
 | 
					 | 
				
			||||||
				if key, err := tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil {
 | 
					 | 
				
			||||||
					// A public key was found, get the node ID for the search
 | 
					 | 
				
			||||||
					dstNodeID = crypto.GetNodeID(&key)
 | 
					 | 
				
			||||||
					// Do a quick check to ensure that the node ID refers to a vaild
 | 
					 | 
				
			||||||
					// Yggdrasil address or subnet - this might be superfluous
 | 
					 | 
				
			||||||
					addr := *address.AddrForNodeID(dstNodeID)
 | 
					 | 
				
			||||||
					copy(dstAddr[:], addr[:])
 | 
					 | 
				
			||||||
					copy(dstSnet[:], addr[:])
 | 
					 | 
				
			||||||
					// Are we certain we looked up a valid node?
 | 
					 | 
				
			||||||
					if !dstAddr.IsValid() && !dstSnet.IsValid() {
 | 
					 | 
				
			||||||
						continue
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					// No public key was found in the CKR table so we've exhausted our options
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			// Do we have an active connection for this node address?
 | 
					 | 
				
			||||||
			tun.mutex.RLock()
 | 
					 | 
				
			||||||
			session, isIn := tun.addrToConn[dstAddr]
 | 
					 | 
				
			||||||
			if !isIn || session == nil {
 | 
					 | 
				
			||||||
				session, isIn = tun.subnetToConn[dstSnet]
 | 
					 | 
				
			||||||
				if !isIn || session == nil {
 | 
					 | 
				
			||||||
					// Neither an address nor a subnet mapping matched, therefore populate
 | 
					 | 
				
			||||||
					// the node ID and mask to commence a search
 | 
					 | 
				
			||||||
					if dstAddr.IsValid() {
 | 
					 | 
				
			||||||
						dstNodeID, dstNodeIDMask = dstAddr.GetNodeIDandMask()
 | 
					 | 
				
			||||||
					} else {
 | 
					 | 
				
			||||||
						dstNodeID, dstNodeIDMask = dstSnet.GetNodeIDandMask()
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			tun.mutex.RUnlock()
 | 
					 | 
				
			||||||
			// If we don't have a connection then we should open one
 | 
					 | 
				
			||||||
			if !isIn || session == nil {
 | 
					 | 
				
			||||||
				// Check we haven't been given empty node ID, really this shouldn't ever
 | 
					 | 
				
			||||||
				// happen but just to be sure...
 | 
					 | 
				
			||||||
				if dstNodeID == nil || dstNodeIDMask == nil {
 | 
					 | 
				
			||||||
					panic("Given empty dstNodeID and dstNodeIDMask - this shouldn't happen")
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				// Dial to the remote node
 | 
					 | 
				
			||||||
				packet := bs
 | 
					 | 
				
			||||||
				go func() {
 | 
					 | 
				
			||||||
					// FIXME just spitting out a goroutine to do this is kind of ugly and means we drop packets until the dial finishes
 | 
					 | 
				
			||||||
					tun.mutex.Lock()
 | 
					 | 
				
			||||||
					_, known := tun.dials[*dstNodeID]
 | 
					 | 
				
			||||||
					tun.dials[*dstNodeID] = append(tun.dials[*dstNodeID], packet)
 | 
					 | 
				
			||||||
					for len(tun.dials[*dstNodeID]) > 32 {
 | 
					 | 
				
			||||||
						util.PutBytes(tun.dials[*dstNodeID][0])
 | 
					 | 
				
			||||||
						tun.dials[*dstNodeID] = tun.dials[*dstNodeID][1:]
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					tun.mutex.Unlock()
 | 
					 | 
				
			||||||
					if known {
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					var tc *tunConn
 | 
					 | 
				
			||||||
					if conn, err := tun.dialer.DialByNodeIDandMask(dstNodeID, dstNodeIDMask); err == nil {
 | 
					 | 
				
			||||||
						// We've been given a connection so prepare the session wrapper
 | 
					 | 
				
			||||||
						if tc, err = tun.wrap(conn); err != nil {
 | 
					 | 
				
			||||||
							// Something went wrong when storing the connection, typically that
 | 
					 | 
				
			||||||
							// something already exists for this address or subnet
 | 
					 | 
				
			||||||
							tun.log.Debugln("TUN/TAP iface wrap:", err)
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					tun.mutex.Lock()
 | 
					 | 
				
			||||||
					packets := tun.dials[*dstNodeID]
 | 
					 | 
				
			||||||
					delete(tun.dials, *dstNodeID)
 | 
					 | 
				
			||||||
					tun.mutex.Unlock()
 | 
					 | 
				
			||||||
					if tc != nil {
 | 
					 | 
				
			||||||
						for _, packet := range packets {
 | 
					 | 
				
			||||||
							select {
 | 
					 | 
				
			||||||
							case tc.send <- packet:
 | 
					 | 
				
			||||||
							default:
 | 
					 | 
				
			||||||
								util.PutBytes(packet)
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}()
 | 
					 | 
				
			||||||
				// While the dial is going on we can't do much else
 | 
					 | 
				
			||||||
				// continuing this iteration - skip to the next one
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			// If we have a connection now, try writing to it
 | 
					 | 
				
			||||||
			if isIn && session != nil {
 | 
					 | 
				
			||||||
				packet := bs
 | 
					 | 
				
			||||||
				select {
 | 
					 | 
				
			||||||
				case session.send <- packet:
 | 
					 | 
				
			||||||
				default:
 | 
					 | 
				
			||||||
					util.PutBytes(packet)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		// 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 {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// 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
 | 
				
			||||||
| 
						 | 
					@ -295,7 +127,180 @@ func (tun *TunAdapter) reader() error {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// 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
 | 
				
			||||||
		// they are present
 | 
							// they are present
 | 
				
			||||||
		bs := append(util.GetBytes(), recvd[offset:offset+n]...)
 | 
							bs := recvd[offset:]
 | 
				
			||||||
 | 
							// If we detect an ICMP packet then hand it to the ICMPv6 module
 | 
				
			||||||
 | 
							if bs[6] == 58 {
 | 
				
			||||||
 | 
								// Found an ICMPv6 packet - we need to make sure to give ICMPv6 the full
 | 
				
			||||||
 | 
								// Ethernet frame rather than just the IPv6 packet as this is needed for
 | 
				
			||||||
 | 
								// NDP to work correctly
 | 
				
			||||||
 | 
								if err := tun.icmpv6.ParsePacket(recvd); err == nil {
 | 
				
			||||||
 | 
									// We acted on the packet in the ICMPv6 module so don't forward or do
 | 
				
			||||||
 | 
									// anything else with it
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Shift forward to avoid leaking bytes off the front of the slide when we eventually store it
 | 
				
			||||||
 | 
							bs = append(recvd[:0], bs...)
 | 
				
			||||||
 | 
							// From the IP header, work out what our source and destination addresses
 | 
				
			||||||
 | 
							// and node IDs are. We will need these in order to work out where to send
 | 
				
			||||||
 | 
							// the packet
 | 
				
			||||||
 | 
							var srcAddr address.Address
 | 
				
			||||||
 | 
							var dstAddr address.Address
 | 
				
			||||||
 | 
							var dstNodeID *crypto.NodeID
 | 
				
			||||||
 | 
							var dstNodeIDMask *crypto.NodeID
 | 
				
			||||||
 | 
							var dstSnet address.Subnet
 | 
				
			||||||
 | 
							var addrlen int
 | 
				
			||||||
 | 
							n := len(bs)
 | 
				
			||||||
 | 
							// Check the IP protocol - if it doesn't match then we drop the packet and
 | 
				
			||||||
 | 
							// do nothing with it
 | 
				
			||||||
 | 
							if bs[0]&0xf0 == 0x60 {
 | 
				
			||||||
 | 
								// Check if we have a fully-sized IPv6 header
 | 
				
			||||||
 | 
								if len(bs) < 40 {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// Check the packet size
 | 
				
			||||||
 | 
								if n-tun_IPv6_HEADER_LENGTH != 256*int(bs[4])+int(bs[5]) {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// IPv6 address
 | 
				
			||||||
 | 
								addrlen = 16
 | 
				
			||||||
 | 
								copy(srcAddr[:addrlen], bs[8:])
 | 
				
			||||||
 | 
								copy(dstAddr[:addrlen], bs[24:])
 | 
				
			||||||
 | 
								copy(dstSnet[:addrlen/2], bs[24:])
 | 
				
			||||||
 | 
							} else if bs[0]&0xf0 == 0x40 {
 | 
				
			||||||
 | 
								// Check if we have a fully-sized IPv4 header
 | 
				
			||||||
 | 
								if len(bs) < 20 {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// Check the packet size
 | 
				
			||||||
 | 
								if n != 256*int(bs[2])+int(bs[3]) {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// IPv4 address
 | 
				
			||||||
 | 
								addrlen = 4
 | 
				
			||||||
 | 
								copy(srcAddr[:addrlen], bs[12:])
 | 
				
			||||||
 | 
								copy(dstAddr[:addrlen], bs[16:])
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// Unknown address length or protocol, so drop the packet and ignore it
 | 
				
			||||||
 | 
								tun.log.Traceln("Unknown packet type, dropping")
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if tun.ckr.isEnabled() && !tun.ckr.isValidSource(srcAddr, addrlen) {
 | 
				
			||||||
 | 
								// The packet had a source address that doesn't belong to us or our
 | 
				
			||||||
 | 
								// configured crypto-key routing source subnets
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !dstAddr.IsValid() && !dstSnet.IsValid() {
 | 
				
			||||||
 | 
								if key, err := tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil {
 | 
				
			||||||
 | 
									// A public key was found, get the node ID for the search
 | 
				
			||||||
 | 
									dstNodeID = crypto.GetNodeID(&key)
 | 
				
			||||||
 | 
									// Do a quick check to ensure that the node ID refers to a vaild
 | 
				
			||||||
 | 
									// Yggdrasil address or subnet - this might be superfluous
 | 
				
			||||||
 | 
									addr := *address.AddrForNodeID(dstNodeID)
 | 
				
			||||||
 | 
									copy(dstAddr[:], addr[:])
 | 
				
			||||||
 | 
									copy(dstSnet[:], addr[:])
 | 
				
			||||||
 | 
									// Are we certain we looked up a valid node?
 | 
				
			||||||
 | 
									if !dstAddr.IsValid() && !dstSnet.IsValid() {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									// No public key was found in the CKR table so we've exhausted our options
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Do we have an active connection for this node address?
 | 
				
			||||||
 | 
							tun.mutex.RLock()
 | 
				
			||||||
 | 
							session, isIn := tun.addrToConn[dstAddr]
 | 
				
			||||||
 | 
							if !isIn || session == nil {
 | 
				
			||||||
 | 
								session, isIn = tun.subnetToConn[dstSnet]
 | 
				
			||||||
 | 
								if !isIn || session == nil {
 | 
				
			||||||
 | 
									// Neither an address nor a subnet mapping matched, therefore populate
 | 
				
			||||||
 | 
									// the node ID and mask to commence a search
 | 
				
			||||||
 | 
									if dstAddr.IsValid() {
 | 
				
			||||||
 | 
										dstNodeID, dstNodeIDMask = dstAddr.GetNodeIDandMask()
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										dstNodeID, dstNodeIDMask = dstSnet.GetNodeIDandMask()
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							tun.mutex.RUnlock()
 | 
				
			||||||
 | 
							// If we don't have a connection then we should open one
 | 
				
			||||||
 | 
							if !isIn || session == nil {
 | 
				
			||||||
 | 
								// Check we haven't been given empty node ID, really this shouldn't ever
 | 
				
			||||||
 | 
								// happen but just to be sure...
 | 
				
			||||||
 | 
								if dstNodeID == nil || dstNodeIDMask == nil {
 | 
				
			||||||
 | 
									panic("Given empty dstNodeID and dstNodeIDMask - this shouldn't happen")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// Dial to the remote node
 | 
				
			||||||
 | 
								go func() {
 | 
				
			||||||
 | 
									// FIXME just spitting out a goroutine to do this is kind of ugly and means we drop packets until the dial finishes
 | 
				
			||||||
 | 
									tun.mutex.Lock()
 | 
				
			||||||
 | 
									_, known := tun.dials[*dstNodeID]
 | 
				
			||||||
 | 
									tun.dials[*dstNodeID] = append(tun.dials[*dstNodeID], bs)
 | 
				
			||||||
 | 
									for len(tun.dials[*dstNodeID]) > 32 {
 | 
				
			||||||
 | 
										util.PutBytes(tun.dials[*dstNodeID][0])
 | 
				
			||||||
 | 
										tun.dials[*dstNodeID] = tun.dials[*dstNodeID][1:]
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									tun.mutex.Unlock()
 | 
				
			||||||
 | 
									if known {
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									var tc *tunConn
 | 
				
			||||||
 | 
									if conn, err := tun.dialer.DialByNodeIDandMask(dstNodeID, dstNodeIDMask); err == nil {
 | 
				
			||||||
 | 
										// We've been given a connection so prepare the session wrapper
 | 
				
			||||||
 | 
										if tc, err = tun.wrap(conn); err != nil {
 | 
				
			||||||
 | 
											// Something went wrong when storing the connection, typically that
 | 
				
			||||||
 | 
											// something already exists for this address or subnet
 | 
				
			||||||
 | 
											tun.log.Debugln("TUN/TAP iface wrap:", err)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									tun.mutex.Lock()
 | 
				
			||||||
 | 
									packets := tun.dials[*dstNodeID]
 | 
				
			||||||
 | 
									delete(tun.dials, *dstNodeID)
 | 
				
			||||||
 | 
									tun.mutex.Unlock()
 | 
				
			||||||
 | 
									if tc != nil {
 | 
				
			||||||
 | 
										for _, packet := range packets {
 | 
				
			||||||
 | 
											select {
 | 
				
			||||||
 | 
											case tc.send <- packet:
 | 
				
			||||||
 | 
											default:
 | 
				
			||||||
 | 
												util.PutBytes(packet)
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}()
 | 
				
			||||||
 | 
								// While the dial is going on we can't do much else
 | 
				
			||||||
 | 
								// continuing this iteration - skip to the next one
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// If we have a connection now, try writing to it
 | 
				
			||||||
 | 
							if isIn && session != nil {
 | 
				
			||||||
 | 
								select {
 | 
				
			||||||
 | 
								case session.send <- bs:
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									util.PutBytes(bs)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (tun *TunAdapter) reader() error {
 | 
				
			||||||
 | 
						recvd := make([]byte, 65535+tun_ETHER_HEADER_LENGTH)
 | 
				
			||||||
 | 
						toWorker := make(chan []byte, 32)
 | 
				
			||||||
 | 
						defer close(toWorker)
 | 
				
			||||||
 | 
						go tun.readerPacketHandler(toWorker)
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							// 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 {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							bs := append(util.GetBytes(), recvd[:n]...)
 | 
				
			||||||
		toWorker <- bs
 | 
							toWorker <- bs
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue