diff options
Diffstat (limited to 'library/vendor/Zend/TimeSync')
-rw-r--r-- | library/vendor/Zend/TimeSync/Exception.php | 63 | ||||
-rw-r--r-- | library/vendor/Zend/TimeSync/Ntp.php | 430 | ||||
-rw-r--r-- | library/vendor/Zend/TimeSync/Protocol.php | 148 | ||||
-rw-r--r-- | library/vendor/Zend/TimeSync/Sntp.php | 118 |
4 files changed, 759 insertions, 0 deletions
diff --git a/library/vendor/Zend/TimeSync/Exception.php b/library/vendor/Zend/TimeSync/Exception.php new file mode 100644 index 0000000..c1a33e4 --- /dev/null +++ b/library/vendor/Zend/TimeSync/Exception.php @@ -0,0 +1,63 @@ +<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_TimeSync + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * Zend_Exception + */ + +/** + * Exception class for Zend_TimeSync + * + * @category Zend + * @package Zend_TimeSync + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_TimeSync_Exception extends Zend_Exception +{ + /** + * Contains array of exceptions thrown in queried server + * + * @var array + */ + protected $_exceptions; + + /** + * Adds an exception to the exception list + * + * @param Zend_TimeSync_Exception $exception New exteption to throw + * @return void + */ + public function addException(Zend_TimeSync_Exception $exception) + { + $this->_exceptions[] = $exception; + } + + /** + * Returns an array of exceptions that were thrown + * + * @return array + */ + public function get() + { + return $this->_exceptions; + } +} diff --git a/library/vendor/Zend/TimeSync/Ntp.php b/library/vendor/Zend/TimeSync/Ntp.php new file mode 100644 index 0000000..0c52530 --- /dev/null +++ b/library/vendor/Zend/TimeSync/Ntp.php @@ -0,0 +1,430 @@ +<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_TimeSync + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * Zend_TimeSync_Protocol + */ + +/** + * NTP Protocol handling class + * + * @category Zend + * @package Zend_TimeSync + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_TimeSync_Ntp extends Zend_TimeSync_Protocol +{ + /** + * NTP port number (123) assigned by the Internet Assigned Numbers Authority + * + * @var integer + */ + protected $_port = 123; + + /** + * NTP class constructor, sets the timeserver and port number + * + * @param string $timeserver Adress of the timeserver to connect to + * @param integer $port (Optional) Port for this timeserver + */ + public function __construct($timeserver, $port = 123) + { + $this->_timeserver = 'udp://' . $timeserver; + if ($port !== null) { + $this->_port = $port; + } + } + + /** + * Prepare local timestamp for transmission in our request packet + * + * NTP timestamps are represented as a 64-bit fixed-point number, in + * seconds relative to 0000 UT on 1 January 1900. The integer part is + * in the first 32 bits and the fraction part in the last 32 bits + * + * @return string + */ + protected function _prepare() + { + $frac = microtime(); + $fracba = ($frac & 0xff000000) >> 24; + $fracbb = ($frac & 0x00ff0000) >> 16; + $fracbc = ($frac & 0x0000ff00) >> 8; + $fracbd = ($frac & 0x000000ff); + + $sec = (time() + 2208988800); + $secba = ($sec & 0xff000000) >> 24; + $secbb = ($sec & 0x00ff0000) >> 16; + $secbc = ($sec & 0x0000ff00) >> 8; + $secbd = ($sec & 0x000000ff); + + // Flags + $nul = chr(0x00); + $nulbyte = $nul . $nul . $nul . $nul; + $ntppacket = chr(0xd9) . $nul . chr(0x0a) . chr(0xfa); + + /* + * Root delay + * + * Indicates the total roundtrip delay to the primary reference + * source at the root of the synchronization subnet, in seconds + */ + $ntppacket .= $nul . $nul . chr(0x1c) . chr(0x9b); + + /* + * Clock Dispersion + * + * Indicates the maximum error relative to the primary reference source at the + * root of the synchronization subnet, in seconds + */ + $ntppacket .= $nul . chr(0x08) . chr(0xd7) . chr(0xff); + + /* + * ReferenceClockID + * + * Identifying the particular reference clock + */ + $ntppacket .= $nulbyte; + + /* + * The local time, in timestamp format, at the peer when its latest NTP message + * was sent. Contanis an integer and a fractional part + */ + $ntppacket .= chr($secba) . chr($secbb) . chr($secbc) . chr($secbd); + $ntppacket .= chr($fracba) . chr($fracbb) . chr($fracbc) . chr($fracbd); + + /* + * The local time, in timestamp format, at the peer. Contains an integer + * and a fractional part. + */ + $ntppacket .= $nulbyte; + $ntppacket .= $nulbyte; + + /* + * This is the local time, in timestamp format, when the latest NTP message from + * the peer arrived. Contanis an integer and a fractional part. + */ + $ntppacket .= $nulbyte; + $ntppacket .= $nulbyte; + + /* + * The local time, in timestamp format, at which the + * NTP message departed the sender. Contanis an integer + * and a fractional part. + */ + $ntppacket .= chr($secba) . chr($secbb) . chr($secbc) . chr($secbd); + $ntppacket .= chr($fracba) . chr($fracbb) . chr($fracbc) . chr($fracbd); + + return $ntppacket; + } + + /** + * Calculates a 32bit integer + * + * @param string $input + * @return integer + */ + protected function _getInteger($input) + { + $f1 = str_pad(ord($input[0]), 2, '0', STR_PAD_LEFT); + $f1 .= str_pad(ord($input[1]), 2, '0', STR_PAD_LEFT); + $f1 .= str_pad(ord($input[2]), 2, '0', STR_PAD_LEFT); + $f1 .= str_pad(ord($input[3]), 2, '0', STR_PAD_LEFT); + return (int) $f1; + } + + /** + * Calculates a 32bit signed fixed point number + * + * @param string $input + * @return float + */ + protected function _getFloat($input) + { + $f1 = str_pad(ord($input[0]), 2, '0', STR_PAD_LEFT); + $f1 .= str_pad(ord($input[1]), 2, '0', STR_PAD_LEFT); + $f1 .= str_pad(ord($input[2]), 2, '0', STR_PAD_LEFT); + $f1 .= str_pad(ord($input[3]), 2, '0', STR_PAD_LEFT); + $f2 = $f1 >> 17; + $f3 = ($f1 & 0x0001FFFF); + $f1 = $f2 . '.' . $f3; + return (float) $f1; + } + + /** + * Calculates a 64bit timestamp + * + * @param string $input + * @return float + */ + protected function _getTimestamp($input) + { + $f1 = (ord($input[0]) * pow(256, 3)); + $f1 += (ord($input[1]) * pow(256, 2)); + $f1 += (ord($input[2]) * pow(256, 1)); + $f1 += (ord($input[3])); + $f1 -= 2208988800; + + $f2 = (ord($input[4]) * pow(256, 3)); + $f2 += (ord($input[5]) * pow(256, 2)); + $f2 += (ord($input[6]) * pow(256, 1)); + $f2 += (ord($input[7])); + + return (float) ($f1 . "." . $f2); + } + + /** + * Reads the data returned from the timeserver + * + * This will return an array with binary data listing: + * + * @return array + * @throws Zend_TimeSync_Exception When timeserver can not be connected + */ + protected function _read() + { + $flags = ord(fread($this->_socket, 1)); + $info = stream_get_meta_data($this->_socket); + + if ($info['timed_out'] === true) { + fclose($this->_socket); + throw new Zend_TimeSync_Exception('could not connect to ' . + "'$this->_timeserver' on port '$this->_port', reason: 'server timed out'"); + } + + $result = array( + 'flags' => $flags, + 'stratum' => ord(fread($this->_socket, 1)), + 'poll' => ord(fread($this->_socket, 1)), + 'precision' => ord(fread($this->_socket, 1)), + 'rootdelay' => $this->_getFloat(fread($this->_socket, 4)), + 'rootdispersion' => $this->_getFloat(fread($this->_socket, 4)), + 'referenceid' => fread($this->_socket, 4), + 'referencestamp' => $this->_getTimestamp(fread($this->_socket, 8)), + 'originatestamp' => $this->_getTimestamp(fread($this->_socket, 8)), + 'receivestamp' => $this->_getTimestamp(fread($this->_socket, 8)), + 'transmitstamp' => $this->_getTimestamp(fread($this->_socket, 8)), + 'clientreceived' => microtime(true) + ); + + $this->_disconnect(); + return $result; + } + + /** + * Sends the NTP packet to the server + * + * @param string $data Data to send to the timeserver + * @return void + */ + protected function _write($data) + { + $this->_connect(); + + fwrite($this->_socket, $data); + stream_set_timeout($this->_socket, Zend_TimeSync::$options['timeout']); + } + + /** + * Extracts the binary data returned from the timeserver + * + * @param string|array $binary Data returned from the timeserver + * @return integer Difference in seconds + */ + protected function _extract($binary) + { + /* + * Leap Indicator bit 1100 0000 + * + * Code warning of impending leap-second to be inserted at the end of + * the last day of the current month. + */ + $leap = ($binary['flags'] & 0xc0) >> 6; + switch($leap) { + case 0: + $this->_info['leap'] = '0 - no warning'; + break; + + case 1: + $this->_info['leap'] = '1 - last minute has 61 seconds'; + break; + + case 2: + $this->_info['leap'] = '2 - last minute has 59 seconds'; + break; + + default: + $this->_info['leap'] = '3 - not syncronised'; + break; + } + + /* + * Version Number bit 0011 1000 + * + * This should be 3 (RFC 1305) + */ + $this->_info['version'] = ($binary['flags'] & 0x38) >> 3; + + /* + * Mode bit 0000 0111 + * + * Except in broadcast mode, an NTP association is formed when two peers + * exchange messages and one or both of them create and maintain an + * instantiation of the protocol machine, called an association. + */ + $mode = ($binary['flags'] & 0x07); + switch($mode) { + case 1: + $this->_info['mode'] = 'symetric active'; + break; + + case 2: + $this->_info['mode'] = 'symetric passive'; + break; + + case 3: + $this->_info['mode'] = 'client'; + break; + + case 4: + $this->_info['mode'] = 'server'; + break; + + case 5: + $this->_info['mode'] = 'broadcast'; + break; + + default: + $this->_info['mode'] = 'reserved'; + break; + } + + $ntpserviceid = 'Unknown Stratum ' . $binary['stratum'] . ' Service'; + + /* + * Reference Clock Identifier + * + * Identifies the particular reference clock. + */ + $refid = strtoupper($binary['referenceid']); + switch($binary['stratum']) { + case 0: + if (substr($refid, 0, 3) === 'DCN') { + $ntpserviceid = 'DCN routing protocol'; + } else if (substr($refid, 0, 4) === 'NIST') { + $ntpserviceid = 'NIST public modem'; + } else if (substr($refid, 0, 3) === 'TSP') { + $ntpserviceid = 'TSP time protocol'; + } else if (substr($refid, 0, 3) === 'DTS') { + $ntpserviceid = 'Digital Time Service'; + } + break; + + case 1: + if (substr($refid, 0, 4) === 'ATOM') { + $ntpserviceid = 'Atomic Clock (calibrated)'; + } else if (substr($refid, 0, 3) === 'VLF') { + $ntpserviceid = 'VLF radio'; + } else if ($refid === 'CALLSIGN') { + $ntpserviceid = 'Generic radio'; + } else if (substr($refid, 0, 4) === 'LORC') { + $ntpserviceid = 'LORAN-C radionavigation'; + } else if (substr($refid, 0, 4) === 'GOES') { + $ntpserviceid = 'GOES UHF environment satellite'; + } else if (substr($refid, 0, 3) === 'GPS') { + $ntpserviceid = 'GPS UHF satellite positioning'; + } + break; + + default: + $ntpserviceid = ord(substr($binary['referenceid'], 0, 1)); + $ntpserviceid .= '.'; + $ntpserviceid .= ord(substr($binary['referenceid'], 1, 1)); + $ntpserviceid .= '.'; + $ntpserviceid .= ord(substr($binary['referenceid'], 2, 1)); + $ntpserviceid .= '.'; + $ntpserviceid .= ord(substr($binary['referenceid'], 3, 1)); + break; + } + + $this->_info['ntpid'] = $ntpserviceid; + + /* + * Stratum + * + * Indicates the stratum level of the local clock + */ + switch($binary['stratum']) { + case 0: + $this->_info['stratum'] = 'undefined'; + break; + + case 1: + $this->_info['stratum'] = 'primary reference'; + break; + + default: + $this->_info['stratum'] = 'secondary reference'; + break; + } + + /* + * Indicates the total roundtrip delay to the primary reference source at the + * root of the synchronization subnet, in seconds. + * + * Both positive and negative values, depending on clock precision and skew, are + * possible. + */ + $this->_info['rootdelay'] = $binary['rootdelay']; + + /* + * Indicates the maximum error relative to the primary reference source at the + * root of the synchronization subnet, in seconds. + * + * Only positive values greater than zero are possible. + */ + $this->_info['rootdispersion'] = $binary['rootdispersion']; + + /* + * The roundtrip delay of the peer clock relative to the local clock + * over the network path between them, in seconds. + * + * Note that this variable can take on both positive and negative values, + * depending on clock precision and skew-error accumulation. + */ + $this->_info['roundtrip'] = $binary['receivestamp']; + $this->_info['roundtrip'] -= $binary['originatestamp']; + $this->_info['roundtrip'] -= $binary['transmitstamp']; + $this->_info['roundtrip'] += $binary['clientreceived']; + $this->_info['roundtrip'] /= 2; + + // The offset of the peer clock relative to the local clock, in seconds. + $this->_info['offset'] = $binary['receivestamp']; + $this->_info['offset'] -= $binary['originatestamp']; + $this->_info['offset'] += $binary['transmitstamp']; + $this->_info['offset'] -= $binary['clientreceived']; + $this->_info['offset'] /= 2; + $time = (time() - $this->_info['offset']); + + return $time; + } +} diff --git a/library/vendor/Zend/TimeSync/Protocol.php b/library/vendor/Zend/TimeSync/Protocol.php new file mode 100644 index 0000000..12dc6d9 --- /dev/null +++ b/library/vendor/Zend/TimeSync/Protocol.php @@ -0,0 +1,148 @@ +<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_TimeSync + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * Abstract class definition for all timeserver protocols + * + * @category Zend + * @package Zend_TimeSync + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +abstract class Zend_TimeSync_Protocol +{ + /** + * Holds the current socket connection + * + * @var array + */ + protected $_socket; + + /** + * Exceptions that might have occured + * + * @var array + */ + protected $_exceptions; + + /** + * Hostname for timeserver + * + * @var string + */ + protected $_timeserver; + + /** + * Holds information passed/returned from timeserver + * + * @var array + */ + protected $_info = array(); + + /** + * Abstract method that prepares the data to send to the timeserver + * + * @return mixed + */ + abstract protected function _prepare(); + + /** + * Abstract method that reads the data returned from the timeserver + * + * @return mixed + */ + abstract protected function _read(); + + /** + * Abstract method that writes data to to the timeserver + * + * @param string $data Data to write + * @return void + */ + abstract protected function _write($data); + + /** + * Abstract method that extracts the binary data returned from the timeserver + * + * @param string|array $data Data returned from the timeserver + * @return integer + */ + abstract protected function _extract($data); + + /** + * Connect to the specified timeserver. + * + * @return void + * @throws Zend_TimeSync_Exception When the connection failed + */ + protected function _connect() + { + $socket = @fsockopen($this->_timeserver, $this->_port, $errno, $errstr, + Zend_TimeSync::$options['timeout']); + if ($socket === false) { + throw new Zend_TimeSync_Exception('could not connect to ' . + "'$this->_timeserver' on port '$this->_port', reason: '$errstr'"); + } + + $this->_socket = $socket; + } + + /** + * Disconnects from the peer, closes the socket. + * + * @return void + */ + protected function _disconnect() + { + @fclose($this->_socket); + $this->_socket = null; + } + + /** + * Return information sent/returned from the timeserver + * + * @return array + */ + public function getInfo() + { + if (empty($this->_info) === true) { + $this->_write($this->_prepare()); + $timestamp = $this->_extract($this->_read()); + } + + return $this->_info; + } + + /** + * Query this timeserver without using the fallback mechanism + * + * @param string|Zend_Locale $locale (Optional) Locale + * @return Zend_Date + */ + public function getDate($locale = null) + { + $this->_write($this->_prepare()); + $timestamp = $this->_extract($this->_read()); + + $date = new Zend_Date($this, null, $locale); + return $date; + } +} diff --git a/library/vendor/Zend/TimeSync/Sntp.php b/library/vendor/Zend/TimeSync/Sntp.php new file mode 100644 index 0000000..6ad0a5e --- /dev/null +++ b/library/vendor/Zend/TimeSync/Sntp.php @@ -0,0 +1,118 @@ +<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_TimeSync + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ + +/** + * Zend_TimeSync_Protocol + */ + +/** + * SNTP Protocol handling class + * + * @category Zend + * @package Zend_TimeSync + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_TimeSync_Sntp extends Zend_TimeSync_Protocol +{ + /** + * Port number for this timeserver + * + * @var integer + */ + protected $_port = 37; + + /** + * Socket delay + * + * @var integer + */ + private $_delay; + + /** + * Class constructor, sets the timeserver and port number + * + * @param string $timeserver Timeserver to connect to + * @param integer $port Port of the timeserver when it differs from the default port + */ + public function __construct($timeserver, $port) + { + $this->_timeserver = 'udp://' . $timeserver; + if ($port !== null) { + $this->_port = $port; + } + } + + /** + * Prepares the data that will be send to the timeserver + * + * @return array + */ + protected function _prepare() + { + return "\n"; + } + + /** + * Reads the data returned from the timeserver + * + * @return string + */ + protected function _read() + { + $result = fread($this->_socket, 49); + $this->_delay = (($this->_delay - time()) / 2); + + return $result; + } + + /** + * Writes data to to the timeserver + * + * @param string $data Data to write to the timeserver + * @return void + */ + protected function _write($data) + { + $this->_connect(); + $this->_delay = time(); + fputs($this->_socket, $data); + } + + /** + * Extracts the data returned from the timeserver + * + * @param string $result Data to extract + * @return integer + */ + protected function _extract($result) + { + $dec = hexdec('7fffffff'); + $time = abs(($dec - hexdec(bin2hex($result))) - $dec); + $time -= 2208988800; + // Socket delay + $time -= $this->_delay; + + $this->_info['offset'] = $this->_delay; + + return $time; + } +} |