anchor.diff:  % !first node
   % 2. Find known hosts
   % no matter which phase, if there are no contact nodes (yet), try to get some
  -process_join_state({join, known_hosts_timeout} = _Msg,
  -                   {join, JoinState, _QueuedMessages} = State) ->
  +process_join_state({join, known_hosts_timeout, JoinUUId} = _Msg,
  +                   {join, JoinState, _QueuedMessages} = State) 
  +  when element(2, JoinState) =:= JoinUUId ->
       ?TRACE1(_Msg, {join, JoinState}),
       case get_connections(JoinState) of
  -        [] -> get_known_nodes();
  +        [] -> get_known_nodes(JoinUUId);
           [_|_] -> ok
       end,
  +    State;
  +
  +% ignore unrelated known_hosts_timeout:
  +process_join_state({join, known_hosts_timeout, _JoinId} = _Msg,
  +                   {join, _JoinState, _QueuedMessages} = State) ->
  +    ?TRACE1(_Msg, {join, _JoinState}),
       State;
   
   %% userdevguide-begin dht_node_join:join_other_p2
  
positive.code:     {join, get_candidate_response, OrigJoinId::?RT:key(), Candidate::lb_op:lb_op(), Conn::connection()} |
      {join, join_response, Succ::node:node_type(), Pred::node:node_type(), MoveFullId::slide_op:id(), CandId::lb_op:id()} |
      {join, join_response, not_responsible, CandId::lb_op:id()} |
      {join, lookup_timeout, Conn::connection()} |
      {join, known_hosts_timeout} |
      {join, get_number_of_samples_timeout, Conn::connection()} |
      {join, join_request_timeout, Timeouts::non_neg_integer(), CandId::lb_op:id()} |
      {join, timeout} |
      % messages at the existing node:
      {join, number_of_samples_request, SourcePid::comm:mypid(), LbPsv::module(), Conn::connection()} |
      {join, get_candidate, Source_PID::comm:mypid(), Key::?RT:key(), LbPsv::module(), Conn::connection()} |
  
negative.code:         [] -> % no candidates -> should not happen in phase4!
              log:log(error, "[ Node ~w ] empty candidate list in join phase 4, "
                          "starting over", [self()]),
              NewJoinState = start_over(JoinState),
              ?TRACE_STATE(NewJoinState),
              {join, NewJoinState, QueuedMessages};
          [Candidate | _Rest] ->
              case lb_op:get(Candidate, id) =:= CandId of
                  false -> State; % unrelated/old message
  