A live DoS attack observed by several nodes in recent days involved repeated rejection of duplicate transactions.
Add a call to AlreadyHave when an unsolicited full tx is received, as was the case in the observed attack. AlreadyHave uses the recentRejects filter.
I tested this change on mainnet while the actual attack was still underway.
The recentRejects filter is cleared when the tip is updated, so nothing stops attacker from re-transmitting a load of rejectable txes after a new block, and in fact our attacker was doing this. But the duplicates are stopped between blocks and the attack could get arbitrarily heavy if multiple attacking peers were involved.