@@ -25,6 +25,7 @@ import (
2525 "github.com/ipfs/go-peertaskqueue/peertracker"
2626 process "github.com/jbenet/goprocess"
2727 "github.com/libp2p/go-libp2p/core/peer"
28+ mh "github.com/multiformats/go-multihash"
2829)
2930
3031// TODO consider taking responsibility for other types of requests. For
@@ -187,6 +188,7 @@ type Engine struct {
187188 maxOutstandingBytesPerPeer int
188189
189190 maxQueuedWantlistEntriesPerPeer uint
191+ maxCidSize uint
190192}
191193
192194// TaskInfo represents the details of a request from a peer.
@@ -272,13 +274,20 @@ func WithMaxOutstandingBytesPerPeer(count int) Option {
272274
273275// WithMaxQueuedWantlistEntriesPerPeer limits how much individual entries each peer is allowed to send.
274276// If a peer send us more than this we will truncate newest entries.
275- // It defaults to DefaultMaxQueuedWantlistEntiresPerPeer.
276277func WithMaxQueuedWantlistEntriesPerPeer (count uint ) Option {
277278 return func (e * Engine ) {
278279 e .maxQueuedWantlistEntriesPerPeer = count
279280 }
280281}
281282
283+ // WithMaxQueuedWantlistEntriesPerPeer limits how much individual entries each peer is allowed to send.
284+ // If a peer send us more than this we will truncate newest entries.
285+ func WithMaxCidSize (n uint ) Option {
286+ return func (e * Engine ) {
287+ e .maxCidSize = n
288+ }
289+ }
290+
282291func WithSetSendDontHave (send bool ) Option {
283292 return func (e * Engine ) {
284293 e .sendDontHaves = send
@@ -357,6 +366,7 @@ func newEngine(
357366 tagQueued : fmt .Sprintf (tagFormat , "queued" , uuid .New ().String ()),
358367 tagUseful : fmt .Sprintf (tagFormat , "useful" , uuid .New ().String ()),
359368 maxQueuedWantlistEntriesPerPeer : defaults .MaxQueuedWantlistEntiresPerPeer ,
369+ maxCidSize : defaults .MaximumAllowedCid ,
360370 }
361371
362372 for _ , opt := range opts {
@@ -617,7 +627,7 @@ func (e *Engine) Peers() []peer.ID {
617627// MessageReceived is called when a message is received from a remote peer.
618628// For each item in the wantlist, add a want-have or want-block entry to the
619629// request queue (this is later popped off by the workerTasks)
620- func (e * Engine ) MessageReceived (ctx context.Context , p peer.ID , m bsmsg.BitSwapMessage ) {
630+ func (e * Engine ) MessageReceived (ctx context.Context , p peer.ID , m bsmsg.BitSwapMessage ) ( mustKillConnection bool ) {
621631 entries := m .Wantlist ()
622632
623633 if len (entries ) > 0 {
@@ -676,10 +686,40 @@ func (e *Engine) MessageReceived(ctx context.Context, p peer.ID, m bsmsg.BitSwap
676686 wants = wants [:available ]
677687 }
678688
689+ filteredWants := wants [:0 ] // shift inplace
690+
679691 for _ , entry := range wants {
692+ if entry .Cid .Prefix ().MhType == mh .IDENTITY {
693+ // This is a truely broken client, let's kill the connection.
694+ e .lock .Unlock ()
695+ log .Warnw ("peer wants an identity CID" , "local" , e .self , "remote" , p )
696+ return true
697+ }
698+ if e .maxCidSize != 0 && uint (entry .Cid .ByteLen ()) > e .maxCidSize {
699+ // Ignore requests about CIDs that big.
700+ continue
701+ }
702+
680703 e .peerLedger .Wants (p , entry .Entry )
704+ filteredWants = append (filteredWants , entry )
705+ }
706+ clear := wants [len (filteredWants ):]
707+ for i := range clear {
708+ clear [i ] = bsmsg.Entry {} // early GC
681709 }
710+ wants = filteredWants
682711 for _ , entry := range cancels {
712+ if entry .Cid .Prefix ().MhType == mh .IDENTITY {
713+ // This is a truely broken client, let's kill the connection.
714+ e .lock .Unlock ()
715+ log .Warnw ("peer canceled an identity CID" , "local" , e .self , "remote" , p )
716+ return true
717+ }
718+ if e .maxCidSize != 0 && uint (entry .Cid .ByteLen ()) > e .maxCidSize {
719+ // Ignore requests about CIDs that big.
720+ continue
721+ }
722+
683723 log .Debugw ("Bitswap engine <- cancel" , "local" , e .self , "from" , p , "cid" , entry .Cid )
684724 if e .peerLedger .CancelWant (p , entry .Cid ) {
685725 e .peerRequestQueue .Remove (entry .Cid , p )
@@ -765,6 +805,7 @@ func (e *Engine) MessageReceived(ctx context.Context, p peer.ID, m bsmsg.BitSwap
765805 e .peerRequestQueue .PushTasksTruncated (e .maxQueuedWantlistEntriesPerPeer , p , activeEntries ... )
766806 e .updateMetrics ()
767807 }
808+ return false
768809}
769810
770811// Split the want-have / want-block entries from the cancel entries
0 commit comments