Add options to configure tunnel host and port

In "adb forward" mode, by default, scrcpy connects to localhost:PORT,
where PORT is the local port passed to "adb forward". This assumes that
the tunnel is established on the local host with a local adb server
(which is the common case).

For advanced usage, add --tunnel-host and --tunnel-port to force the
connection to a different destination.

Fixes #2801 <https://github.com/Genymobile/scrcpy/issues/2801>
PR #2807 <https://github.com/Genymobile/scrcpy/pull/2807>

Signed-off-by: Romain Vimont <rom@rom1v.com>
This commit is contained in:
RipleyTom 2021-11-18 01:02:53 +01:00 committed by Romain Vimont
parent 52e5181c84
commit 7bdbde7363
8 changed files with 88 additions and 8 deletions

View file

@ -207,6 +207,7 @@ if get_option('buildtype') == 'debug'
'tests/test_cli.c', 'tests/test_cli.c',
'src/cli.c', 'src/cli.c',
'src/options.c', 'src/options.c',
'src/util/net.c',
'src/util/str.c', 'src/util/str.c',
'src/util/strbuf.c', 'src/util/strbuf.c',
'src/util/term.c', 'src/util/term.c',

View file

@ -203,6 +203,18 @@ Enable "show touches" on start, restore the initial value on exit.
It only shows physical touches (not clicks from scrcpy). It only shows physical touches (not clicks from scrcpy).
.TP
.BI "\-\-tunnel\-host " ip
Set the IP address of the adb tunnel to reach the scrcpy server. This option automatically enables --force-adb-forward.
Default is localhost.
.TP
.BI "\-\-tunnel\-port " port
Set the TCP port of the adb tunnel to reach the scrcpy server. This option automatically enables --force-adb-forward.
Default is 0 (not forced): the local port used for establishing the tunnel will be used.
.TP .TP
.BI "\-\-v4l2-sink " /dev/videoN .BI "\-\-v4l2-sink " /dev/videoN
Output to v4l2loopback device. Output to v4l2loopback device.

View file

@ -9,6 +9,7 @@
#include "options.h" #include "options.h"
#include "util/log.h" #include "util/log.h"
#include "util/net.h"
#include "util/str.h" #include "util/str.h"
#include "util/strbuf.h" #include "util/strbuf.h"
#include "util/term.h" #include "util/term.h"
@ -46,6 +47,8 @@
#define OPT_V4L2_SINK 1027 #define OPT_V4L2_SINK 1027
#define OPT_DISPLAY_BUFFER 1028 #define OPT_DISPLAY_BUFFER 1028
#define OPT_V4L2_BUFFER 1029 #define OPT_V4L2_BUFFER 1029
#define OPT_TUNNEL_HOST 1030
#define OPT_TUNNEL_PORT 1031
struct sc_option { struct sc_option {
char shortopt; char shortopt;
@ -330,6 +333,25 @@ static const struct sc_option options[] = {
"on exit.\n" "on exit.\n"
"It only shows physical touches (not clicks from scrcpy).", "It only shows physical touches (not clicks from scrcpy).",
}, },
{
.longopt_id = OPT_TUNNEL_HOST,
.longopt = "tunnel-host",
.argdesc = "ip",
.text = "Set the IP address of the adb tunnel to reach the scrcpy "
"server. This option automatically enables "
"--force-adb-forward.\n"
"Default is localhost.",
},
{
.longopt_id = OPT_TUNNEL_PORT,
.longopt = "tunnel-port",
.argdesc = "port",
.text = "Set the TCP port of the adb tunnel to reach the scrcpy "
"server. This option automatically enables "
"--force-adb-forward.\n"
"Default is 0 (not forced): the local port used for "
"establishing the tunnel will be used.",
},
#ifdef HAVE_V4L2 #ifdef HAVE_V4L2
{ {
.longopt_id = OPT_V4L2_SINK, .longopt_id = OPT_V4L2_SINK,
@ -1127,6 +1149,21 @@ parse_record_format(const char *optarg, enum sc_record_format *format) {
return false; return false;
} }
static bool
parse_ip(const char *optarg, uint32_t *ipv4) {
return net_parse_ipv4(optarg, ipv4);
}
static bool
parse_port(const char *optarg, uint16_t *port) {
long value;
if (!parse_integer_arg(optarg, &value, false, 0, 0xFFFF, "port")) {
return false;
}
*port = (uint16_t) value;
return true;
}
static enum sc_record_format static enum sc_record_format
guess_record_format(const char *filename) { guess_record_format(const char *filename) {
size_t len = strlen(filename); size_t len = strlen(filename);
@ -1199,6 +1236,16 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
return false; return false;
} }
break; break;
case OPT_TUNNEL_HOST:
if (!parse_ip(optarg, &opts->tunnel_host)) {
return false;
}
break;
case OPT_TUNNEL_PORT:
if (!parse_port(optarg, &opts->tunnel_port)) {
return false;
}
break;
case 'n': case 'n':
opts->control = false; opts->control = false;
break; break;

View file

@ -19,6 +19,8 @@ const struct scrcpy_options scrcpy_options_default = {
.first = DEFAULT_LOCAL_PORT_RANGE_FIRST, .first = DEFAULT_LOCAL_PORT_RANGE_FIRST,
.last = DEFAULT_LOCAL_PORT_RANGE_LAST, .last = DEFAULT_LOCAL_PORT_RANGE_LAST,
}, },
.tunnel_host = 0,
.tunnel_port = 0,
.shortcut_mods = { .shortcut_mods = {
.data = {SC_MOD_LALT, SC_MOD_LSUPER}, .data = {SC_MOD_LALT, SC_MOD_LSUPER},
.count = 2, .count = 2,

View file

@ -77,6 +77,8 @@ struct scrcpy_options {
enum sc_record_format record_format; enum sc_record_format record_format;
enum sc_keyboard_input_mode keyboard_input_mode; enum sc_keyboard_input_mode keyboard_input_mode;
struct sc_port_range port_range; struct sc_port_range port_range;
uint32_t tunnel_host;
uint16_t tunnel_port;
struct sc_shortcut_mods shortcut_mods; struct sc_shortcut_mods shortcut_mods;
uint16_t max_size; uint16_t max_size;
uint32_t bit_rate; uint32_t bit_rate;

View file

@ -345,6 +345,8 @@ scrcpy(struct scrcpy_options *options) {
.log_level = options->log_level, .log_level = options->log_level,
.crop = options->crop, .crop = options->crop,
.port_range = options->port_range, .port_range = options->port_range,
.tunnel_host = options->tunnel_host,
.tunnel_port = options->tunnel_port,
.max_size = options->max_size, .max_size = options->max_size,
.bit_rate = options->bit_rate, .bit_rate = options->bit_rate,
.max_fps = options->max_fps, .max_fps = options->max_fps,

View file

@ -202,8 +202,9 @@ execute_server(struct sc_server *server,
} }
static bool static bool
connect_and_read_byte(struct sc_intr *intr, sc_socket socket, uint16_t port) { connect_and_read_byte(struct sc_intr *intr, sc_socket socket,
bool ok = net_connect_intr(intr, socket, IPV4_LOCALHOST, port); uint32_t tunnel_host, uint16_t tunnel_port) {
bool ok = net_connect_intr(intr, socket, tunnel_host, tunnel_port);
if (!ok) { if (!ok) {
return false; return false;
} }
@ -220,13 +221,13 @@ connect_and_read_byte(struct sc_intr *intr, sc_socket socket, uint16_t port) {
} }
static sc_socket static sc_socket
connect_to_server(struct sc_server *server, uint32_t attempts, sc_tick delay) { connect_to_server(struct sc_server *server, uint32_t attempts, sc_tick delay,
uint16_t port = server->tunnel.local_port; uint32_t host, uint16_t port) {
do { do {
LOGD("Remaining connection attempts: %d", (int) attempts); LOGD("Remaining connection attempts: %d", (int) attempts);
sc_socket socket = net_socket(); sc_socket socket = net_socket();
if (socket != SC_SOCKET_NONE) { if (socket != SC_SOCKET_NONE) {
bool ok = connect_and_read_byte(&server->intr, socket, port); bool ok = connect_and_read_byte(&server->intr, socket, host, port);
if (ok) { if (ok) {
// it worked! // it worked!
return socket; return socket;
@ -352,9 +353,20 @@ sc_server_connect_to(struct sc_server *server, struct sc_server_info *info) {
goto fail; goto fail;
} }
} else { } else {
uint32_t tunnel_host = server->params.tunnel_host;
if (!tunnel_host) {
tunnel_host = IPV4_LOCALHOST;
}
uint16_t tunnel_port = server->params.tunnel_port;
if (!tunnel_port) {
tunnel_port = tunnel->local_port;
}
uint32_t attempts = 100; uint32_t attempts = 100;
sc_tick delay = SC_TICK_FROM_MS(100); sc_tick delay = SC_TICK_FROM_MS(100);
video_socket = connect_to_server(server, attempts, delay); video_socket = connect_to_server(server, attempts, delay, tunnel_host,
tunnel_port);
if (video_socket == SC_SOCKET_NONE) { if (video_socket == SC_SOCKET_NONE) {
goto fail; goto fail;
} }
@ -364,8 +376,8 @@ sc_server_connect_to(struct sc_server *server, struct sc_server_info *info) {
if (control_socket == SC_SOCKET_NONE) { if (control_socket == SC_SOCKET_NONE) {
goto fail; goto fail;
} }
bool ok = net_connect_intr(&server->intr, control_socket, bool ok = net_connect_intr(&server->intr, control_socket, tunnel_host,
IPV4_LOCALHOST, tunnel->local_port); tunnel_port);
if (!ok) { if (!ok) {
goto fail; goto fail;
} }

View file

@ -29,6 +29,8 @@ struct sc_server_params {
const char *codec_options; const char *codec_options;
const char *encoder_name; const char *encoder_name;
struct sc_port_range port_range; struct sc_port_range port_range;
uint32_t tunnel_host;
uint16_t tunnel_port;
uint16_t max_size; uint16_t max_size;
uint32_t bit_rate; uint32_t bit_rate;
uint16_t max_fps; uint16_t max_fps;