UDP message size difference - udp

Say that A sends B a UDP message of size N like
sockaddr_in to;
to.sin_family=AF_INET;
to.sin_port=htons(port);
to.sin_addr.s_addr=inet_addr(address);
sendto(sock,(const char*)buffer,N,0,(sockaddr*)&to,sizeof(to));
Now B receives this message expecting it to be of size N_1
sockaddr from;
socklen_t length_from=sizeof(from);
recvfrom(sock,(char*)buffer,N_1,0,&from,&length_from);
What happens when N_1!=N ?

What happens when N_1!=N ?
If the receive buffer is larger than the incoming datagram, the entire datagram is transferred into the buffer and the actual length is returned as the return value of recfvrom(). You're presently ignoring it. Don't do that.
If the receive buffer is smaller than the incoming datagram, it is truncated to fit into the receive buffer and he excess beyond that is discarded. The actual length of data transferred into the buffer is returned.

Related

How ETX (Estimated Transmissions) is implemented in contikiRPL?

I am working on creating a modified version of MRHOF for RPL. However, I
have some doubts about the ETX metrics used. i am running an rpl-udp example (..../contiki-3.0/examples/ipv6/rpl-udp).
As per my understanding, the general definition of ETX is following:
ETX = 1/(df * dr)
where df is the measured probability that a data packet successfully arrives at the recipient and dr is the probability that the ACK packet is successfully received.
The implementation of ETX is defined in neighbor_link_callback(rpl_parent_t *p, int status, int numtx) (contiki/core/net/rpl/rpl-mrhof.c) as below:
new_etx = ((uint32_t)recorded_etx * ETX_ALPHA +(uint32_t)packet_etx * (ETX_SCALE - ETX_ALPHA)) / ETX_SCALE
where
recorded_etx = nbr->link_metric
packet_etx = MAX_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR
nbr->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR (rpl-dag.c)
RPL_INIT_LINK_METRIC = 2 (rpl-conf.h)
ETX_SCALE = 100
ETX_ALPHA = 90
RPL_DAG_MC_ETX_DIVISOR = 256 (rpl-private.h)
MAX_LINK_METRIC = 10
Here every time when link layer receives an ACK or time-out event the function inside this file (neighbor_link_callback) is fired.
I understood the formal definition of ETX, but when i am trying to map the standard ETX formula with contikiRPL's ETX formula then i am facing some trouble in understanding the implementation of ETX in contikiRPL.
How the probability of a data packet successfully arrives at the recipient (df) and probability that the ACK packet is successfully received (dr) are implemented in ContikiRPL?
In the code, df and dr individually are not known. The algorithm is run on the sender device, which has no means to differentiate between the case when the packet is lost and the case when the ACK is lost. They look exactly the same to it: as the absence of the
The value of packet_etx roughly corresponds to 1 / (df * dr) of the last packet. Note that a single packet already may have had multiple retransmissions on the link. The metric is updated only when the packet is successfully ACKed or when the maximal number of retransmissions is exceeded.
Another issue in Contiki is that since its designed for embedded systems, it does not have the memory to keep in track the ETX of many recent packets. Instead, this information is aggregated in single value with the help of exponentially weighted moving average (EWMA) filter. The \alpha paramter of the algorithm is given as ETX_ALPHA / ETX_SCALE in the code; the scaling is done to avoid the more expensive floating point operations.
The value of recorded_etx is the previous value of the ETX, reflecting the ETX calculated from all of the previous packets. The value of new_etx is the value of the link's ETX when the previous ETX and the last packet's ETX have been combined with the ETX algorithm.

How to send/receive variable length protocol messages independently on the transmission layer

I'm writing a very specific application protocol to enable communication between 2 nodes. Node 1 is an embedded platform (a microcontroller), while node 2 is a common computer.
Such protocol defines messages of variable length. This means that sometimes node 1 sends a message of 100 bytes to node 2, while another time it sends a message of 452 bytes.
Such protocol shall be independent on how the messages are transmitted. For instance, the same message can be sent over USB, Bluetooth, etc.
Let's assume that a protocol message is defined as:
| Length (4 bytes) | ...Payload (variable length)... |
I'm struggling about how the receiver can recognise how long is the incoming message. So far, I have thought about 2 approaches.
1st approach
The sender sends the length first (4 bytes, always fixed size), and the message afterwards.
For instance, the sender does something like this:
// assuming that the parameters of send() are: data, length of data
send(msg_length, 4)
send(msg, msg_length - 4)
While the receiver side does:
msg_length = receive(4)
msg = receive(msg_length)
This may be ok with some "physical protocols" (e.g. UART), but with more complex ones (e.g. USB) transmitting the length with a separate packet may introduce some overhead. The reason being that an additional USB packet (with control data, ACK packets as well) is required to be transmitted for only 4 bytes.
However, with this approach the receiver side is pretty simple.
2nd approach
The alternative would be that the receiver keeps receiving data into a buffer, and at some point tries to find a valid message. Valid means: finding the length of the message first, and then its payload.
Most likely this approach requires adding some "start message" byte(s) at the beginning of the message, such that the receiver can use them to identify where a message is starting.

What is the correct MTU setting for the gnuradio UDP Source block for a payload size less than the default 1472?

The gnuradio UDP Source block has a default Payload Size of 1472. The documentation indicates
"payload_size : UDP payload size by default set to 1472 = (1500 MTU - (8 byte UDP header) - (20 byte IP header))"
My C client program sends packets of 16 bytes to the gnuradio udp source once every second.
Should I set the MTU value to 16?
Thank you.
No, the Payload Size refers to the maximum packet size that can be handled by the block. However, the block then handles your 16 byte as a stream, so if you like to keep this packet form additional steps are required.

Recvfrom() return value

Im using UDP packets and I want to be cleared about some points :
1 - what exactly does "recvfrom" Returns ? I mean if i send a packet with size of 450 byte + 20 byte of IP header + 8 byte UDP header does recvfrom returns 478 bytes as a whole or there could be something like :
it received 10 bytes,300 bytes,100 bytes,68 bytes ?
2 - does the return value of "recvfrom" related to packet fragmentation ?
note :
* Im talking with the assumption that "recvfrom" was successful
* I chose 450 byte to be sure that Im less than the min MTU
For an UDP socket, recvfrom() reads the UDP data. So it returns 450 , provided you supply a buffer that is at least 450 bytes big.
If you supply a buffer that is smaller than the received data, the data will be truncated, and recvfrom() will read as much data as can fit in the buffer you give it.
The IP layer will be the part that fragments an UDP packet, on the receiving host it will reassemble it. This is transparent to the sending/receiving application.

read specific size of data from boost asio udp socket

I want to read specific number of bytes from udp socket. In tcp socket I can use socket.read where I can specify the amount of data to receive. I don't find similar function for UDP socket. I am using receive_from() where I can specify the amount of data to read, but if there is more data then no data is read and I get following error.
"A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself" std::basic_string<char,std::char_traits<char>,std::allocator<char> >
I am not able to find what value do I need to give for message_flags (3rd arg to receive_from) so that it will read the number of bytes specified. Currenly I am using the following code to read data but it either reads all data or no data.
size_t size=socket.receive_from(boost::asio::buffer((const void*)&discRsp,sizeof(DataStructure)),remote_endpoint,0,errors);
Try this:
socket.set_option(boost::asio::socket_base::receive_buffer_size(65536));