Repository: bluenviron/gortsplib
Pull request #337 (2023-07-30 20:37:18)

return an error in case the random number generator fails

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) Report
> Merging [#337](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) (c7b205e) into [main](https://app.codecov.io/gh/bluenviron/gortsplib/commit/577d6f3a284a1c5c7e9b7993c1050aa0d4006e5c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) (577d6f3) will **decrease** coverage by `1.35%`.
> The diff coverage is `38.30%`.

```diff
@@            Coverage Diff             @@
##             main     #337      +/-   ##
==========================================
- Coverage   84.43%   83.08%   -1.35%     
==========================================
  Files         101      101              
  Lines       10204    10354     +150     
==========================================
- Hits         8616     8603      -13     
- Misses       1262     1375     +113     
- Partials      326      376      +50     
```


| [Files Changed](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) | Coverage Δ | |
|---|---|---|
| [pkg/formats/rtpmjpeg/encoder.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL2Zvcm1hdHMvcnRwbWpwZWcvZW5jb2Rlci5nbw==) | `51.72% <0.00%> (-2.69%)` | :arrow_down: |
| [pkg/rtcpreceiver/rtcpreceiver.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL3J0Y3ByZWNlaXZlci9ydGNwcmVjZWl2ZXIuZ28=) | `81.69% <25.00%> (-3.05%)` | :arrow_down: |
| [pkg/auth/validator.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL2F1dGgvdmFsaWRhdG9yLmdv) | `40.16% <33.33%> (-2.12%)` | :arrow_down: |
| [pkg/formats/rtpav1/encoder.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL2Zvcm1hdHMvcnRwYXYxL2VuY29kZXIuZ28=) | `84.37% <40.00%> (-12.14%)` | :arrow_down: |
| [pkg/formats/rtph264/encoder.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL2Zvcm1hdHMvcnRwaDI2NC9lbmNvZGVyLmdv) | `88.46% <40.00%> (-6.31%)` | :arrow_down: |
| [pkg/formats/rtph265/encoder.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL2Zvcm1hdHMvcnRwaDI2NS9lbmNvZGVyLmdv) | `86.51% <40.00%> (-6.35%)` | :arrow_down: |
| [pkg/formats/rtplpcm/encoder.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL2Zvcm1hdHMvcnRwbHBjbS9lbmNvZGVyLmdv) | `80.26% <40.00%> (-15.20%)` | :arrow_down: |
| [pkg/formats/rtpmpeg2audio/encoder.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL2Zvcm1hdHMvcnRwbXBlZzJhdWRpby9lbmNvZGVyLmdv) | `78.67% <40.00%> (-7.84%)` | :arrow_down: |
| [pkg/formats/rtpmpeg4audiogeneric/encoder.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL2Zvcm1hdHMvcnRwbXBlZzRhdWRpb2dlbmVyaWMvZW5jb2Rlci5nbw==) | `90.42% <40.00%> (-6.21%)` | :arrow_down: |
| [pkg/formats/rtpmpeg4audiolatm/encoder.go](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron#diff-cGtnL2Zvcm1hdHMvcnRwbXBlZzRhdWRpb2xhdG0vZW5jb2Rlci5nbw==) | `83.69% <40.00%> (-12.65%)` | :arrow_down: |
| ... and [9 more](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron) | |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/bluenviron/gortsplib/pull/337/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron)

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bluenviron)


Patch:
diff --git a/client_format.go b/client_format.go
index e77a67d5..328a9fd2 100644
--- a/client_format.go
+++ b/client_format.go
@@ -61,12 +61,16 @@ func (ct *clientFormat) start() {
 	if ct.cm.c.state == clientStatePlay {
 		if ct.cm.udpRTPListener != nil {
 			ct.udpReorderer = rtpreorderer.New()
-			ct.udpRTCPReceiver = rtcpreceiver.New(
+			var err error
+			ct.udpRTCPReceiver, err = rtcpreceiver.New(
 				ct.cm.c.udpReceiverReportPeriod,
 				nil,
 				ct.format.ClockRate(), func(pkt rtcp.Packet) {
 					ct.cm.writePacketRTCP(pkt)
 				})
+			if err != nil {
+				panic(err)
+			}
 		} else {
 			ct.tcpLossDetector = rtplossdetector.New()
 		}
diff --git a/client_media.go b/client_media.go
index 7964c0e2..66496bee 100644
--- a/client_media.go
+++ b/client_media.go
@@ -70,12 +70,13 @@ func (cm *clientMedia) allocateUDPListeners(multicast bool, rtpAddress string, r
 		return nil
 	}
 
-	cm.udpRTPListener, cm.udpRTCPListener = newClientUDPListenerPair(
+	var err error
+	cm.udpRTPListener, cm.udpRTCPListener, err = newClientUDPListenerPair(
 		cm.c.ListenPacket,
 		cm.c.AnyPortEnable,
 		cm.c.WriteTimeout,
 	)
-	return nil
+	return err
 }
 
 func (cm *clientMedia) setMedia(medi *media.Media) {
diff --git a/client_udp_listener.go b/client_udp_listener.go
index 088fe9cf..6696f82a 100644
--- a/client_udp_listener.go
+++ b/client_udp_listener.go
@@ -15,10 +15,13 @@ func int64Ptr(v int64) *int64 {
 	return &v
 }
 
-func randInRange(max int) int {
+func randInRange(max int) (int, error) {
 	b := big.NewInt(int64(max + 1))
-	n, _ := rand.Int(rand.Reader, b)
-	return int(n.Int64())
+	n, err := rand.Int(rand.Reader, b)
+	if err != nil {
+		return 0, err
+	}
+	return int(n.Int64()), nil
 }
 
 type clientUDPListener struct {
@@ -41,11 +44,16 @@ func newClientUDPListenerPair(
 	listenPacket func(network, address string) (net.PacketConn, error),
 	anyPortEnable bool,
 	writeTimeout time.Duration,
-) (*clientUDPListener, *clientUDPListener) {
+) (*clientUDPListener, *clientUDPListener, error) {
 	// choose two consecutive ports in range 65535-10000
 	// RTP port must be even and RTCP port odd
 	for {
-		rtpPort := randInRange((65535-10000)/2)*2 + 10000
+		v, err := randInRange((65535 - 10000) / 2)
+		if err != nil {
+			return nil, nil, err
+		}
+
+		rtpPort := v*2 + 10000
 		rtpListener, err := newClientUDPListener(
 			listenPacket,
 			anyPortEnable,
@@ -70,7 +78,7 @@ func newClientUDPListenerPair(
 			continue
 		}
 
-		return rtpListener, rtcpListener
+		return rtpListener, rtcpListener, nil
 	}
 }
 
diff --git a/pkg/auth/validate.go b/pkg/auth/validate.go
index 6bbedd58..3fd5cf6f 100644
--- a/pkg/auth/validate.go
+++ b/pkg/auth/validate.go
@@ -11,10 +11,14 @@ import (
 )
 
 // GenerateNonce generates a nonce that can be used in Validate().
-func GenerateNonce() string {
+func GenerateNonce() (string, error) {
 	byts := make([]byte, 16)
-	rand.Read(byts)
-	return hex.EncodeToString(byts)
+	_, err := rand.Read(byts)
+	if err != nil {
+		return "", err
+	}
+
+	return hex.EncodeToString(byts), nil
 }
 
 // GenerateWWWAuthenticate generates a WWW-Authenticate header.
diff --git a/pkg/auth/validator.go b/pkg/auth/validator.go
index 47511392..fc4a4def 100644
--- a/pkg/auth/validator.go
+++ b/pkg/auth/validator.go
@@ -2,7 +2,6 @@ package auth
 
 import (
 	"crypto/md5"
-	"crypto/rand"
 	"crypto/sha256"
 	"encoding/base64"
 	"encoding/hex"
@@ -65,9 +64,10 @@ func NewValidator(user string, pass string, methods []headers.AuthMethod) *Valid
 		methods = []headers.AuthMethod{headers.AuthBasic}
 	}
 
-	nonceByts := make([]byte, 16)
-	rand.Read(nonceByts)
-	nonce := hex.EncodeToString(nonceByts)
+	nonce, err := GenerateNonce()
+	if err != nil {
+		panic(err)
+	}
 
 	return &Validator{
 		user:       user,
diff --git a/pkg/formats/rtpav1/encoder.go b/pkg/formats/rtpav1/encoder.go
index 4c5fdbec..fc867d05 100644
--- a/pkg/formats/rtpav1/encoder.go
+++ b/pkg/formats/rtpav1/encoder.go
@@ -14,10 +14,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/AV1 encoder.
@@ -49,15 +52,25 @@ type Encoder struct {
 // Init initializes the encoder.
 func (e *Encoder) Init() error {
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtph264/encoder.go b/pkg/formats/rtph264/encoder.go
index fb81ccc5..5ec7910a 100644
--- a/pkg/formats/rtph264/encoder.go
+++ b/pkg/formats/rtph264/encoder.go
@@ -15,10 +15,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/H264 encoder.
@@ -56,15 +59,25 @@ func (e *Encoder) Init() error {
 	}
 
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtph265/encoder.go b/pkg/formats/rtph265/encoder.go
index e79e0435..3bf138bc 100644
--- a/pkg/formats/rtph265/encoder.go
+++ b/pkg/formats/rtph265/encoder.go
@@ -14,10 +14,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/H265 encoder.
@@ -56,15 +59,25 @@ func (e *Encoder) Init() error {
 	}
 
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtplpcm/encoder.go b/pkg/formats/rtplpcm/encoder.go
index dffc4850..b409138f 100644
--- a/pkg/formats/rtplpcm/encoder.go
+++ b/pkg/formats/rtplpcm/encoder.go
@@ -14,10 +14,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/LPCM encoder.
@@ -55,15 +58,25 @@ type Encoder struct {
 // Init initializes the encoder.
 func (e *Encoder) Init() error {
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtpmjpeg/encoder.go b/pkg/formats/rtpmjpeg/encoder.go
index 26f80f6c..a7bdb3b8 100644
--- a/pkg/formats/rtpmjpeg/encoder.go
+++ b/pkg/formats/rtpmjpeg/encoder.go
@@ -17,10 +17,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/M-JPEG encoder.
@@ -49,15 +52,25 @@ type Encoder struct {
 // Init initializes the encoder.
 func (e *Encoder) Init() error {
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtpmpeg2audio/encoder.go b/pkg/formats/rtpmpeg2audio/encoder.go
index 3d801352..f136f3fc 100644
--- a/pkg/formats/rtpmpeg2audio/encoder.go
+++ b/pkg/formats/rtpmpeg2audio/encoder.go
@@ -14,10 +14,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 func lenAggregated(frames [][]byte, frame []byte) int {
@@ -54,15 +57,25 @@ type Encoder struct {
 // Init initializes the encoder.
 func (e *Encoder) Init() error {
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtpmpeg4audiogeneric/encoder.go b/pkg/formats/rtpmpeg4audiogeneric/encoder.go
index 85c92bfb..5dcc4646 100644
--- a/pkg/formats/rtpmpeg4audiogeneric/encoder.go
+++ b/pkg/formats/rtpmpeg4audiogeneric/encoder.go
@@ -15,10 +15,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/MPEG4-audio encoder.
@@ -62,15 +65,25 @@ type Encoder struct {
 // Init initializes the encoder.
 func (e *Encoder) Init() error {
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtpmpeg4audiolatm/encoder.go b/pkg/formats/rtpmpeg4audiolatm/encoder.go
index 9f540f9d..ab5bf690 100644
--- a/pkg/formats/rtpmpeg4audiolatm/encoder.go
+++ b/pkg/formats/rtpmpeg4audiolatm/encoder.go
@@ -15,10 +15,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/MPEG4-audio encoder.
@@ -57,15 +60,25 @@ func (e *Encoder) Init() error {
 	}
 
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtpmpeg4video/encoder.go b/pkg/formats/rtpmpeg4video/encoder.go
index 4b2ba8c0..eab4c263 100644
--- a/pkg/formats/rtpmpeg4video/encoder.go
+++ b/pkg/formats/rtpmpeg4video/encoder.go
@@ -13,10 +13,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/MPEG-4 Video encoder.
@@ -48,15 +51,25 @@ type Encoder struct {
 // Init initializes the encoder.
 func (e *Encoder) Init() error {
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtpsimpleaudio/encoder.go b/pkg/formats/rtpsimpleaudio/encoder.go
index af397621..1f6e8ee4 100644
--- a/pkg/formats/rtpsimpleaudio/encoder.go
+++ b/pkg/formats/rtpsimpleaudio/encoder.go
@@ -14,10 +14,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/simple audio encoder.
@@ -50,15 +53,25 @@ type Encoder struct {
 // Init initializes the encoder.
 func (e *Encoder) Init() error {
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtpvp8/encoder.go b/pkg/formats/rtpvp8/encoder.go
index c11783b0..efbadc8a 100644
--- a/pkg/formats/rtpvp8/encoder.go
+++ b/pkg/formats/rtpvp8/encoder.go
@@ -15,10 +15,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/VP8 encoder.
@@ -51,15 +54,25 @@ type Encoder struct {
 // Init initializes the encoder.
 func (e *Encoder) Init() error {
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
diff --git a/pkg/formats/rtpvp9/encoder.go b/pkg/formats/rtpvp9/encoder.go
index 23fbe315..761dbf50 100644
--- a/pkg/formats/rtpvp9/encoder.go
+++ b/pkg/formats/rtpvp9/encoder.go
@@ -15,10 +15,13 @@ const (
 	rtpVersion = 2
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 // Encoder is a RTP/VP9 encoder.
@@ -55,23 +58,37 @@ type Encoder struct {
 // Init initializes the encoder.
 func (e *Encoder) Init() error {
 	if e.SSRC == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.SSRC = &v
 	}
 	if e.InitialSequenceNumber == nil {
-		v := uint16(randUint32())
-		e.InitialSequenceNumber = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialSequenceNumber = &v2
 	}
 	if e.InitialTimestamp == nil {
-		v := randUint32()
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
 		e.InitialTimestamp = &v
 	}
 	if e.PayloadMaxSize == 0 {
 		e.PayloadMaxSize = 1460 // 1500 (UDP MTU) - 20 (IP header) - 8 (UDP header) - 12 (RTP header)
 	}
 	if e.InitialPictureID == nil {
-		v := uint16(randUint32())
-		e.InitialPictureID = &v
+		v, err := randUint32()
+		if err != nil {
+			return err
+		}
+		v2 := uint16(v)
+		e.InitialPictureID = &v2
 	}
 
 	e.sequenceNumber = *e.InitialSequenceNumber
diff --git a/pkg/rtcpreceiver/rtcpreceiver.go b/pkg/rtcpreceiver/rtcpreceiver.go
index 10c5b4d2..fcde0d6d 100644
--- a/pkg/rtcpreceiver/rtcpreceiver.go
+++ b/pkg/rtcpreceiver/rtcpreceiver.go
@@ -10,10 +10,13 @@ import (
 	"github.com/pion/rtp"
 )
 
-func randUint32() uint32 {
+func randUint32() (uint32, error) {
 	var b [4]byte
-	rand.Read(b[:])
-	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
+	_, err := rand.Read(b[:])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
 }
 
 var now = time.Now
@@ -54,15 +57,18 @@ func New(
 	receiverSSRC *uint32,
 	clockRate int,
 	writePacketRTCP func(rtcp.Packet),
-) *RTCPReceiver {
+) (*RTCPReceiver, error) {
+	if receiverSSRC == nil {
+		v, err := randUint32()
+		if err != nil {
+			return nil, err
+		}
+		receiverSSRC = &v
+	}
+
 	rr := &RTCPReceiver{
-		period: period,
-		receiverSSRC: func() uint32 {
-			if receiverSSRC == nil {
-				return randUint32()
-			}
-			return *receiverSSRC
-		}(),
+		period:          period,
+		receiverSSRC:    *receiverSSRC,
 		clockRate:       float64(clockRate),
 		writePacketRTCP: writePacketRTCP,
 		terminate:       make(chan struct{}),
@@ -71,7 +77,7 @@ func New(
 
 	go rr.run()
 
-	return rr
+	return rr, nil
 }
 
 // Close closes the RTCPReceiver.
diff --git a/server_session_format.go b/server_session_format.go
index 3a3c3f80..a772d6d9 100644
--- a/server_session_format.go
+++ b/server_session_format.go
@@ -34,13 +34,17 @@ func (sf *serverSessionFormat) start() {
 	if sf.sm.ss.state != ServerSessionStatePlay {
 		if *sf.sm.ss.setuppedTransport == TransportUDP || *sf.sm.ss.setuppedTransport == TransportUDPMulticast {
 			sf.udpReorderer = rtpreorderer.New()
-			sf.udpRTCPReceiver = rtcpreceiver.New(
+			var err error
+			sf.udpRTCPReceiver, err = rtcpreceiver.New(
 				sf.sm.ss.s.udpReceiverReportPeriod,
 				nil,
 				sf.format.ClockRate(),
 				func(pkt rtcp.Packet) {
 					sf.sm.ss.WritePacketRTCP(sf.sm.media, pkt)
 				})
+			if err != nil {
+				panic(err)
+			}
 		} else {
 			sf.tcpLossDetector = rtplossdetector.New()
 		}


Test patch:
diff --git a/client_play_test.go b/client_play_test.go
index 3c3f7721..15860e43 100644
--- a/client_play_test.go
+++ b/client_play_test.go
@@ -1286,7 +1286,8 @@ func TestClientPlayAutomaticProtocol(t *testing.T) {
 				require.NoError(t, err)
 				require.Equal(t, base.Describe, req.Method)
 
-				nonce := auth.GenerateNonce()
+				nonce, err := auth.GenerateNonce()
+				require.NoError(t, err)
 
 				err = conn.WriteResponse(&base.Response{
 					StatusCode: base.StatusUnauthorized,
@@ -1399,7 +1400,8 @@ func TestClientPlayAutomaticProtocol(t *testing.T) {
 				require.NoError(t, err)
 				require.Equal(t, base.Setup, req.Method)
 
-				nonce := auth.GenerateNonce()
+				nonce, err := auth.GenerateNonce()
+				require.NoError(t, err)
 
 				err = conn.WriteResponse(&base.Response{
 					StatusCode: base.StatusUnauthorized,
diff --git a/client_test.go b/client_test.go
index 40810ff0..6e22f9be 100644
--- a/client_test.go
+++ b/client_test.go
@@ -194,7 +194,8 @@ func TestClientAuth(t *testing.T) {
 		require.NoError(t, err)
 		require.Equal(t, base.Describe, req.Method)
 
-		nonce := auth.GenerateNonce()
+		nonce, err := auth.GenerateNonce()
+		require.NoError(t, err)
 
 		err = conn.WriteResponse(&base.Response{
 			StatusCode: base.StatusUnauthorized,
diff --git a/pkg/auth/auth_test.go b/pkg/auth/auth_test.go
index a2731a88..5a19310b 100644
--- a/pkg/auth/auth_test.go
+++ b/pkg/auth/auth_test.go
@@ -47,7 +47,8 @@ func TestAuth(t *testing.T) {
 			}
 
 			t.Run(c1.name+"_"+conf, func(t *testing.T) {
-				nonce := GenerateNonce()
+				nonce, err := GenerateNonce()
+				require.NoError(t, err)
 
 				se, err := NewSender(
 					GenerateWWWAuthenticate(c1.methods, "IPCAM", nonce),
@@ -104,7 +105,8 @@ func TestAuthVLC(t *testing.T) {
 			"rtsp://myhost/mypath/test?testing/trackID=0",
 		},
 	} {
-		nonce := GenerateNonce()
+		nonce, err := GenerateNonce()
+		require.NoError(t, err)
 
 		se, err := NewSender(
 			GenerateWWWAuthenticate(nil, "IPCAM", nonce),
diff --git a/pkg/rtcpreceiver/rtcpreceiver_test.go b/pkg/rtcpreceiver/rtcpreceiver_test.go
index a06d8f8e..f80b256d 100644
--- a/pkg/rtcpreceiver/rtcpreceiver_test.go
+++ b/pkg/rtcpreceiver/rtcpreceiver_test.go
@@ -16,7 +16,7 @@ func TestRTCPReceiverBase(t *testing.T) {
 	done := make(chan struct{})
 	v := uint32(0x65f83afb)
 
-	rr := New(500*time.Millisecond, &v, 90000,
+	rr, err := New(500*time.Millisecond, &v, 90000,
 		func(pkt rtcp.Packet) {
 			require.Equal(t, &rtcp.ReceiverReport{
 				SSRC: 0x65f83afb,
@@ -31,6 +31,7 @@ func TestRTCPReceiverBase(t *testing.T) {
 			}, pkt)
 			close(done)
 		})
+	require.NoError(t, err)
 	defer rr.Close()
 
 	srPkt := rtcp.SenderReport{
@@ -81,7 +82,7 @@ func TestRTCPReceiverOverflow(t *testing.T) {
 	}
 	v := uint32(0x65f83afb)
 
-	rr := New(250*time.Millisecond, &v, 90000, func(pkt rtcp.Packet) {
+	rr, err := New(250*time.Millisecond, &v, 90000, func(pkt rtcp.Packet) {
 		require.Equal(t, &rtcp.ReceiverReport{
 			SSRC: 0x65f83afb,
 			Reports: []rtcp.ReceptionReport{
@@ -95,6 +96,7 @@ func TestRTCPReceiverOverflow(t *testing.T) {
 		}, pkt)
 		close(done)
 	})
+	require.NoError(t, err)
 	defer rr.Close()
 
 	time.Sleep(400 * time.Millisecond)
@@ -147,7 +149,7 @@ func TestRTCPReceiverPacketLost(t *testing.T) {
 	}
 	v := uint32(0x65f83afb)
 
-	rr := New(500*time.Millisecond, &v, 90000, func(pkt rtcp.Packet) {
+	rr, err := New(500*time.Millisecond, &v, 90000, func(pkt rtcp.Packet) {
 		require.Equal(t, &rtcp.ReceiverReport{
 			SSRC: 0x65f83afb,
 			Reports: []rtcp.ReceptionReport{
@@ -166,6 +168,7 @@ func TestRTCPReceiverPacketLost(t *testing.T) {
 		}, pkt)
 		close(done)
 	})
+	require.NoError(t, err)
 	defer rr.Close()
 
 	srPkt := rtcp.SenderReport{
@@ -216,7 +219,7 @@ func TestRTCPReceiverOverflowPacketLost(t *testing.T) {
 	}
 	v := uint32(0x65f83afb)
 
-	rr := New(500*time.Millisecond, &v, 90000, func(pkt rtcp.Packet) {
+	rr, err := New(500*time.Millisecond, &v, 90000, func(pkt rtcp.Packet) {
 		require.Equal(t, &rtcp.ReceiverReport{
 			SSRC: 0x65f83afb,
 			Reports: []rtcp.ReceptionReport{
@@ -235,6 +238,7 @@ func TestRTCPReceiverOverflowPacketLost(t *testing.T) {
 		}, pkt)
 		close(done)
 	})
+	require.NoError(t, err)
 	defer rr.Close()
 
 	srPkt := rtcp.SenderReport{
@@ -285,7 +289,7 @@ func TestRTCPReceiverJitter(t *testing.T) {
 	}
 	v := uint32(0x65f83afb)
 
-	rr := New(500*time.Millisecond, &v, 90000, func(pkt rtcp.Packet) {
+	rr, err := New(500*time.Millisecond, &v, 90000, func(pkt rtcp.Packet) {
 		require.Equal(t, &rtcp.ReceiverReport{
 			SSRC: 0x65f83afb,
 			Reports: []rtcp.ReceptionReport{
@@ -300,6 +304,7 @@ func TestRTCPReceiverJitter(t *testing.T) {
 		}, pkt)
 		close(done)
 	})
+	require.NoError(t, err)
 	defer rr.Close()
 
 	srPkt := rtcp.SenderReport{
diff --git a/server_test.go b/server_test.go
index f2ce23fd..c6bc3f85 100644
--- a/server_test.go
+++ b/server_test.go
@@ -1045,7 +1045,8 @@ func TestServerSessionTeardown(t *testing.T) {
 }
 
 func TestServerAuth(t *testing.T) {
-	nonce := auth.GenerateNonce()
+	nonce, err := auth.GenerateNonce()
+	require.NoError(t, err)
 
 	s := &Server{
 		Handler: &testServerHandler{
@@ -1068,7 +1069,7 @@ func TestServerAuth(t *testing.T) {
 		RTSPAddress: "localhost:8554",
 	}
 
-	err := s.Start()
+	err = s.Start()
 	require.NoError(t, err)
 	defer s.Close()