File:
1.00.1a/server/base/tests.inc.php (
View as Code)
1: 2: /* -------------------------------------------------------------
3: This file is part of FreeNATS
4:
5: FreeNATS is (C) Copyright 2008 PurplePixie Systems
6:
7: FreeNATS is free software: you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation, either version 3 of the License, or
10: (at your option) any later version.
11:
12: FreeNATS is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with FreeNATS. If not, see www.gnu.org/licenses
19:
20: For more information see www.purplepixie.org/freenats
21: -------------------------------------------------------------- */
22:
23: if (!isset($BaseDir)) $BaseDir="../base/"; //
24: require_once($BaseDir."timer.inc.php"); // just in case standalone
25:
26: // FreeNATS_Local_Test Base Class - Local Tests (run from FreeNATS server) must extend from this
27:
28: class FreeNATS_Local_Test
29: {
30: function DoTest($testname,$param,$hostname="",$timeout=-1,$params=false)
31: {
32: return 0;
33: }
34:
35: function Evaluate($result)
36: {
37: return -1;
38: }
39:
40: function DisplayForm(&$row)
41: {
42: return false;
43: }
44:
45: function ProtectOutput(&$row)
46: {
47: return false;
48: }
49: }
50:
51: // ------------------------------------------------------------------------------------------------
52:
53: require($BaseDir."tests/mysql.inc.php");
54: require($BaseDir."tests/imap.inc.php");
55: require($BaseDir."tests/smtp.inc.php");
56: require($BaseDir."tests/dns.inc.php");
57:
58: function ip_lookup($hostname) // "safe" DNS lookup function to call with a hostname, URL or IP - returns 0 if unsuccessful
59: {
60: // Is it already an IP adress?
61: $out=str_replace(".","",$hostname);
62: if (is_numeric($out)) return $hostname; // yes it is
63:
64: // No it is not
65: $ip=@gethostbyname($hostname);
66: if ($ip==$hostname) return 0; // unmodified host - lookup failed
67:
68: return $ip;
69: }
70:
71: function next_run_x($interval)
72: {
73: if ($interval<1) return time();
74: return time()+(($interval)*60)-30;
75: }
76:
77: function test_sleep()
78: {
79: global $NATS;
80: if (!isset($NATS)) return false;
81: $sleep=$NATS->Cfg->Get("test.interval",0);
82: if ($sleep<=0) return false;
83: $sleep=$sleep*1000000; // convert to usec
84: usleep($sleep);
85: return true;
86: }
87:
88: function url_lookup($url)
89: {
90: // Sod regular expressions here as we'd have to do it twice or with cleverness I lack
91: // Is it a URL?
92: $colon=strpos($url,":");
93: if ($colon != 0) // exists so it a URL
94: {
95: $out=preg_match("@^(?:http[s]*://)?([^/|\?|:]+)@i",$url,$matches);
96: $hostname=$matches[1];
97: }
98: else $hostname=$url; // try direct
99:
100: return ip_lookup($hostname);
101: }
102:
103:
104:
105:
106:
107:
108:
109: function icmpChecksum($data)
110: {
111: if (strlen($data)%2)
112: $data .= "\x00";
113:
114: $bit = unpack('n*', $data);
115: $sum = array_sum($bit);
116:
117: while ($sum >> 16)
118: $sum = ($sum >> 16) + ($sum & 0xffff);
119:
120: return pack('n*', ~$sum);
121: }
122:
123: function PingTest($host,$ctimeout=-1)
124: {
125: global $NATS;
126: $FreeNATS_Timer=new TFNTimer();
127: // Make Package
128: $type= "\x08";
129: $code= "\x00";
130: $checksum= "\x00\x00";
131: $identifier = "\x00\x00";
132: $seqNumber = "\x00\x00";
133: $data= "FreeNATS";
134: $package = $type.$code.$checksum.$identifier.$seqNumber.$data;
135: $checksum = icmpChecksum($package); // Calculate the checksum
136: $package = $type.$code.$checksum.$identifier.$seqNumber.$data;
137:
138: // Return s or ms(s*1000)
139: $returnsecs=true;
140: if (isset($NATS))
141: {
142: if ($NATS->Cfg->Get("test.icmp.returnms",0)==1) $returnsecs=false;
143: }
144:
145: // Timeout Values
146: if (isset($NATS)) $timeout=$NATS->Cfg->Get("test.icmp.timeout",10);
147: else $timeout=10;
148: if ($ctimeout>0) $timeout=$ctimeout; // use custom timeout if passed
149: if ($timeout<=0) $timeout=10; // catch-all for defaults bug
150:
151: // Create Socket
152: $socket = @socket_create(AF_INET, SOCK_RAW, 1);
153: //or die(socket_strerror(socket_last_error()));
154: if (!$socket) return 0;
155:
156: // Set Non-Blocking
157: @socket_set_nonblock($socket);
158:
159: // Connect Socket
160: $sconn=@socket_connect($socket, $host, null);
161: if (!$sconn) return 0;
162:
163: // Send Data
164: @socket_send($socket, $package, strLen($package), 0);
165:
166: // Start Timer
167: $FreeNATS_Timer->Start();
168: $startTime = microtime(true); // need this for the looping section
169:
170:
171: // Read Data
172: $keepon=true;
173:
174: while( (!(@socket_read($socket, 255))) && $keepon)
175: { // basically just kill time
176: // consider putting some sort of sleepy thing here to lower load but would f* with figures!
177:
178: if ( (microtime(true) - $startTime) > $timeout )
179: $keepon=false;
180: }
181:
182: if ($keepon) // didn't time out - read data
183: {
184: $elapsed=$FreeNATS_Timer->Stop();
185: if ($returnsecs) $elapsed=round($elapsed,4);
186: else $elapsed=round( ($elapsed*1000),4 );
187: @socket_close($socket);
188: // $ret=round(microtime(true) - $startTime, 4); -- old method
189: if ($elapsed<=0) $elapsed="0.0001"; // safety catch-all
190: return $elapsed;
191: /*
192: if ($ret==0) return "0.0001";
193: else
194: {
195: if ($ret<=0) return "0.0001";
196: else return $ret;
197: }
198: */
199: }
200:
201: // Socket timed out
202: @socket_close($socket);
203: return 0;
204: }
205:
206: function WebTest($url,$timeout=-1)
207: {
208: global $NATS;
209: if ($timeout<=0) // use NATS or env
210: {
211: if (isset($NATS))
212: {
213: $nto=$NATS->Cfg->Get("test.http.timeout",-1);
214: if ($nto>0) $timeout=$nto; // use NATS timeout
215: }
216: }
217: if ($timeout>0) // use the set timeout
218: $oldtimeout=ini_set("default_socket_timeout",$timeout);
219:
220: if (function_exists("curl_getinfo")) // use CURL if present
221: {
222: $ch=curl_init();
223: curl_setopt($ch,CURLOPT_URL,$url);
224: curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
225: curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
226: curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0);
227: curl_setopt($ch,CURLOPT_HEADER,1);
228: if ($timeout>0) curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
229: if ($timeout>0) curl_setopt($ch,CURLOPT_TIMEOUT,$timeout);
230: if (!$output=curl_exec($ch))
231: {
232: $ctr=-1; // failed
233: }
234: else $ctr=round(curl_getinfo($ch,CURLINFO_SIZE_DOWNLOAD)/1024,2);
235: curl_close($ch);
236:
237: if ($ctr==0) $ctr="0.0001";
238:
239: }
240: else
241: { // no CURL - use fopen()
242: $fp=@fopen($url,"r");
243: if ($fp<=0)
244: {
245: if ($timeout>0) ini_set("default_socket_timeout",$oldtimeout);
246: return -1;
247: }
248: $ctr=0;
249: while ($body=@fgets($fp,1024)) $ctr+=sizeof($body);
250: @fclose($fp);
251: }
252:
253:
254:
255: if ($timeout>0) ini_set("default_socket_timeout",$oldtimeout);
256: return $ctr;
257: }
258:
259: function DoTest($test,$param,$hostname="",$timeout=-1,$params=0,$nodeid="")
260: {
261: global $NATS;
262: if (!is_array($params))
263: {
264: $params=array();
265: for ($a=0; $a<10; $a++) $params[$a]="";
266: }
267:
268: switch ($test)
269: {
270: case "web": case "wsize":
271: // Don't bother with pre-resolution as size only
272: return WebTest($param,$timeout);
273: break;
274: case "tcp": // nb TCP does not support timeouts currently
275: $ip=ip_lookup($hostname);
276: if ($ip=="0") return 0;
277: $fp=@fsockopen($ip,$param);
278: if ($fp<=0) return 0;
279: @fclose($fp);
280: return 1;
281: break;
282: case "wtime":
283: $timer=new TFNTimer();
284: // Do a pre-lookup
285: $ip=url_lookup($param);
286: if ($ip=="0") return -1; // dns lookup failed
287: $timer->Start();
288: $r=WebTest($param,$timeout);
289: $elapsedTime=$timer->Stop();
290: $elapsedTime=round($elapsedTime,4);
291: if ($r<0) return -1; // open failed
292: if ($r==0) return -2; // no chars shown as returned
293: if ($elapsedTime<=0) return 0.0001;
294: return $elapsedTime;
295: break;
296:
297: case "host":
298: $timer=new TFNTimer();
299: if (preg_match("/[a-zA-Z]/",$param)>0) $is_ip=false;
300: else $is_ip=true;
301:
302: $timer->Start();
303: if ($is_ip) $result=gethostbyaddr($param);
304: else $result=gethostbyname($param);
305: $elapsedTime=$timer->Stop();
306:
307: if ($result==$param) // lookup failed
308: return -1;
309:
310: if ($result=="") // lookup failed
311: return -1;
312:
313: $elapsedTime=round($elapsedTime,4);
314: if ($elapsedTime<=0) return 0.0001;
315: return $elapsedTime;
316: break;
317:
318: case "dns":
319: $timer=new TFNTimer();
320: if ($param=="") $dnsserver=$hostname;
321: else $dnsserver=$param;
322: if ($dnsserver=="") return -3;
323: if ($timeout<=0) $timeout=60;
324: if ($params[4]==1) $udp=false; // use TCP
325: else $udp=true;
326: if (($params[3]=="")||($params[3]==0)) $port=53;
327: else $port=$params[3];
328:
329: $dns_query=new DNSQuery($dnsserver,$port,$timeout,$udp,false); // run with debug off
330: $type=$params[2];
331: $query=$params[1];
332:
333: $timer->Start();
334: $answer=$dns_query->Query($query,$type);
335: $elapsedTime=$timer->Stop();
336:
337: if ( ($answer===false) || ($dns_query->error) ) return -2; // query error
338: if ($answer->count<=0) return -1; // no records returned
339:
340: // otherwise we've got some results ok
341: $elapsedTime=round($elapsedTime,4);
342: if ($elapsedTime<=0) return 0.0001;
343: return $elapsedTime;
344: break;
345:
346: case "testloop":
347: return $param;
348: break;
349:
350: case "testrand":
351: mt_srand(microtime()*1000000);
352: if ( ($param=="") || ($param==0) ) $param=100;
353: return mt_rand(0,$param);
354: break;
355:
356: case "ping":
357: return PingTest($param,$timeout);
358: break;
359: /* // now handled as a module
360: case "smtp":
361: $ip=ip_lookup($param);
362: if ($ip=="0") return -1;
363: return smtp_test_time($ip,$params[1],$timeout);
364: break;
365: */
366: case "imap":
367: if ($params[5]==1) $ssl=true;
368: else $ssl=false;
369:
370: $ip=ip_lookup($param);
371: if ($ip=="0") return -1;
372:
373: return imap_test_time($ip,$params[1],$params[2],$timeout,$params[3],$params[4],$ssl);
374: break;
375:
376: case "mysql":
377: $ip=ip_lookup($param);
378: if ($ip=="0") return -1; // cache only as 127.0.0.1 is not the same connection as localhost for MySQL auth!
379:
380: return mysql_test_time($param,$params[1],$params[2],$params[3],$timeout,$params[4]);
381: break;
382:
383: case "mysqlrows":
384: $ip=ip_lookup($param);
385: if ($ip=="0") return -1; // cache only - see above
386: return mysql_test_rows($param,$params[1],$params[2],$params[3],$timeout,$params[4]);
387: break;
388:
389: default:
390: if (isset($NATS)) // try and see if a test is registered
391: {
392: if (isset($NATS->Tests->QuickList[$test])) // exists
393: {
394: $NATS->Tests->Tests[$test]->Create();
395: return $NATS->Tests->Tests[$test]->instance->DoTest($test,$param,$hostname,$timeout,$params);
396: }
397: }
398:
399: }
400: return -1; // did not run any test so untested
401: }
402:
403: function SimpleEval($test,$result)
404: {
405: global $NATS;
406: switch($test)
407: {
408: case "ping": // handles both types of simple evaluation (inbuilt ICMP and remote ping)
409: if ($result<=0) return 2;
410: return 0;
411: case "web": case "wsize":
412: if ($result<=0) return 2;
413: return 0;
414: case "tcp":
415: if ($result==1) return 0;
416: return 2;
417: case "wtime":
418: if ($result<0) return 2;
419: return 0;
420:
421: case "imap":
422: if ($result<=0) return 2;
423: return 0;
424: /*
425: case "smtp":
426: if ($result<=0) return 2;
427: return 0;
428: */
429: case "mysql":
430: if ($result<=0) return 2;
431: return 0;
432:
433: case "mysqlrows":
434: if ($result<=0) return 2; // no rows returned or error
435: return 0;
436:
437: case "host": case "dns":
438: if ($result<=0) return 2; // no records returned or error
439:
440: case "testloop":
441: return 0;
442: case "testrand":
443: return 0;
444:
445: default:
446: if (isset($NATS))
447: {
448: if (isset($NATS->Tests->QuickList[$test]))
449: {
450: $NATS->Tests->Tests[$test]->Create();
451: return $NATS->Tests->Tests[$test]->instance->Evaluate($result);
452: }
453: }
454: }
455: return -1; // untested if we don't know WTF the result was
456: }
457:
458: function aText($al)
459: {
460: return oText($al); // uses function in tests.inc.php with site config support
461: /* -- depreciated
462: switch($al)
463: {
464: case -1: return "Untested";
465: case 0: return "Passed";
466: case 1: return "Warning";
467: case 2: return "Failed";
468: default: return "Unknown";
469: }
470: */
471: }
472: ?>