I have two main concerns:
1. Is there any 'first-responder' bias in determining which node to ask for block data from? If there is, then a malicious user with access to a very low-latency connection could disrupt the network by responding extremely quickly to any request with some form of false data - perhaps simply by saying that no new block has been hashed yet - and get disproportionate influence over the consensus this way. If HighSpeedCheater can supply information so fast that he responds first 99% of the time to your query, then you need to do 68-69 queries just to get 50/50 odds that you reach a single node that isn't a HighSpeedCheater sockpuppet - and that node itself might be fooled by HighSpeedCheater and unwittingly be repeating false information. Probably unrealistic for an individual to pull this off, but I can see a big, widely distributed system like a botnet or Google being able to do it. Even then, nodes could get around it just by checking everything 140x as much as they used to.
Nodes send an inv message to all peers when they get a new block; if a node gets an inv message for an unknown block, it will always request it (initially from the node that announced it, but I believe it moves on to others if that one fails to respond). So all it takes is one connection to a 'good' node and you'll get the real block chain. Additionally, when a connection is established, each node queries the other for its 'best' block, and asks for it if it's unknown.
Okay. I was confused by this in the function ProcessMessage
static int nAskedForBlocks;
if (!pfrom->fClient && (nAskedForBlocks < 1 || vNodes.size() <= 1))
I forgot static means that nAskedForBlocks is persistent across function calls. If it wasn't then the client would ask for blocks from every node that sends it a message.