diff options
Diffstat (limited to 'deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js')
-rwxr-xr-x | deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js | 817 |
1 files changed, 409 insertions, 408 deletions
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js index c680e2ebb5..e492cd9386 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/lib/index.js @@ -1,408 +1,409 @@ -// Load modules
-
-var Dgram = require('dgram');
-var Dns = require('dns');
-var Hoek = require('hoek');
-
-
-// Declare internals
-
-var internals = {};
-
-
-exports.time = function (options, callback) {
-
- if (arguments.length !== 2) {
- callback = arguments[0];
- options = {};
- }
-
- var settings = Hoek.clone(options);
- settings.host = settings.host || 'pool.ntp.org';
- settings.port = settings.port || 123;
- settings.resolveReference = settings.resolveReference || false;
-
- // Declare variables used by callback
-
- var timeoutId = 0;
- var sent = 0;
-
- // Ensure callback is only called once
-
- var isFinished = false;
- var finish = function (err, result) {
-
- if (timeoutId) {
- clearTimeout(timeoutId);
- timeoutId = 0;
- }
-
- if (!isFinished) {
- isFinished = true;
- socket.close();
- return callback(err, result);
- }
- };
-
- // Create UDP socket
-
- var socket = Dgram.createSocket('udp4');
-
- socket.on('error', function (err) {
-
- return finish(err);
- });
-
- // Listen to incoming messages
-
- socket.on('message', function (buffer, rinfo) {
-
- var received = Date.now();
-
- var message = new internals.NtpMessage(buffer);
- if (!message.isValid) {
- return finish(new Error('Invalid server response'), message);
- }
-
- if (message.originateTimestamp !== sent) {
- return finish(new Error('Wrong originate timestamp'), message);
- }
-
- // Timestamp Name ID When Generated
- // ------------------------------------------------------------
- // Originate Timestamp T1 time request sent by client
- // Receive Timestamp T2 time request received by server
- // Transmit Timestamp T3 time reply sent by server
- // Destination Timestamp T4 time reply received by client
- //
- // The roundtrip delay d and system clock offset t are defined as:
- //
- // d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2
-
- var T1 = message.originateTimestamp;
- var T2 = message.receiveTimestamp;
- var T3 = message.transmitTimestamp;
- var T4 = received;
-
- message.d = (T4 - T1) - (T3 - T2);
- message.t = ((T2 - T1) + (T3 - T4)) / 2;
- message.receivedLocally = received;
-
- if (!settings.resolveReference ||
- message.stratum !== 'secondary') {
-
- return finish(null, message);
- }
-
- // Resolve reference IP address
-
- Dns.reverse(message.referenceId, function (err, domains) {
-
- if (!err) {
- message.referenceHost = domains[0];
- }
-
- return finish(null, message);
- });
- });
-
- // Set timeout
-
- if (settings.timeout) {
- timeoutId = setTimeout(function () {
-
- timeoutId = 0;
- return finish(new Error('Timeout'));
- }, settings.timeout);
- }
-
- // Construct NTP message
-
- var message = new Buffer(48);
- for (var i = 0; i < 48; i++) { // Zero message
- message[i] = 0;
- }
-
- message[0] = (0 << 6) + (4 << 3) + (3 << 0) // Set version number to 4 and Mode to 3 (client)
- sent = Date.now();
- internals.fromMsecs(sent, message, 40); // Set transmit timestamp (returns as originate)
-
- // Send NTP request
-
- socket.send(message, 0, message.length, settings.port, settings.host, function (err, bytes) {
-
- if (err ||
- bytes !== 48) {
-
- return finish(err || new Error('Could not send entire message'));
- }
- });
-};
-
-
-internals.NtpMessage = function (buffer) {
-
- this.isValid = false;
-
- // Validate
-
- if (buffer.length !== 48) {
- return;
- }
-
- // Leap indicator
-
- var li = (buffer[0] >> 6);
- switch (li) {
- case 0: this.leapIndicator = 'no-warning'; break;
- case 1: this.leapIndicator = 'last-minute-61'; break;
- case 2: this.leapIndicator = 'last-minute-59'; break;
- case 3: this.leapIndicator = 'alarm'; break;
- }
-
- // Version
-
- var vn = ((buffer[0] & 0x38) >> 3);
- this.version = vn;
-
- // Mode
-
- var mode = (buffer[0] & 0x7);
- switch (mode) {
- case 1: this.mode = 'symmetric-active'; break;
- case 2: this.mode = 'symmetric-passive'; break;
- case 3: this.mode = 'client'; break;
- case 4: this.mode = 'server'; break;
- case 5: this.mode = 'broadcast'; break;
- case 0:
- case 6:
- case 7: this.mode = 'reserved'; break;
- }
-
- // Stratum
-
- var stratum = buffer[1];
- if (stratum === 0) {
- this.stratum = 'death';
- }
- else if (stratum === 1) {
- this.stratum = 'primary';
- }
- else if (stratum <= 15) {
- this.stratum = 'secondary';
- }
- else {
- this.stratum = 'reserved';
- }
-
- // Poll interval (msec)
-
- this.pollInterval = Math.round(Math.pow(2, buffer[2])) * 1000;
-
- // Precision (msecs)
-
- this.precision = Math.pow(2, buffer[3]) * 1000;
-
- // Root delay (msecs)
-
- var rootDelay = 256 * (256 * (256 * buffer[4] + buffer[5]) + buffer[6]) + buffer[7];
- this.rootDelay = 1000 * (rootDelay / 0x10000);
-
- // Root dispersion (msecs)
-
- this.rootDispersion = ((buffer[8] << 8) + buffer[9] + ((buffer[10] << 8) + buffer[11]) / Math.pow(2, 16)) * 1000;
-
- // Reference identifier
-
- this.referenceId = '';
- switch (this.stratum) {
- case 'death':
- case 'primary':
- this.referenceId = String.fromCharCode(buffer[12]) + String.fromCharCode(buffer[13]) + String.fromCharCode(buffer[14]) + String.fromCharCode(buffer[15]);
- break;
- case 'secondary':
- this.referenceId = '' + buffer[12] + '.' + buffer[13] + '.' + buffer[14] + '.' + buffer[15];
- break;
- }
-
- // Reference timestamp
-
- this.referenceTimestamp = internals.toMsecs(buffer, 16);
-
- // Originate timestamp
-
- this.originateTimestamp = internals.toMsecs(buffer, 24);
-
- // Receive timestamp
-
- this.receiveTimestamp = internals.toMsecs(buffer, 32);
-
- // Transmit timestamp
-
- this.transmitTimestamp = internals.toMsecs(buffer, 40);
-
- // Validate
-
- if (this.version === 4 &&
- this.stratum !== 'reserved' &&
- this.mode === 'server' &&
- this.originateTimestamp &&
- this.receiveTimestamp &&
- this.transmitTimestamp) {
-
- this.isValid = true;
- }
-
- return this;
-};
-
-
-internals.toMsecs = function (buffer, offset) {
-
- var seconds = 0;
- var fraction = 0;
-
- for (var i = 0; i < 4; ++i) {
- seconds = (seconds * 256) + buffer[offset + i];
- }
-
- for (i = 4; i < 8; ++i) {
- fraction = (fraction * 256) + buffer[offset + i];
- }
-
- return ((seconds - 2208988800 + (fraction / Math.pow(2, 32))) * 1000);
-};
-
-
-internals.fromMsecs = function (ts, buffer, offset) {
-
- var seconds = Math.floor(ts / 1000) + 2208988800;
- var fraction = Math.round((ts % 1000) / 1000 * Math.pow(2, 32));
-
- buffer[offset + 0] = (seconds & 0xFF000000) >> 24;
- buffer[offset + 1] = (seconds & 0x00FF0000) >> 16;
- buffer[offset + 2] = (seconds & 0x0000FF00) >> 8;
- buffer[offset + 3] = (seconds & 0x000000FF);
-
- buffer[offset + 4] = (fraction & 0xFF000000) >> 24;
- buffer[offset + 5] = (fraction & 0x00FF0000) >> 16;
- buffer[offset + 6] = (fraction & 0x0000FF00) >> 8;
- buffer[offset + 7] = (fraction & 0x000000FF);
-};
-
-
-// Offset singleton
-
-internals.last = {
- offset: 0,
- expires: 0,
- host: '',
- port: 0
-};
-
-
-exports.offset = function (options, callback) {
-
- if (arguments.length !== 2) {
- callback = arguments[0];
- options = {};
- }
-
- var now = Date.now();
- var clockSyncRefresh = options.clockSyncRefresh || 24 * 60 * 60 * 1000; // Daily
-
- if (internals.last.offset &&
- internals.last.host === options.host &&
- internals.last.port === options.port &&
- now < internals.last.expires) {
-
- process.nextTick(function () {
-
- callback(null, internals.last.offset);
- });
-
- return;
- }
-
- exports.time(options, function (err, time) {
-
- if (err) {
- return callback(err, 0);
- }
-
- internals.last = {
- offset: Math.round(time.t),
- expires: now + clockSyncRefresh,
- host: options.host,
- port: options.port
- };
-
- return callback(null, internals.last.offset);
- });
-};
-
-
-// Now singleton
-
-internals.now = {
- intervalId: 0
-};
-
-
-exports.start = function (options, callback) {
-
- if (arguments.length !== 2) {
- callback = arguments[0];
- options = {};
- }
-
- if (internals.now.intervalId) {
- process.nextTick(function () {
-
- callback();
- });
-
- return;
- }
-
- exports.offset(options, function (err, offset) {
-
- internals.now.intervalId = setInterval(function () {
-
- exports.offset(options, function () { });
- }, options.clockSyncRefresh || 24 * 60 * 60 * 1000); // Daily
-
- return callback();
- });
-};
-
-
-exports.stop = function () {
-
- if (!internals.now.intervalId) {
- return;
- }
-
- clearInterval(internals.now.intervalId);
- internals.now.intervalId = 0;
-};
-
-
-exports.isLive = function () {
-
- return !!internals.now.intervalId;
-};
-
-
-exports.now = function () {
-
- var now = Date.now();
- if (!exports.isLive() ||
- now >= internals.last.expires) {
-
- return now;
- }
-
- return now + internals.last.offset;
-};
-
+// Load modules + +var Dgram = require('dgram'); +var Dns = require('dns'); +var Hoek = require('hoek'); + + +// Declare internals + +var internals = {}; + + +exports.time = function (options, callback) { + + if (arguments.length !== 2) { + callback = arguments[0]; + options = {}; + } + + var settings = Hoek.clone(options); + settings.host = settings.host || 'pool.ntp.org'; + settings.port = settings.port || 123; + settings.resolveReference = settings.resolveReference || false; + + // Declare variables used by callback + + var timeoutId = 0; + var sent = 0; + + // Ensure callback is only called once + + var isFinished = false; + var finish = function (err, result) { + + if (timeoutId) { + clearTimeout(timeoutId); + timeoutId = 0; + } + + if (!isFinished) { + isFinished = true; + socket.removeAllListeners(); + socket.close(); + return callback(err, result); + } + }; + + // Create UDP socket + + var socket = Dgram.createSocket('udp4'); + + socket.once('error', function (err) { + + return finish(err); + }); + + // Listen to incoming messages + + socket.on('message', function (buffer, rinfo) { + + var received = Date.now(); + + var message = new internals.NtpMessage(buffer); + if (!message.isValid) { + return finish(new Error('Invalid server response'), message); + } + + if (message.originateTimestamp !== sent) { + return finish(new Error('Wrong originate timestamp'), message); + } + + // Timestamp Name ID When Generated + // ------------------------------------------------------------ + // Originate Timestamp T1 time request sent by client + // Receive Timestamp T2 time request received by server + // Transmit Timestamp T3 time reply sent by server + // Destination Timestamp T4 time reply received by client + // + // The roundtrip delay d and system clock offset t are defined as: + // + // d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2 + + var T1 = message.originateTimestamp; + var T2 = message.receiveTimestamp; + var T3 = message.transmitTimestamp; + var T4 = received; + + message.d = (T4 - T1) - (T3 - T2); + message.t = ((T2 - T1) + (T3 - T4)) / 2; + message.receivedLocally = received; + + if (!settings.resolveReference || + message.stratum !== 'secondary') { + + return finish(null, message); + } + + // Resolve reference IP address + + Dns.reverse(message.referenceId, function (err, domains) { + + if (!err) { + message.referenceHost = domains[0]; + } + + return finish(null, message); + }); + }); + + // Set timeout + + if (settings.timeout) { + timeoutId = setTimeout(function () { + + timeoutId = 0; + return finish(new Error('Timeout')); + }, settings.timeout); + } + + // Construct NTP message + + var message = new Buffer(48); + for (var i = 0; i < 48; i++) { // Zero message + message[i] = 0; + } + + message[0] = (0 << 6) + (4 << 3) + (3 << 0) // Set version number to 4 and Mode to 3 (client) + sent = Date.now(); + internals.fromMsecs(sent, message, 40); // Set transmit timestamp (returns as originate) + + // Send NTP request + + socket.send(message, 0, message.length, settings.port, settings.host, function (err, bytes) { + + if (err || + bytes !== 48) { + + return finish(err || new Error('Could not send entire message')); + } + }); +}; + + +internals.NtpMessage = function (buffer) { + + this.isValid = false; + + // Validate + + if (buffer.length !== 48) { + return; + } + + // Leap indicator + + var li = (buffer[0] >> 6); + switch (li) { + case 0: this.leapIndicator = 'no-warning'; break; + case 1: this.leapIndicator = 'last-minute-61'; break; + case 2: this.leapIndicator = 'last-minute-59'; break; + case 3: this.leapIndicator = 'alarm'; break; + } + + // Version + + var vn = ((buffer[0] & 0x38) >> 3); + this.version = vn; + + // Mode + + var mode = (buffer[0] & 0x7); + switch (mode) { + case 1: this.mode = 'symmetric-active'; break; + case 2: this.mode = 'symmetric-passive'; break; + case 3: this.mode = 'client'; break; + case 4: this.mode = 'server'; break; + case 5: this.mode = 'broadcast'; break; + case 0: + case 6: + case 7: this.mode = 'reserved'; break; + } + + // Stratum + + var stratum = buffer[1]; + if (stratum === 0) { + this.stratum = 'death'; + } + else if (stratum === 1) { + this.stratum = 'primary'; + } + else if (stratum <= 15) { + this.stratum = 'secondary'; + } + else { + this.stratum = 'reserved'; + } + + // Poll interval (msec) + + this.pollInterval = Math.round(Math.pow(2, buffer[2])) * 1000; + + // Precision (msecs) + + this.precision = Math.pow(2, buffer[3]) * 1000; + + // Root delay (msecs) + + var rootDelay = 256 * (256 * (256 * buffer[4] + buffer[5]) + buffer[6]) + buffer[7]; + this.rootDelay = 1000 * (rootDelay / 0x10000); + + // Root dispersion (msecs) + + this.rootDispersion = ((buffer[8] << 8) + buffer[9] + ((buffer[10] << 8) + buffer[11]) / Math.pow(2, 16)) * 1000; + + // Reference identifier + + this.referenceId = ''; + switch (this.stratum) { + case 'death': + case 'primary': + this.referenceId = String.fromCharCode(buffer[12]) + String.fromCharCode(buffer[13]) + String.fromCharCode(buffer[14]) + String.fromCharCode(buffer[15]); + break; + case 'secondary': + this.referenceId = '' + buffer[12] + '.' + buffer[13] + '.' + buffer[14] + '.' + buffer[15]; + break; + } + + // Reference timestamp + + this.referenceTimestamp = internals.toMsecs(buffer, 16); + + // Originate timestamp + + this.originateTimestamp = internals.toMsecs(buffer, 24); + + // Receive timestamp + + this.receiveTimestamp = internals.toMsecs(buffer, 32); + + // Transmit timestamp + + this.transmitTimestamp = internals.toMsecs(buffer, 40); + + // Validate + + if (this.version === 4 && + this.stratum !== 'reserved' && + this.mode === 'server' && + this.originateTimestamp && + this.receiveTimestamp && + this.transmitTimestamp) { + + this.isValid = true; + } + + return this; +}; + + +internals.toMsecs = function (buffer, offset) { + + var seconds = 0; + var fraction = 0; + + for (var i = 0; i < 4; ++i) { + seconds = (seconds * 256) + buffer[offset + i]; + } + + for (i = 4; i < 8; ++i) { + fraction = (fraction * 256) + buffer[offset + i]; + } + + return ((seconds - 2208988800 + (fraction / Math.pow(2, 32))) * 1000); +}; + + +internals.fromMsecs = function (ts, buffer, offset) { + + var seconds = Math.floor(ts / 1000) + 2208988800; + var fraction = Math.round((ts % 1000) / 1000 * Math.pow(2, 32)); + + buffer[offset + 0] = (seconds & 0xFF000000) >> 24; + buffer[offset + 1] = (seconds & 0x00FF0000) >> 16; + buffer[offset + 2] = (seconds & 0x0000FF00) >> 8; + buffer[offset + 3] = (seconds & 0x000000FF); + + buffer[offset + 4] = (fraction & 0xFF000000) >> 24; + buffer[offset + 5] = (fraction & 0x00FF0000) >> 16; + buffer[offset + 6] = (fraction & 0x0000FF00) >> 8; + buffer[offset + 7] = (fraction & 0x000000FF); +}; + + +// Offset singleton + +internals.last = { + offset: 0, + expires: 0, + host: '', + port: 0 +}; + + +exports.offset = function (options, callback) { + + if (arguments.length !== 2) { + callback = arguments[0]; + options = {}; + } + + var now = Date.now(); + var clockSyncRefresh = options.clockSyncRefresh || 24 * 60 * 60 * 1000; // Daily + + if (internals.last.offset && + internals.last.host === options.host && + internals.last.port === options.port && + now < internals.last.expires) { + + process.nextTick(function () { + + callback(null, internals.last.offset); + }); + + return; + } + + exports.time(options, function (err, time) { + + if (err) { + return callback(err, 0); + } + + internals.last = { + offset: Math.round(time.t), + expires: now + clockSyncRefresh, + host: options.host, + port: options.port + }; + + return callback(null, internals.last.offset); + }); +}; + + +// Now singleton + +internals.now = { + intervalId: 0 +}; + + +exports.start = function (options, callback) { + + if (arguments.length !== 2) { + callback = arguments[0]; + options = {}; + } + + if (internals.now.intervalId) { + process.nextTick(function () { + + callback(); + }); + + return; + } + + exports.offset(options, function (err, offset) { + + internals.now.intervalId = setInterval(function () { + + exports.offset(options, function () { }); + }, options.clockSyncRefresh || 24 * 60 * 60 * 1000); // Daily + + return callback(); + }); +}; + + +exports.stop = function () { + + if (!internals.now.intervalId) { + return; + } + + clearInterval(internals.now.intervalId); + internals.now.intervalId = 0; +}; + + +exports.isLive = function () { + + return !!internals.now.intervalId; +}; + + +exports.now = function () { + + var now = Date.now(); + if (!exports.isLive() || + now >= internals.last.expires) { + + return now; + } + + return now + internals.last.offset; +}; + |