Is kernel did de-fragmentation - c

When I received packet with recv at linux, is the kernel did de-fragmentation so I will get de-fragmentation data? Or should I take care of it on user-space?

When receiving UDP data via a socket of type SOCK_DGRAM, you'll only receive the complete datagram (assuming your input buffer is large enough to receive it).
Any IP fragmentation is handled transparently from userspace.
If you're using raw sockets, then you need to handle defragmentation yourself.

ip fragmentation takes place at the IP level in the protocol stack. The layers TCP and UDP already receive recomposed packets due to fragmentation, so the TCP can receive full segments (despite that TCP tries to neve send segments that result in fragmented packets) and UPD receive full datagrams to preserve datagram boundaries.
Only if you use raw sockets you'll receive raw packets. (this meaning fragments of IP packets) TCP gives you already reliable data streams (preserving data sequence, repetitions and retransmission of missing/faulty packets) and udp gives you the datagram as it was sent, or nothing at all.
Of course, all these modules are in the kernel, so it's the kernel that recomposes packets. It's worth noting that, once a packet is fragmented in pieces, it is not recomposed until it reaches its destination, so it's the IP layer at destination who is responsible of reassembling the fragments.

Related

Who take care tcp message order

I listen to tcp socket in linux with recv or recvfrom.
Who taking care that I will get the tcp packets on the right order?
Is that the kernel taking care so if packet 1 came after packet 2 the kernel will drop out both/save packet 2 until packet 1 will come?
Or maybe I need to take care on user-space to the order of tcp packet?
On Linux based systems in any normal scenario, this is handled by the kernel.
You can find the source code here, and here's an abridged version:
/* Queue data for delivery to the user.
* Packets in sequence go to the receive queue.
* Out of sequence packets to the out_of_order_queue.
*/
if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
/* packet is in order */
}
if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) {
/* already received */
}
if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt + tcp_receive_window(tp)))
goto out_of_window;
if (before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
/* Partial packet, seq < rcv_next < end_seq */
}
/* append to out-of-order queue */
tcp_data_queue_ofo(sk, skb);
along with the actual implementation that does the reordering using RB trees:
To quote Wikipedia,
At the lower levels of the protocol stack, due to network congestion, traffic load balancing, or unpredictable network behaviour, IP packets may be lost, duplicated, or delivered out of order. TCP detects these problems, requests re-transmission of lost data, rearranges out-of-order data, [...]
It's an inherent property of the protocol that you will receive the data in the correct order (or not at all).
Note that TCP is a stream protocol, so you can't even detect packet boundaries. A call to recv/recvfrom may return a portion of a packet, and it may return bytes that came from more than one packet.

No packet loss in sending packets over local UDP sockets

Is it normal that there will be no packet losses in a UDP client-server if both are on the same machine? I'm currently calculating packet loss by taking the difference between the bytes obtained from the sendto and recvfrom functions on the client side ? Am I doing something wrong ?
I would be very surprised if there was any packet loss in such a case. But on the other hand you use the wrong way to calculate any loss.
Remember that UDP is a packet oriented protocol, which means that what you send will be a packet, and what you receive will be a packet, and there will be no difference in the size of what you send and receive. If you send a 512-byte packet, the receiver will always receive the full 512-byte packet, or nothing at all.
That means you should count the number of times you call sendto, and compare the number of times that recvfrom returns with a packet.

Path of the UDP packet from kernel to user-space in Linux

I'm maintaining some network driver and I've got some problems with lost of data. The effect is that when I send for example ICMP or UDP ping using ping or nping some of the udp/icmp packets are lost.
I'm sure that on ping/nping side of the transmission the ping reply is received by my driver and the kernel (tcpdump shows incoming udp or icmp packets as a reply).
But application ping/nping shows sometimes that for example 80% packets are lost. I suspect that those packets are lost somewhere between kernel and user space.
I know that for UDP there is procedure udp_rcv() for maintenance of UDP packets, but I don't know which procedure is next in the path of delivering of the packet to user space application.
Linux kernel is in version 3.3.8.
My question is - how to trace the whole path of transition of the packet from my driver to user space socket buffer?
udp_rcv() is a callback that is passed to struct net_protocol as a .handler.
You may either look at usage of this handler field in the structure, or you can also see if some error occurs. There is a callback err_handler. Maybe packet loss happens here and error handler will be called.
P. S. Remember that UDP does not guarantee 100% transmit success, and one lost packet out of 100 might be expected behavior. (:

Can LoadRunner Receive Data By UDP Packets?

We want to receive packets from udp sockets, the udp packets have variable length and we don't know how long they really are until we receive them (parts of them exactly, length were written in the sixth byte).
We tried the function lrs_set_receive_option with MarkerEnd only to find it has no help on this issue. The reason why we want to receive by packets is that we need to respond some packet by sending back user-defined udp packets.
Is there anybody knows how achieve that?
UPDATE
The LR version seems to be v10 or v11.
We need respond an incoming udp packet by sending back a udp packet immediately.
The udp packet may be like this
| orc code | packet length | Real DATA |
Issue is we can't let loadrunner return data for each packets, sometimes it returns many packets in a buffer, sometimes it waits until timeout though when there has been an incoming packet in the socket buffer. While in the c programming language world, when calling recvfrom(udp socket) we are returned only one udp packet per time (per call) which is want we really want.
If you need raw socket support to intercept at the packet level then you are likely going to have to jump to a DLL virtual user in Visual Studio with the raw socket support.
As to your question on UDP support: Yes, a Winsock user supports both core transport types, UDP and TCP. TCP being the more common variant as connection oriented. However, packet examination is at layer 3 of the OSI model for the carrier protocol IP. The ACK should come before you receive the dataflow for your use in the script. You are looking at assembled data flows in the data.ws when you jump to the TCP and UDP level.
Now, you are likely receiving a warning on receive buffer size mismatch which is taking you down this path with a mismatch to the recording size. There is an easy way to address this. If you take your send buffer and construct it using the lrs_set_send_buffer() function, then anything that returns will be taken as correct, ignoring the previously recorded buffer size and not having to wait for a match or timeout before continuing.

Can a Non Blocking UDP write return with fewer bytes than requested?

I have an application that sends data point to point from a sender to the receiver over an link that can operate in simplex (one way transmission) or duplex modes (two way). In simplex mode, the application sends data using UDP, and in duplex it uses TCP. Since a write on TCP socket may block, we are using Non Blocking IO (ioctl with FIONBIO - O_NONBLOCK and fcntl are not supported on this distribution) and the select() system call to determine when data can be written. NIO is used so that we can abort out of send early after a timeout if needed should network conditions deteriorate. I'd like to use the same basic code to do the sending but instead change between TCP/UDP at a higher abstraction. This works great for TCP.
However I am concerned about how Non Blocking IO works for a UDP socket. I may be reading the man pages incorrectly, but since write() may return indicating fewer bytes sent than requested, does that mean that a client will receive fewer bytes in its datagram? To send a given buffer of data, multiple writes may be needed, which may be the case since I am using non blocking IO. I am concerned that this will translate into multiple UDP datagrams received by the client.
I am fairly new to socket programming so please forgive me if have some misconceptions here. Thank you.
Assuming a correct (not broken) UDP implementation, then each send/sendmsg/sendto will correspond to exactly one whole datagram sent and each recv/recvmsg/recvfrom will correspond to exactly one whole datagram received.
If a UDP message cannot be transmitted in its entirety, you should receive an EMSGSIZE error. A sent message might still fail due to size at some point in the network, in which case it will simply not arrive. But it will not be delivered in pieces (unless the IP stack is severely buggy).
A good rule of thumb is to keep your UDP payload size to at most 1400 bytes. That is very approximate and leaves a lot of room for various forms of tunneling so as to avoid fragmentation.

Resources