diff options
author | Gisle Aas <gisle@aas.no> | 2006-01-18 01:28:24 -0800 |
---|---|---|
committer | Gisle Aas <gisle@activestate.com> | 2006-01-23 09:57:10 +0000 |
commit | ebcd0cc070f3e120eecf39e812e058e26485aa69 (patch) | |
tree | 55c12e4e2458f88cfb4f502ad15aaa39055f6c32 /ext/IO | |
parent | 1bd1db6feafb0e0b6bfb34267e8489cdec623282 (diff) | |
download | perl-ebcd0cc070f3e120eecf39e812e058e26485aa69.tar.gz |
Avoid most getprotobyname/number calls in IO::Socket::INET
Message-ID: <lr3bjlbg3r.fsf@caliper.activestate.com>
p4raw-id: //depot/perl@26921
Diffstat (limited to 'ext/IO')
-rw-r--r-- | ext/IO/lib/IO/Socket/INET.pm | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/ext/IO/lib/IO/Socket/INET.pm b/ext/IO/lib/IO/Socket/INET.pm index 73f4abd6c0..a50b11c630 100644 --- a/ext/IO/lib/IO/Socket/INET.pm +++ b/ext/IO/lib/IO/Socket/INET.pm @@ -24,6 +24,11 @@ my %socket_type = ( tcp => SOCK_STREAM, udp => SOCK_DGRAM, icmp => SOCK_RAW ); +my %proto_number; +$proto_number{tcp} = Socket::IPPROTO_TCP() if defined &Socket::IPPROTO_TCP; +$proto_number{upd} = Socket::IPPROTO_UDP() if defined &Socket::IPPROTO_UDP; +$proto_number{icmp} = Socket::IPPROTO_ICMP() if defined &Socket::IPPROTO_ICMP; +my %proto_name = reverse %proto_number; sub new { my $class = shift; @@ -31,30 +36,60 @@ sub new { return $class->SUPER::new(@_); } +sub _cache_proto { + my @proto = @_; + for (map lc($_), $proto[0], split(' ', $proto[1])) { + $proto_number{$_} = $proto[2]; + } + $proto_name{$proto[2]} = $proto[0]; +} + +sub _get_proto_number { + my $name = lc(shift); + return undef unless defined $name; + return $proto_number{$name} if exists $proto_number{$name}; + + my @proto = getprotobyname($name); + return undef unless @proto; + _cache_proto(@proto); + + return $proto[2]; +} + +sub _get_proto_name { + my $num = shift; + return undef unless defined $num; + return $proto_name{$num} if exists $proto_name{$num}; + + my @proto = getprotobynumber($num); + return undef unless @proto; + _cache_proto(@proto); + + return $proto[0]; +} + sub _sock_info { my($addr,$port,$proto) = @_; my $origport = $port; - my @proto = (); my @serv = (); $port = $1 if(defined $addr && $addr =~ s,:([\w\(\)/]+)$,,); if(defined $proto && $proto =~ /\D/) { - if(@proto = getprotobyname($proto)) { - $proto = $proto[2] || undef; - } - else { + my $num = _get_proto_number($proto); + unless (defined $num) { $@ = "Bad protocol '$proto'"; return; } + $proto = $num; } if(defined $port) { my $defport = ($port =~ s,\((\d+)\)$,,) ? $1 : undef; my $pnum = ($port =~ m,^(\d+)$,)[0]; - @serv = getservbyname($port, $proto[0] || "") + @serv = getservbyname($port, _get_proto_name($proto) || "") if ($port =~ m,\D,); $port = $serv[2] || $defport || $pnum; @@ -63,8 +98,7 @@ sub _sock_info { return; } - $proto = (getprotobyname($serv[3]))[2] || undef - if @serv && !$proto; + $proto = _get_proto_number($serv[3]) if @serv && !$proto; } return ($addr || undef, @@ -128,10 +162,9 @@ sub configure { or return _error($sock, $!, $@); } - $proto ||= (getprotobyname('tcp'))[2]; + $proto ||= _get_proto_number('tcp'); - my $pname = (getprotobynumber($proto))[0]; - $type = $arg->{Type} || $socket_type{lc $pname}; + $type = $arg->{Type} || $socket_type{lc _get_proto_name($proto)}; my @raddr = (); |