if ($^O eq 'MSWin32') {
eval '*EINPROGRESS = sub { 10036 };' unless defined *EINPROGRESS;
eval '*EWOULDBLOCK = *EAGAIN = sub { 10035 };' unless defined *EWOULDBLOCK;
- eval '*F_GETFL = sub { 0 };';
- eval '*F_SETFL = sub { 0 };';
- eval '*IPPROTO_TCP = sub { 6 };';
- eval '*TCP_NODELAY = sub { 1 };';
+ 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 :-(
}
}
$noconns++;
- dbg("Connection created ($noconns)") if isdbg('connll');
+ dbg("$class Connection $conn->{cnum} created (total $noconns)") if isdbg('connll');
return bless $conn, $class;
}
if (ref $pkg) {
$call = $pkg->{call} unless $call;
return undef unless $call;
- dbg("changing $pkg->{call} to $call") if isdbg('connll') && exists $pkg->{call} && $call ne $pkg->{call};
+ dbg((ref $pkg) . " changing $pkg->{call} to $call") if isdbg('connll') && exists $pkg->{call} && $call ne $pkg->{call};
delete $conns{$pkg->{call}} if exists $pkg->{call} && exists $conns{$pkg->{call}} && $pkg->{call} ne $call;
$pkg->{call} = $call;
$ref = $conns{$call} = $pkg;
- dbg("Connection $pkg->{cnum} $call stored") if isdbg('connll');
+ dbg((ref $pkg) . " Connection $pkg->{cnum} $call stored") if isdbg('connll');
} else {
$ref = $conns{$call};
}
}
}
+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 {
$conn->{peerhost} = $to_host;
$conn->{peerport} = $to_port;
$conn->{sort} = 'Outgoing';
-
- # Create a new internet socket
- my $sock = $io_socket->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;
- # does the host resolve?
- my $ip = gethostbyname($to_host);
- return undef unless $ip;
+ dbg((ref $conn) . " connecting $conn->{cnum} to $to_host:$to_port") if isdbg('connll');
- my $r = connect($sock, pack_sockaddr_in($to_port, $ip));
- return undef unless $r || _err_will_block($!);
+ 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;
+
+ 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
+
+ dbg((ref $conn) . " connected $conn->{cnum} to $to_host:$to_port") if isdbg('connll');
+
if ($conn->{rproc}) {
my $callback = sub {$conn->_rcv};
set_event_handler ($sock, read => $callback);
delete $conns{$call} if $ref && $ref == $conn;
}
$call ||= 'unallocated';
- dbg("Connection $conn->{cnum} $call disconnected") if isdbg('connll');
+ dbg((ref $conn) . " Connection $conn->{cnum} $call disconnected") if isdbg('connll');
# get rid of any references
for (keys %$conn) {
if (defined($sock)) {
set_event_handler ($sock, read => undef, write => undef, error => undef);
- shutdown($sock, 3);
+ shutdown($sock, 2);
close($sock);
}
my $self = $pkg->new($login_proc);
$self->{sock} = $io_socket->new (
- LocalAddr => "$my_host:$my_port",
-# LocalPort => $my_port,
+ LocalAddr => $my_host,
+ LocalPort => $my_port,
Listen => SOMAXCONN,
Proto => 'tcp',
Reuse => 1);
sub dequeue
{
my $conn = shift;
-
- if ($conn->{msg} =~ /\n/) {
- my @lines = split /\r?\n/, $conn->{msg};
- if ($conn->{msg} =~ /\n$/) {
+ return if $conn->{disconnecting};
+
+ if ($conn->{msg} =~ /\cJ/) {
+ my @lines = split /\cM?\cJ/, $conn->{msg};
+ if ($conn->{msg} =~ /\cM?\cJ$/) {
delete $conn->{msg};
} else {
$conn->{msg} = pop @lines;
}
for (@lines) {
+ last if $conn->{disconnecting};
&{$conn->{rproc}}($conn, defined $_ ? $_ : '');
}
}
my $call = $conn->{call} || 'unallocated';
my $host = $conn->{peerhost} || '';
my $port = $conn->{peerport} || '';
- dbg("Connection $conn->{cnum} $call [$host $port] being destroyed") if isdbg('connll');
$noconns--;
+ dbg((ref $conn) . " Connection $conn->{cnum} $call [$host $port] being destroyed (total $noconns)") if isdbg('connll');
}
1;