Redis Connection via socket on Node.js - sockets

Because of shared hosting, my redis server on the target host does not run on a port, but on a very specific socket, which can be connected to via the socket file, only accessible to my user.
However, I have not found how I can specify connection via a socket in the node_redis and connect-redis packages, the ones I want to use.
Anyone know how to do it?

Update: My answer below is not really correct. It turns out that the solution in the issue I mention below actually still works. It's more of a coincidence, IMO, but you can do something like this, and it should work:
var redis = require('redis'),
client = redis.createClient('/tmp/redis.sock');
As you see from the code snippet below, this will get passed to net.createConnection which will connect to the unix socket /tmp/redis.sock.
Old answer:
There is a closed issue about this node_redis/issues/204. It seems, thought, that the underlying node.js net.createConnection API has since changed. It looks as though it would be a quite small fix in node_redis' exports.createClient function:
exports.createClient = function (port_arg, host_arg, options) {
var port = port_arg || default_port,
host = host_arg || default_host,
redis_client, net_client;
net_client = net.createConnection(port, host);
redis_client = new RedisClient(net_client, options);
redis_client.port = port;
redis_client.host = host;
return redis_client;
};
It seems as though net.createConnection will attempt to connect to a unix socket if it's called with one argument, that looks like a path. I suggest you implement a fix and send a pull request, since this seems like something worth supporting.

There is no longer a connect string...
var client = redis.createClient(9000); // Open a port on localhost
var client = redis.createClient('/tmp/redis.sock'); // Open a unix socket
var client = redis.createClient(9000, 'example.com');
This, and options are documented on the README.

Related

How to make SSL reads block?

I am trying to make SSL_read() block until data is received from the server. I tried setting the socket to blocking in my "connect" code like so
{
u_long iMode = 1;
i = ioctlsocket(sock, FIONBIO, &iMode);
}
but strangely I get a stack overflow exception every time.
Is there another more correct way to do this?
(Note: the app works just fine if I omit this code).
I've searched SO on this issue but everywhere people seem to have just the opposite problem, namely blocking when they want non-blocking.
Code Synopsis:
Get method: TLS_client_method()
Get CTX: SSL_CTX_new(method)
Create socket 'sock'
set socket to blocking (code above)
Connect sock to host on port 443
Create SSL*: ssl=SSL_new(ctx)
SSL_set_fd(ssl, sock)
Do SSL_reads and writes
I achieved what I wanted by switching from SSL_* calls to BIO_* calls for connect, read, write, etc..
The BIO family includes function 'BIO_set_nbio()' which sets blocking/nonblocking mode. Worked great.
Sample Code Synopsis (e.g., for google.com):
Get method: method = TLS_client_method()
Get CTX: ctx = SSL_CTX_new(method)
Create BIO object: bio = BIO_new_ssl_connect( ctx )
Create socket 'sock'
Connect 'sock' to google.com, port 443
Create SSL*: ssl = SSL_new(ctx)
SSL_set_mode( ssl, SSL_MODE_AUTO_RETRY )
BIO_set_conn_hostname( bio, "google.com:443" )
BIO_do_connect( bio )
BIO_set_nbio( bio, mode ) (with mode=0 for blocking)
Now can do blocking BIO_reads and writes (with BIO_read, BIO_write)

MQTT connection creation and subscribe

I'm setting up a new mqtt conection in my app but there is a problem when i would like to create the main connection of mqtt.
I'm using mqtt.js.
I've tried all what is done in MQTT documentation but nothing happens..
mqttFunction(){
var mqtt = require('mqtt');
var client = mqtt.connect([{host: 'localhost', port: '1883'},]);
client.subscribe('presence')
client.on('message', function (topic, message) {
console.log(message);
});
}
I expect the output of the mqtt broker to be 'ON' when i asked it to respond.
The error is: ERROR ReferenceError: process is not defined
The documentation you followed is intended for Node.js and various other back-end JavaScript frameworks. Even though it uses NPM, Ionic ultimately produces a front-end framework, and its applications run a bit differently.
For example, Ionic programs may not have a global process variable like Node.js. mqtt.js expects this variable, with code like:
if (commist.parse(process.argv.slice(2)) !== null){...}
You could declare a process object, and get past this particular error. Other obstacles could come up.
var process = {env : {NODE_ENV: 'production'}}
If there are still issues with that, you could try the instructions for browser usage, which point to a specially compiled version, like https://unpkg.com/mqtt#3.0.0/dist/mqtt.min.js. I have had less luck with mqtt.js in the browser, and you may want an alternative like web-mqtt-cient / Paho if more complex connections are involved.

Milo: get IP of client

Is there a way to get a Clients IP in Context of a write?
I want to get the IP of an Client that writes to my Milo-OPCUA-Server, so I can handle these writes differently based on the Clients IP (local Clients should be able to write directly on the Server, whilst other writes should get forwarded to another Server)
Okay, this is not part of any official API right now, so it almost certainly will break in the future, but:
With the OperationContext you get when implementing AttributeManager#write(WriteContext, List<WriteValue>):
context.getSession().ifPresent(session -> {
UaStackServer stackServer = context.getServer().getServer();
if (stackServer instanceof UaTcpStackServer) {
ServerSecureChannel secureChannel = ((UaTcpStackServer) stackServer)
.getSecureChannel(session.getSecureChannelId());
Channel channel = secureChannel.attr(UaTcpStackServer.BoundChannelKey).get();
SocketAddress remoteAddress = channel.remoteAddress();
}
});
I'll have to add some official API to do this, probably something hanging off the Session object.

Knowing from which udp socket the Radius request came. Using FreeRadius

I know the question isn't very well. Sorry my english.
I want to setup a (one instance of) FreeRadius server to listen to several ports (with a bunch of 'listen' sections) and then pass the that udp port as a parameter along with User-Name and User-Password to a script that I want to use to make the authentication.
The basic idea is make some kind of domain separation. Some Firewall use radius port 2000 to make authentication. Some other different firewall (with a different set of users) use radius port 2020, for example. At the end, all the request fall in the same script that has the knowledge of both set of users and use one or the other according to the given extra attribute (port number)
I know that is possible making a virtual server per 'domain'. but I prefer not to replicate configuration files. and i think is shorter to add a little 'listen' section for every domain I want.
I tried to add an atribute this way:
listen {
ipaddr = *
port = 0
type = auth
update control {
Login-TCP-Port = 1812
}
}
and tried to read it:
autorize {
if ("%{User-Name}" == "bob") {
update reply {
Reply-Message = "This is only %{Login-TCP-Port} an example."
}
update control {
Cleartext-Password := "bob"
}
ok
}
[...]
}
But don't work.
How can i make it right?
Is this posible?
Hope you can help me.
I'm answering myself. I found (looking a like further on google) that the Packet-Dst-Port attribute have the data that I want.
I get it from here (now that I found it, look pretty obvious :P)

Any off the shelf app to rebroadcast tcp packets?

I am working with a 3rd party device which opens a tcp port that only allows one connection at a time. If my app connects to the port, all other connections are denied.
I'd like to find an app that basically connects to this port, then allows others to connect to it on a different port.
Any data sent out of the device's port is then rebroadcast to any connected client.
I know how to write such an app, but it seems like it would be something someone else has already thought off and written it & shared, and I could avoid taking the time to write it.
basicaly code would be:
1) start a tcp socket server, binding to TO_PORT (clients connect to this)
2) connect as a client to DEVICE_IP:DEVICE_PORT
3) when data is read into a buffer from DEVICE_IP:DEVICE_PORT, the buffer content is resent to each connected client.
4) everything else that makes it a stable, working program.
This is for windows, and I'd prefer it not require a java install.
My google skills have failed me.
Anyone know of such an app?
Not a complete solution for you, but might be interesting, though
http://www.codeproject.com/KB/IP/serversocket.aspx
http://www.codeproject.com/KB/IP/UniversalTCPSocketClass.aspx
Guess I'll answer my own question.
I implemented the solution my self.
Key points to my solution:
A class named IPClient which wraps up a TcpClient instance, uses async model of calling TcpClient.BeginConnect, BeginRead, etc. It has a Timer used for reconnecting if it loses connection.
This is the class that connects to the device.
It's public interface would look something like this:
public class IPClient{
public event EventHandler<MyConnectedArgs> Connected;
public event EventHandler<MyDisconnectedArgs>Disconnected;
public event EventHandler<MyDataReceivedArgs> DataReceived;
public bool Connect(string address, int port){...}
public bool Disconnect() {...}
}
To open the port that would allow other clients to connect, I used this library: http://codeproject.com/KB/IP/BasicTcpServer.aspx and modified it a bit.
It's job was to open a port, accept connections, and do the following:
in the Connected handler, start the listening port
in the Disconnected handler, stop the listening port
in the DataReceived handler, broadcast the data to any connected clients.
I'll leave out the rest of the boring details, but say it wasn't "too hard", and eventually I just had to roll my own.
command line usage: myapp.exe remote_addr remote_port listen_port
psuedocode/main idea of my program main:
static int Main(string[] args){
//SetConsoleCtrlHandler(my callback re: ctrl+C,etc)
//get command line params
var ipClient = new IPClient();
var myprovider = MyTcpServiceProvider();
var server = new TcpServer(myProvider, listenPort);
ipClient.Connected += (sender, e) => server.Start();
ipClient.Disconnected += (sender,e) => server.Stop();
ipClient.DataReceived += (sender,e)=> provider.BroadcastToClients(e.Data);
ipClient.Connect(remoteAddress, remotePort);
//wait for Ctrl+C or program exit
//shutdown code,etc
return 0;
}