run two tunnels, which is probably wrong (leads to timeouts on local host)
This commit is contained in:
parent
dea6a2ec1b
commit
351a5190c9
267
pulseaudio-tcp
267
pulseaudio-tcp
@ -94,6 +94,70 @@ do_setup() {
|
||||
fi
|
||||
done
|
||||
|
||||
inbound=${inbound:-true}
|
||||
|
||||
while true ; do
|
||||
if "$inbound" ; then
|
||||
prompt="Y/n"
|
||||
else
|
||||
prompt="y/N"
|
||||
fi
|
||||
|
||||
read -r -p "Enable inbound audio ($prompt): " inbound_in
|
||||
|
||||
case "$inbound_in" in
|
||||
"")
|
||||
if test -n "$inbound" ; then
|
||||
inbound_in=$inbound
|
||||
break 2
|
||||
fi
|
||||
;;
|
||||
y|Y)
|
||||
inbound_in=true
|
||||
break 2
|
||||
;;
|
||||
n|N)
|
||||
inbound_in=false
|
||||
break 2
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Please type \"y\" or \"n\"." >&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
outbound=${outbound:-true}
|
||||
|
||||
while true ; do
|
||||
if "$outbound" ; then
|
||||
prompt="Y/n"
|
||||
else
|
||||
prompt="y/N"
|
||||
fi
|
||||
|
||||
read -r -p "Enable outbound audio ($prompt): " outbound_in
|
||||
|
||||
case "$outbound_in" in
|
||||
"")
|
||||
if test -n "$outbound" ; then
|
||||
outbound_in=$outbound
|
||||
break 2
|
||||
fi
|
||||
;;
|
||||
y|Y)
|
||||
outbound_in=true
|
||||
break 2
|
||||
;;
|
||||
n|N)
|
||||
outbound_in=false
|
||||
break 2
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Please type \"y\" or \"n\"." >&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
cat > "$config" << EOF
|
||||
# Configuration file for pulseaudio-tcp
|
||||
# Generated on $(LC_ALL=C date) by $USER using $0
|
||||
@ -103,40 +167,78 @@ remote_ip="$remote_ip_in"
|
||||
|
||||
# Username on remote host
|
||||
remote_user="$remote_user_in"
|
||||
|
||||
# Enable inbound audio from $remote_user @$remote_ip?
|
||||
inbound=$inbound_in
|
||||
|
||||
# Enable outbound audio to $remote_user @$remote_ip?
|
||||
outbound=$outbound_in
|
||||
EOF
|
||||
}
|
||||
|
||||
# Check if SSH port forwarding is running
|
||||
check_pa_ssh() {
|
||||
for pid in $(pidof ssh) ; do
|
||||
grep -Fq $USER-pulseaudio /proc/"$pid"/cmdline && return 0
|
||||
done
|
||||
if ! "$outbound" && ! "$inbound" ; then
|
||||
return 0
|
||||
else
|
||||
for pid in $(pidof ssh) ; do
|
||||
if grep -Fq $USER-pulseaudio /proc/"$pid"/cmdline ; then
|
||||
if "$outbound" ; then
|
||||
grep -Fq -e -L /proc/"$pid"/cmdline || {
|
||||
echo "ERROR: No SSH port forwarding to remote server for outbound audio established." >&2
|
||||
return 1 ;
|
||||
}
|
||||
fi
|
||||
|
||||
return 1
|
||||
if "$inbound" ; then
|
||||
grep -Fq -e -L /proc/"$pid"/cmdline || {
|
||||
echo "ERROR: No SSH port forwarding from remote server for inbound audio established." >&2
|
||||
return 1 ;
|
||||
}
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "ERROR: No SSH port forwarding established." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Perform status operation
|
||||
do_status() {
|
||||
rv=0
|
||||
|
||||
if ! _ssh pactl list modules | grep -Fq "Name: module-native-protocol-tcp" ; then
|
||||
echo "ERROR: PulseAudio module \"module-native-protocol-tcp\" is not loaded on remote_ip=$remote_ip." >&2
|
||||
rv=1
|
||||
fi
|
||||
|
||||
if ! check_pa_ssh ; then
|
||||
echo "ERROR: SSH port forwarding to remote_ip=$remote_ip is not running." >&2
|
||||
rv=1
|
||||
fi
|
||||
|
||||
if ! pactl list modules | grep -Fq "Name: module-tunnel-sink" ; then
|
||||
echo "ERROR: PulseAudio module \"module-tunnel-sink\" is not loaded." >&2
|
||||
rv=1
|
||||
if "$outbound" ; then
|
||||
if ! _ssh pactl list modules | grep -Fq "Name: module-native-protocol-tcp" ; then
|
||||
echo "ERROR: PulseAudio module \"module-native-protocol-tcp\" is not loaded on remote_ip=$remote_ip." >&2
|
||||
rv=1
|
||||
fi
|
||||
|
||||
if ! pactl list modules | grep -Fq "Name: module-tunnel-sink" ; then
|
||||
echo "ERROR: PulseAudio module \"module-tunnel-sink\" is not loaded." >&2
|
||||
rv=1
|
||||
fi
|
||||
|
||||
if ! pactl get-default-sink | grep -Fq "tunnel-sink.tcp:127.0.0.1" ; then
|
||||
echo "ERROR: \"tunnel-sink.tcp:127.0.0.1\" is not the default PulseAudio sink." >&2
|
||||
rv=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! pactl get-default-sink | grep -Fq "tunnel-sink.tcp:127.0.0.1" ; then
|
||||
echo "ERROR: \"tunnel-sink.tcp:127.0.0.1\" is not the default PulseAudio sink." >&2
|
||||
rv=1
|
||||
if "$inbound" ; then
|
||||
if ! pactl list modules | grep -Fq "Name: module-native-protocol-tcp" ; then
|
||||
echo "ERROR: PulseAudio module \"module-native-protocol-tcp\" is not loaded." >&2
|
||||
rv=1
|
||||
fi
|
||||
|
||||
if ! _ssh pactl list modules | grep -Fq "Name: module-tunnel-sink" ; then
|
||||
echo "ERROR: PulseAudio module \"module-tunnel-sink\" is not loaded on remote_ip=$remote_ip." >&2
|
||||
rv=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$rv" -eq 0 ; then
|
||||
@ -158,7 +260,7 @@ sync_pa_cookie() {
|
||||
}
|
||||
|
||||
# Enable PulseAudio TCP tunnel server on remote host
|
||||
enable_pa_tunnel_server() {
|
||||
enable_remote_pa_tunnel_server() {
|
||||
if _ssh pactl list modules | grep -Fq "Name: module-native-protocol-tcp" ; then
|
||||
echo "INFO: PulseAudio module \"module-native-protocol-tcp\" already loaded on remote_ip=$remote_ip." >&2
|
||||
return 0
|
||||
@ -171,13 +273,33 @@ enable_pa_tunnel_server() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Enable PulseAudio TCP tunnel server on local host
|
||||
enable_local_pa_tunnel_server() {
|
||||
if pactl list modules | grep -Fq "Name: module-native-protocol-tcp" ; then
|
||||
echo "INFO: PulseAudio module \"module-native-protocol-tcp\" already loaded." >&2
|
||||
return 0
|
||||
elif pactl load-module module-native-protocol-tcp listen=127.0.0.1 auth-ip-acl=127.0.0.1 ; then
|
||||
echo "INFO: Loaded PulseAudio module \"module-native-protocol-tcp\"." >&2
|
||||
return 0
|
||||
else
|
||||
echo "ERROR: Unable to load PulseAudio module \"module-native-protocol-tcp\"." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Establish SSH port forwarding to PulseAudio TCP server on remote host
|
||||
establish_ssh_portforward() {
|
||||
_ssh -fNT -L 127.0.0.1:4713:127.0.0.1:4713
|
||||
if "$outbound" && ! "$inbound" ; then
|
||||
_ssh -fNT -L 127.0.0.1:4713:127.0.0.1:4713
|
||||
elif "$inbound" && ! "$outbound" ; then
|
||||
_ssh -fNT -R 127.0.0.1:4713:127.0.0.1:4713
|
||||
elif "$outbound" && "$inbound" ; then
|
||||
_ssh -fNT -L 127.0.0.1:4713:127.0.0.1:4713 -R 127.0.0.1:4713:127.0.0.1:4713
|
||||
fi
|
||||
}
|
||||
|
||||
# Enable tunnel sink on local host
|
||||
enable_pa_tunnel_sink() {
|
||||
enable_local_pa_tunnel_sink() {
|
||||
if pactl list modules | grep -Fq "Name: module-tunnel-sink" ; then
|
||||
echo "INFO: PulseAudio module \"module-tunnel-sink\" already loaded." >&2
|
||||
return 0
|
||||
@ -190,8 +312,22 @@ enable_pa_tunnel_sink() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Enable tunnel sink on remote host
|
||||
enable_remote_pa_tunnel_sink() {
|
||||
if _ssh pactl list modules | grep -Fq "Name: module-tunnel-sink" ; then
|
||||
echo "INFO: PulseAudio module \"module-tunnel-sink\" already loaded on remote_ip=$remote_ip." >&2
|
||||
return 0
|
||||
elif _ssh pactl load-module module-tunnel-sink server=tcp:127.0.0.1 ; then
|
||||
echo "INFO: Loaded PulseAudio module \"module-tunnel-sink\" on remote_ip=$remote_ip." >&2
|
||||
return 0
|
||||
else
|
||||
echo "ERROR: Unable to load PulseAudio module \"module-tunnel-sink\" on remote_ip=$remote_ip." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Set tunnel sink as default sink on local host
|
||||
set_pa_tunnel_sink_as_default() {
|
||||
set_local_pa_tunnel_sink_as_default() {
|
||||
if pactl set-default-sink tunnel-sink.tcp:127.0.0.1 ; then
|
||||
echo "INFO: Set \"tunnel-sink.tcp:127.0.0.1\" as default PulseAudio sink." >&2
|
||||
return 0
|
||||
@ -204,16 +340,48 @@ set_pa_tunnel_sink_as_default() {
|
||||
# Perform start operation
|
||||
do_start() {
|
||||
sync_pa_cookie || return 1
|
||||
enable_pa_tunnel_server || return 1
|
||||
establish_ssh_portforward || return 1
|
||||
enable_pa_tunnel_sink || return 1
|
||||
set_pa_tunnel_sink_as_default || return 1
|
||||
|
||||
if "$outbound" ; then
|
||||
enable_remote_pa_tunnel_server || return 1
|
||||
enable_local_pa_tunnel_sink || return 1
|
||||
set_local_pa_tunnel_sink_as_default || return 1
|
||||
fi
|
||||
|
||||
if "$inbound" ; then
|
||||
enable_local_pa_tunnel_server || return 1
|
||||
enable_remote_pa_tunnel_sink || return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Remove PulseAudio TCP tunnel sink on remote host
|
||||
remove_remote_pa_tunnel_sink() {
|
||||
if ! _ssh pactl list modules | grep -Fq "Name: module-tunnel-sink" ; then
|
||||
echo "INFO: PulseAudio module \"module-tunnel-sink\" is not loaded on remote_ip=$remote_ip." >&2
|
||||
return 0
|
||||
elif ! _ssh pactl list sinks | grep -Fq "tunnel-sink.tcp:127.0.0.1" ; then
|
||||
echo "INFO: No PulseAudio tunnel sink to 127.0.0.1 exists on remote_ip=$remote_ip." >&2
|
||||
return 0
|
||||
else
|
||||
owner_module=$(
|
||||
_ssh pactl --format json list sinks 2>/dev/null | \
|
||||
jq '.[] | select(.name=="tunnel-sink.tcp:127.0.0.1") | .owner_module' -r
|
||||
)
|
||||
|
||||
if ! _ssh pactl unload-module "$owner_module" ; then
|
||||
echo "ERROR: Could not unload owner module $owner_module of PulseAudio sink \"tunnel-sink.tcp:127.0.0.1\" on remote_ip=$remote_ip." >&2
|
||||
return 1
|
||||
else
|
||||
echo "INFO: Unloaded owner module $owner_module of PulseAudio sink \"tunnel-sink.tcp:127.0.0.1\" on remote_ip=$remote_ip." >&2
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Remove PulseAudio TCP tunnel sink on local host
|
||||
remove_pa_tunnel_sink() {
|
||||
remove_local_pa_tunnel_sink() {
|
||||
if ! pactl list modules | grep -Fq "Name: module-tunnel-sink" ; then
|
||||
echo "INFO: PulseAudio module \"module-tunnel-sink\" is not loaded." >&2
|
||||
return 0
|
||||
@ -236,17 +404,22 @@ remove_pa_tunnel_sink() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Terminate SSH portforwarding session
|
||||
terminate_ssh_portforward() {
|
||||
for pid in $(pidof ssh) ; do
|
||||
if grep -Fq $USER-pulseaudio /proc/"$pid"/cmdline ; then
|
||||
kill -TERM "$pid"
|
||||
fi
|
||||
done
|
||||
# Stop PulseAudio TCP tunnel server on local host.
|
||||
disable_local_pa_tunnel_server() {
|
||||
if ! pactl list modules | grep -Fq "Name: module-native-protocol-tcp" ; then
|
||||
echo "INFO: PulseAudio module \"module-native-protocol-tcp\" not loaded." >&2
|
||||
return 0
|
||||
elif ! pactl unload-module module-native-protocol-tcp ; then
|
||||
echo "ERROR: Could not unload PulseAudio module \"module-native-protocol-tcp\"." >&2
|
||||
return 1
|
||||
else
|
||||
echo "INFO: Unloaded PulseAudio module \"module-native-protocol-tcp\"." >&2
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Stop PulseAudio TCP tunnel server on remote host.
|
||||
disable_pa_tunnel_server() {
|
||||
disable_remote_pa_tunnel_server() {
|
||||
if ! _ssh pactl list modules | grep -Fq "Name: module-native-protocol-tcp" ; then
|
||||
echo "INFO: PulseAudio module \"module-native-protocol-tcp\" not loaded on remote_ip=$remote_ip." >&2
|
||||
return 0
|
||||
@ -259,11 +432,28 @@ disable_pa_tunnel_server() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Terminate SSH portforwarding session
|
||||
terminate_ssh_portforward() {
|
||||
for pid in $(pidof ssh) ; do
|
||||
if grep -Fq $USER-pulseaudio /proc/"$pid"/cmdline ; then
|
||||
kill -TERM "$pid"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Perform stop operation
|
||||
do_stop() {
|
||||
remove_pa_tunnel_sink || return 1
|
||||
if "$outbound" ; then
|
||||
remove_local_pa_tunnel_sink || return 1
|
||||
disable_remote_pa_tunnel_server || return 1
|
||||
fi
|
||||
|
||||
if "$inbound" ; then
|
||||
remove_remote_pa_tunnel_sink || return 1
|
||||
disable_local_pa_tunnel_server || return 1
|
||||
fi
|
||||
|
||||
terminate_ssh_portforward || return 1
|
||||
disable_pa_tunnel_server || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
@ -316,7 +506,7 @@ else
|
||||
""|-h|--help)
|
||||
cat << EOF
|
||||
Setup and run encrypted connection to remote PulseAudio/Pipewire server
|
||||
Usage: $0 setup|start|stop|status
|
||||
Usage: $0 restart|setup|start|status|stop
|
||||
EOF
|
||||
rv=0
|
||||
;;
|
||||
@ -332,12 +522,17 @@ EOF
|
||||
do_stop
|
||||
rv=$?
|
||||
;;
|
||||
restart)
|
||||
do_stop
|
||||
do_start
|
||||
rv=$?
|
||||
;;
|
||||
status)
|
||||
do_status
|
||||
rv=$?
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Usage: $0 setup|start|stop|status" >&2
|
||||
echo "ERROR: Usage: $0 restart|setup|start|status|stop" >&2
|
||||
rv=1
|
||||
;;
|
||||
esac
|
||||
|
Loading…
Reference in New Issue
Block a user