registration using sip.js and websockets in Node (wss or ws) - javascript

I'm trying to register SIP agents using sip.js and Node to start load testing to my Kamailio
Node version v0.10.32
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
global.WebSocket = require('ws')
// SipJS Initialization
var SIP = require('./sip-0.6.0.js');
var Uaconfig = {
traceSip: true,
register: true,
userAgentString: 'sipJS Test tool',
uri: 'ramenlabs.io',
wsServers: ['wss://ramenlabs.io:5063'],
authorizationUser: 'gogasca',
password: '********'
//hackIpInContact: true
};
var userAgent = new SIP.UA(Uaconfig);
When I run I get an error:
Thu Oct 16 2014 03:40:53 GMT+0000 (UTC) | sip.transport | WebSocket connection error: Error: unexpected server response (400)
Because initial Websocket from Sip.js lacks Sec-WebSocket-Protocol: sip to indicate SIP Protocol.
If i use sample web page it works perfectly with same parameters, but not from my node command line.
How to force this?
In API js I do see the 'sip' extra header but contains the window.Websocket
try {
this.ws = new window.WebSocket(this.server.ws_uri, 'sip');
}
catch(e) {
this.logger.log('Error connecting to WebSocket ' + this.server.ws_uri + ': ' + e);
//return false;
}

You can set debug=3 in kamailio.cfg, restart and try again. Then look in syslog file (/var/log/syslog or /var/log/messages) for debug messages from Kamailio to see if you get a hint on why the connection is not accepted.

Related

Paho MQTT host invalid argument when using an IP address as hostname?

REVISION: Please note I am now using IP address 10.0.0.15, my device publishing to the MQTT broker is 10.0.0.122. This is still all working through terminal.
I think I am getting somewhere with an MQTT connector. I have moved forward after having issues as describe in the post below
Can't connect to localhost Mosquitto Broker with Javascript?
I am now seeing the following error.
mqttws31.js:1585 Uncaught Error: AMQJS0013E Invalid argument
169.254.118.199 for host.
at new M (mqttws31.js:1585)
at startConnect (n.js:29)
at HTMLInputElement.onclick ((index):107)
which according to the js file indicates a match error. I have tried prefixing the ip address to be wss://169.254.118.199 but this doesn't resolve the issue. Do you know what could be causing this?
I have tried the following
wss://169.254.118.199
ws://169.254.118.199
wss://localhost
tcp://169.254.118.199
tcp://localhost
They all produce the same error
This is the bit of code in mqttws31.js that the error points to.
if (arguments.length == 2) {
// host: must be full ws:// uri
// port: clientId
clientId = port;
uri = host;
var match = uri.match(/^(wss?):\/\/((\[(.+)\])|([^\/]+?))(:(\d+))?
(\/.*)$/);
if (match) {
host = match[4]||match[2];
port = parseInt(match[7]);
path = match[8];
} else {
--> this is where error is pointing throw new Error(format(ERROR.INVALID_ARGUMENT,[host,"host"]));
}
} else {
if (arguments.length == 3) {
clientId = path;
path = "/mqtt";
}
if (typeof port !== "number" || port < 0)
throw new Error(format(ERROR.INVALID_TYPE, [typeof port, "port"]));
if (typeof path !== "string")
throw new Error(format(ERROR.INVALID_TYPE, [typeof path, "path"]));
var ipv6AddSBracket = (host.indexOf(":") != -1 && host.slice(0,1) != "[" &&
host.slice(-1) != "]");
uri = "ws://"+(ipv6AddSBracket?"["+host+"]":host)+":"+port+path;
}
EDIT: in the print out I am seeing the following being sent to the Paho client on my webpage:
Connecting to: 10.0.0.122 on port: 8083
Using the following client value: clientID-64
I am hoping to sucessfully connect with the IP address and get the MQTT payload
To get the error you are seeing, you can not be using the code you have posted in the other questions:
clientID = "clientID-" + parseInt(Math.random() * 100);
// Fetch the hostname/IP address and port number from the form
host = document.getElementById("host").value;
port = document.getElementById("port").value;
// Print output for the user in the messages div
// Initialize new Paho client connection
client = new Paho.MQTT.Client(host, Number(port), clientID);
That error can only happen if you only pass 2 arguments to the Paho.MQTT.Client() constructor not 3. In which case the first argument is interpreted as a full URI (e.g. ws://10.0.0.122:8083/mqtt), the second as the ClientID.

I'm getting a net::ERR_INSECURE_RESPONSE with socket.io/node.js

Here is the current code that I am using to try to connect my web application running socket.io to my node application.
var options = {
key: fs.readFileSync('csgo2x.key').toString(),
cert: fs.readFileSync('csgo2x.crt').toString(),
ca : [fs.readFileSync("csgo2x.pem").toString()],
rejectUnauthorized: false
};
var server = require('https').createServer(options);
var portNo = 443;
server.listen(portNo, function() {
console.log((new Date()) + " Server is listening on port " + portNo);
});
However...when I try to connect my socket.io application running on my Ubuntu server...it gives the error net::ERR_INSECURE_RESPONSE.
I am using certificates from Cloudflare btw and for some reason it's not working

Stilts.js Unable to connect to websocket server with secure true

I am having issues with subscribing to my websocket server when I turn the secure option to true. I ran an SSL validator to make sure it was set up properly and everything passed. Also to be safe, I also checked with my hosting provider so I dont believe that is the issue. And also, everything does work when secure is set to false.
The WSS is running on port 8676, and I did make sure that port is open.
I am using the Stomp Javascript library. I downloaded the latest version from their github master branch (https://github.com/projectodd/stilts/blob/master/stomp-client-js/src/main/javascript/stomp.js).
I keep getting this error inside the _transmit() function: can't call transmit on undefined
It seems to not be setting the _transport property inside of _buildConnector() function. I added some console.logs and it always goes to the else statement in this function.
Any ideas on a fix? Or am I just missing something?
This is how I am initializing my connection:
client = new Stomp.Client('my.ip.address', 8676, true);
Here is where I am logging some of the functions:
Stomp.Client = function(host, port, secure) {
console.log('host param: ' + host);
console.log('port param: ' + port);
console.log('secure param: ' + secure);
this._host = host || Stomp.DEFAULT_HOST;
this._port = port || Stomp.DEFAULT_PORT || 8675;
this._secure = secure || Stomp.DEFAULT_SECURE_FLAG || false;
console.log('this._host: ' + this._host);
console.log('this._port: ' + this._port);
console.log('this._secure: ' + this._secure);
}
Output:
host param: my.ip.address
port param: 8676
secure param: true
this._host: my.ip.address
this._port: 8676
this._secure: true
_buildConnector: function(transports, i) {
console.log('INSIDE _buildConnector()');
var callback = this._connectCallback;
var client = this;
if ( i < transports.length ) {
console.log('IF!!!');
return function() {
var fallback = client._buildConnector( transports, i+1, callback );
try {
console.log('_buildConnector::IF::TRY');
transports[i].connect( function() {
client._transport = transports[i];
callback();
}, fallback );
} catch (err) {
console.log('_buildConnector::IF::CATCH');
fallback();
}
};
} else {
console.log('_buildConnector::ELSE');
return client.connectionFailed.bind(this);
}
}
Output:
INSIDE _buildConnector()
IF!!!
INSIDE _buildConnector()
IF!!!
_buildConnector::IF::TRY
INSIDE _buildConnector()
_buildConnector::ELSE
_buildConnector::IF::TRY
connectionFailed: function() {
console.log('INSIDE connectionFailed()');
if (this._errorCallback)
{
console.log('connectionFailed::IF');
console.log('this._errorCallback');
console.log(this._errorCallback);
console.log('arguments');
console.log(arguments);
this._errorCallback.apply(this._errorCallback, arguments);
}
else
{
console.log('connectionFailed::ELSE');
console.log('unable to connect :(');
Stomp.logger.log( "unable to connect" );
}
}
Output:
No output..
I discovered this node.js tool called wscat which can be used to send messages to a websocket server (http://einaros.github.io/ws/).
When entering the command using the external address:
wscat -c wss://my.ip.address:8676
I kept getting the following error: error: Error: Hostname/IP doesn't match certificate's altnames
But when I changed it to my domain name:
wscat -c wss://mydomain.com:8676
I was given this message: connected (press CTRL+C to quit)
Which led me to:
I am setting the host value in Javascript as the external ip address of the server where STOMP lives. But the SSL cert is configured for a domain name. This led me to think that I should use mydomain.com instead of my.ip.address for the host parameter in new Stomp.Client. But this is resulting in the following error in the Torquebox log file:
NoSuchHostException: No such host: mydomain.com
So then in the torquebox.yml file the host property needed to be configured to mydomain.com as well.
So the conclusion is: You need to use the domain name that was registered to the SSL cert when trying to connect to your websocket server, not the external ip address. huzzah!
Credit to: #bobmcwhirter who helped lead me to this solution here: https://github.com/projectodd/stilts/issues/20

How do I build a simple node js server that sends and receives to a client?

I have a node js server, and a html/javascript client.
I simply want to allow the client to send a json-string to the node.js server, the server process's that string and returns a result string back to the client.
I started by setting up the html-client to call like so :
var msg =
{
type: "message",
text: "Hello"
};
function CallWebSocket()
{
var socket = new WebSocket("ws://127.0.0.1:8080","test");
socket.onopen = function (event)
{
alert(JSON.stringify(msg));
socket.send(JSON.stringify(msg));
};
socket.onmessage = function(event)
{
alert(event.data);
}
}
and node.js :
var net = require('net');
var server = net.createServer(function(socket)
{
// do what you need
socket.setEncoding("utf8");
socket.on('data', function(data)
{
var jsonData = JSON.parse(data);
socket.write(jsonData.text);
socket.end();
process.exit(0);
});
});
server.listen(8080);
but on the server I get this error :
undefined:1
``GET / HTTP/1.1
^
SyntaxError: Unexpected token G
at Object.parse (native)
at Socket.<anonymous> (/home/jay/projects/nodejs/test/json-server.js:8:23)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:746:14)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:408:10)
at emitReadable (_stream_readable.js:404:5)
at readableAddChunk (_stream_readable.js:165:9)
at Socket.Readable.push (_stream_readable.js:127:10)
at TCP.onread (net.js:526:21)
Any help is much appreciated.
UPDATE
The updated server code :
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
var connection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(message.utf8Data);
}
else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
This solved my problem and I am now getting the message back.
A websocket is not a plain TCP socket. That is basically the core of your problem.
The websocket protocol looks like a modified HTTP protocol that allows two way communication using a single (TCP) socket. Read the RFC for more info on how the websocket protocol actually works: https://www.rfc-editor.org/rfc/rfc6455#section-1.2
You have two options if you want to use websockets with node servers:
Read the RFC and write a function to handle the websocket protocol so you can pass that function to socket.on.
Use a websocket server module that someone else have written. Go to npm and search for "websocket server" or google "websocket server npm". There are lots of modules out there. Pick one you like best.
There is a third alternative. Use socket.io. Socket.io is a library that communicates between client and server using websocket if possible (preferred) but is able to degrade to other transports such as Flash and ajax on older browsers.

WebSocket opcode 7 with wss://

I tried to launch a server in wss:// last Tuesday, but it didn't work. Today I decided to look at the WebSocket code and I found why my WebSocket closed directly. This is error code I found:
1002 Unsupported usage of rsv bits without negotiated extension.
VALUE OF RSV1:Opcode: 7, fin: false, length: 69, hasPayload: true, masked: false
My program works with ws:// but not with wss://. I can't understand why TLS is blocked.
I precise IPtables are stopped and my certificate is OK.
Do you have any idea?
Below is my code if you want to look:
var fs = require('fs');
var https = require('https');
var WebSocketServer = require('websocket').server;
var express = require('express');
var serverTLS = express.createServer({
key: fs.readFileSync(__dirname + '/notification_mail/notification.mail.com.key'),
cert: fs.readFileSync(__dirname + '/notification_mail/notification.mail.com.crt')
});
serverTLS.configure(function(){
serverTLS.set('views',__dirname);
serverTLS.set('view engine','ejs');
});
serverTLS.get('/',function(req,res){
res.render('index',{layout: false });
});
serverTLS.listen("443");
var wss = new WebSocketServer({ httpServer: serverTLS, autoAcceptConnections: true });
wss.on('connect', function(connection) {
console.log((new Date()) + " Connection accepted.");
connection.on('close', function(connection) {
console.log((new Date()) + " Disconnected");
});
});
console.log("Server launch");
And my HTML file
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
<h1>Serveur 2</h1>
<div id="tchat"></div>
<script>
var url = "wss://notification.mail.com";
var wsCtor = window['MozWebSocket'] ? MozWebSocket : WebSocket;
this.socket = new wsCtor(url, 'connect');
this.socket.onclose = function(){
alert ("Connection lost");
}
</script>
</body>
</html>
The error message is confusing, since
opcode 7 is indeed reserved (https://www.rfc-editor.org/rfc/rfc6455#section-5.2), but
it also mentions RSV1 which is also reserved, but gives no observed value
Did you try Chrome or IE10?
You could also try running AutobahnTestsuite against your node server.
The testsuite has a fuzzingclient mode that supports WSS. The testsuite includes extensive wire log reports which might help finding out what happens.
Disclosure: I am original author of Autobahn and work for Tavendo.
I launched wss:// (but on .NET) and I got 7 opcode, too. I used ReadTimeout (ReceiveTimeout) every 5 seconds for sending "ping" to client. In ws:// and wss:// all worked well, but in wss:// every 5 seconds I got "7 opcode".
I removed the timeout and it worked.

Categories

Resources