Merge branch 'dtrace'
This commit is contained in:
commit
5fe70eb739
12
lib/dn.js
12
lib/dn.js
|
@ -21,7 +21,17 @@ function isWhitespace(c) {
|
|||
return re.test(c);
|
||||
}
|
||||
|
||||
function RDN() {}
|
||||
function RDN(obj) {
|
||||
var self = this;
|
||||
|
||||
if (obj) {
|
||||
Object.keys(obj).forEach(function(k) {
|
||||
self[k] = obj[k];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RDN.prototype.toString = function() {
|
||||
var self = this;
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
||||
|
||||
var dtrace = require('dtrace-provider');
|
||||
|
||||
|
||||
|
||||
///--- Globals
|
||||
|
||||
var SERVER_PROVIDER;
|
||||
|
||||
/* Args:
|
||||
* 0 -> RequestId (<ip>:<src port>:<msgID>)
|
||||
* 1 -> remoteIP
|
||||
* 2 -> bindDN
|
||||
* 3 -> req.dn
|
||||
* 4,5 -> op specific
|
||||
*/
|
||||
var SERVER_PROBES = {
|
||||
|
||||
// 4: attributes.length
|
||||
add: ['char *', 'char *', 'char *', 'char *', 'int'],
|
||||
|
||||
bind: ['char *', 'char *', 'char *', 'char *'],
|
||||
|
||||
// 4: attribute, 5: value
|
||||
compare: ['char *', 'char *', 'char *', 'char *', 'char *', 'char *'],
|
||||
|
||||
'delete': ['char *', 'char *', 'char *', 'char *'],
|
||||
|
||||
// 4: requestName, 5: requestValue
|
||||
exop: ['char *', 'char *', 'char *', 'char *', 'char *', 'char *'],
|
||||
|
||||
// 4: changes.length
|
||||
modify: ['char *', 'char *', 'char *', 'char *', 'int'],
|
||||
|
||||
// 4: newRdn, 5: newSuperior
|
||||
modifyDN: ['char *', 'char *', 'char *', 'char *', 'char *', 'char *'],
|
||||
|
||||
// 4: filter, 5: scope
|
||||
search: ['char *', 'char *', 'char *', 'char *', 'char *', 'char *'],
|
||||
|
||||
unbind: ['char *', 'char *', 'char *', 'char *'],
|
||||
|
||||
// remote IP
|
||||
connection: ['char *'],
|
||||
|
||||
request: ['char *', 'char *', 'char *', 'char *'],
|
||||
|
||||
// requestId, remoteIp, bindDN, request.dn, statusCode, errorMessage
|
||||
response: ['char *', 'char *', 'char *', 'char *', 'int', 'char *']
|
||||
};
|
||||
|
||||
|
||||
///--- API
|
||||
|
||||
module.exports = function() {
|
||||
if (!SERVER_PROVIDER) {
|
||||
SERVER_PROVIDER = dtrace.createDTraceProvider('ldapjs');
|
||||
|
||||
Object.keys(SERVER_PROBES).forEach(function(p) {
|
||||
var args = SERVER_PROBES[p].splice(0);
|
||||
args.unshift(p);
|
||||
|
||||
dtrace.DTraceProvider.prototype.addProbe.apply(SERVER_PROVIDER, args);
|
||||
});
|
||||
|
||||
SERVER_PROVIDER.enable();
|
||||
}
|
||||
|
||||
return SERVER_PROVIDER;
|
||||
}();
|
||||
|
|
@ -8,7 +8,7 @@ var asn1 = require('asn1');
|
|||
var LDAPMessage = require('./message');
|
||||
|
||||
var Protocol = require('../protocol');
|
||||
|
||||
var dtrace = require('../dtrace');
|
||||
|
||||
|
||||
///--- Globals
|
||||
|
@ -17,6 +17,7 @@ var Ber = asn1.Ber;
|
|||
var BerWriter = asn1.BerWriter;
|
||||
|
||||
|
||||
|
||||
///--- API
|
||||
|
||||
function LDAPResult(options) {
|
||||
|
@ -66,11 +67,25 @@ LDAPResult.prototype.end = function(status) {
|
|||
this.log.debug('%s: sending: %j', this.connection.ldap.id, this.json);
|
||||
|
||||
try {
|
||||
var self = this;
|
||||
this.connection.write(ber);
|
||||
|
||||
dtrace.fire('response', function() {
|
||||
var c = self.connection || {ldap: {bindDN: ''}};
|
||||
return [
|
||||
(self.logId || ''),
|
||||
(c.remoteAddress || ''),
|
||||
c.ldap.bindDN.toString(),
|
||||
(self.requestDN ? self.requestDN.toString() : ''),
|
||||
self.status,
|
||||
self.errorMessage
|
||||
];
|
||||
});
|
||||
} catch (e) {
|
||||
this.log.warn('%s failure to write message %j: %s',
|
||||
this.connection.ldap.id, this.json, e.toString());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ var asn1 = require('asn1');
|
|||
var LDAPMessage = require('./message');
|
||||
var LDAPResult = require('./result');
|
||||
|
||||
var DN = require('../dn').DN;
|
||||
var dn = require('../dn');
|
||||
var Protocol = require('../protocol');
|
||||
|
||||
|
||||
|
@ -17,6 +17,8 @@ var Protocol = require('../protocol');
|
|||
|
||||
var Ber = asn1.Ber;
|
||||
|
||||
var DN = dn.DN;
|
||||
var RDN = dn.RDN;
|
||||
|
||||
|
||||
///--- API
|
||||
|
@ -32,8 +34,14 @@ function UnbindRequest(options) {
|
|||
options.protocolOp = Protocol.LDAP_REQ_UNBIND;
|
||||
LDAPMessage.call(this, options);
|
||||
|
||||
var self = this;
|
||||
this.__defineGetter__('type', function() { return 'UnbindRequest'; });
|
||||
this.__defineGetter__('_dn', function() { return new DN([{}]); });
|
||||
this.__defineGetter__('_dn', function() {
|
||||
if (self.connection)
|
||||
return self.connection.ldap.bindDN;
|
||||
|
||||
return new DN([new RDN({cn: 'anonymous'})]);
|
||||
});
|
||||
}
|
||||
util.inherits(UnbindRequest, LDAPMessage);
|
||||
module.exports = UnbindRequest;
|
||||
|
|
138
lib/server.js
138
lib/server.js
|
@ -10,6 +10,7 @@ var asn1 = require('asn1');
|
|||
var sprintf = require('sprintf').sprintf;
|
||||
|
||||
var dn = require('./dn');
|
||||
var dtrace = require('./dtrace');
|
||||
var errors = require('./errors');
|
||||
var Protocol = require('./protocol');
|
||||
var logStub = require('./log_stub');
|
||||
|
@ -173,6 +174,25 @@ function noExOpHandler(req, res, next) {
|
|||
}
|
||||
|
||||
|
||||
function getDTraceHander(op, cb1, cb2) {
|
||||
assert.ok(op);
|
||||
|
||||
return function(req, res, next) {
|
||||
dtrace.fire(op, function() {
|
||||
var c = req.connection;
|
||||
return [
|
||||
req.logId,
|
||||
c.remoteAddress,
|
||||
c.ldap.bindDN.toString(),
|
||||
req.dn.toString(),
|
||||
cb1 ? cb1(req, res) : undefined,
|
||||
cb2 ? cb2(req, res) : undefined
|
||||
];
|
||||
});
|
||||
return next();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///--- API
|
||||
|
||||
|
@ -226,9 +246,12 @@ function Server(options) {
|
|||
c.remotePort = c.fd;
|
||||
}
|
||||
|
||||
var rdn = new dn.RDN({cn: 'anonymous'});
|
||||
|
||||
c.ldap = {
|
||||
id: c.remoteAddress + ':' + c.remotePort,
|
||||
config: options
|
||||
config: options,
|
||||
_bindDN: new DN([rdn])
|
||||
};
|
||||
c.addListener('timeout', function() {
|
||||
log.trace('%s timed out', c.ldap.id);
|
||||
|
@ -247,7 +270,7 @@ function Server(options) {
|
|||
});
|
||||
|
||||
c.ldap.__defineGetter__('bindDN', function() {
|
||||
return c.ldap._bindDN || new DN([{cn: 'anonymous'}]);
|
||||
return c.ldap._bindDN;
|
||||
});
|
||||
c.ldap.__defineSetter__('bindDN', function(val) {
|
||||
if (!(val instanceof DN))
|
||||
|
@ -264,6 +287,8 @@ function Server(options) {
|
|||
if (log.isTraceEnabled())
|
||||
log.trace('new connection from %s', c.ldap.id);
|
||||
|
||||
dtrace.fire('connection', function() { return [c.remoteAddress]; });
|
||||
|
||||
c.parser = new Parser({
|
||||
log4js: options.log4js
|
||||
});
|
||||
|
@ -274,6 +299,15 @@ function Server(options) {
|
|||
if (log.isDebugEnabled())
|
||||
log.debug('%s: message received: req=%j', c.ldap.id, req.json);
|
||||
|
||||
dtrace.fire('request', function() {
|
||||
return [
|
||||
req.logId,
|
||||
c.remoteAddress,
|
||||
c.ldap.bindDN.toString(),
|
||||
req.dn.toString()
|
||||
];
|
||||
});
|
||||
|
||||
var res = getResponse(req);
|
||||
if (!res) {
|
||||
log.warn('Unimplemented server method: %s', req.type);
|
||||
|
@ -281,6 +315,10 @@ function Server(options) {
|
|||
return;
|
||||
}
|
||||
|
||||
res.connection = c;
|
||||
res.logId = req.logId;
|
||||
res.requestDN = req.dn;
|
||||
|
||||
var chain = self._getHandlerChain(req);
|
||||
|
||||
var i = 0;
|
||||
|
@ -387,9 +425,13 @@ module.exports = Server;
|
|||
* @throws {TypeError} on bad input
|
||||
*/
|
||||
Server.prototype.add = function(name) {
|
||||
return this._mount(Protocol.LDAP_REQ_ADD,
|
||||
name,
|
||||
Array.prototype.slice.call(arguments, 1));
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(getDTraceHander('add',
|
||||
function(req, res) {
|
||||
return req.attributes.length;
|
||||
}));
|
||||
|
||||
return this._mount(Protocol.LDAP_REQ_ADD, name, args);
|
||||
};
|
||||
|
||||
|
||||
|
@ -404,9 +446,10 @@ Server.prototype.add = function(name) {
|
|||
* @throws {TypeError} on bad input
|
||||
*/
|
||||
Server.prototype.bind = function(name) {
|
||||
return this._mount(Protocol.LDAP_REQ_BIND,
|
||||
name,
|
||||
Array.prototype.slice.call(arguments, 1));
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(getDTraceHander('bind'));
|
||||
|
||||
return this._mount(Protocol.LDAP_REQ_BIND, name, args);
|
||||
};
|
||||
|
||||
|
||||
|
@ -421,9 +464,16 @@ Server.prototype.bind = function(name) {
|
|||
* @throws {TypeError} on bad input
|
||||
*/
|
||||
Server.prototype.compare = function(name) {
|
||||
return this._mount(Protocol.LDAP_REQ_COMPARE,
|
||||
name,
|
||||
Array.prototype.slice.call(arguments, 1));
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(getDTraceHander('compare',
|
||||
function(req, res) {
|
||||
return req.attribute;
|
||||
},
|
||||
function(req, res) {
|
||||
return req.value;
|
||||
}));
|
||||
|
||||
return this._mount(Protocol.LDAP_REQ_COMPARE, name, args);
|
||||
};
|
||||
|
||||
|
||||
|
@ -438,9 +488,10 @@ Server.prototype.compare = function(name) {
|
|||
* @throws {TypeError} on bad input
|
||||
*/
|
||||
Server.prototype.del = function(name) {
|
||||
return this._mount(Protocol.LDAP_REQ_DELETE,
|
||||
name,
|
||||
Array.prototype.slice.call(arguments, 1));
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(getDTraceHander('delete'));
|
||||
|
||||
return this._mount(Protocol.LDAP_REQ_DELETE, name, args);
|
||||
};
|
||||
|
||||
|
||||
|
@ -455,10 +506,16 @@ Server.prototype.del = function(name) {
|
|||
* @throws {TypeError} on bad input.
|
||||
*/
|
||||
Server.prototype.exop = function(name) {
|
||||
return this._mount(Protocol.LDAP_REQ_EXTENSION,
|
||||
name,
|
||||
Array.prototype.slice.call(arguments, 1),
|
||||
true);
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(getDTraceHander('exop',
|
||||
function(req, res) {
|
||||
return req.name;
|
||||
},
|
||||
function(req, res) {
|
||||
return req.value;
|
||||
}));
|
||||
|
||||
return this._mount(Protocol.LDAP_REQ_EXTENSION, name, args, true);
|
||||
};
|
||||
|
||||
|
||||
|
@ -473,9 +530,13 @@ Server.prototype.exop = function(name) {
|
|||
* @throws {TypeError} on bad input
|
||||
*/
|
||||
Server.prototype.modify = function(name) {
|
||||
return this._mount(Protocol.LDAP_REQ_MODIFY,
|
||||
name,
|
||||
Array.prototype.slice.call(arguments, 1));
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(getDTraceHander('modify',
|
||||
function(req, res) {
|
||||
return req.changes.length;
|
||||
}));
|
||||
|
||||
return this._mount(Protocol.LDAP_REQ_MODIFY, name, args);
|
||||
};
|
||||
|
||||
|
||||
|
@ -490,9 +551,17 @@ Server.prototype.modify = function(name) {
|
|||
* @throws {TypeError} on bad input
|
||||
*/
|
||||
Server.prototype.modifyDN = function(name) {
|
||||
return this._mount(Protocol.LDAP_REQ_MODRDN,
|
||||
name,
|
||||
Array.prototype.slice.call(arguments, 1));
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(getDTraceHander('modifyDN',
|
||||
function(req, res) {
|
||||
return req.newRdn.toString();
|
||||
},
|
||||
function(req, res) {
|
||||
return (req.newSuperior ?
|
||||
req.newSuperior.toString() : '');
|
||||
}));
|
||||
|
||||
return this._mount(Protocol.LDAP_REQ_MODRDN, name, args);
|
||||
};
|
||||
|
||||
|
||||
|
@ -507,9 +576,16 @@ Server.prototype.modifyDN = function(name) {
|
|||
* @throws {TypeError} on bad input
|
||||
*/
|
||||
Server.prototype.search = function(name) {
|
||||
return this._mount(Protocol.LDAP_REQ_SEARCH,
|
||||
name,
|
||||
Array.prototype.slice.call(arguments, 1));
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(getDTraceHander('search',
|
||||
function(req, res) {
|
||||
return req.scope;
|
||||
},
|
||||
function(req, res) {
|
||||
return req.filter.toString();
|
||||
}));
|
||||
|
||||
return this._mount(Protocol.LDAP_REQ_SEARCH, name, args);
|
||||
};
|
||||
|
||||
|
||||
|
@ -523,10 +599,10 @@ Server.prototype.search = function(name) {
|
|||
* @throws {TypeError} on bad input
|
||||
*/
|
||||
Server.prototype.unbind = function() {
|
||||
return this._mount(Protocol.LDAP_REQ_UNBIND,
|
||||
'unbind',
|
||||
Array.prototype.slice.call(arguments, 0),
|
||||
true);
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
args.unshift(getDTraceHander('unbind'));
|
||||
|
||||
return this._mount(Protocol.LDAP_REQ_UNBIND, 'unbind', args, true);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"dependencies": {
|
||||
"asn1": "~0.1.5",
|
||||
"buffertools": "~1.0.3",
|
||||
"dtrace-provider": "~0.0.2",
|
||||
"sprintf": "~0.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
Loading…
Reference in New Issue