Skip to content

Commit 29928cc

Browse files
committed
PbReader fix: audio packets from anonymous users results in panic (#37)
For each user an Audio Codec is created on the fly with the first received packet. The Protobuf Message contains a UserID field which should be set by the client. The UserID is used to ensure that the audio frames are correcty decoded and that simultaneously received packets from multiple users are not mixed. In case a packet with an empty UserID is received, the userID will be set to 'unknown-client' and a warning is logged.
1 parent 5093f0b commit 29928cc

File tree

7 files changed

+85
-54
lines changed

7 files changed

+85
-54
lines changed

.github/workflows/build.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ jobs:
5454
OS: darwin
5555
ARCH: arm64
5656
steps:
57-
- name: Set up Go 1.17
57+
- name: Set up Go 1.18
5858
uses: actions/setup-go@v1
5959
id: go
6060
with:
61-
go-version: 1.17
61+
go-version: 1.18
6262
- uses: actions/checkout@v1
6363
with:
6464
submodules: true

audio/sinks/pbWriter/pbWriter.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/dh1tw/gosamplerate"
1010
"github.com/dh1tw/remoteAudio/audio"
1111
"github.com/dh1tw/remoteAudio/audiocodec/opus"
12+
"github.com/dh1tw/remoteAudio/utils"
1213
"github.com/golang/protobuf/proto"
1314

1415
sbAudio "github.com/dh1tw/remoteAudio/sb_audio"
@@ -45,7 +46,7 @@ func NewPbWriter(opts ...Option) (*PbWriter, error) {
4546
DeviceName: "ProtoBufWriter",
4647
Channels: 1,
4748
FramesPerBuffer: 960,
48-
UserID: "myCallsign",
49+
UserID: fmt.Sprintf("user-%s", utils.RandStringRunes(5)),
4950
},
5051
buffer: make([]byte, 10000),
5152
volume: 0.7,

audio/sources/pbReader/pbReader.go

+19-6
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ import (
1717
// received from the network.
1818
type PbReader struct {
1919
sync.RWMutex
20-
enabled bool
21-
name string
22-
decoders map[string]audiocodec.Decoder
23-
decoder audiocodec.Decoder
24-
callback audio.OnDataCb
25-
lastUser string
20+
enabled bool
21+
name string
22+
decoders map[string]audiocodec.Decoder
23+
decoder audiocodec.Decoder
24+
callback audio.OnDataCb
25+
lastUser string
26+
emptyUserIDWarning sync.Once
2627
}
2728

2829
// NewPbReader is the constructor for a PbReader object.
@@ -104,6 +105,14 @@ func (pbr *PbReader) Enqueue(data []byte) error {
104105
return nil
105106
}
106107

108+
if len(msg.GetUserId()) == 0 {
109+
msg.UserId = "unknown-client"
110+
pbr.emptyUserIDWarning.Do(func() {
111+
log.Println("incoming audio frames from unknown user; consider setting the username on the client")
112+
log.Println("simultaneous audio frames from multiple anonymous users will result in distorted audio")
113+
})
114+
}
115+
107116
codecName := msg.GetCodec().String()
108117

109118
switch codecName {
@@ -141,6 +150,10 @@ func (pbr *PbReader) Enqueue(data []byte) error {
141150
pbr.lastUser = txUser
142151
}
143152

153+
if pbr.decoder == nil {
154+
return fmt.Errorf("no decoder set for audio frames from user: '%s'", txUser)
155+
}
156+
144157
num, err := pbr.decoder.Decode(msg.Data, buf)
145158
if err != nil {
146159
// in case the txUser has switched from stereo to mono

cmd/client_nats.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/dh1tw/remoteAudio/audiocodec/opus"
2626
"github.com/dh1tw/remoteAudio/proxy"
2727
"github.com/dh1tw/remoteAudio/trx"
28+
"github.com/dh1tw/remoteAudio/utils"
2829
"github.com/dh1tw/remoteAudio/webserver"
2930
"github.com/gordonklaus/portaudio"
3031
"github.com/nats-io/nats.go"
@@ -253,11 +254,17 @@ func natsAudioClient(cmd *cobra.Command, args []string) {
253254
exit(err)
254255
}
255256

257+
userName := natsUsername
258+
if len(userName) == 0 {
259+
userName = fmt.Sprintf("client-%s", utils.RandStringRunes(5))
260+
log.Printf("username not set; auto generated unique username '%s'\n", userName)
261+
}
262+
256263
toNetwork, err := pbWriter.NewPbWriter(
257264
pbWriter.Encoder(opusEncoder),
258265
pbWriter.Channels(iChannels),
259266
pbWriter.FramesPerBuffer(audioFramesPerBuffer),
260-
pbWriter.UserID(natsUsername),
267+
pbWriter.UserID(userName),
261268
)
262269
if err != nil {
263270
exit(err)

cmd/server_nats.go

+1
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ func natsAudioServer(cmd *cobra.Command, args []string) {
269269
pbWriter.Channels(iChannels),
270270
pbWriter.FramesPerBuffer(audioFramesPerBuffer),
271271
pbWriter.ToWireCb(ns.toWireCb),
272+
pbWriter.UserID(serverName),
272273
)
273274
if err != nil {
274275
exit(err)

go.mod

+10-6
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@ require (
1414
github.com/go-audio/audio v1.0.0
1515
github.com/go-audio/wav v1.0.0
1616
github.com/golang/protobuf v1.5.2
17-
github.com/gordonklaus/portaudio v0.0.0-20200911161147-bb74aa485641
17+
github.com/gordonklaus/portaudio v0.0.0-20220320131553-cc649ad523c1
1818
github.com/gorilla/mux v1.8.0
19-
github.com/gorilla/websocket v1.4.2
19+
github.com/gorilla/websocket v1.5.0
20+
github.com/magiconair/properties v1.8.6 // indirect
2021
github.com/nats-io/nats.go v1.13.0
21-
github.com/spf13/cobra v1.2.1
22-
github.com/spf13/viper v1.10.0
23-
google.golang.org/protobuf v1.27.1
24-
gopkg.in/hraban/opus.v2 v2.0.0-20211030232353-1a9beeaf0764
22+
github.com/spf13/afero v1.8.2 // indirect
23+
github.com/spf13/cobra v1.4.0
24+
github.com/spf13/viper v1.10.1
25+
golang.org/x/sys v0.0.0-20220403205710-6acee93ad0eb // indirect
26+
google.golang.org/protobuf v1.28.0
27+
gopkg.in/hraban/opus.v2 v2.0.0-20220302220929-eeacdbcb92d0
28+
gopkg.in/ini.v1 v1.66.4 // indirect
2529
)

0 commit comments

Comments
 (0)