github.com/anacrolix/dht/v2 v2.19.2-0.20221121215055-066ad8494444
github.com/anacrolix/envpprof v1.3.0
github.com/anacrolix/fuse v0.2.0
- github.com/anacrolix/generics v0.0.2-0.20240227122613-f95486179cab
+ github.com/anacrolix/generics v0.0.3-0.20240902042256-7fb2702ef0ca
github.com/anacrolix/go-libutp v1.3.1
github.com/anacrolix/gostdapp v0.1.0
github.com/anacrolix/log v0.15.3-0.20240627045001-cd912c641d83
github.com/anacrolix/fuse v0.2.0 h1:pc+To78kI2d/WUjIyrsdqeJQAesuwpGxlI3h1nAv3Do=
github.com/anacrolix/fuse v0.2.0/go.mod h1:Kfu02xBwnySDpH3N23BmrP3MDfwAQGRLUCj6XyeOvBQ=
github.com/anacrolix/generics v0.0.0-20230113004304-d6428d516633/go.mod h1:ff2rHB/joTV03aMSSn/AZNnaIpUw0h3njetGsaXcMy8=
-github.com/anacrolix/generics v0.0.2-0.20240227122613-f95486179cab h1:MvuAC/UJtcohN6xWc8zYXSZfllh1LVNepQ0R3BCX5I4=
-github.com/anacrolix/generics v0.0.2-0.20240227122613-f95486179cab/go.mod h1:ff2rHB/joTV03aMSSn/AZNnaIpUw0h3njetGsaXcMy8=
+github.com/anacrolix/generics v0.0.3-0.20240902042256-7fb2702ef0ca h1:aiiGqSQWjtVNdi8zUMfA//IrM8fPkv2bWwZVPbDe0wg=
+github.com/anacrolix/generics v0.0.3-0.20240902042256-7fb2702ef0ca/go.mod h1:MN3ve08Z3zSV/rTuX/ouI4lNdlfTxgdafQJiLzyNRB8=
github.com/anacrolix/go-libutp v1.3.1 h1:idJzreNLl+hNjGC3ZnUOjujEaryeOGgkwHLqSGoige0=
github.com/anacrolix/go-libutp v1.3.1/go.mod h1:heF41EC8kN0qCLMokLBVkB8NXiLwx3t8R8810MTNI5o=
github.com/anacrolix/gostdapp v0.1.0 h1:sZC+gSLhA7Hdalak5rPCkhO0YSEl0tt/lsovxh6qka4=
import (
"context"
"encoding/hex"
- "errors"
"fmt"
+ "github.com/anacrolix/missinggo/v2/panicif"
"github.com/anacrolix/torrent/internal/ctxrw"
"io"
"math/bits"
- "strconv"
"strings"
"unsafe"
}()
post := func(bb []byte) {
- select {
- case postCh <- bb:
- default:
- panic("mustn't block while posting")
- }
+ panicif.SendBlocks(postCh, bb)
}
- post([]byte(Protocol))
+ post(protocolBytes())
post(extensions[:])
if ih != nil { // We already know what we want.
post(ih[:])
post(peerID[:])
}
- var b [68]byte
- _, err = io.ReadFull(sock, b[:68])
+
+ // Putting an array on the heap still escapes.
+ b := make([]byte, 68)
+ // Read in one hit to avoid potential overhead in underlying reader.
+ _, err = io.ReadFull(sock, b[:])
if err != nil {
return res, fmt.Errorf("while reading: %w", err)
}
- if string(b[:20]) != Protocol {
- return res, errors.New("unexpected protocol string")
- }
- copyExact := func(dst, src []byte) {
- if dstLen, srcLen := uint64(len(dst)), uint64(len(src)); dstLen != srcLen {
- panic("dst len " + strconv.FormatUint(dstLen, 10) + " != src len " + strconv.FormatUint(srcLen, 10))
- }
- copy(dst, src)
+ p := b[:len(Protocol)]
+ // This gets optimized to runtime.memequal
+ if string(p) != Protocol {
+ return res, fmt.Errorf("unexpected protocol string %q", string(p))
+ }
+ b = b[len(p):]
+ read := func(dst []byte) {
+ n := copy(dst, b)
+ panicif.NotEq(n, len(dst))
+ b = b[n:]
}
- copyExact(res.PeerExtensionBits[:], b[20:28])
- copyExact(res.Hash[:], b[28:48])
- copyExact(res.PeerID[:], b[48:68])
+ read(res.PeerExtensionBits[:])
+ read(res.Hash[:])
+ read(res.PeerID[:])
+ panicif.NotEq(len(b), 0)
// peerExtensions.Add(res.PeerExtensionBits.String(), 1)
// TODO: Maybe we can just drop peers here if we're not interested. This