diff options
author | runge <[email protected]> | 2010-04-18 19:37:37 -0400 |
---|---|---|
committer | runge <[email protected]> | 2010-04-18 19:37:37 -0400 |
commit | b74c8f4241ec8c3d972ee97d0ce9a399ddd09ce1 (patch) | |
tree | c8c8aaec90fd51a10790795030777b2dda548fe7 /x11vnc/misc | |
parent | 2a8ba97ec5b0f7fbfcfc8adab6732a95e95c7204 (diff) | |
download | libtdevnc-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-x | x11vnc/misc/connect_switch | 62 | ||||
-rwxr-xr-x | x11vnc/misc/desktop.cgi | 92 | ||||
-rwxr-xr-x | x11vnc/misc/ultravnc_repeater.pl | 192 |
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}; } |