code: func (net *Network) handle(n *Node, ev nodeEvent, pkt *ingressPacket) error {
  	//fmt.Println("handle", n.addr().String(), n.state, ev)
  	if pkt != nil {
  		if err := net.checkPacket(n, ev, pkt); err != nil {
  			//fmt.Println("check err:", err)
  			return err
  		}
  		// Start the background expiration goroutine after the first
  		// successful communication. Subsequent calls have no effect if it
  		// is already running. We do this here instead of somewhere else
  		// so that the search for seed nodes also considers older nodes
  		// that would otherwise be removed by the expirer.
  		if net.db != nil {
  			net.db.ensureExpirer()
  		}
  	}
  	if n.state == nil {
  		n.state = unknown //???
  	}
  	next, err := n.state.handle(net, n, ev, pkt)
  	net.transition(n, next)
  	//fmt.Println("new state:", n.state)
  	return err
  }
docs: // handle processes packets sent by n and events related to n.