summaryrefslogtreecommitdiffstats
path: root/x11vnc/misc
diff options
context:
space:
mode:
authorrunge <[email protected]>2010-04-18 19:37:37 -0400
committerrunge <[email protected]>2010-04-18 19:37:37 -0400
commitb74c8f4241ec8c3d972ee97d0ce9a399ddd09ce1 (patch)
treec8c8aaec90fd51a10790795030777b2dda548fe7 /x11vnc/misc
parent2a8ba97ec5b0f7fbfcfc8adab6732a95e95c7204 (diff)
downloadlibtdevnc-b74c8f4241ec8c3d972ee97d0ce9a399ddd09ce1.tar.gz
libtdevnc-b74c8f4241ec8c3d972ee97d0ce9a399ddd09ce1.zip
Improvements to demo scripts. Alias -coe for -connect_or_exit. Fix HAVE_V4L2. Warn no Xvfb, Xdummy, or Xvnc. Xinerama screens.
Diffstat (limited to 'x11vnc/misc')
-rwxr-xr-xx11vnc/misc/connect_switch62
-rwxr-xr-xx11vnc/misc/desktop.cgi92
-rwxr-xr-xx11vnc/misc/ultravnc_repeater.pl192
3 files changed, 290 insertions, 56 deletions
diff --git a/x11vnc/misc/connect_switch b/x11vnc/misc/connect_switch
index a25610d..08376c6 100755
--- a/x11vnc/misc/connect_switch
+++ b/x11vnc/misc/connect_switch
@@ -231,7 +231,11 @@ if (exists $ENV{CONNECT_SWITCH_LISTEN}) {
#
# E.g. CONNECT_SWITCH_LISTEN=192.168.0.32:443
#
- ($listen_host, $listen_port) = split(/:/, $ENV{CONNECT_SWITCH_LISTEN});
+ $listen_host = '';
+ $listen_port = '';
+ if ($ENV{CONNECT_SWITCH_LISTEN} =~ /^(.*):(\d+)$/) {
+ ($listen_host, $listen_port) = ($1, $2);
+ }
}
my $httpd_host = 'localhost';
@@ -241,7 +245,11 @@ if (exists $ENV{CONNECT_SWITCH_HTTPD}) {
#
# E.g. CONNECT_SWITCH_HTTPD=127.0.0.1:443
#
- ($httpd_host, $httpd_port) = split(/:/, $ENV{CONNECT_SWITCH_HTTPD});
+ $httpd_host = '';
+ $httpd_port = '';
+ if ($ENV{CONNECT_SWITCH_HTTPD} =~ /^(.*):(\d+)$/) {
+ ($httpd_host, $httpd_port) = ($1, $2);
+ }
}
my $bufsize = 8192;
@@ -353,6 +361,12 @@ use IO::Socket::INET;
use strict;
use warnings;
+# Test for INET6 support:
+#
+my $have_inet6 = 0;
+eval "use IO::Socket::INET6;";
+$have_inet6 = 1 if $@ eq "";
+
my $killpid = 1;
setpgrp(0, 0);
@@ -360,14 +374,13 @@ setpgrp(0, 0);
if (exists $ENV{CONNECT_SWITCH_LISTEN_IPV6}) {
# note we leave out LocalAddr.
my $cmd = '
- use IO::Socket::INET6;
- $listen_sock = IO::Socket::INET6->new(
- Listen => 10,
- LocalPort => $listen_port,
- ReuseAddr => 1,
- Domain => AF_INET6,
- Proto => "tcp"
- );
+ $listen_sock = IO::Socket::INET6->new(
+ Listen => 10,
+ LocalPort => $listen_port,
+ ReuseAddr => 1,
+ Domain => AF_INET6,
+ Proto => "tcp"
+ );
';
eval $cmd;
die "$@\n" if $@;
@@ -493,8 +506,12 @@ sub handle_conn {
if ($str =~ /^CONNECT\s+(\S+)\s+HTTP\/(\S+)/) {
$hostport = $1;
$http_vers = $2;
+ my $h = '';
+ my $p = '';
- my ($h, $p) = split(/:/, $hostport);
+ if ($hostport =~ /^(.*):(\d+)$/) {
+ ($h, $p) = ($1, $2);
+ }
if ($p =~ /^\d+$/) {
# check allowed host list:
foreach my $hp (@allow) {
@@ -532,7 +549,12 @@ sub handle_conn {
exit 0;
}
- my ($host, $port) = split(/:/, $hostport);
+ my $host = '';
+ my $port = '';
+
+ if ($hostport =~ /^(.*):(\d+)$/) {
+ ($host, $port) = ($1, $2);
+ }
print STDERR "connecting to: $host:$port\n" if $verbose;
@@ -541,6 +563,15 @@ sub handle_conn {
PeerPort => $port,
Proto => "tcp"
);
+ print STDERR "connect to host='$host' port='$port' failed: $!\n" if !$sock;
+ if (! $sock && $have_inet6) {
+ eval {$sock = IO::Socket::INET6->new(
+ PeerAddr => $host,
+ PeerPort => $port,
+ Proto => "tcp"
+ );};
+ print STDERR "connect to host='$host' port='$port' failed: $! (ipv6)\n" if !$sock;
+ }
my $msg;
# send the connect proxy reply:
@@ -561,6 +592,13 @@ sub handle_conn {
PeerPort => $httpd_port,
Proto => "tcp"
);
+ if (! $sock && $have_inet6) {
+ eval {$sock = IO::Socket::INET6->new(
+ PeerAddr => $httpd_host,
+ PeerPort => $httpd_port,
+ Proto => "tcp"
+ );};
+ }
}
if (! $sock) {
diff --git a/x11vnc/misc/desktop.cgi b/x11vnc/misc/desktop.cgi
index f656146..d99a39c 100755
--- a/x11vnc/misc/desktop.cgi
+++ b/x11vnc/misc/desktop.cgi
@@ -218,6 +218,11 @@
use strict;
use IO::Socket::INET;
+# Test for INET6 support:
+#
+my $have_inet6 = 0;
+eval "use IO::Socket::INET6;";
+$have_inet6 = 1 if $@ eq "";
##########################################################################
# Path to the x11vnc program:
@@ -261,6 +266,10 @@ my $find_free_port = 0;
#
my $starting_port = 7000;
+# Listen on AF_INET6 if IO::Socket::INET6 is available.
+#
+my $listen_on_ipv6 = 0;
+
##########################################################################
# Port redirection mode:
@@ -978,12 +987,24 @@ sub auto_select_port {
# Now try to find a free one:
#
for (my $p = $pmin; $p <= $pmax; $p++) {
- my $sock = IO::Socket::INET->new(
- Listen => 1,
- LocalPort => $p,
- ReuseAddr => 1,
- Proto => "tcp"
- );
+ my $sock = '';
+ if ($have_inet6 && $listen_on_ipv6) {
+ eval {$sock = IO::Socket::INET6->new(
+ Listen => 1,
+ LocalPort => $p,
+ ReuseAddr => 1,
+ Domain => AF_INET6,
+ LocalAddr => "::",
+ Proto => "tcp"
+ );};
+ } else {
+ $sock = IO::Socket::INET->new(
+ Listen => 1,
+ LocalPort => $p,
+ ReuseAddr => 1,
+ Proto => "tcp"
+ );
+ }
if ($sock) {
# we will keep this open until we call x11vnc:
$find_free_port = $sock;
@@ -1159,12 +1180,23 @@ sub lock_fixed_port {
$reason = 'locked';
} else {
# unlocked, try to listen on port:
- $sock = IO::Socket::INET->new(
- Listen => 1,
- LocalPort => $vnc_port,
- ReuseAddr => 1,
- Proto => "tcp"
- );
+ if ($have_inet6 && $listen_on_ipv6) {
+ eval {$sock = IO::Socket::INET6->new(
+ Listen => 1,
+ LocalPort => $vnc_port,
+ ReuseAddr => 1,
+ Domain => AF_INET6,
+ LocalAddr => "::",
+ Proto => "tcp"
+ );};
+ } else {
+ $sock = IO::Socket::INET->new(
+ Listen => 1,
+ LocalPort => $vnc_port,
+ ReuseAddr => 1,
+ Proto => "tcp"
+ );
+ }
if ($sock) {
# we got it, now try to lock:
my $str = "$$:" . time();
@@ -1266,12 +1298,23 @@ sub port_redir {
$rmlock = lock_fixed_port(90, 60);
} elsif ($find_free_port eq '0') {
- $find_free_port = IO::Socket::INET->new(
- Listen => 1,
- LocalPort => $vnc_port,
- ReuseAddr => 1,
- Proto => "tcp"
- );
+ if ($have_inet6 && $listen_on_ipv6) {
+ eval {$find_free_port = IO::Socket::INET6->new(
+ Listen => 1,
+ LocalPort => $vnc_port,
+ ReuseAddr => 1,
+ Domain => AF_INET6,
+ LocalAddr => "::",
+ Proto => "tcp"
+ );};
+ } else {
+ $find_free_port = IO::Socket::INET->new(
+ Listen => 1,
+ LocalPort => $vnc_port,
+ ReuseAddr => 1,
+ Proto => "tcp"
+ );
+ }
}
# In all cases, at this point $find_free_port is the listening
# socket.
@@ -1409,13 +1452,24 @@ sub handle_conn {
exit 1;
}
- my ($host, $port) = split(/:/, $redirect_host);
+ my $host = '';
+ my $port = '';
+ if ($redirect_host =~ /^(.*):(\d+)$/) {
+ ($host, $port) = ($1, $2);
+ }
my $sock = IO::Socket::INET->new(
PeerAddr => $host,
PeerPort => $port,
Proto => "tcp"
);
+ if (! $sock && $have_inet6) {
+ eval {$sock = IO::Socket::INET6->new(
+ PeerAddr => $host,
+ PeerPort => $port,
+ Proto => "tcp"
+ );};
+ }
if (! $sock) {
close $client;
diff --git a/x11vnc/misc/ultravnc_repeater.pl b/x11vnc/misc/ultravnc_repeater.pl
index a305ebe..5528bed 100755
--- a/x11vnc/misc/ultravnc_repeater.pl
+++ b/x11vnc/misc/ultravnc_repeater.pl
@@ -28,17 +28,19 @@ protocol: Listen on one port for vnc clients (default 5900.)
Read 250 bytes from connecting vnc client or server.
Accept ID:<string> from clients and servers, connect them
together once both are present.
+
The string "RFB 000.000\n" is sent to the client (the client
must understand this means send ID:... or host:port.)
Also accept <host>:<port> from clients and make the
connection to the vnc server immediately.
+
Note there is no authentication or security WRT ID names or
- identities; it us up to the client and server to manage that
- and whether to encrypt the session, etc.
+ identities; it is up to the client and server to completely
+ manage that aspect and whether to encrypt the session, etc.
usage: ultravnc_repeater.pl [-r] [client_port [server_port]]
-Use -r to refuse new server/client connections with an existing
+Use -r to refuse new server/client connections when there is an existing
server/client ID. The default is to close the previous one.
To write to a log file set the env. var ULTRAVNC_REPEATER_LOGFILE.
@@ -175,11 +177,18 @@ use warnings;
use IO::Socket::INET;
use IO::Select;
+# Test for INET6 support:
+#
+my $have_inet6 = 0;
+eval "use IO::Socket::INET6;";
+$have_inet6 = 1 if $@ eq "";
+print "perl module IO::Socket::INET6 not available: no IPv6 support.\n" if ! $have_inet6;
+
my $prog = 'ultravnc_repeater.pl';
my %ID;
my $refuse = 0;
-my $init_timeout = 3;
+my $init_timeout = 5;
if (@ARGV && $ARGV[0] =~ /-h/) {
print $usage;
@@ -187,6 +196,7 @@ if (@ARGV && $ARGV[0] =~ /-h/) {
}
if (@ARGV && $ARGV[0] eq '-r') {
$refuse = 1;
+ print "enabling refuse mode (-r).\n";
shift;
}
@@ -196,6 +206,7 @@ my $server_port = shift;
$client_port = 5900 unless $client_port;
$server_port = 5500 unless $server_port;
+my $uname = `uname`;
my $repeater_bufsize = 250;
$repeater_bufsize = $ENV{BUFSIZE} if exists $ENV{BUFSIZE};
@@ -208,9 +219,25 @@ my $client_listen = IO::Socket::INET->new(
ReuseAddr => 1,
Proto => "tcp"
);
-if (! $client_listen) {
+my $err1 = $!;
+my $err2 = '';
+$client_listen = '' if ! $client_listen;
+
+my $client_listen6 = '';
+if ($have_inet6) {
+ eval {$client_listen6 = IO::Socket::INET6->new(
+ Listen => 10,
+ LocalPort => $client_port,
+ ReuseAddr => 1,
+ Domain => AF_INET6,
+ LocalAddr => "::",
+ Proto => "tcp"
+ );};
+ $err2 = $!;
+}
+if (! $client_listen && ! $client_listen6) {
cleanup();
- die "$prog: error: client listen on port $client_port: $!\n";
+ die "$prog: error: client listen on port $client_port: $err1 - $err2\n";
}
my $server_listen = IO::Socket::INET->new(
@@ -219,9 +246,25 @@ my $server_listen = IO::Socket::INET->new(
ReuseAddr => 1,
Proto => "tcp"
);
-if (! $server_listen) {
+$err1 = $!;
+$err2 = '';
+$server_listen = '' if ! $server_listen;
+
+my $server_listen6 = '';
+if ($have_inet6) {
+ eval {$server_listen6 = IO::Socket::INET6->new(
+ Listen => 10,
+ LocalPort => $server_port,
+ ReuseAddr => 1,
+ Domain => AF_INET6,
+ LocalAddr => "::",
+ Proto => "tcp"
+ );};
+ $err2 = $!;
+}
+if (! $server_listen && ! $server_listen6) {
cleanup();
- die "$prog: error: server listen on port $server_port: $!\n";
+ die "$prog: error: server listen on port $server_port: $err1 - $err2\n";
}
my $select = new IO::Select();
@@ -230,8 +273,10 @@ if (! $select) {
die "$prog: select $!\n";
}
-$select->add($client_listen);
-$select->add($server_listen);
+$select->add($client_listen) if $client_listen;
+$select->add($client_listen6) if $client_listen6;
+$select->add($server_listen) if $server_listen;
+$select->add($server_listen6) if $server_listen6;
$SIG{INT} = sub {cleanup(); exit;};
$SIG{TERM} = sub {cleanup(); exit;};
@@ -240,7 +285,10 @@ my $SOCK1 = '';
my $SOCK2 = '';
my $CURR = '';
-print "watching for connections on ports $server_port/server and $client_port/client\n";
+print "watching for IPv4 connections on $client_port/client\n" if $client_listen;
+print "watching for IPv4 connections on $server_port/server\n" if $server_listen;
+print "watching for IPv6 connections on $client_port/client\n" if $client_listen6;
+print "watching for IPv6 connections on $server_port/server\n" if $server_listen6;
my $alarm_sock = '';
my $got_alarm = 0;
@@ -255,9 +303,9 @@ sub alarm_handler {
while (my @ready = $select->can_read()) {
foreach my $fh (@ready) {
- if ($fh == $client_listen) {
+ if ($fh == $client_listen || $fh == $client_listen6) {
print "new vnc client connecting at ", scalar(localtime), "\n";
- } elsif ($fh == $server_listen) {
+ } elsif ($fh == $server_listen || $fh == $server_listen6) {
print "new vnc server connecting at ", scalar(localtime), "\n";
}
my $sock = $fh->accept();
@@ -266,7 +314,7 @@ while (my @ready = $select->can_read()) {
next;
}
- if ($fh == $client_listen) {
+ if ($fh == $client_listen || $fh == $client_listen6) {
my $str = "RFB 000.000\n";
my $len = length $str;
my $n = syswrite($sock, $str, $len, 0);
@@ -294,9 +342,9 @@ while (my @ready = $select->can_read()) {
} elsif ($repeater_bufsize > 0 && $n != $size) {
print "$prog: short read $n != $size $!\n";
close $sock;
- } elsif ($fh == $client_listen) {
+ } elsif ($fh == $client_listen || $fh == $client_listen6) {
do_new_client($sock, $buf);
- } elsif ($fh == $server_listen) {
+ } elsif ($fh == $server_listen || $fh == $server_listen6) {
do_new_server($sock, $buf);
}
}
@@ -309,10 +357,12 @@ sub do_new_client {
my $id = $1;
if (exists $ID{$id}) {
if ($ID{$id}{client}) {
- print "refusing extra vnc client for ID:$id\n";
- close $sock;
- return;
- if ($refuse) {
+ my $ref = $refuse;
+ if ($ref && !established($ID{$id}{sock})) {
+ print "socket for ID:$id is no longer established, closing it.\n";
+ $ref = 0;
+ }
+ if ($ref) {
print "refusing extra vnc client for ID:$id\n";
close $sock;
return;
@@ -337,9 +387,11 @@ sub do_new_client {
}
} else {
my $str = sprintf("%s", $buf);
+ $str =~ s/\s*$//g;
+ $str =~ s/\0*$//g;
my $host = '';
my $port = '';
- if ($str =~ /^(.+):(\d+)/) {
+ if ($str =~ /^(.+):(\d+)$/) {
$host = $1;
$port = $2;
} else {
@@ -355,12 +407,23 @@ sub do_new_client {
print "resetting port from $port to $pnew\n";
$port = $pnew;
}
- print "making vnc client connection directly to vnc server $host:$port\n";
+ print "making vnc client connection directly to vnc server host='$host' port='$port'\n";
my $sock2 = IO::Socket::INET->new(
PeerAddr => $host,
PeerPort => $port,
Proto => "tcp"
);
+ if (! $sock2 && $have_inet6) {
+ print "IPv4 connect error: $!, trying IPv6 ...\n";
+ eval{$sock2 = IO::Socket::INET6->new(
+ PeerAddr => $host,
+ PeerPort => $port,
+ Proto => "tcp"
+ );};
+ print "IPv6 connect error: $!\n" if !$sock2;
+ } else {
+ print "IPv4 connect error: $!\n" if !$sock2;
+ }
if (!$sock2) {
print "failed to connect to $host:$port\n";
close $sock;
@@ -378,7 +441,12 @@ sub do_new_server {
my $store = 1;
if (exists $ID{$id}) {
if (! $ID{$id}{client}) {
- if ($refuse) {
+ my $ref = $refuse;
+ if ($ref && !established($ID{$id}{sock})) {
+ print "socket for ID:$id is no longer established, closing it.\n";
+ $ref = 0;
+ }
+ if ($ref) {
print "refusing extra vnc server for ID:$id\n";
close $sock;
return;
@@ -408,6 +476,78 @@ sub do_new_server {
}
}
+sub established {
+ # hack for Linux to see if remote side has gone away:
+ my $fh = shift;
+
+ # if we can't figure things out, we return true.
+ if ($uname !~ /Linux/) {
+ return 1;
+ }
+
+ my @proc_net_tcp = ();
+ if (-e "/proc/net/tcp") {
+ push @proc_net_tcp, "/proc/net/tcp";
+ }
+ if (-e "/proc/net/tcp6") {
+ push @proc_net_tcp, "/proc/net/tcp6";
+ }
+ if (! @proc_net_tcp) {
+ return 1;
+ }
+
+ my $n = fileno($fh);
+ if (!defined($n)) {
+ return 1;
+ }
+
+ my $proc_fd = "/proc/$$/fd/$n";
+ if (! -e $proc_fd) {
+ return 1;
+ }
+
+ my $val = readlink($proc_fd);
+ if (! defined $val || $val !~ /socket:\[(\d+)\]/) {
+ return 1;
+ }
+ my $num = $1;
+
+ my $st = '';
+
+ foreach my $tcp (@proc_net_tcp) {
+ if (! open(TCP, "<$tcp")) {
+ next;
+ }
+ while (<TCP>) {
+ next if /^\s*[A-z]/;
+ chomp;
+ # sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
+ # 170: 0102000A:170C FE02000A:87FA 01 00000000:00000000 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1
+ # 172: 0102000A:170C FE02000A:87FA 08 00000000:00000001 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1
+ my @items = split(' ', $_);
+ my $state = $items[3];
+ my $inode = $items[9];
+ if (!defined $state || $state !~ /^\d+$/) {
+ next;
+ }
+ if (!defined $inode || $inode !~ /^\d+$/) {
+ next;
+ }
+ if ($inode == $num) {
+ $st = $state;
+ last;
+ }
+ }
+ close TCP;
+ last if $st ne '';
+ }
+
+ if ($st ne '' && $st != 1) {
+ return 0;
+ }
+ return 1;
+}
+
sub handler {
print STDERR "$prog\[$$/$CURR]: got SIGTERM.\n";
close $SOCK1 if $SOCK1;
@@ -535,8 +675,10 @@ sub xfer_both {
}
sub cleanup {
- close $client_listen if defined $client_listen;
- close $server_listen if defined $server_listen;
+ close $client_listen if $client_listen;
+ close $client_listen6 if $client_listen6;
+ close $server_listen if $server_listen;
+ close $server_listen6 if $server_listen6;
foreach my $id (keys %ID) {
close $ID{$id}{sock};
}