NTPTimeProvider.php 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. <?php
  2. namespace RobThree\Auth\Providers\Time;
  3. /**
  4. * Takes the time from any NTP server
  5. */
  6. class NTPTimeProvider implements ITimeProvider
  7. {
  8. public $host;
  9. public $port;
  10. public $timeout;
  11. function __construct($host = 'pool.ntp.org', $port = 123, $timeout = 1)
  12. {
  13. $this->host = $host;
  14. if (!is_int($port) || $port <= 0 || $port > 65535)
  15. throw new \TimeException('Port must be 0 < port < 65535');
  16. $this->port = $port;
  17. if (!is_int($timeout) || $timeout < 0)
  18. throw new \TimeException('Timeout must be >= 0');
  19. $this->timeout = $timeout;
  20. }
  21. public function getTime() {
  22. try {
  23. /* Create a socket and connect to NTP server */
  24. $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
  25. socket_connect($sock, $this->host, $this->port);
  26. /* Send request */
  27. $msg = "\010" . str_repeat("\0", 47);
  28. socket_send($sock, $msg, strlen($msg), 0);
  29. /* Receive response and close socket */
  30. socket_recv($sock, $recv, 48, MSG_WAITALL);
  31. socket_close($sock);
  32. /* Interpret response */
  33. $data = unpack('N12', $recv);
  34. $timestamp = sprintf('%u', $data[9]);
  35. /* NTP is number of seconds since 0000 UT on 1 January 1900 Unix time is seconds since 0000 UT on 1 January 1970 */
  36. return $timestamp - 2208988800;
  37. }
  38. catch (Exception $ex) {
  39. throw new \TimeException(sprintf('Unable to retrieve time from %s (%s)', $this->host, $ex->getMessage()));
  40. }
  41. }
  42. }