Add -tcp flag to disable UDP and force audio through TCP tunnel
Adds Config.DisableUDP field. When set: - DialWithDialer skips startUDP() entirely (no UDP socket, no UDP reader) - WriteAudio skips WriteAudioUDP and goes straight to TCP-tunneled audio Useful for debugging crypto/transport issues — rules out UDP-specific problems like NAT, firewall, or OCB2 counter mismatches.
This commit is contained in:
committed by
Brandon McGinty
parent
8967fdff1a
commit
819ed6931d
+18
-10
@@ -142,10 +142,14 @@ func DialWithDialer(dialer *net.Dialer, config *Config, tlsConfig *tls.Config) (
|
|||||||
|
|
||||||
// Start UDP transport immediately so it's ready when CryptSetup
|
// Start UDP transport immediately so it's ready when CryptSetup
|
||||||
// arrives during the sync handshake.
|
// arrives during the sync handshake.
|
||||||
if err := client.startUDP(); err != nil {
|
if !client.Config.DisableUDP {
|
||||||
log.Warn("UDP setup failed, audio will use TCP tunnel: %v", err)
|
if err := client.startUDP(); err != nil {
|
||||||
} else if client.udpConn != nil {
|
log.Warn("UDP setup failed, audio will use TCP tunnel: %v", err)
|
||||||
log.Info("UDP socket opened to %s, waiting for CryptSetup", client.udpConn.RemoteAddr())
|
} else if client.udpConn != nil {
|
||||||
|
log.Info("UDP socket opened to %s, waiting for CryptSetup", client.udpConn.RemoteAddr())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Info("UDP disabled by config, audio will use TCP tunnel")
|
||||||
}
|
}
|
||||||
|
|
||||||
go client.pingRoutine()
|
go client.pingRoutine()
|
||||||
@@ -330,17 +334,21 @@ func (c *Client) EnableStereoEncoder() {
|
|||||||
var udpFallbackLogged bool
|
var udpFallbackLogged bool
|
||||||
|
|
||||||
func (c *Client) WriteAudio(format, target byte, sequence int64, final bool, data []byte, X, Y, Z *float32) error {
|
func (c *Client) WriteAudio(format, target byte, sequence int64, final bool, data []byte, X, Y, Z *float32) error {
|
||||||
// Try UDP first
|
// Try UDP first (unless disabled)
|
||||||
if sent, err := c.WriteAudioUDP(format, target, sequence, final, data, X, Y, Z); sent {
|
if !c.Config.DisableUDP {
|
||||||
if err != nil {
|
if sent, err := c.WriteAudioUDP(format, target, sequence, final, data, X, Y, Z); sent {
|
||||||
log.Error("UDP send error: %v", err)
|
if err != nil {
|
||||||
|
log.Error("UDP send error: %v", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// Fall back to TCP tunnel — log once per process
|
// Fall back to TCP tunnel — log once per process
|
||||||
if !udpFallbackLogged {
|
if !udpFallbackLogged {
|
||||||
udpFallbackLogged = true
|
udpFallbackLogged = true
|
||||||
if c.udpConn == nil {
|
if c.Config.DisableUDP {
|
||||||
|
log.Info("UDP disabled, audio using TCP tunnel")
|
||||||
|
} else if c.udpConn == nil {
|
||||||
log.Info("no UDP socket, audio using TCP tunnel")
|
log.Info("no UDP socket, audio using TCP tunnel")
|
||||||
} else if !c.cryptOut.initialized {
|
} else if !c.cryptOut.initialized {
|
||||||
log.Info("waiting for CryptSetup, audio using TCP tunnel")
|
log.Info("waiting for CryptSetup, audio using TCP tunnel")
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ type Config struct {
|
|||||||
// AudioDataBytes is the number of bytes that an audio frame can use.
|
// AudioDataBytes is the number of bytes that an audio frame can use.
|
||||||
AudioDataBytes int
|
AudioDataBytes int
|
||||||
|
|
||||||
|
// DisableUDP forces all audio to use the TCP tunnel instead of UDP.
|
||||||
|
DisableUDP bool
|
||||||
|
|
||||||
// The event listeners used when client events are triggered.
|
// The event listeners used when client events are triggered.
|
||||||
Listeners Listeners
|
Listeners Listeners
|
||||||
AudioListeners AudioListeners
|
AudioListeners AudioListeners
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ func main() {
|
|||||||
autoTransmit := flag.Bool("auto-transmit", false, "start transmitting immediately on connect")
|
autoTransmit := flag.Bool("auto-transmit", false, "start transmitting immediately on connect")
|
||||||
toneTest := flag.Bool("tone-test", false, "send a 440 Hz test tone instead of microphone (bypasses soundcard)")
|
toneTest := flag.Bool("tone-test", false, "send a 440 Hz test tone instead of microphone (bypasses soundcard)")
|
||||||
toneTestOutput := flag.String("tone-out", "incoming.pcm", "file to save incoming audio to in tone-test mode")
|
toneTestOutput := flag.String("tone-out", "incoming.pcm", "file to save incoming audio to in tone-test mode")
|
||||||
|
tcpOnly := flag.Bool("tcp", false, "disable UDP, force audio through TCP tunnel")
|
||||||
logLevel := flag.String("log", "warn", "log level: debug, info, warn, error")
|
logLevel := flag.String("log", "warn", "log level: debug, info, warn, error")
|
||||||
logFile := flag.String("logfile", "", "write logs to this file (in addition to stderr)")
|
logFile := flag.String("logfile", "", "write logs to this file (in addition to stderr)")
|
||||||
|
|
||||||
@@ -218,6 +219,7 @@ func main() {
|
|||||||
NoiseSuppressor: noise.NewSuppressor(),
|
NoiseSuppressor: noise.NewSuppressor(),
|
||||||
}
|
}
|
||||||
b.Config.Buffers = *buffers
|
b.Config.Buffers = *buffers
|
||||||
|
b.Config.DisableUDP = *tcpOnly
|
||||||
|
|
||||||
b.Hotkeys = b.UserConfig.GetHotkeys()
|
b.Hotkeys = b.UserConfig.GetHotkeys()
|
||||||
b.UserConfig.SaveConfig()
|
b.UserConfig.SaveConfig()
|
||||||
|
|||||||
Reference in New Issue
Block a user