root/lib/Core/TcpService.pm

Revision 8c072a266ecd5f184ce47e1110c3d695b8cec75b, 2.6 kB (checked in by Jason Dixon <jdixon@omniti.com>, 4 years ago)

no svn executable

git-svn-id: https://labs.omniti.com/resmon/branches/resmon2@324 8c0face9-b7db-6ec6-c4b3-d5f7145c7d55

  • Property mode set to 100644
Line 
1 package Core::TcpService;
2
3 use strict;
4 use warnings;
5
6 use base 'Resmon::Module';
7
8 use Resmon::ExtComm qw(run_command cache_command);
9 use Socket;
10 use Fcntl;
11 use IO::Select;
12 use IO::Handle;
13
14 =pod
15
16 =head1 NAME
17
18 Core::TcpService - Test connections to a TCP service.
19
20 =head1 SYNOPSIS
21
22  Core::TcpService {
23      connect : noop
24  }
25
26  Core::TcpService {
27      connect : host => 127.0.0.1, port => 22, timeout => 10
28  }
29
30 =head1 DESCRIPTION
31
32 This module connects to TCP services and tests for a response.
33
34 =head1 CONFIGURATION
35
36 =over
37
38 =item check_name
39
40 The check name is used for descriptive purposes only.  It is not used for
41 anything functional.
42
43 =item host
44
45 The host to connect to (required).
46
47 =item port
48
49 The port to connect to (required).
50
51 =item timeout
52
53 Override the default timeout value (optional).  Default value is 5.
54
55 =item prepost
56
57 A string to send on connection (optional).  Useful if the service requires
58 something to be entered before showing a banner.
59
60 =item post
61
62 A string to send after the initial banner (optional).
63
64 =back
65
66 =head1 METRICS
67
68 =over
69
70 =item status
71
72 Status of the connection attempt.
73
74 =item banner
75
76 Banner string returned by the target service, if available.
77
78 =back
79
80 =cut
81
82 sub handler {
83     my $self = shift;
84     my $config = $self->{'config'};
85     my $host = $config->{'host'} || die "Host is required";
86     my $port = $config->{'port'} || die "Port is required";
87     my $timeout = $config->{'timeout'} || 5;
88     my $banner;
89     my $proto = getprotobyname('tcp');
90     my $c = IO::Select->new();
91     my $h = IO::Handle->new();
92
93     socket($h, Socket::PF_INET, Socket::SOCK_STREAM, $proto) || return { 'status' => ['socket error', 's'] };
94     $h->autoflush(1);
95
96     fcntl($h, Fcntl::F_SETFL, Fcntl::O_NONBLOCK) || (close($h) && return { 'status' => ['fcntl error', 's'] } );
97
98     my $s = Socket::sockaddr_in($port, Socket::inet_aton($host));
99     connect($h, $s);
100     $c->add($h);
101     my ($fd) = $c->can_write($timeout);
102     if ($fd == $h) {
103         my $error = unpack("s", getsockopt($h, Socket::SOL_SOCKET, Socket::SO_ERROR));
104         if ($error != 0) {
105             close($h);
106             return { 'status' => ['connection failed', 's'] };
107         }
108         print $h $config->{'prepost'}."\r\n" if ($config->{'prepost'});
109         ($fd) = $c->can_read($timeout);
110         if ($fd == $h) {
111             chomp($banner = <$h>);
112             print $h $config->{'post'} if ($config->{'post'});
113             close($h);
114             $banner =~ s/([^\s\d\w.,;\/\\])/sprintf "\\%o", $1/eg;
115         }
116     }
117     close($h);
118
119     return {
120         'banner' => [$banner, 's'],
121         'status' => ['connection successful', 's']
122     };
123 };
124
125 1;
126
Note: See TracBrowser for help on using the browser.