mirror of
https://github.com/netbirdio/ice.git
synced 2026-05-22 17:10:58 -07:00
Use pion/randutil
Move common random generators to pion/randutil.
This commit is contained in:
@@ -7,6 +7,7 @@ require (
|
||||
github.com/pion/dtls/v2 v2.0.1
|
||||
github.com/pion/logging v0.2.2
|
||||
github.com/pion/mdns v0.0.4
|
||||
github.com/pion/randutil v0.0.0
|
||||
github.com/pion/stun v0.3.5
|
||||
github.com/pion/transport v0.10.1
|
||||
github.com/pion/turn/v2 v2.0.4
|
||||
|
||||
@@ -8,6 +8,8 @@ github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
|
||||
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
|
||||
github.com/pion/mdns v0.0.4 h1:O4vvVqr4DGX63vzmO6Fw9vpy3lfztVWHGCQfyw0ZLSY=
|
||||
github.com/pion/mdns v0.0.4/go.mod h1:R1sL0p50l42S5lJs91oNdUL58nm0QHrhxnSegr++qC0=
|
||||
github.com/pion/randutil v0.0.0 h1:aLWLVhTG2jzoD25F0OlW6nXvXrjoGwiXq2Sz7j7NzL0=
|
||||
github.com/pion/randutil v0.0.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
||||
github.com/pion/stun v0.3.5 h1:uLUCBCkQby4S1cf6CGuR9QrVOKcvUwFeemaC865QHDg=
|
||||
github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA=
|
||||
github.com/pion/transport v0.8.10 h1:lTiobMEw2PG6BH/mgIVqTV2mBp/mPT+IJLaN8ZxgdHk=
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
package ice
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"encoding/binary"
|
||||
"math/big"
|
||||
mrand "math/rand" // used for non-crypto unique ID and random port selection
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
import "github.com/pion/randutil"
|
||||
|
||||
const (
|
||||
runesAlpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
@@ -21,58 +14,19 @@ const (
|
||||
// Seeding random generator each time limits number of generated sequence to 31-bits,
|
||||
// and causes collision on low time accuracy environments.
|
||||
// Use global random generator seeded by crypto grade random.
|
||||
var globalMathRandomGenerator = newMathRandomGenerator()
|
||||
var globalMathRandomGenerator = randutil.NewMathRandomGenerator()
|
||||
var globalCandidateIDGenerator = candidateIDGenerator{globalMathRandomGenerator}
|
||||
|
||||
// mathRandomGenerator is a random generator for non-crypto usage.
|
||||
type mathRandomGenerator struct {
|
||||
r *mrand.Rand
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func newMathRandomGenerator() *mathRandomGenerator {
|
||||
var seed int64
|
||||
if err := binary.Read(crand.Reader, binary.LittleEndian, &seed); err != nil {
|
||||
// crypto/rand is unavailable. Fallback to seed by time.
|
||||
seed = time.Now().UnixNano()
|
||||
}
|
||||
|
||||
return &mathRandomGenerator{r: mrand.New(mrand.NewSource(seed))}
|
||||
}
|
||||
|
||||
func (g *mathRandomGenerator) Intn(n int) int {
|
||||
g.mu.Lock()
|
||||
v := g.r.Intn(n)
|
||||
g.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
|
||||
func (g *mathRandomGenerator) Uint64() uint64 {
|
||||
g.mu.Lock()
|
||||
v := g.r.Uint64()
|
||||
g.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
|
||||
func (g *mathRandomGenerator) GenerateString(n int, runes string) string {
|
||||
letters := []rune(runes)
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letters[g.Intn(len(letters))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// candidateIDGenerator is a random candidate ID generator.
|
||||
// Candidate ID is used in SDP and always shared to the other peer.
|
||||
// It doesn't require cryptographic random.
|
||||
type candidateIDGenerator struct {
|
||||
*mathRandomGenerator
|
||||
randutil.MathRandomGenerator
|
||||
}
|
||||
|
||||
func newCandidateIDGenerator() *candidateIDGenerator {
|
||||
return &candidateIDGenerator{
|
||||
newMathRandomGenerator(),
|
||||
randutil.NewMathRandomGenerator(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,31 +35,17 @@ func (g *candidateIDGenerator) Generate() string {
|
||||
// candidate-id = "candidate" ":" foundation
|
||||
// foundation = 1*32ice-char
|
||||
// ice-char = ALPHA / DIGIT / "+" / "/"
|
||||
return "candidate:" + g.mathRandomGenerator.GenerateString(32, runesCandidateIDFoundation)
|
||||
}
|
||||
|
||||
// generateCryptoRandomString generates a random string for crypto usage.
|
||||
func generateCryptoRandomString(n int, runes string) (string, error) {
|
||||
letters := []rune(runes)
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
v, err := crand.Int(crand.Reader, big.NewInt(int64(len(letters))))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
b[i] = letters[v.Int64()]
|
||||
}
|
||||
return string(b), nil
|
||||
return "candidate:" + g.MathRandomGenerator.GenerateString(32, runesCandidateIDFoundation)
|
||||
}
|
||||
|
||||
// generatePwd generates ICE pwd.
|
||||
// This internally uses generateCryptoRandomString.
|
||||
func generatePwd() (string, error) {
|
||||
return generateCryptoRandomString(lenPwd, runesAlpha)
|
||||
return randutil.GenerateCryptoRandomString(lenPwd, runesAlpha)
|
||||
}
|
||||
|
||||
// generateUFrag generates ICE user fragment.
|
||||
// This internally uses generateCryptoRandomString.
|
||||
func generateUFrag() (string, error) {
|
||||
return generateCryptoRandomString(lenUFrag, runesAlpha)
|
||||
return randutil.GenerateCryptoRandomString(lenUFrag, runesAlpha)
|
||||
}
|
||||
|
||||
@@ -1,43 +1,10 @@
|
||||
package ice
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMathRandomGenerator(t *testing.T) {
|
||||
g := newMathRandomGenerator()
|
||||
isLetter := regexp.MustCompile(`^[a-zA-Z]+$`).MatchString
|
||||
|
||||
for i := 0; i < 10000; i++ {
|
||||
s := g.GenerateString(10, runesAlpha)
|
||||
if len(s) != 10 {
|
||||
t.Error("Generator returned invalid length")
|
||||
}
|
||||
if !isLetter(s) {
|
||||
t.Errorf("Generator returned unexpected character: %s", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCryptoRandomGenerator(t *testing.T) {
|
||||
isLetter := regexp.MustCompile(`^[a-zA-Z]+$`).MatchString
|
||||
|
||||
for i := 0; i < 10000; i++ {
|
||||
s, err := generateCryptoRandomString(10, runesAlpha)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(s) != 10 {
|
||||
t.Error("Generator returned invalid length")
|
||||
}
|
||||
if !isLetter(s) {
|
||||
t.Errorf("Generator returned unexpected character: %s", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandomGeneratorCollision(t *testing.T) {
|
||||
candidateIDGen := newCandidateIDGenerator()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user