Cannot receive messages on subscriber VM (ZeroMQ on VirtualBox) - virtualbox

I have two OpenWrt (18.06.4) VM's (A and B) in VirtualBox and I'm trying to send messages in a publisher-subscriber scheme using ZeroMQ. A is the server, B is the client.
I'm using the following code:
Publisher code: http://zguide.zeromq.org/c:psenvpub
Subscriber code: http://zguide.zeromq.org/c:psenvsub
and it works on my computer, so I decided to try it on the VMs.
I had to compile both (using the SDK) so I can execute them in the VMs. I compiled two times, changing one minor detail:
1) client listening to the IP 10.0.1.4 of the server
2) client listening to the IP 192.168.56.10 of the server
Both versions were tested in the VMs and in both, the server sends the messages (the send function executes and prints the message sent) but the client never receives any message (message is always null).
About my network configuration. In VirtualBox, I have a Nat Network (10.0.1.0/24) and a virtualbox network (192.168.56.1/24). Both VM A and B have a host-only adapter (vboxnet0) and a NAT network adapter.
The machines can ping each other.
The network configuration of the machines is the following:
A
config interface 'loopback'
option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'
config globals 'globals'
option ula_prefix 'fd03:84ea:bc33::/48'
config interface 'lan'
option ifname 'eth0'
option proto 'static'
option ipaddr '192.168.56.10'
option netmask '255.255.255.0'
config interface 'wan'
option ifname 'eth1'
option proto 'dhcp'
Note: The NAT network IP ('wan') is currently 10.0.1.4
B
config interface 'loopback'
option ifname 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'
config globals 'globals'
option ula_prefix 'fdea:4700:64aa::/48'
config interface 'lan'
option ifname 'eth0'
option proto 'static'
option ipaddr '192.168.56.20'
option netmask '255.255.255.0'
config interface 'wan'
option ifname 'eth1'
option proto 'dhcp'
Note: The NAT network IP ('wan') is currently 10.0.1.5
Do you guys have any idea what the problem might be? Should I change the network configuration inside each VM and/or change the adapters on VirtualBox?

Avoid the dependency on symbolic-address resolution:
// zmq_bind (publisher, "tcp://*:5563"); // PUB-side wildcard-address translated
zmq_bind (publisher, "tcp://10.0.1.4:5563"); // explicit address
// zmq_connect (subscriber, "tcp://localhost:5563"); // SUB-side symbolic-address
zmq_connect (subscriber, "tcp://10.0.1.4:5563"); // explicit-address

Related

Tomcat9 remote debugging

Is there some trick for remote debugging a Tomcat9 from outside localhost?
I have a AWS bastion -> server setup and on the server itself
ss -tunlp sees 127.0.0.1:8787 0.0.0.0:*
but nmap on the bastion server doesn't see 8787 open
the other (visible) stuff on the server ss lists as *:port which looks "wider" for sure
The security group for the server is OK and a reachability analysis confirms it. A also see all the other stuff (MySQL, RDP, SSH etc) that I use in exactly the same way
Thanks in advance,
Nik
/etc/default/tomcat9 (on Ubuntu 20) has the line
#JAVA_OPTS="${JAVA_OPTS} -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"
which should be uncommented but apparently is implicitly for binding the listener only on localhost. Changing the port format to
JAVA_OPTS="${JAVA_OPTS} -agentlib:jdwp=transport=dt_socket,address=*:8080,server=y,suspend=n"
widens the binding to external access

Receiving multicast on linux host with multiple interfaces

I have a host running Ubuntu 16.04 connected to one network via the primary wired network interface, and to another network via a USB-to-Ethernet adapter. Using tcpdump, I am able to verify incoming multicast packets on both network interfaces. However, my application does not receive any multicast data from the secondary interface. If I disconnect the cable to the primary interface, and then restart my application, then I do receive the data from the secondary interface. It is only with both interfaces connected that the application does not receive from the secondary interface.
I found a similar problem (Raspberry Pi Zero with USB-to-Ethernet adaptor, fails to respond to mDNS queries). To work out if your problem is the same, does does your app correctly receive multicast traffic whilst running tcpdump at the same time? And does running tcpdump with --no-promiscuous-mode not see multicast traffic?
If your answer is yes to both, then the workaround I've found is simply ip link set eth0 promisc on. I don't know if it is a hardware bug (I'm using a Kontron DM9601 adaptor, ID 0FE6:9700) or a driver bug, but either way, enabling promiscuous mode seems to fix multicast reception for me. Alternatively you could try a better USB-to-ethernet adaptor.
The ip_mreq stucture is passed as the option value for the IP_ADD_MEMBERSHIP socket option to join a multicast group. From the Multicast programming HOWTO from the The Linux Documentation Project:
The first member, imr_multiaddr, holds the group address you want to join. Remember that memberships are also associated with interfaces, not just groups. This is the reason you have to provide a value for the second member: imr_interface. This way, if you are in a multihomed host, you can join the same group in several interfaces. You can always fill this last member with the wildcard address (INADDR_ANY) and then the kernel will deal with the task of choosing the interface.
The IP_MULTICAT_IF socket option is also relevant on a multihomed host to set the outbound interface for multicast data sent via the socket. More information on these socket options, the ip_mreq structure, and the newer ip_mreqn stucture is found here.
For those using Boost on a multihomed host, you will need to use the native handle to join the group on specific interfaces. As of Boost 1.58 running on Ubuntu 16.04, the socket option abstraction ip::multiast::join_group() joins the group on an interface of the kernel's choosing and does not allow the developer to specify an interface. The socket option abstraction ip::multicast::outbound_interface() controls the outbound interface but does not affect which interface the socket receives on.
Here is a code sample to join a group on a specific interface based on the local interface IP address:
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(discovery_ip);
mreq.imr_interface.s_addr = inet_addr(local_interface_ip);
if(setsockopt(socket_.native_handle(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) {
... handle error ...
}

How to make a .cpp file to act as an accessible server

I have written a simple program with Linux (Cent OS 7.0) and C++. It is a very small server which sends back a string of characters to the client. But my problem is that I don't know how should I access that server using an IP address?
I have used Linux Socket Interface (Berkeley), and in the section which defines the address, my code does the following:
serverObject.
sin_family = AF_INET;
serverObject.sin_addr.
s_addr = htonl(INADDR_ANY);
serverObject.
sin_port = htonl(portNumber);
I use INADDR_ANY as my server's address which is defined in its definition as:
/* Address to accept any incoming messages. */
Now, how should I run the server, and then use my simple client program to send request to it. My simple client program accepts an IP address as it's destination address, this address should be the one destined toward to the server. How should I relate it then?
INADDR_ANY goes to specify that all active network interfaces in the system should be bound to. So if you're connected to more than one network, you'll be able to communicate with connections coming in from all of them. Most systems will usually have just one, though, and this still goes to say that if the IP bound to that interface happens to change, you'll still bind to that interface.
So, once you specify INADDR_ANY, you need to initiate connections according to the following rules:
If you're connecting from the same physical machine, the easiest thing would be to use the loopback interface (127.0.0.1). However, you can still do (2).
If you're connecting from another machine, you need to pick the accessible IP address of your server from that machine. As said above, if your server is only connected to one network, this will simply be the IP address of the server. Within an internal network this will often be something like 192.168.x.y, or 10.0.x.y—but it doesn't have to.
If you're connecting from a different network which uses a gateway to access your server, then you will need to set up port forwarding in the relevant routers so that when they receive connection to port X, they will know to internally transfer it to your server.
As a server programmer, you decide the port on which to listen, but not the address.
The internet address is provided by your internet provider, or 127.0.0.1 to test on your own machine.
There are plenty of web pages on internet that provide tools to tell you your current public address (search for What is my Ip).
Most of the "home" internet routers implement NAT: they have a single internet address and map them to many device, that carry the Port number to be changed (your port 80 become port (e.g.) 2345 for outside). To allows a client from outside your home to access your server, you are required to configure your router to map the server port, so for example your public port 80 map to your server port 80.
With that said, you should be able to connect your client to your server through an address and port.
If then you want to use a name (example.org) instead of an IP (93.184.216.34), a Domain Name Server is used. But that is another topic.

C++ Socket Programming- Finding client machines IP, TrueIP, and bind port

I am having some trouble figuring out how to fill out a custom UDP header. The client normally connects to a server/port specified in the arguments, and optionally it also accepts a relay IP and port number, the relay then uses the info in the header to forward to the server. Currently the program works if provided a raw IP address (i.e. 127.0.0.1), however I cannot get the relay to function properly.
I am using the following arguments:
clientport=atoi(argv[5]); //port on current machine to bind (default 0)
relayport=atoi(argv[4]); //port on relay to connect to
relay = argv[3]; //relay IP
port = atoi(argv[2]); //server port
servername = argv[1]; //server IP
I need to fill out the following in my header for the relay (in network byte order):
uint32_t from_IP, to_IP; // Ultimate destination, not the relay
uint32_t trueFromIP, trueToIP; // AWS may change public IP vs private IP
uint16_t from_Port, to_Port; // Ultimate source & destination, Not relay
I understand that if 0 is provided for the clientport it will choose any port (this happens by default when binding), how can I figure out which port is chosen and include it as 'from_port'?
How do I get the client machine's IP address, and "true" IP address?
How can I detect if a hostname is used as an argument rather than an IP address, and how would I code it so either would work? Right now I am using something like :
inet_aton(servername OR relay, &server.sin_addr);
to fill out the sin_addr for the server/relay's sockaddr_in, which only works if provided an IP address.
after you call bind(), you can use getsockname() to find out the port that bind() chose.
a machine can have multiple IPs install, so to get the "true" IP, you need to know which specific NIC/Adapter is being used to communicate with the relay, and then you can retrieve that NIC/Adapter's IP. There is nothing in the socket API for getting that IP, you need to use platform-specific APIs instead, like GetAdaptersInfo()/GetAdapterAddresses() on Windows, or getifaddrs() on other platforms. Once you have decided on a particular NIC/adapter, you can bind() the client socket to that IP.
use getaddrinfo(), or just parse the string yourself using platform-specific APIs, like WSAStringToAddress() or RtlIpv(4/6)StringToAddress() on Windows.

configure networking between vm on virtualbox

I installed virtual box on my window 7 laptop, when i install new vm and install ubuntu os,now when i choose nat everything works fine when i am unable to configure host-only network on it .
and one more problem i am facing when i clone that machine and start it and change mac address from setting and start sometime no network configured on the machine .
i actually want to start two vm on virtual box ,both machine have 2 network adapter 1 for nat to communicate any where and one for host and local vms. if is possible or not if yes tell me configuration . i already tried solution from googling no luck still .
You can achieve that using only "Host-only Networking".
Setup is as follows:
Host:
At least 1 Host-only Network is present and configured, e.g.
- ip address is set to: 192.168.56.1
- dhcp server: enabled or disabled (works on both)
Note the name of the Host-only network, e.g. "vboxnet0". This will be used in the next steps.
Guest VM 1:
1. Set Adapter 1 (or any other adapters) to "Host-only Adapter".
2. Make sure Name is set to the name noted in the Host section above, e.g. "vboxnet0".
Guest VM 2 (same steps with Guest VM 1):
1. Set Adapter 1 (or any other adapters) to "Host-only Adapter".
2. Make sure Name is set to the name noted in the Host section above, e.g. "vboxnet0".
You can now start your VMs, and verify connectivity by pinging.
Note that if you are using Windows, you must disable firewall or just enable network sharing and discovery.
i found the solution , we can use bridge networking/host -only networking for establish communication channel among vms and host os
we can use nat for one n/w adapter and we choose either bridge networking or host -only on another adapter .
nat for connecting vm to internet
bridge networking/host -only -- communication among vms and host machine
1-if you have firewall switch it off
do a bridged network using you primary adapter.
use static IP on both
it will work just did and it worked fine for me.
Adding more details :
open vmware
click on file --> preference--> network--> Host-only Networks
Step 1 :Click on add and give a name lets say : Virtual Host-only Ethernet Adapter
select tab:
Adapter : 192.168.92.1 (we can select ip range own)
Ipv4 Network Mask: 255.255.255.0
without this it will also work ,For safe side configure dhcp too:
select tab --> DHCP Server
Server Address : 192.168.92.1
Server Mask: 255.255.255.0
Lower Address Bound : 192.168.92.2
Upper Address Bound : 192.168.92.200
VM Machine level configuration:
Adapter1 : enable this adapter for NAT
Adapter2 : Enable Network Adapter --> select this checkbox
Attached to : Host-only Adapter
Name: Virtual Host-only Ethernet Adapter( name get from Step 1)
on linux machine :
2nd network interface configuration, eth1
#append below line in networking conf : /etc/network/interfaces
auto eth1
iface eth1 inet dhcp
for statics:
#append below line in networking conf : /etc/network/interfaces
auto eth1
iface eth1 inet static
address 192.168.92.5
#gateway 192.168.92.1
netmask 255.255.255.0
broadcast 192.168.92.255
network 192.168.92.0