Prevent peer flooding inv request queue (redux) (redux) #7079

pull gmaxwell wants to merge 2 commits into bitcoin:master from gmaxwell:setAskFor changing 3 files +12 −1
  1. gmaxwell commented at 2:13 am on November 23, 2015: contributor

    Currently it’s possible for peers to send duplicate invs of the same object and push the inv request time far back.

    PR #4547 sought to address this, but was closed with the expectation that it would be replaced by the more comprehensive #4831 but the latter hasn’t yet reached escape velocity. I agree a comprehensive rework is better, but I think we should not let a simple improvement wait for that.

    PR #6306 tried a simpler version, but by reusing the setInventoryKnown it gets the logic somewhat wrong, e.g. not allowing duplicate INVs even for objects we’d mempool retired but now would be accept again.

    Here I bring back #4547 and add size limiting and make an important change to the logic (which I believe was originally flawed, though no one seems to have commented on that in the original PR):

    The earlier PR would remove the suppression as soon as the getdata was requested, rather than removing it when response was returned. This one removes only when we decide to not getdata (because we already have) or when the getdata returns. This means that a peer can only have one in-flight INV for a particular tx at once; which is what we want.

  2. prevent peer flooding request queue for an inv
    mapAlreadyAskedFor does not keep track of which peer has a request queued for a
    particular tx. As a result, a peer can blind a node to a tx indefinitely by
    sending many invs for the same tx, and then never replying to getdatas for it.
    Each inv received will be placed 2 minutes farther back in mapAlreadyAskedFor,
    so a short message containing 10 invs would render that tx unavailable for 20
    minutes.
    
    This is fixed by disallowing a peer from having more than one entry for a
    particular inv in mapAlreadyAskedFor at a time.
    5029698186
  3. Limit setAskFor and retire requested entries only when a getdata returns.
    The setAskFor duplicate elimination was too eager and removed entries
     when we still had no getdata response, allowing the peer to keep
     INVing and not responding.
    ebb25f4c23
  4. laanwj added the label P2P on Nov 24, 2015
  5. laanwj commented at 8:22 am on November 24, 2015: member
    concept ACK
  6. laanwj added this to the milestone 0.12.0 on Nov 24, 2015
  7. dgenr8 commented at 2:16 am on November 25, 2015: contributor

    e.g. not allowing duplicate INVs even for objects we’d mempool retired but now would be accept again.

    That’s a bug in CTxMemPool::Expire. It should clean the tx out of all setInventoryKnowns anyway, else we won’t try to re-inv it to peers when it comes in again.

  8. gmaxwell commented at 5:05 am on November 25, 2015: contributor
    @dgenr8 I don’t think it is, or at least it’s debatable… we won’t reinv to peers we already INVed it to– they may well still have it– we should still reinv to anyone we haven’t.
  9. dcousens commented at 9:09 am on November 25, 2015: contributor
    concept ACK
  10. dgenr8 commented at 10:02 pm on November 25, 2015: contributor
    @gmaxwell Ah well, as long as the attack is mitigated. It’s also possible to drop the timeout to 20s (from 2m) and only miss a response 1% of the time. .4% at 30s.
  11. gmaxwell commented at 10:35 pm on November 25, 2015: contributor

    The timeouts must be set very conservatively or otherwise a congested node (e.g. one under dos attack) can exhaust itself with repeated transmissions. You cannot count on the average case measured on a node with good connectivity.

    I’m also not particularly interested if someone– with a bunch of work– can delay a transaction by a couple minutes; it’s not a very interesting attack compared to self congestion collapse (which can happen absent any attacker at all). 2 minutes is the appropriate scaling from the 20 minute value used elsewhere, with respect to a the maximum size standard transaction being 1/10th the block size.

  12. sipa commented at 9:15 pm on November 26, 2015: member
    Untested ACK
  13. laanwj commented at 11:57 am on November 30, 2015: member
    utACK
  14. laanwj merged this on Dec 1, 2015
  15. laanwj closed this on Dec 1, 2015

  16. laanwj referenced this in commit 1b5118bfa0 on Dec 1, 2015
  17. luke-jr referenced this in commit 45c7ab2db2 on Jan 10, 2016
  18. luke-jr referenced this in commit 3b21a5ecd2 on Jan 10, 2016
  19. luke-jr referenced this in commit b83ab95d8d on Jan 10, 2016
  20. luke-jr referenced this in commit 0d43146081 on Jan 10, 2016
  21. zkbot referenced this in commit 5ef7fecf14 on Sep 20, 2016
  22. Fuzzbawls referenced this in commit 50285d0427 on Sep 26, 2016
  23. random-zebra referenced this in commit 71275c1896 on Jun 9, 2021
  24. MarcoFalke locked this on Sep 8, 2021


gmaxwell laanwj dgenr8 dcousens sipa

Labels
P2P

Milestone
0.12.0


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-11-17 03:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me