ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-SNMP-XS/XS.pm
(Generate patch)

Comparing Net-SNMP-XS/XS.pm (file contents):
Revision 1.2 by root, Wed Apr 8 10:39:32 2009 UTC vs.
Revision 1.16 by root, Fri Dec 21 11:21:06 2018 UTC

13This module tries to speed up Net::SNMP response packet decoding. 13This module tries to speed up Net::SNMP response packet decoding.
14 14
15It does this by overriding a few selected internal method by (almost) 15It does this by overriding a few selected internal method by (almost)
16equivalent XS methods. 16equivalent XS methods.
17 17
18This currently reduces decode time by some 70%. 18This currently reduces decode time by a factor of ten for typical bulk
19responses.
19 20
20There are currently the following limitations when using this module: 21There are currently the following limitations when using this module:
21 22
22=over 4 23=over 4
23 24
24=item leading dots are required for iods 25=item overriding internal functions might cause the module to
26malfunction with future versions of Net::SNMP
25 27
26=item error handling is currently broken (but parse errors will be detected) 28=item error messages will be simpler/different
27
28=item oid components are limited to unsigned 32 bit integers
29 29
30=item translation will be ignored (all values will be delivered "raw") 30=item translation will be ignored (all values will be delivered "raw")
31 31
32=item a 64 bit perl is required
33
34=item a moderately modern (>= C99) C compiler is required 32=item a moderately modern (>= C99) C compiler is required
35 33
36=item only tested with 5.10 34=item only tested with 5.10, no intentions to port to older perls
35
36=item duplicate OIDs are not supported
37
38=item REPORT PDUs are not supported
37 39
38=back 40=back
39 41
40=cut 42=cut
41 43
42package Net::SNMP::XS; 44package Net::SNMP::XS;
43 45
44use strict qw(vars subs); 46use common::sense;
45no warnings;
46 47
47use Guard; 48use Net::SNMP ();
48
49use Net::SNMP::PDU (); 49use Net::SNMP::PDU ();
50use Net::SNMP::Message (); 50use Net::SNMP::Message ();
51use Net::SNMP::MessageProcessing (); 51use Net::SNMP::MessageProcessing ();
52 52
53our $VERSION; 53our $VERSION;
54our $old_prepare;
55 54
56BEGIN { 55BEGIN {
57 $VERSION = '0.01'; 56 $VERSION = 1.32;
58 57
59 $old_prepare = \&Net::SNMP::MessageProcessing::prepare_data_elements; 58 # this overrides many methods inside Net::SNMP and it's submodules
60
61 # this overrides many methods inside
62 require XSLoader; 59 require XSLoader;
63 XSLoader::load Net::SNMP::XS, $VERSION; 60 XSLoader::load Net::SNMP::XS, $VERSION;
64} 61}
65 62
66sub Net::SNMP::MessageProcessing::prepare_data_elements { 63package Net::SNMP::Message;
67 my ($self, $msg) = @_;
68 64
69 set_msg $msg, $msg->{_buffer}; 65Net::SNMP::XS::set_type INTEGER , \&_process_integer32;
70 scope_guard \&clr_msg; 66Net::SNMP::XS::set_type OCTET_STRING , \&_process_octet_string;
71 &$old_prepare 67Net::SNMP::XS::set_type NULL , \&_process_null;
72} 68Net::SNMP::XS::set_type OBJECT_IDENTIFIER, \&_process_object_identifier;
69Net::SNMP::XS::set_type SEQUENCE , \&_process_sequence;
70Net::SNMP::XS::set_type IPADDRESS , \&_process_ipaddress;
71Net::SNMP::XS::set_type COUNTER , \&_process_counter;
72Net::SNMP::XS::set_type GAUGE , \&_process_gauge;
73Net::SNMP::XS::set_type TIMETICKS , \&_process_timeticks;
74Net::SNMP::XS::set_type OPAQUE , \&_process_opaque;
75Net::SNMP::XS::set_type COUNTER64 , \&_process_counter64;
76Net::SNMP::XS::set_type NOSUCHOBJECT , \&_process_nosuchobject;
77Net::SNMP::XS::set_type NOSUCHINSTANCE , \&_process_nosuchinstance;
78Net::SNMP::XS::set_type ENDOFMIBVIEW , \&_process_endofmibview;
79Net::SNMP::XS::set_type GET_REQUEST , \&_process_get_request;
80Net::SNMP::XS::set_type GET_NEXT_REQUEST , \&_process_get_next_request;
81Net::SNMP::XS::set_type GET_RESPONSE , \&_process_get_response;
82Net::SNMP::XS::set_type SET_REQUEST , \&_process_set_request;
83Net::SNMP::XS::set_type TRAP , \&_process_trap;
84Net::SNMP::XS::set_type GET_BULK_REQUEST , \&_process_get_bulk_request;
85Net::SNMP::XS::set_type INFORM_REQUEST , \&_process_inform_request;
86Net::SNMP::XS::set_type SNMPV2_TRAP , \&_process_v2_trap;
87Net::SNMP::XS::set_type REPORT , \&_process_report;
73 88
74# almost direct copy from Net::SNMP::Message, as we cannot access $process_methods 89package Net::SNMP::PDU;
90
91# var_bind_list hardcodes oid_lex_sort. *sigh*
92# we copy it 1:1, except for using oid_lex_sort.
93
94sub var_bind_list
75{ 95{
76 package Net::SNMP::Message; 96 my ($this, $vbl, $types) = @_;
77 97
78 my @process_methods; 98 return if defined($this->{_error});
79 99
80 $process_methods [INTEGER ] = \&_process_integer32; 100 if (@_ > 1) {
81 $process_methods [OCTET_STRING ] = \&_process_octet_string; 101 # The VarBindList HASH is being updated from an external
82 $process_methods [NULL ] = \&_process_null; 102 # source. We need to update the VarBind names ARRAY to
83 $process_methods [OBJECT_IDENTIFIER] = \&_process_object_identifier; 103 # correspond to the new keys of the HASH. If the updated
84 $process_methods [SEQUENCE ] = \&_process_sequence; 104 # information is valid, we will use lexicographical ordering
85 $process_methods [IPADDRESS ] = \&_process_ipaddress; 105 # for the ARRAY entries since we do not have a PDU to use
86 $process_methods [COUNTER ] = \&_process_counter; 106 # to determine the ordering. The ASN.1 types HASH is also
87 $process_methods [GAUGE ] = \&_process_gauge; 107 # updated here if a cooresponding HASH is passed. We double
88 $process_methods [TIMETICKS ] = \&_process_timeticks; 108 # check the mapping by populating the hash with the keys of
89 $process_methods [OPAQUE ] = \&_process_opaque; 109 # the VarBindList HASH.
90 $process_methods [COUNTER64 ] = \&_process_counter64;
91 $process_methods [NOSUCHOBJECT ] = \&_process_nosuchobject;
92 $process_methods [NOSUCHINSTANCE ] = \&_process_nosuchinstance;
93 $process_methods [ENDOFMIBVIEW ] = \&_process_endofmibview;
94 $process_methods [GET_REQUEST ] = \&_process_get_request;
95 $process_methods [GET_NEXT_REQUEST ] = \&_process_get_next_request;
96 $process_methods [GET_RESPONSE ] = \&_process_get_response;
97 $process_methods [SET_REQUEST ] = \&_process_set_request;
98 $process_methods [TRAP ] = \&_process_trap;
99 $process_methods [GET_BULK_REQUEST ] = \&_process_get_bulk_request;
100 $process_methods [INFORM_REQUEST ] = \&_process_inform_request;
101 $process_methods [SNMPV2_TRAP ] = \&_process_v2_trap;
102 $process_methods [REPORT ] = \&_process_report;
103 110
104 # should be done in XS 111 if (!defined($vbl) || (ref($vbl) ne 'HASH')) {
105 sub process
106 {
107# my ($this, $expected, $found) = @_;
108 112
109 return $_[0]->_error if defined($_[0]->{_error}); 113 $this->{_var_bind_list} = undef;
110 return $_[0]->_error unless defined(my $type = _buffer_get($_[0], 1)); 114 $this->{_var_bind_names} = [];
115 $this->{_var_bind_types} = undef;
111 116
112 $type = unpack 'C', $type; 117 } else {
113 118
114 if ($process_methods[$type]) { 119 $this->{_var_bind_list} = $vbl;
115 if (@_ >= 2 && (defined $_[1]) && $type != $_[1]) { 120
116 return $_[0]->_error( 121 @{$this->{_var_bind_names}} = Net::SNMP::oid_lex_sort keys %$vbl;
117 'Expected %s, but found %s', asn1_itoa($_[1]), asn1_itoa($type) 122
118 ); 123 if (!defined($types) || (ref($types) ne 'HASH')) {
124 $types = {};
119 } 125 }
120 $_[2] = $type if (@_ == 3); 126
121 $process_methods[$type]->($_[0], $type); 127 map {
122 } else { 128 $this->{_var_bind_types}->{$_} =
123 $_[0]->_error('Unknown ASN.1 type [0x%02x]', $type); 129 exists($types->{$_}) ? $types->{$_} : undef;
130 } keys(%{$vbl});
131
124 } 132 }
133
125 } 134 }
135
136 $this->{_var_bind_list};
126} 137}
127 138
1281; 1391;
129 140
130=head1 AUTHOR 141=head1 AUTHOR

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines