Skip to content

Commit 5cf2258

Browse files
committed
add v0.10 support and a smattering of logging
1 parent 3417e75 commit 5cf2258

10 files changed

+117
-42
lines changed

config.sample.js

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ var key = fs.readFileSync(path.join(__dirname, 'key.pem'));
55
var cert = fs.readFileSync(path.join(__dirname, 'cert.pem'));
66

77
module.exports = {
8+
loggingConfig: {
9+
// any otpions you would pass to createLogger
10+
// https://github.com/trentm/node-bunyan
11+
level: 'trace',
12+
},
813
listeners: [
914
{
1015
host: '0.0.0.0',

index.js

+39-19
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
var child_process = require('child_process');
66
var net = require('net');
77
var tls = require('tls');
8+
var util = require('util');
9+
10+
var bunyan = require('bunyan');
811

912
var CertCloak = require('./lib/certcloak');
1013
var ConnectStream = require('./lib/connectstream');
@@ -16,6 +19,22 @@ var TorFilter = require('./lib/torfilter');
1619

1720
var config = require('./config');
1821

22+
var logConfig = util._extend({
23+
name: 'webirc',
24+
}, config.loggingConfig);
25+
26+
var LOG = bunyan.createLogger(logConfig);
27+
28+
LOG.addSerializers({
29+
client: function clientSerializer(client) {
30+
return util.format('%d:[%s:%d] (isTor: %s)',
31+
client.clientId,
32+
client.remoteAddress,
33+
client.remotePort,
34+
client.isTor);
35+
},
36+
});
37+
1938
var definedListeners = {};
2039

2140
config.listeners.forEach(function eachListener(listener) {
@@ -29,6 +48,7 @@ config.listeners.forEach(function eachListener(listener) {
2948
var serverOptions = {};
3049

3150
var eventName = 'connection';
51+
3252
switch (listener.type) {
3353
case 'plain':
3454
proto = net;
@@ -75,31 +95,33 @@ function enableListener(key) {
7595
var listener = definedListeners[key];
7696

7797
if (!listener) {
78-
console.error('trying to enable undefined listener', key);
98+
LOG.error('trying to enable undefined listener', key);
7999
return;
80100
}
81101

82102
if (listener.server) {
83-
console.error('trying to renable enabled listener', key);
103+
LOG.error('trying to renable enabled listener', key);
84104
return;
85105
}
86106

107+
LOG.info('starting listener', key);
108+
87109
var server = listener.proto.createServer(listener.serverOptions);
88110

89-
server.listen(listener.listenOptions);
111+
server.listen(listener.listenOptions.port, listener.listenOptions.host);
90112

91113
server.on('listening', function serverListening() {
92-
ConnectStream(server, { eventName: listener.eventName })
93-
.pipe(Throttle(config))
94-
.pipe(DNSFilter(config))
95-
.pipe(CertCloak(config))
96-
.pipe(TorFilter(config))
97-
.pipe(IRCProxy(config))
114+
ConnectStream(server, { eventName: listener.eventName, logger: LOG })
115+
.pipe(Throttle(config, LOG))
116+
.pipe(DNSFilter(config, LOG))
117+
.pipe(CertCloak(config, LOG))
118+
.pipe(TorFilter(config, LOG))
119+
.pipe(IRCProxy(config, LOG))
98120
.resume(); // Don't stop accepting new clients
99121
});
100122

101123
server.on('error', function serverError(err) {
102-
console.error('listener failed', err);
124+
LOG.error('listener failed', err);
103125
// TODO restart listener?
104126
});
105127

@@ -110,12 +132,12 @@ function disableListener(key) {
110132
var listener = definedListeners[key];
111133

112134
if (!listener) {
113-
console.error('trying to disable undefined listener', key);
135+
LOG.error(key, 'trying to disable undefined listener');
114136
return;
115137
}
116138

117139
if (!listener.server) {
118-
console.error('listener already disabled', key);
140+
LOG.error(key, 'listener already disabled');
119141
return;
120142
}
121143

@@ -135,8 +157,7 @@ process.on('SIGHUP', function configReload() {
135157
},
136158
function readConifg(error, stdout, stderr) {
137159
if (error) {
138-
console.error('Failed to read configuration file');
139-
console.error(stderr);
160+
LOG.error(stderr, 'Failed to read configuration file');
140161
} else {
141162
try {
142163
var newConfig = JSON.parse(stdout);
@@ -145,25 +166,24 @@ process.on('SIGHUP', function configReload() {
145166
var definedListener = definedListeners[key];
146167

147168
if (!definedListener) {
148-
console.error('cannot add new listeners with reload, ignoring', key);
169+
LOG.error('cannot add new listeners with reload, ignoring', key);
149170
return;
150171
}
151172

152173
if (listener.enabled && !definedListener.server) {
153-
console.error('enabling', key, 'listener');
174+
LOG.error('enabling', key, 'listener');
154175
enableListener(key);
155176
}
156177

157178
if (!listener.enabled && definedListener.server) {
158-
console.error('disabling', key, 'listener');
179+
LOG.error('disabling', key, 'listener');
159180
disableListener(key);
160181
}
161182
});
162183
config.blockTor = !!newConfig.blockTor;
163184
config.blockTorMessage = newConfig.blockTorMessage;
164185
} catch (e) {
165-
console.error('Failed to parse configuration file');
166-
console.error(e);
186+
LOG.error(e, 'Failed to parse configuration file');
167187
}
168188
}
169189
});

lib/certcloak.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,25 @@ var child_process = require('child_process');
44
var stream = require('stream');
55
var util = require('util');
66

7-
function CertCloak(config) {
7+
function CertCloak(config, logger) {
88
if (!(this instanceof CertCloak))
9-
return new CertCloak(config);
9+
return new CertCloak(config, logger);
1010

1111
stream.Transform.call(this, {
1212
objectMode: true,
1313
highWaterMark: 0,
1414
});
1515

16+
this.log = logger.child({ pipeline: 'certcloak' });
17+
1618
this.cloak_config = config.cloaks;
1719
}
1820
util.inherits(CertCloak, stream.Transform);
1921

2022

2123
CertCloak.prototype._transform = function certCloakTransform(client, e, cb) {
24+
this.log.trace({ client: client }, 'got client');
25+
2226
// We have a TLS Socket
2327
if (!client.getPeerCertificate) {
2428
this.push(client);

lib/connectstream.js

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ function ConnectStream(socket, options) {
1313
objectMode: true,
1414
});
1515

16+
this.log = options.logger.child({ pipeline: 'connectstream'});
17+
1618
this.cs_socket = socket;
1719

1820
var self = this;
@@ -22,12 +24,14 @@ function ConnectStream(socket, options) {
2224

2325
socket.on(evt, function socketOnConnect(client) {
2426
client.clientId = CLIENT_ID++;
27+
self.log.trace({ client: client }, 'connected');
2528
self.push(client);
2629
});
2730

2831
socket.on('close', function socketClosing() {
2932
// We are no longer expecting new connections, so clear the pipeline
3033
// pushing null means EOF which closes the writeables along the way
34+
self.log.trace({ client: client }, 'disconnected');
3135
self.push(null);
3236
});
3337
}

lib/dnsfilter.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ var vasync = require('vasync');
88

99
var DNSBLQuery = require('./dnsbl');
1010

11-
function DNSFilter(config) {
11+
function DNSFilter(config, logger) {
1212
if (!(this instanceof DNSFilter))
13-
return new DNSFilter(config);
13+
return new DNSFilter(config, logger);
1414

1515
stream.Transform.call(this, {
1616
objectMode: true,
1717
highWaterMark: 0,
1818
});
1919

20+
this.log = logger.child({ pipeline: 'dnsfilter' });
21+
2022
this.dnsfltr_config = config.dnsbl;
2123
}
2224
util.inherits(DNSFilter, stream.Transform);
@@ -25,6 +27,8 @@ util.inherits(DNSFilter, stream.Transform);
2527
DNSFilter.prototype._transform = function dnsfltrTransform(client, enc, cb) {
2628
var self = this;
2729

30+
this.log.trace({ client: client }, 'got client');
31+
2832
var work = vasync.parallel({
2933
funcs: [
3034
function reverseDns(next) {
@@ -51,10 +55,11 @@ DNSFilter.prototype._transform = function dnsfltrTransform(client, enc, cb) {
5155
client.score = score.total;
5256

5357
if (score.total > self.dnsfltr_config.maxScore) {
54-
console.error('client', client.remoteAddress,
55-
'exceeded dnsbl score', score.total, 'max of',
56-
self.dnsfltr_config.maxScore, 'reasons:',
57-
score.reasons.join('|'));
58+
self.log.error({
59+
client: client,
60+
score: score,
61+
config: self.dnsfltr_config
62+
}, 'client exceeded dnsbl score');
5863
client.end('Administratively refused');
5964
return client.destroy();
6065
}

lib/ircproxy.js

+20-5
Original file line numberDiff line numberDiff line change
@@ -9,61 +9,76 @@ var lstream = require('lstream');
99

1010
var WebIRC = require('./webirc');
1111

12-
function IRCProxy(config) {
12+
function IRCProxy(config, logger) {
1313
if (!(this instanceof IRCProxy))
14-
return new IRCProxy(config);
14+
return new IRCProxy(config, logger);
1515

1616
stream.Transform.call(this, {
1717
objectMode: true,
1818
highWaterMark: 0,
1919
});
2020

2121
this.ircp_config = config;
22+
this.ircp_connect_event = 'connect';
2223

2324
switch (config.destination.type) {
2425
case 'plain':
2526
this.ircp_proto = net;
2627
break;
2728
case 'tls':
2829
this.ircp_proto = tls;
30+
this.ircp_connect_event = 'secureConnect';
2931
break;
3032
default:
3133
throw new Error('Must define an outbound protocol');
3234
break;
3335
}
3436

37+
this.log = logger.child({ pipeline: 'ircproxy' });
38+
3539
this.ircp_options = util._extend({}, config.destination);
3640
}
3741
util.inherits(IRCProxy, stream.Transform);
3842

3943
IRCProxy.prototype._transform = function ircProxyTransform(client, enc, cb) {
44+
this.log.trace({ client: client }, 'got client');
45+
client.log = this.log.child({ client: client });
46+
47+
client.log.trace({
48+
opts: this.ircp_options,
49+
proto: this.ircp_proto,
50+
}, 'connecting to irc');
51+
4052
var outbound = this.ircp_proto.connect(this.ircp_options);
4153

4254
var self = this;
4355

44-
outbound.on('connect', function outboundConnected() {
56+
outbound.on(this.ircp_connect_event, function outboundConnected() {
57+
client.log.info('connected to irc');
4558
client
4659
.pipe(WebIRC(client, self.ircp_config))
4760
.pipe(outbound)
4861
.pipe(client);
4962
});
5063

5164
client.on('close', function clientClosed() {
65+
client.log.info('client closed');
5266
outbound.destroy();
5367
});
5468

5569
outbound.on('close', function outboundClosed() {
70+
client.log.info('outbound closed');
5671
client.destroy();
5772
});
5873

5974
outbound.on('error', function outboundError(err) {
6075
// TODO relay error
61-
console.error('outbound connection error', client.remoteAddress, err.message);
76+
client.log.error({ err: err }, 'outbound connection error');
6277
});
6378

6479
client.on('error', function clientError(err) {
6580
// TODO relay error
66-
console.error('client connection error', client.remoteAddress, err.message);
81+
client.log.error({ err: err }, 'client connection error');
6782
});
6883

6984
cb();

lib/throttle.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ var util = require('util');
55

66
var CONNECTIONS = {};
77

8-
function Throttle(config) {
8+
function Throttle(config, logger) {
99
if (!(this instanceof Throttle))
10-
return new Throttle(config);
10+
return new Throttle(config, logger);
1111

1212
stream.Transform.call(this, {
1313
objectMode: true,
1414
highWaterMakr: 0,
1515
});
1616

17+
this.log = logger.child({ pipeline: 'throttle' });
1718
this.thrt_timeout = config.reconnectTime;
1819

1920
var self = this;
@@ -34,17 +35,25 @@ util.inherits(Throttle, stream.Transform);
3435

3536

3637
Throttle.prototype._transform = function thrtlTransform(client, enc, cb) {
38+
this.log.trace({ client: client }, 'got client');
39+
3740
var time = CONNECTIONS[client.remoteAddress];
3841
var cur = Date.now();
3942
var timeout = this.thrt_timeout;
4043

4144
if (time && (cur - time) < timeout) {
42-
console.error('Throttling client', client.remoteAddress);
45+
this.log.error('throttling client', {
46+
remoteAddress: client.remoteAddress,
47+
ts: cur,
48+
prev: time,
49+
timeout: timeout,
50+
});
4351
client.end('ERROR :Trying to reconnect too fast.\r\n');
4452
client.destroy();
4553
return cb();
4654
}
4755

56+
this.log.trace('client time registered', { remoteAddress: client.remoteAddress, ts: cur });
4857
CONNECTIONS[client.remoteAddress] = cur;
4958
this.push(client);
5059
return cb();

0 commit comments

Comments
 (0)