You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
4.2 KiB
142 lines
4.2 KiB
14 years ago
|
var sys = require("sys"),
|
||
|
net = require("net"),
|
||
|
XMLNS = require("./xmlns.js"),
|
||
|
xmpp = require("node-xmpp"),
|
||
|
colors = require("colors"),
|
||
|
events = require("events");
|
||
|
|
||
|
var BytestreamServer = function(client) {
|
||
|
var self = this;
|
||
|
this.client = client;
|
||
|
this.port = (client.params.s5bPort == null) ? 8010 : client.params.s5bPort;
|
||
|
this.host = (client.params.s5bHost == null) ? "proxy." + client.params.host : client.params.s5bHost;
|
||
|
this._clients = {};
|
||
|
this._handlers = {};
|
||
|
this.tcpSocket = net.createServer(function(stream) {self.handleConnection(stream);});
|
||
|
this.tcpSocket.on("error", function(error) {
|
||
|
console.log("Error with S5B server!");
|
||
|
console.log(error);
|
||
|
});
|
||
|
|
||
|
this.tcpSocket.listen(this.port, "0.0.0.0");
|
||
|
};
|
||
|
|
||
|
exports.BytestreamServer = BytestreamServer;
|
||
|
|
||
|
BytestreamServer.prototype.close = function() {
|
||
|
for (ii in this._clients) {
|
||
|
this._clients[ii].end();
|
||
|
}
|
||
|
|
||
|
this.tcpSocket.close();
|
||
|
};
|
||
|
|
||
|
BytestreamServer.prototype.addHandler = function(iqId, sidHash, data, cbSuccess, cbFailure) {
|
||
|
this._handlers[sidHash] = {id: iqId, data: data, cbSuccess:cbSuccess, cbFailure:cbFailure};
|
||
|
};
|
||
|
|
||
|
BytestreamServer.prototype.handleConnection = function(stream) {
|
||
|
var self = this;
|
||
|
this._clients[stream.remoteAddress] = new BytestreamHandler(stream, self);
|
||
|
this._clients[stream.remoteAddress].established = false;
|
||
|
this._clients[stream.remoteAddress].transfered = false;
|
||
|
|
||
|
stream.on("error", function(error) {
|
||
|
console.log("S5B stream error from "+ stream.remoteAddress);
|
||
|
console.log(error);
|
||
|
|
||
|
stream.end();
|
||
|
delete self._clients[stream.remoteAddress];
|
||
|
});
|
||
|
|
||
|
stream.on("connect", this._clients[stream.remoteAddress].onConnect);
|
||
|
stream.on("data", this._clients[stream.remoteAddress].onData);
|
||
|
stream.on("end", this._clients[stream.remoteAddress].onEnd);
|
||
|
};
|
||
|
|
||
|
BytestreamServer.prototype.iq = function(bytestream, query, to, id) {
|
||
|
var self = this;
|
||
|
var jabber = self.client;
|
||
|
|
||
|
if (typeof to === "undefined") {
|
||
|
var to = bytestream.to;
|
||
|
}
|
||
|
|
||
|
if (typeof id === "undefined") {
|
||
|
var id = bytestream.idIq;
|
||
|
}
|
||
|
|
||
|
var params = {
|
||
|
type: "set",
|
||
|
id: id,
|
||
|
to: to
|
||
|
};
|
||
|
|
||
|
jabber.xmpp.send(new xmpp.Element('iq', params).cnode(query).tree());
|
||
|
};
|
||
|
|
||
|
var BytestreamHandler = function(self, parent) {
|
||
|
self.parent = parent;
|
||
|
self.iqId = null;
|
||
|
|
||
|
this.onConnect = function(data) {};
|
||
|
|
||
|
this.onData = function(data) {
|
||
|
// TODO: Disconnect client when BS data is entered
|
||
|
// just a start
|
||
|
if (data[0] !== 0x05 && data[1] > 0x0F) {
|
||
|
console.log("Received erroneous data from " + self.remoteAddress);
|
||
|
self.end();
|
||
|
}
|
||
|
|
||
|
if (self.parent._clients[self.remoteAddress].established === false
|
||
|
&& data.length >= 1 && data[0] === 0x05) {
|
||
|
if (data.length >= 3 && (data[1] === 0x01 || data[1] === 0x02) && data[2] === 0x00) {
|
||
|
if (data[1] === 0x01 || (data.length >= 4 && data[3] === 0x02)) {
|
||
|
self.parent._clients[self.remoteAddress].established = true;
|
||
|
|
||
|
self.write(new Buffer([0x05,0x00])); // Ack
|
||
|
}
|
||
|
}
|
||
|
} else if (self.parent._clients[self.remoteAddress].established === true && data.length == 47
|
||
|
&& data[data.length - 1] === 0x00 && data[data.length - 2] === 0x00) {
|
||
|
var reqHash = data.toString("ascii", 5, 45);
|
||
|
if ((reqHash in self.parent._handlers) === true) {
|
||
|
var buff = [0x05,0x00,0x00,0x03]; // Request header
|
||
|
buff.push(reqHash.length); // Announce data length
|
||
|
// Push our reqHash in the buffer
|
||
|
reqHash.split("").forEach(function(val) {
|
||
|
buff.push(val.charCodeAt(0));
|
||
|
});
|
||
|
|
||
|
// DST.PORT is two bytes
|
||
|
buff.push(0x00, 0x00);
|
||
|
|
||
|
// Add iq handler for receiving the target's ack
|
||
|
self.iqId = self.parent._handlers[reqHash].id;
|
||
|
self.parent.client._iqCallback[self.iqId] = {};
|
||
|
self.parent.client._iqCallback[self.iqId].success = function(data) {
|
||
|
if (typeof self.parent._handlers[reqHash].data === "function") {
|
||
|
self.parent._handlers[reqHash].data(self);
|
||
|
} else {
|
||
|
self.write(self.parent._handlers[reqHash].data);
|
||
|
}
|
||
|
|
||
|
self.parent._clients[self.remoteAddress].transfered = true;
|
||
|
delete self.parent.client._iqCallback[self.iqId];
|
||
|
};
|
||
|
|
||
|
self.parent.client._iqCallback[self.iqId].error = function(error) {
|
||
|
console.log(error);
|
||
|
};
|
||
|
|
||
|
self.write(new Buffer(buff));
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
this.onEnd = function(data) {
|
||
|
delete self.parent._clients[self.remoteAddress];
|
||
|
};
|
||
|
};
|