X-Git-Url: http://dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FMsg.pm;h=5aebab650caac475f3b05600ff2a2e7e3d46f35b;hb=d17f05b19fac36a0a8a2f828912a1a7ebefae79f;hp=00569928165bb2a630862b4d1fd9603ee05f6d8a;hpb=a204e3cd89e849e97db25879b4ddf62b770bd227;p=spider.git diff --git a/perl/Msg.pm b/perl/Msg.pm index 00569928..5aebab65 100644 --- a/perl/Msg.pm +++ b/perl/Msg.pm @@ -5,25 +5,19 @@ # # I have modified it to suit my devious purposes (Dirk Koopman G1TLH) # -# $Id$ +# # package Msg; use strict; -use vars qw($VERSION $BRANCH); -$VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ ); -$BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ || (0,0)); -$main::build += $VERSION; -$main::branch += $BRANCH; +use DXUtil; -use IO::Select; -use IO::Socket; use DXDebug; use Timer; -use vars qw(%rd_callbacks %wt_callbacks %er_callbacks $rd_handles $wt_handles $er_handles $now %conns $noconns $blocking_supported $cnum $total_in $total_out); +use vars qw(%rd_callbacks %wt_callbacks %er_callbacks $rd_handles $wt_handles $er_handles $now %conns $noconns $blocking_supported $cnum $total_in $total_out $io_socket); %rd_callbacks = (); %wt_callbacks = (); @@ -41,12 +35,25 @@ BEGIN { local $^W; require POSIX; POSIX->import(qw(O_NONBLOCK F_SETFL F_GETFL)) }; + + eval { + local $^W; + require IO::Socket::INET6; + }; + + if ($@) { + dbg($@); + require IO::Socket; + $io_socket = 'IO::Socket::INET'; + } else { + $io_socket = 'IO::Socket::INET6'; + } + $io_socket->import; + if ($@ || $main::is_win) { -# print STDERR "POSIX Blocking *** NOT *** supported $@\n"; - $blocking_supported = 0; + $blocking_supported = $io_socket->can('blocking') ? 2 : 0; } else { - $blocking_supported = 1; -# print STDERR "POSIX Blocking enabled\n"; + $blocking_supported = $io_socket->can('blocking') ? 2 : 1; } @@ -72,12 +79,12 @@ BEGIN { # defines EINPROGRESS as 10035. We provide it here because some # Win32 users report POSIX::EINPROGRESS is not vendor-supported. if ($^O eq 'MSWin32') { - eval '*EINPROGRESS = sub { 10036 };'; - eval '*EWOULDBLOCK = *EAGAIN = sub { 10035 };'; - eval '*F_GETFL = sub { 0 };'; - eval '*F_SETFL = sub { 0 };'; - eval '*IPPROTO_TCP = sub { 6 };'; - eval '*TCP_NODELAY = sub { 1 };'; + eval '*EINPROGRESS = sub { 10036 };' unless defined *EINPROGRESS; + eval '*EWOULDBLOCK = *EAGAIN = sub { 10035 };' unless defined *EWOULDBLOCK; + eval '*F_GETFL = sub { 0 };' unless defined *F_GETFL; + eval '*F_SETFL = sub { 0 };' unless defined *F_SETFL; + eval 'sub IPPROTO_TCP { 6 };'; + eval 'sub TCP_NODELAY { 1 };'; $blocking_supported = 0; # it appears that this DOESN'T work :-( } } @@ -139,12 +146,8 @@ sub blocking return unless $blocking_supported; # Make the handle stop blocking, the Windows way. - if ($main::is_win) { - # 126 is FIONBIO (some docs say 0x7F << 16) - ioctl( $_[0], - 0x80000000 | (4 << 16) | (ord('f') << 8) | 126, - "$_[1]" - ); + if ($blocking_supported) { + $_[0]->blocking($_[1]); } else { my $flags = fcntl ($_[0], F_GETFL, 0); if ($_[1]) { @@ -189,6 +192,21 @@ sub pid_gone } } +sub ax25 +{ + my $conn = shift; + return $conn->{csort} eq 'ax25'; +} + +sub peerhost +{ + my $conn = shift; + $conn->{peerhost} ||= 'ax25' if $conn->ax25; + $conn->{peerhost} ||= $conn->{sock}->peerhost if $conn->{sock} && $conn->{sock}->isa('IO::Socket::INET'); + $conn->{peerhost} ||= 'UNKNOWN'; + return $conn->{peerhost}; +} + #----------------------------------------------------------------- # Send side routines sub connect { @@ -203,25 +221,31 @@ sub connect { $conn->{peerport} = $to_port; $conn->{sort} = 'Outgoing'; - # Create a new internet socket - my $sock = IO::Socket::INET->new(); - return undef unless $sock; - - my $proto = getprotobyname('tcp'); - $sock->socket(AF_INET, SOCK_STREAM, $proto) or return undef; - - blocking($sock, 0); - $conn->{blocking} = 0; + my $sock; + if ($blocking_supported) { + $sock = $io_socket->new(PeerAddr => $to_host, PeerPort => $to_port, Proto => 'tcp', Blocking =>0) or return undef; + } else { + # Create a new internet socket + $sock = $io_socket->new(); + return undef unless $sock; - # does the host resolve? - my $ip = gethostbyname($to_host); - return undef unless $ip; - - my $r = connect($sock, pack_sockaddr_in($to_port, $ip)); - return undef unless $r || _err_will_block($!); + my $proto = getprotobyname('tcp'); + $sock->socket(AF_INET, SOCK_STREAM, $proto) or return undef; + + blocking($sock, 0); + $conn->{blocking} = 0; + + # does the host resolve? + my $ip = gethostbyname($to_host); + return undef unless $ip; + + my $r = connect($sock, pack_sockaddr_in($to_port, $ip)); + return undef unless $r || _err_will_block($!); + } $conn->{sock} = $sock; - + $conn->{peerhost} = $sock->peerhost; # for consistency + if ($conn->{rproc}) { my $callback = sub {$conn->_rcv}; set_event_handler ($sock, read => $callback); @@ -235,7 +259,7 @@ sub start_program my $pid; local $^F = 10000; # make sure it ain't closed on exec - my ($a, $b) = IO::Socket->socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC); + my ($a, $b) = $io_socket->socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC); if ($a && $b) { $a->autoflush(1); $b->autoflush(1); @@ -306,7 +330,7 @@ sub disconnect if (defined($sock)) { set_event_handler ($sock, read => undef, write => undef, error => undef); - shutdown($sock, 3); + shutdown($sock, 2); close($sock); } @@ -346,10 +370,10 @@ sub _send { # return to the event loop only after every message, or if it # is likely to block in the middle of a message. - if ($conn->{blocking} != $flush) { - blocking($sock, $flush); - $conn->{blocking} = $flush; - } +# if ($conn->{blocking} != $flush) { +# blocking($sock, $flush); +# $conn->{blocking} = $flush; +# } my $offset = (exists $conn->{send_offset}) ? $conn->{send_offset} : 0; while (@$rq) { @@ -434,7 +458,7 @@ sub new_server { my ($pkg, $my_host, $my_port, $login_proc) = @_; my $self = $pkg->new($login_proc); - $self->{sock} = IO::Socket::INET->new ( + $self->{sock} = $io_socket->new ( LocalAddr => "$my_host:$my_port", # LocalPort => $my_port, Listen => SOMAXCONN, @@ -497,10 +521,10 @@ sub _rcv { # Complement to _send return unless defined($sock); my @lines; - if ($conn->{blocking}) { - blocking($sock, 0); - $conn->{blocking} = 0; - } +# if ($conn->{blocking}) { +# blocking($sock, 0); +# $conn->{blocking} = 0; +# } $bytes_read = sysread ($sock, $msg, 1024, 0); if (defined ($bytes_read)) { if ($bytes_read > 0) {