diff options
author | Péter Szilágyi <peterke@gmail.com> | 2015-07-01 20:19:11 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2015-07-01 20:21:35 +0800 |
commit | d6f2c0a76f6635ebeb245815c5f686c545ed527d (patch) | |
tree | 4de6598a2f8df2086b5b3892f25750757aeeede6 /eth/downloader/downloader.go | |
parent | 1ae80aaf64c5acfde19fee5ee3bc4579db7ea76e (diff) | |
download | dexon-d6f2c0a76f6635ebeb245815c5f686c545ed527d.tar dexon-d6f2c0a76f6635ebeb245815c5f686c545ed527d.tar.gz dexon-d6f2c0a76f6635ebeb245815c5f686c545ed527d.tar.bz2 dexon-d6f2c0a76f6635ebeb245815c5f686c545ed527d.tar.lz dexon-d6f2c0a76f6635ebeb245815c5f686c545ed527d.tar.xz dexon-d6f2c0a76f6635ebeb245815c5f686c545ed527d.tar.zst dexon-d6f2c0a76f6635ebeb245815c5f686c545ed527d.zip |
eth, eth/downloader: fix #1231, DOS vulnerability in hash queueing
Diffstat (limited to 'eth/downloader/downloader.go')
-rw-r--r-- | eth/downloader/downloader.go | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index ce85aec17..c788048e9 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -34,8 +34,9 @@ var ( blockHardTTL = 3 * blockSoftTTL // Maximum time allowance before a block request is considered expired crossCheckCycle = time.Second // Period after which to check for expired cross checks - maxBannedHashes = 4096 // Number of bannable hashes before phasing old ones out - maxBlockProcess = 256 // Number of blocks to import at once into the chain + maxQueuedHashes = 256 * 1024 // Maximum number of hashes to queue for import (DOS protection) + maxBannedHashes = 4096 // Number of bannable hashes before phasing old ones out + maxBlockProcess = 256 // Number of blocks to import at once into the chain ) var ( @@ -780,6 +781,8 @@ func (d *Downloader) fetchHashes(p *peer, from uint64) error { defer timeout.Stop() getHashes := func(from uint64) { + glog.V(logger.Detail).Infof("%v: fetching %d hashes from #%d", p, MaxHashFetch, from) + go p.getAbsHashes(from, MaxHashFetch) timeout.Reset(hashTTL) } @@ -809,16 +812,23 @@ func (d *Downloader) fetchHashes(p *peer, from uint64) error { return nil } // Otherwise insert all the new hashes, aborting in case of junk + glog.V(logger.Detail).Infof("%v: inserting %d hashes from #%d", p, len(hashPack.hashes), from) + inserts := d.queue.Insert(hashPack.hashes, true) if len(inserts) != len(hashPack.hashes) { glog.V(logger.Debug).Infof("%v: stale hashes", p) return errBadPeer } - // Notify the block fetcher of new hashes, and continue fetching + // Notify the block fetcher of new hashes, but stop if queue is full + cont := d.queue.Pending() < maxQueuedHashes select { - case d.processCh <- true: + case d.processCh <- cont: default: } + if !cont { + return nil + } + // Queue not yet full, fetch the next batch from += uint64(len(hashPack.hashes)) getHashes(from) |