mirror of
https://github.com/sot-tech/mochi.git
synced 2026-07-27 09:48:09 -07:00
(partially tested) add scrape JWT validation
* remove `xorshift` package, add internal function in `varinterval` * change `bittorrent.QueryParams` getters to search case insensitive keys
This commit is contained in:
@@ -3,14 +3,15 @@ package varinterval
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sot-tech/mochi/bittorrent"
|
||||
"github.com/sot-tech/mochi/middleware"
|
||||
"github.com/sot-tech/mochi/middleware/pkg/random"
|
||||
"github.com/sot-tech/mochi/pkg/conf"
|
||||
"github.com/sot-tech/mochi/storage"
|
||||
)
|
||||
@@ -79,14 +80,12 @@ type hook struct {
|
||||
}
|
||||
|
||||
func (h *hook) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest, resp *bittorrent.AnnounceResponse) (context.Context, error) {
|
||||
s0, s1 := random.DeriveEntropyFromRequest(req)
|
||||
// Generate a probability p < 1.0.
|
||||
v, s0, s1 := random.Intn(s0, s1, 1<<24)
|
||||
p := float32(v) / (1 << 24)
|
||||
if h.cfg.ModifyResponseProbability == 1 || p < h.cfg.ModifyResponseProbability {
|
||||
p, s0, s1 := xoroshiro128p(deriveEntropyFromRequest(req))
|
||||
if float32(float64(p)/math.MaxUint64) < h.cfg.ModifyResponseProbability {
|
||||
// Generate the increase delta.
|
||||
v, _, _ = random.Intn(s0, s1, h.cfg.MaxIncreaseDelta)
|
||||
add := time.Duration(v+1) * time.Second
|
||||
v, _, _ := xoroshiro128p(s0, s1)
|
||||
add := time.Duration(v%uint64(h.cfg.MaxIncreaseDelta)+1) * time.Second
|
||||
|
||||
resp.Interval += add
|
||||
|
||||
@@ -102,3 +101,26 @@ func (h *hook) HandleScrape(ctx context.Context, _ *bittorrent.ScrapeRequest, _
|
||||
// Scrapes are not altered.
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// deriveEntropyFromRequest generates 2*64 bits of pseudo random state from an
|
||||
// bittorrent.AnnounceRequest.
|
||||
//
|
||||
// Calling deriveEntropyFromRequest multiple times yields the same values.
|
||||
func deriveEntropyFromRequest(req *bittorrent.AnnounceRequest) (v0 uint64, v1 uint64) {
|
||||
if len(req.InfoHash) >= bittorrent.InfoHashV1Len {
|
||||
v0 = binary.BigEndian.Uint64([]byte(req.InfoHash[:8])) + binary.BigEndian.Uint64([]byte(req.InfoHash[8:16]))
|
||||
}
|
||||
v1 = binary.BigEndian.Uint64(req.ID[:8]) + binary.BigEndian.Uint64(req.ID[8:16])
|
||||
return
|
||||
}
|
||||
|
||||
// xoroshiro128p calculates predictable pseudorandom number
|
||||
// with XOR/rotate/shift/rotate 128+ algorithm.
|
||||
// see https://prng.di.unimi.it/xoroshiro128plus.c
|
||||
func xoroshiro128p(s0, s1 uint64) (result, ns0, ns1 uint64) {
|
||||
result = s0 + s1
|
||||
s1 ^= s0
|
||||
ns0 = ((s0 << 24) | (s0 >> 40)) ^ s1 ^ (s1 << 16) // rotl(s0, 24) ^ s1 ^ (s1 << 16)
|
||||
ns1 = (s1 << 37) | (s1 >> 27) // rotl(s1, 37)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,12 +3,15 @@ package varinterval
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/sot-tech/mochi/bittorrent"
|
||||
"github.com/sot-tech/mochi/pkg/conf"
|
||||
|
||||
_ "github.com/sot-tech/mochi/pkg/randseed"
|
||||
)
|
||||
|
||||
var configTests = []struct {
|
||||
@@ -61,3 +64,13 @@ func TestHandleAnnounce(t *testing.T) {
|
||||
require.True(t, resp.Interval > 0, "interval should have been increased")
|
||||
require.True(t, resp.MinInterval > 0, "min_interval should have been increased")
|
||||
}
|
||||
|
||||
func BenchmarkXORoShiRo128Plus(b *testing.B) {
|
||||
s0, s1 := rand.Uint64(), rand.Uint64()
|
||||
var v uint64
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
v, s0, s1 = xoroshiro128p(s0, s1)
|
||||
}
|
||||
_, _, _ = v, s0, s1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user