Re: [Bacnet-developers] using automatic source port in bacnet-stack
Brought to you by:
skarg
|
From: Radoslav K. <rad...@em...> - 2020-07-01 22:05:56
|
На ср, 1.07.2020 г. в 20:28 Mikhail Tchernychev via BACnet-developers <bac...@li...> написа: > There seem to be simpler a way of doing it. It is enough to assign source port as "0" and system would automatically > pick available port for connection to the server port 48808. That would be the usual way to implement an UDP client. I don't remember where, but while reading up on BACnet I remember seeing somewhere that there is no such thing as 'pure client' in BACnet. Every participant in the BACnet network is required to also be a server supporting some minimal set of services and properties. Maybe this kind of port allocation has something to do with this requirement, but it should be just binding and listening on the port, not using it as the source port for outgoing packets. > I wonder if it would be possible to make bacnet-stack thread safe, to handle multiple servers in one app, or at least to consider it. I don't have this requirement, but from what I've gathered looking at the code it seems your approach is the only one possible at this time as currently there are global static variables in most files. While scrounging the mailing list archives I have run into the 'jbennet' branch, which is unfortunately 10 years out of date, but it implements a 'session object'. Might be interesting for you too check it for some ideas. > On Wednesday, July 1, 2020, 9:48:58 AM PDT, Steve Karg <st...@ka...> wrote: > * This is useful when trying to run a BACnet server and simultaneously > * use the BACnet command-line utilties on a single Linux host. > * Ordinarily this would be impossible as each of these "apps" would > * need to bind to and receive on the standard BACnet UDP port (47808), > * and Linux doesn't allow multiple processes to share a UDP socket > * in a useful way (i.e., such that all processes receive all packets). As a side effect from virtualisation and containers Linux has evolved a very flexible virtual networking support. I'd dub Steve's way to solve the above problem the 'BACnet way', but for people like me - more familiar with Linux than BACnet there is an alternative. We can create a new 'network namespace' and run the client or server inside it. This will isolate the client and server and allow them to bind to the same ports (each on a different IP address, as if running on two separate machines connected to the same network) and communication to work as expected. It would go something like this: #create a new network namespace for the bacnet server ip netns add bacnet #add a virtual network link between the current (default) network namespace and the bacnet one ip link add veth0 type veth peer name veth1 netns bacnet #assign IP addresses and bring the veth0 interfaces in the default namespace ip addr add 10.1.1.1/24 dev veth0 ip link set dev veth0 up #set correct interface to be used by bacnet-stack examples export BACNET_IFACE=veth0 #start the server example apps/server/bacserv 123 Now open a new terminal window. To save some typing of 'ip netns exec bacnet' before every command we'll start a shell inside the new network namespace and run the commands through it: ip netns exec bacnet bash #assign IP addresses and bring the veth1 interfaces in the bacnet namespace ip addr add 10.1.1.1/24 dev veth1 ip link set dev veth1 up #set correct interface to be used by bacnet-stack examples export BACNET_IFACE=veth1 #start the read property example and read the present value of analog output 3 readprop 123 analog-output 3 present-value The above could be extended to an arbitrary number of bacnet servers or clients running on the same Linux host by creating a separate network namespace for each one and connecting all of them together via a virtual bridge. I think it can be useful, especially during development/testing. |