When you build the tree you ask each peer for its headers using an exponentially backed-off index of your own. The peer will send its headers starting at the highest known common block. This is standard p2p behavior. We do not want to allow a subset of peers determine the chain, so these requests are promiscuous. And there is no prioritization but response time (unlike block download) apart from the configured peer timeouts, since we also don’t want to let fast peers determine the chain. All peers compete to built the tree, and the set of headers that a peer has is not knowable until they are received. So if all peers are in sync there will be up to N times duplicate headers. This doesn’t always happen in practice since the fastest responder causes subsequent requests to have higher common points.