Bind udp binding to more then one port

I use the udp binding to receive messages. This is working fine

I use udp.cfg:

#port=56000
addressmask=true

The problem is, that I now be able to receive udp packages to every port. This causes problems becasue I will act on every other udp package too.

If I try to set “port=56000” then I will receive only packages send to this port (only this port is listening). This is better, so unwanted packages on unwanted pots are received. But how to receive packages from other devices on other ports

I want to receive from 10.4.1.3 to port 56000 on OH udp binding
I want to receive from 10.4.1.7 to port 56001 on OH udp binding

I use udp.cfg:

port=56000,56001
addressmask=true

Is not working. Any idea?

I don’t use this binding but my understanding is that you provide the ip/port mapping on the binding config of the Item, not in the udp.cfg.

You can specify the port in the item definition

udp="<[192.168.0.1:3000:'MAP(my.device.map)')]

and comment out the port line in the udp.cfg file

As discussed in another post the port in the item config is the sending port of the remote device not the listening port on OH.

I checked this. And it is correct. Only if I use it in udp.cfg OH is listen to a single port.

Again, I don’t use this binding but according to the docs:

https://docs.openhab.org/addons/bindings/tcp1/readme.html#binding-configuration

The TCP and UDP bindings can be configured in the files services/tcp.cfg and services/udp.cfg, respectively.

Note: This is optional for the configuration and not necessary for receiving data. Item-defintions are enough for receiving data. (Developer confirm? 20150128). There’s a bug in the binding that requires at least one udp configuration to be defined or the binding will not send UDP messages.

That is the case for outgoing configs, i.e. Items that publish messages, i.e items with a config that starts with >.

For incoming configs, i.e. Items that receive messages, i.e items with a config that starts with <, the IP:port is the IP address:port of the machine sending the message.

< for inbound-triggered communication, whereby the openHAB runtime will act as a server and listen for incoming connections from the specified <ip address>:<port>

Hello rich,

I tested this. If I do not configure anything in udp.cfg, the binding does not receive any data. I have to configure just one line in the config be enable of receiving of data.

If I configure ip address:port in the item the debug log tells me, that a packet arrived with wrong source port and the binding does not know what to do. If I user ip address:* in the item, it is working because now, the source port doesn’t matter.

What I want to have is to configure the listening port in OH for the binding. In the remote device I can only configure the destination port not the source port of the packet

Which is why I quoted the more about the bug in UDP.

Which means your client is trying to connect to a different port than the ones you have configured in your Items.

The source port is the port the client is connecting to on OH. I may not know this binding but I do know socket programming.

The way it works is you have a client and a server. The server listens for connections on a certain port. Clients initiate connections to that same port. The clients do not have a pretty if their own.

So the error is that the client is trying to open a convention to a different port than what is configured on the Item. Why this would be the case I can’t say. I don’t know what the clients are.

Hi Rich, we are thinking the same, only my englisch is to bad.

on OH:
upd binding is listening on 56000 by udp.cfg file

This here tells OH-binding the source port of the sending device (not OH)
item = udp="<[192.168.0.1:3000

If I send a packet from these sending device to port 56000 on OH I cannot configure the source port on these device. The next free one is used.

And if this free one is not 3000 the binding tells me in the log “received packet with wrong source port” no matching item. Because binding will receive packet maybe with 192.168.0.1:27432. Does not match with item config

No. The server owns the port. So it is OH that is listening on port 56000.

So your client needs to open a socket connection to oh server’s IP address and port 56000.

So if your client is in IP address 10.10 1.123 then the item needs to be configured with 1010.1.123:56000 because it is comming from IP 10.10.1.123 and connecting to port 56000 on the server.

That is going to be your big problem. My understanding is that OH won’t support this. It can only listen on specific ports. It won’t support arbitrary ports.

And frankly that doesn’t make much sense. Typically the way dynamic ports work is that the client connects to a will known port (56000) and then there is a negotiation between the server and client to select another port and move the communication to that new port. Or the client connects to the server at a well known port (56000) and tells the server to connect back to the client’s server at a given port… OH does not support either of these.

The only thing the binding supports is:

  • client: connect to a server at a given IP address and port and send messages
  • server: open a port and listen for connections from a client at a specific IP address on that port and receive messages

It cannot both send and receive on the same socket. It cannot send or receive on dynamic ports.

Hi Rich,

again we are talking about the same, just my englisch is not good enough.

This defines not the OH listen port it defines the source ip and port of the sender (in your word client) of the packet.

If I do a config like that (10.10.1.123:56000), and the client (10.10.1.123) sends the packet to destination port 56000 (on the OH server) the binding tells me, that the port in the item config does not match the source port from the client. And this is clear because in my client I can only configure the destinaten port on the OH server and not the source port on the client.

This is the biggest confusion I think. There really is no source port, at least not in the way that you are describing.

  • The server has a port it listens on: 56000
  • The client connects to the port that the server is listening on: 56000
  • The Item needs to list the IP address of the Item and the port that the client will connect to

So it makes sense that you can’t configure a source port on the client. There is no such thing. The client doesn’t send a packet from a port. It sends a packet to a port.

So are you certain that the packet is indeed being sent to port 56000?

Please post the exact error log statement so I can find it in the source and see under what circumstances it gets logged. My interpretation of the error is that the client is sending the packet to some other port for some reason, or the client is trying to set up a two way socket (in which case the client does open up a port because it is also a server in this case).

This is wrong I think:

I’ve done some tests:

On the client (10.4.1.4) which acts as udp-device which send data to OH server (10.4.1.107):

OH-Server item config:

String ekeyHomeTest         "ekeyHomeTest [%s]"     { udp="<[10.4.1.4:56000:'REGEX((.*))']" }

Log after saving item file:

2018-04-23 19:02:54.882 [INFO ] [g.tcp.AbstractDatagramChannelBinding] - We will accept data coming from the remote end /10.4.1.4:56000
2018-04-23 19:14:54.819 [DEBUG] [g.tcp.AbstractDatagramChannelBinding] - Setting up the inbound channel Channel [item=ekeyHomeTest, command=0, direction=IN, remote=/10.4.1.4:56000, buffer=, isBlocking=false, isReconnecting=false, host=10.4.1.4, port=56000]

Look at the log. “Will receive data from 10.4.1.4:56000” Which means the source port must be 56000!

If you are right, the binding should listen on 56000 for IP-Address 10.4.1.4 and accept packets only for port 56000 on OH IP-Address

2018-04-23 19:18:58.796 [WARN ] [g.tcp.AbstractDatagramChannelBinding] - Received data This is Teststring 01                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            from an undefined remote end /10.4.1.4:61032. We will not process it
2018-04-23 19:18:58.799 [WARN ] [g.tcp.AbstractDatagramChannelBinding] - No channel is active or defined for the data we received from /10.4.1.4:61032. It will be discarded.

For me this means OH binding is only accepting data form source port 56000. The client sends a packet from source port 10.4.1.4:61032 to 10.4.1.107:56000. But this does not match the item and will fail.

If I change item config to

String ekeyHomeTest         "ekeyHomeTest [%s]"     { udp="<[10.4.1.4:*:'REGEX((.*))']" }

it is working.

I’ve written socket programs before. Your interpretation of the comment is incorrect. That log statement, said another way is “We (i.e. openHAB) will accept data coming from the computer at address 10.4.1.4 to my port 56000.”

That is how I interpret the README. I’m assuming that the binding has some code in place to reject connections from IP addresses other than 10.4.1.4. I’ve not looked to verify that. By default, a socket will accept connections from any IP address on that port. This is something specifically implemented by the binding.

This sentence doesn’t make sense. There isn’t a “from port” with UDP packets. There is only a “to port”. The client sends a packet from IP 10.4.1.4 to port 61032 on your OH server. That is why there is no place in your UDP test tool to configure a source port. There is no concept of a source port in UDP sockets. Only the destination port.

I don’t doubt it. If your client is sending the packet to port 61032 instead of port 56000, accepting all packets on all ports from 10.4.1.4 then it would work.

All I can say is that either I have absolutely no memory of how sockets work (unlikely since I’ve had to code this stuff before myself, but always a possibility) or for some reason your test app is not actually sending the messages to port 56000.

I looked at the code a bit and luckily I end up in standard Java code pretty quickly. The address:port combo in the log statement above is coming from a SocketAddress object carried by the DatagramChannel. In the OH code it calls theChannel.channel.connect(theChannel.remote) and remote and I think that is where the hangup is coming from.

UDP is connectionless but when you call connect it sets up a two-way connection. So now I’m wondering if the error is indicating that you don’t have an outgoing Item config for 10.4.1.4:61032 so it doesn’t know how to set up the outgoing connection to send responses back to your client, even though your client is not expecting any.

Based on the README I assumed that the binding was using bind for the incoming connections, not connect. This does change things significantly.

Anyway, the tl;dr is that you will have to set up the Item using * like you have been doing and set up the incoming port in udp.cfg since someone (I’m not sure if it is the client or the server) is choosing a random port for the return communication that isn’t even going to be used.

I have no idea why they would set it up this way and perhaps I’m misreading the code.

This is a similar thread to this one.