5. Packet Analysis Examples

5.1. Example: Analyzing User Data

Let’s consider an example scenario that involves two hosts, each running a Connext DDS application:

  • Host 1 (10.70.0.246) is running a Connext DDS publishing application, App1.
  • Host 2 (10.70.0.183) is running a Connext DDS subscribing application, App2.
  • The QoS for the writer and the reader have been set up to use Reliable communication.

App1 writes user data every four seconds. To create the sample capture file, Wireshark started capturing packets on the subscribing host after the discovery process completed, using the following capture filter:

rtps && (ip.src == 10.20.1.86 || ip.dst == 10.10.30.100)

Figure 5.1 below shows the packets captured by Wireshark, which include three types of RTPS packets:

  1. Data from the writer to the reader.
  2. Acknowledgements from the reader to the writer.
  3. Heartbeats sent regularly from the writer to the reader.
User Data Sample Packets

Figure 5.1 User Data sample packets

Table 5.1 and Figure 5.2 describe the trace shown in Figure 5.1.

Table 5.1 Analysis of User Data Sample Trace
Packet # Direction Description
1 App1 -> App2 Data packet sent to the reader, containing both INFO_TS and DATA submessages. The packet has a sequence number = 2 (expand the protocol tree in the Packet Details pane and check the writerSeqNumber value, as seen in Figure 5.3 below.)
2 App1 -> App2 HEARTBEAT from writer to reader.
3 App1 <- App2 ACKNACK to acknowledge all data packets up to, but not including, sequence number 3 (expand the protocol tree in the Packet Details pane and check the readerSNState.bitmapBase value).
4 App1 -> App2 Another data packet (sequence number 3).
5 App1 -> App2 HEARTBEAT from writer to reader.
6 App1 <- App2 ACKNACK to acknowledge packet # 4.
7 App1 -> App2 Another data packet (sequence number 4).
8 App1 -> App2 HEARTBEAT from writer to reader.
9 App1 <- App2 ACKNACK to acknowledge packet # 7.
User Data Sample Packet Flow

Figure 5.2 User Data sample packet Flow

To examine a packet in the Packet List:

  • Click on an RTPS packet.
  • Expand the submessage details under “Real-Time Publish-Subscribe Wire Protocol” and expand the submessages to examine them.
Examining Packet Details

Figure 5.3 Examining packet details

5.2. Example: Analyzing Discovery Data Sample Trace

Consider an example scenario that involves two hosts, each running one Connext DDS application.

  • Host 1 (10.10.100.65) is running a Connext DDS publishing application, App1.
  • Host 2 (10.10.30.100) is running a Connext DDS subscribing application, App2.
  • Both applications have a maximum participant index of 1 and have each other in their initial_peers list.
  • All but one QoS are at default values; this default includes the use of automatic discovery via the default UDPv4 transport. The one non-default QoS sets both applications’ initial_participant_announcements to 1, because this reduces the number of redundant announcements in the example trace.

Wireshark was set up to start capturing packets before either application was started. The publishing application was started first, followed (about 6 seconds later) by the subscribing application. Figure 5.4 shows the packets captured by Wireshark.

Discovery Data Sample File

Figure 5.4 Discovery data sample file

Let’s walk through the RTPS packets to understand what occurred in this sequence. Table 5.2 describes what happened (non-RTPS packets are omitted). In the table, the term “meta DATA” refers to DATA packets containing meta (discovery) data (as opposed to user data).

Table 5.2 Analysis of Sample File’s Packets
Packet #’s Direction Description
1-12 App1 -> App2

When the writer participant starts, Connext DDS announces the creation of a new participant to all potential participants in the initial_peers list.

Potential participants are initially calculated as: for each peer in the initial_peers list, peer/participant(i), where i <= maximum participant index.

Since the participant’s maximum participant index is 1 and the initial_peers list contains only 10.10.30.100, the potential participant list is {10.10.30.100/participant(0), 10.10.30.100/participant(1)}.

Since each participant gets its own receive locator, we send separate (but identical) packets to each potential participant listening on its own locator.

Before sending packets with participant information, the participant sends a PING packet to each receive locator (as packets #1 and #2). These packets serve to prime ARP tables and to see if the locators are reachable destinations. Since there is no other Connext DDS application in the same domain, these locators are unreachable (packets #3 and #4).

Because the participant is newly created, it sends its information to each locator (as packets #5 and #6). These are to unreachable destinations (packets #7 and #8). It then again sends its information (packets #9 and #10), in accordance with its initial_participant_announcements QoS of 1. Again, these are to unreachable destinations (packets #11 and #12).

13-18 App1 <- App2

Similar to the writer participant, when the reader participant starts, Connext DDS announces the new participant.

Note: The destination of the writer participant is reachable, so no “unreachable destination” packets are generated.

19-20 App1 -> App2 When the writer participant learns about the new reader participant, it uses HEARTBEATs and ACKNACKs from its builtin discovery endpoints to tell the reader participant about the writer and readers it has. First, it tells the reader participant about its builtin participant liveliness reader (packet #19) and writer (packet #20).
21-22 App1 -> App2 Repeat announcements about the writer participant, which reduces the chance that the newly created reader participant will drop the reply from the writer participant.
23-24 App1 -> App2

HEARTBEATs telling the reader participant how many readers (0) and writers (1) it has. The reader participant will know from this that it has to get a meta DATA from the writer.

Note: To be precise, each meta DATA reflects a change to the state of the writer or reader. The number of writer samples would increase if the writer was changed or deleted.

25 App1 -> App2 Writer participant packet #22 for reader participant index 1 was not reachable, because the reader participant was created with participant ID 0.
26-27 App1 -> App2 ACKNACKs telling the reader participant that builtin discovery readers for publications and subscriptions are created.
28 App1 <- App2 Reader participant begins to announce its builtin discovery endpoints after receiving the writer participant’s announcements. ACKNACK from the reader participant’s builtin participant liveliness.
29-30 App1 <- App2 Re-announcements of reader participant info, triggered by receiving the writer announcements.
31-35 App1 <- App2 Initial HEARTBEATs and ACKNACKs from the reader participant’s builtin discovery endpoints, indicating it has one reader and no writers.
36 App1 <- App2 ACKNACK in response to HEARTBEAT packet #24, requesting that the writer participant’s builtin publication writer resend the meta DATA for its writer.
37-39 App1 <- App2 HEARTBEATs in response to writer ACKNACKs, announcing that the reader participant has one reader and no writers.
40 App1 -> App2 Initial HEARTBEAT from participant liveliness writer, of no samples written.
41 App1 <- App2 ACKNACK from participant liveliness reader, of no samples received.
42-43 App1 -> App2 ACKNACK from writer participant for reader participant to resend the meta DATA for its reader.
44 App1 <- App2 Further HEARTBEATs from the reader participant.
45 App1 -> App2 Resent meta DATA about the reader, sent in response to the ACKNACK of packet #41.
46-49 App1 <- App2 Resent meta DATA about the writer, sent in response to the ACKNACK of packet #36.
50 App1 -> App2 Ping from the application writer to the application reader’s locator.
51-53 App1 -> App2 Writer finally sends user DATA to the reader.