Any examples of UDPServer and joining multicast group? - reactor-netty

Just getting started with Netty-Reactor and was wondering if anyone had any examples on how to use the UdpServer to join a multicast group and process the incoming packets. I'd also like to use UdpClient to send messages over the wire.
The current documentation is a little sparse on examples.
I'm confused how much of Netty custom objects I need to write versus what the Netty-Reactor project hides from me.. I see there are UdpInbound and UdpOutbound.. how are those related to channel encoder and decoders? Do I still need those?
I'd like to make an example of a UDP server listening on a multicast group and to listen for Google Protobuf messages send to the group. I know how to do all the protobuf processing off the wire..
I'm just not sure how to do the actual listening on the wire with Netty-Reactor.
I see there is UdpInbound.join() which looks like what I want..but I'm lost after that.
Can anyone point me to examples?
Thanks
UPDATE:
#Violeta - Thanks for the help and link! It helped me a litte bit more.
I think I found a bug? or maybe I misunderstand how to get both IPv4 and IPv6 working on the same server. I noticed in your example code that you use the .runOn(resources, InternetProtocolFamily.IPv4).
Without this code, my binding fails when I have an InetInterface that has both IPv4 and IPv6 address assigned.
I would like to support both IPv4/IPv6 on the same server and all interfaces since the code will run on multi-homed machines.
I don't see a way to specify the InternetProtocolFamily on the connection other than to use the .runOn method.
I get the following error:
IFace: name:en0 (en0) Address class: /fe80:0:0:0:1ce8:a828:3c15:4f4b%en0 is Inet4Address = false
IFace: name:en0 (en0) Address class: /192.168.1.151 is Inet4Address = true
09:42:35.615 [udp-nio-1] INFO server.Application - Joining iFace name:en0 (en0) to Multicast Group /224.0.0.224
09:42:35.621 [udp-nio-1] ERROR reactor.Flux.ConcatArray.1 - onError(java.lang.IllegalArgumentException: IPv6 socket cannot join IPv4 multicast group)
09:42:35.623 [udp-nio-1] ERROR reactor.Flux.ConcatArray.1 -
java.lang.IllegalArgumentException: IPv6 socket cannot join IPv4 multicast group
at sun.nio.ch.DatagramChannelImpl.innerJoin(DatagramChannelImpl.java:814)
at sun.nio.ch.DatagramChannelImpl.join(DatagramChannelImpl.java:900)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:414)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:391)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:384)
at reactor.netty.udp.UdpOperations.join(UdpOperations.java:65)
at server.Application.lambda$null$2(Application.java:45)

UdpInbound.join() returns Mono<Void>, the publisher will be complete when the group has been joined.
After that you can start receiving packages using UdpInbound.receive().
in.join(...)
.thenMany(in.receive()
...)
...
See here for some examples.
You can use either handler method for handling the I/O (as it is in the link), or you can just bind and when you receive the Connection, you can invoke Connection.inbound() and then you can join and start receiving packages.
About decoders/encoders we encourage you to use the operators from Reactor Core for transforming the incoming packages. If you cannot achieve this with that approach you can always add a standard Netty handler, using for example doOnBound(conn -> conn.addHandler...)

Related

How to store receiving SMS in GSM Module memory (SM or ME)?

I am using AI Thinker A7 GSM/GPRS/GPS Module demo v7.1.
I am trying to send and receive SMS through AI-Thinker Serial Tools V1.2.3.0
This module is working fine with making a call and receiving a call, sending and receiving an SMS. They work exactly fine.
The problem is that it does not store SMS in the memory?
I have done a lot of things to make it work, but there is no progress.
For instance, my AT commands and their responses are here,
AT+CPMS=?
+CPMS: ("ME","SM"),("ME","SM"),("ME","SM")
and
AT+CPMS="SM"
+CPMS: 0,35,0,35,0,25
and
AT+CPMS="ME"
+CPMS: 0,25,0,35,0,25
And I have tried CNMI settings like these,
AT+CNMI=1,1,0,0,0
OK
After these, I send msgs, and then tried to check through AT+CPMS and AT+CMGL, but there are no messages stored.
then I tried
AT +CNMI = 2,1,0,0,0
OK
and the same with
AT +CNMI = 2,2,0,0,0
OK
similarly
AT +CNMI = 0,1,0,0,0
OK
But still, I have not succeeded in getting message stored in memories.
Please help, if there are any other settings I need to do or my commands are wrong or my module doesn't support storing SMS (i highly doubt it since it has memory spaces which are showing that 25 SMS in SM, 35 in ME can be stored)??
If I understand your problem correctly, you are trying to read incoming SMS but can't list them.
Well, you need to understand that your GSM module doesn't store any incoming SMS by default. You have to command your GSM Module to store it. As you mentioned, you were very close to command for that. you need to command it this way:
AT+CPMS=mem1,mem2,mem3
AT+CPMS="SM","SM","SM"
As per documentation, you can mention three memories as the parameter for different operations like:
mem1 (in this example SM) - a memory from which messages are read and delete
mem2 (in this example SM; but could be ME) - a memory from which writing and sending operations are made
mem3 (in this example SM; but could be ME) - memory to which received messages are preferred to be stored
Now your GSM module will store all incoming messages into the SIM card and you'll be able to list all the messages with AT+CMGL=ALL
This way it worked for me.

How to pick up IP packets and inject on different VM and interface

I have been trying to solve these 2 problems, but without success.
I wonder if it's possible to remove specific packets from an interface with Gopacket or is it just for listening on the wire? For example when I send a UDP packet to a wrong port and then with Gopacket I correct it, it will send 2 packets, 1 to the wrong port and 1 to the correct one. Is there a way to discard/drop the wrong packet with Gopacket?
What I am trying to do, is to pick up all packets that are sent by a client over IP and then encapsulate each packet as a payload in another protocol X and send to the remote host which will receive on protocol X, get the payload and send it on its interface to reach the server over IP again. (IP (Client) -> Protocol X (Sniffer 1) -> Protocol X (Sniffer 2) -> IP (Server))
I have verified that the packet which Sniffer 1 picks up from the Client's interface is the same which arrives at Sniffer 2, but the problem is when Sniffer 2 injects it on the Server's interface. I can't see that packet with tcpdump or any other tool. The packet is injected with this command:
if handle, err := pcap.OpenLive("enp0s8", 1600, true, 100); err != nil {
panic(err)
} else {
err = handle.WritePacketData(packet.Data())
}
If the Protocol X part is avoided, then the server will receive messages from client, but with Protocol X it is not possible.
Thanks in advance!
According to the Documentation
Package pcap allows users of gopacket to read packets off the wire or
from pcap files.
To discard packages, you will need to be able to intercept them. Depending on how generic you want to solve this problem, you probably need to hook into the kernel. I recommend looking into iptables and netfilters.
I found some VPN that are written in go, maybe look into how they are built, as you want to do something similar (tunnelling of packets).

Differences between io.to(), io.in(), and socket.to() for emitting to all clients in a room

The Socket.io documentation seems to specify a few ways to emit an event to all connected clients in a room. They are as follows:
io.to(), as found in the first example here: https://socket.io/docs/server-api/#socket-join-room-callback
io.in(), as found in the emit cheatsheet, found here: https://socket.io/docs/emit-cheatsheet/
socket.to(), as found here: https://socket.io/docs/server-api/#socket-to-room
Other than the examples linked above, both io.to() and io.in() are not listed anywhere else in the documentation. What do these methods do exactly, and where can I find more information on them?
socket.to() can be used inside the io.on('connection', callback) event, like so:
io.on('connection', function(socket){
// to one room
socket.to('others').emit('an event', { some: 'data' });
// to multiple rooms
socket.to('room1').to('room2').emit('hello');
});
However, this does not make sense, as the socket object passed into this callback represents a connected client. How can the incoming socket object be used to broadcast to all other connected sockets, as shown in the above example?
Definitive explanations of the above are appreciated.
However, this does not make sense, as the socket object passed into this callback represents a connected client.
If you trace into those call in a debugger, you can see what is going on.
First off, the socket.to() creates a property on the socket named _rooms that is an array of room names. You can see the whole code in context here in the Github repository, but here's the relevant portion for .to():
Socket.prototype.to =
Socket.prototype.in = function(name){
if (!~this._rooms.indexOf(name)) this._rooms.push(name);
return this;
};
Each successive call to .to() just an addition room to the array.
Then, socket.emit() checks to see if the _rooms property exists and if it does, it calls this.adapter.broadcast(...) which grabs the adapter and tells it to broadcast this message to all sockets on that adapter except the current one. The whole code for socket.emit() is here on Github. The particular broadcast part of the code is this:
if (this._rooms.length || this.flags.broadcast) {
this.adapter.broadcast(packet, {
except: [this.id],
rooms: this._rooms,
flags: this.flags
});
} else {
// dispatch packet
this.packet(packet, this.flags);
}
How can the incoming socket object be used to broadcast to all other connected sockets, as shown in the above example?
Each socket contains a reference to the adapter and the adapter has a list of all sockets on that adapter. So, it's possible to get form the socket to the adapter, to all the other sockets.
I would agree that this is a bit of an odd overloading of functionality, but that's how they do it. I'm guessing they wanted to give people access to broadcast functionality when all you had a reference to was an individual socket.
FYI, the only way to really answer these types of questions yourself that are not documented is by looking at the code and that is certainly one of the huge advantages of using open source libraries. I find that the quickest way to get to the right source is to step into the method of interest in the debugger. Fire up the debugger, set a breakpoint in your code, then step into the function of choice and it will show you the relevant source code immediately. You can then further step through that function if you want to see what path it is taking.
For anyone coming across this question like me, here is the link to the docs for explanation:
https://socket.io/docs/v3/rooms/index.html

What are the use of ID and Kind of a wireless sensor node in Omnet?

How and why sensor node Id is used ?
what are the different type of kind of a sensor node?
why kind is used ?
i need some example of using kind in sensor node application.
Need references and help.
setKind() and getKind() are used to set different type of sensor nodes you want to create through the msg packet they send.you can setKind() for different type of message packets. for example for mobile node you may want to get location of node through msg packet you received you can set a kind to that msg packet at sending end let call it "positionMsg". similarly you can use getKind() ar receiving end to identify that whether the message was for positionMsg or something else.you can give identity to node as well as message using these methods. Similarly you can setKind() for msg packet delivered by different nodes.And at receiving end you can getKind() to identify from which node message was sent.
similarly you can use setId() and getId() method to use identify different sensor nodes. These methods are useful when you are working with multiple types of nodes .
Sensor nodes can be of different types.It all depends on yours implementation. It is implemented using simple module or compound module.Its nature may vary upon implementation.You can use them as router / gateway,cluster head , mobile node(data mules) etc depending upon your need.
For more information you can use omnet++ user manual 1>https://omnetpp.org/doc/omnetpp/Manual.pdf
use this link for implementation guide https://omnetpp.org/doc/omnetpp/api/classcMessage.html
Use tictoc tutorial and and use these methods with cMessage objects.

how do I get the IP of incoming ICMP due to UDP-send to dead client in Ruby?

so.. I'm doing a small multiplayer game with blocking UDP and IO.select. To my problem.. (In the server) reading from a UDP socket (packet, sender = #socket.recvfrom(1000)) which have just sent a packet to a dead client results in a ICMP unreachable (and exception Errno::ECONNRESET in ruby). The problem is that I can't find any way whatsoever to extract the IP of that ICMP.. so I can clean out that dead client.
Anyone know how to achieve this?
thanks
You'll need to call recvmsg for the socket, and pass MSG_ERRQUEUE as the flag.
The original destination address of the datagram that caused the error is supplied via msg_name.
It's worth noting that the source IP address of the ICMP packet will not always be the same address as your client. Any router that handles packets for this connection could be the source, and the payload of the ICMP packet would contain the IP header + the first 8 bytes of the packet it relates to.

Resources