{"id":457980,"date":"2025-04-29T09:29:34","date_gmt":"2025-04-29T09:29:34","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=457980"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=457980","title":{"rendered":"<span>What is DPI Engine?<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/aeb\/b0f\/c03\/aebb0fc039cb44c074993c821bf5490d.png\" alt=\"DPI Engine\" title=\"DPI Engine\" width=\"1781\" height=\"855\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/aeb\/b0f\/c03\/aebb0fc039cb44c074993c821bf5490d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/aeb\/b0f\/c03\/aebb0fc039cb44c074993c821bf5490d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>DPI Engine<\/figcaption><\/div>\n<\/figure>\n<h3>Content table<\/h3>\n<ul>\n<li>\n<p><a href=\"#introduction\" rel=\"noopener noreferrer nofollow\">Introduction<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-network-protocol-packet-layer\" rel=\"noopener noreferrer nofollow\">What is a network protocol, packet, layer?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#osi\" rel=\"noopener noreferrer nofollow\">OSI<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-network-flow\" rel=\"noopener noreferrer nofollow\">What is a network flow?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#flow-direction\" rel=\"noopener noreferrer nofollow\">Flow direction<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-uplink-downlink\" rel=\"noopener noreferrer nofollow\">What is Uplink\/Downlink and why is it not the same as CTS\/STC?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-reassembling\" rel=\"noopener noreferrer nofollow\">What is reassembling?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#how-reassembling-affects-on-flow-classification\" rel=\"noopener noreferrer nofollow\">How can reassembling affect traffic classification?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-service\" rel=\"noopener noreferrer nofollow\">What is a service?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#few-services-on-single-server\" rel=\"noopener noreferrer nofollow\">More than one service on a single server<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#traffic-classification\" rel=\"noopener noreferrer nofollow\">Traffic classification<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#protocol-detection-methods\" rel=\"noopener noreferrer nofollow\">Methods for protocol detection<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#internet-services-classification-methods\" rel=\"noopener noreferrer nofollow\">Methods for classifying internet services<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#workflow-classification\" rel=\"noopener noreferrer nofollow\">Workflow type classification<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#why-is-difficult\" rel=\"noopener noreferrer nofollow\">Why is it difficult?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-else-dpi-engine-does\" rel=\"noopener noreferrer nofollow\">What else is interesting about the DPI Engine?<\/a><\/p>\n<\/li>\n<\/ul>\n<h3>Introduction<\/h3>\n<p><a class=\"anchor\" name=\"introduction\" id=\"introduction\"><\/a><\/p>\n<p>For those familiar with the term DPI (<strong>Deep Packet Inspection<\/strong>), it often evokes unpleasant associations: blocking, regulators, censorship, tightening controls, and so on. In reality, DPI is simply the name of a technology whose essence lies in the deep analysis of network traffic.<\/p>\n<p>It is important to clarify from the outset that DPI examines traffic &#171;inline&#187; \u2014 meaning it analyzes the entire packet (across all OSI model layers), not just the payload (such as the HTTP layer, which, by the way, is almost always encrypted for an in-line analyzer unless it engages in certificate substitution).<\/p>\n<p>Returning to why DPI should not be viewed negatively:<\/p>\n<ul>\n<li>\n<p>is used, in one form or another, in all information security solutions (NTA, NGFW, Network Monitors, NPF, etc.);<\/p>\n<\/li>\n<li>\n<p>helps system administrators monitor events within a network;<\/p>\n<\/li>\n<li>\n<p>enables mobile operators to create attractive plans for subscribers (since this requires traffic classification, for instance, to exclude traffic from messengers if they are unlimited under a given plan);<\/p>\n<\/li>\n<li>\n<p>allows load balancing across the network, providing subscribers with approximately equal connection speeds in high-traffic areas (such as during football matches or concerts \u2014 heavy load on cells, where it is better to provide fair access to messaging and browsing services while limiting bandwidth for platforms like YouTube).<\/p>\n<\/li>\n<\/ul>\n<p>In an operator\u2019s network, DPI must not only classify network flows but also authenticate subscribers, retrieve policies, and monitor their enforcement (throttle speeds, block prohibited resources, restrict access to internal services when the balance is zero, etc.).<\/p>\n<p>The task of traffic classification is fundamental to a full-fledged DPI solution and belongs to a distinct class known as <strong>DPI Engine<\/strong>. This is due to the constant evolution of services \u2014 names change (e.g., Twitter -&gt; X), new domain names, CDNs, new service optimization methods are developed (such as voice or video calls), and new protocols are adopted. As a result, a separate segment of tasks arises that is independent of the type of network (Mobile Core, ISP, Wi-Fi AP, etc.), yet solving these tasks remains essential for each network type. For this reason, deep traffic analysis and network flow classification are carried out specifically by <strong>DPI Engine<\/strong> solutions.<\/p>\n<details class=\"spoiler\">\n<summary>Inline vs. Mirroring<\/summary>\n<div class=\"spoiler__content\">\n<p>DPI solutions typically operate in one of two modes: inline or mirroring.<\/p>\n<p>Inline deployment means that the DPI system is positioned between the client and the external network and must make real-time decisions regarding traffic flow without delayed processing. In contrast, in mirroring mode, the DPI system receives a copy of the traffic rather than the actual live packets. Even when operating in mirroring mode, a DPI can still influence session behavior (for example, by terminating a session through sending a TCP-RST packet); however, such intervention does not require introducing delays to the rest of the packet flow.<\/p>\n<\/div>\n<\/details>\n<h3>What is Network Protocol, Packet, and Layer?<\/h3>\n<p><a class=\"anchor\" name=\"what-is-network-protocol-packet-layer\" id=\"what-is-network-protocol-packet-layer\"><\/a><\/p>\n<p>In order to explain how traffic classification works, it is necessary to introduce some basic concepts. While these may be familiar to experienced readers, it is still worth defining them.<\/p>\n<p><strong>Packet<\/strong> \u2014 a packet is a set of bytes, structured in a specific way, that is received or transmitted over a network interface.<\/p>\n<p><strong>Protocol<\/strong> \u2014 a protocol is a set of rules that govern how data is transmitted between different nodes in a network. Protocols define how data should be formatted, processed, transmitted in order, and more. Different protocols serve different roles in data transmission and are responsible for various functions.<\/p>\n<p><strong>Layer<\/strong> \u2014 a layer refers to the portion of a network packet associated with a particular protocol. This section (<em>set of bytes<\/em>) cannot belong to more than one protocol at the same time.<\/p>\n<p><strong>Field<\/strong> \u2014 a field is a part of a layer (<em>a set of bytes<\/em>) that stores information for specific, predefined purposes. For example, in an IPv4 layer, which occupies 20 bytes (without Options), the sender\u2019s address (4 bytes) is located at byte offset 12, while the receiver\u2019s address (also 4 bytes) is located at offset 16.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fae\/2e8\/e94\/fae2e8e94bfc8a5087a5297a4ece886d.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 1: \u0421\u043b\u043e\u0438 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043a\u0435\u0442\u0430\" title=\"Scheme 1: Protocol layers inside a packet\" width=\"673\" height=\"345\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/fae\/2e8\/e94\/fae2e8e94bfc8a5087a5297a4ece886d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fae\/2e8\/e94\/fae2e8e94bfc8a5087a5297a4ece886d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 1: Protocol layers inside a packet<\/figcaption><\/div>\n<\/figure>\n<h3>OSI<\/h3>\n<p><a class=\"anchor\" name=\"osi\" id=\"osi\"><\/a><\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/OSI_model\" rel=\"noopener noreferrer nofollow\">OSI<\/a> (<strong>O<\/strong>pen <strong>S<\/strong>ystems <strong>I<\/strong>nterconnection model) is a hierarchical, multi-layered framework for network protocols, where each layer plays a specific role in ensuring the successful transmission of data.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/87e\/e54\/264\/87ee54264ded214dbf90c757200084c4.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 2: \u041c\u043e\u0434\u0435\u043b\u044c OSI\" title=\"Scheme 2: OSI model\" width=\"1024\" height=\"668\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/87e\/e54\/264\/87ee54264ded214dbf90c757200084c4.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/87e\/e54\/264\/87ee54264ded214dbf90c757200084c4.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 2: OSI model<\/figcaption><\/div>\n<\/figure>\n<p>The diagram was taken from <a href=\"https:\/\/www.linkedin.com\/pulse\/what-protocol-data-unitpdu-rahima-aktar-mvp1e\" rel=\"noopener noreferrer nofollow\">here<\/a>.<\/p>\n<p>By simplifying the formal definitions of the OSI model layers, we can say the following:<\/p>\n<ul>\n<li>\n<p>Network layer protocols are responsible for data transmission based on the IP addresses of the recipients..<\/p>\n<\/li>\n<li>\n<p>Transport layer protocols ensure that, once data reaches the destination server, the correct application can process it (based on ports). In other words, they &#171;navigate&#187; data not between network nodes but between applications on a device.<\/p>\n<\/li>\n<li>\n<p>Presentation layer protocols determine how the data will be transmitted (encryption, compression, etc.).<\/p>\n<\/li>\n<li>\n<p>Application layer protocols are used to structure data between the client and server applications, so both can process it. For example, in the HTTP protocol (application layer), before the actual data payload (request or response body) is transmitted, information is provided about which resource the request is for, the format of the payload, whether compression is used, and so on. In essence, application layer protocols are what programs\/services on end devices process.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/94e\/d8b\/a15\/94ed8ba1572061ca23c5a8f4b373bd68.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 3: \u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043c\u043e\u0434\u0435\u043b\u0438 OSI\" title=\"Scheme 3: Data transmission according to the OSI model\" width=\"1074\" height=\"720\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/94e\/d8b\/a15\/94ed8ba1572061ca23c5a8f4b373bd68.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/94e\/d8b\/a15\/94ed8ba1572061ca23c5a8f4b373bd68.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 3: Data transmission according to the OSI model<\/figcaption><\/div>\n<\/figure>\n<\/li>\n<\/ul>\n<p>The diagram was taken from <a href=\"https:\/\/www.linkedin.com\/pulse\/how-do-devices-talk-each-other-rahima-aktar-yhbbc\" rel=\"noopener noreferrer nofollow\">here<\/a>.<\/p>\n<h3>What is a network flow?<\/h3>\n<p><a class=\"anchor\" name=\"what-is-network-flow\" id=\"what-is-network-flow\"><\/a><\/p>\n<p>A <strong>network flow<\/strong> (<strong>Network flow<\/strong> or simply <strong>flow<\/strong>) is an abstraction over network packets, used to group them. For example, consider the Internet, which can be viewed as a large number of packets being transmitted between different network participants. Packets are the smallest unit of network exchange. While a packet represents a more physical abstraction (information, a set of bytes transmitted over a communication channel), a flow is more of a logical entity that helps organize packets into groups. For instance, if the sender and receiver IP addresses are the same, that would constitute an IP flow. Another example: when both the sender and receiver IP addresses, as well as the TCP ports, match. This flow could be considered as part of a specific TCP connection. There can be several TCP connections (and not just TCP) between a sender and a receiver.<\/p>\n<p>Thus, the chaos of packets within the network takes on a more structured form when the packets are divided into groups. To better understand, it is easier to imagine a flow as a pipe through which packets fly. From the sender to the receiver, they travel through one pipe (the forward flow), while the return packets go through a neighboring one (the reverse flow). In this example, the pipe represents a grouping of packets.<\/p>\n<blockquote>\n<p>It is important to distinguish between a network flow and an execution thread. A network flow is referred to as <strong>flow<\/strong>, while an execution thread is called <strong>thread<\/strong>.<\/p>\n<\/blockquote>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6fc\/235\/d52\/6fc235d526a6dcc9b3fa2a0727df5ee0.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 4: \u041f\u0440\u044f\u043c\u043e\u0439 \u0438 \u0440\u0435\u0432\u0435\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a\u0438\" title=\"Scheme 4: Forward and reverse flows\" width=\"761\" height=\"251\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/6fc\/235\/d52\/6fc235d526a6dcc9b3fa2a0727df5ee0.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6fc\/235\/d52\/6fc235d526a6dcc9b3fa2a0727df5ee0.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 4: Forward and reverse flows<\/figcaption><\/div>\n<\/figure>\n<p>Packets need to be divided into flows for several reasons. For example, to keep statistics (such as the number of processed packets, bytes, timestamps, etc.), which can be useful for traffic classification or for <a href=\"https:\/\/en.wikipedia.org\/wiki\/Traffic_shaping\" rel=\"noopener noreferrer nofollow\">shaping<\/a> (speed limiting).<\/p>\n<p>The forward and reverse flows are linked to each other (referencing each other), forming a session. A <strong>session<\/strong> is a collection of shared information for related flows. For instance, for two TLS flows (forming a session) after the handshake is completed, parameters such as <em>supported_version<\/em>, <em>application_layer_protocol_negotiation<\/em>, <em>session_id<\/em>, <em>tls_cipher_suite<\/em>, and <em>compression_method<\/em> are common to both flows.<\/p>\n<p>In Diagram 4, the session context is presented as a shared entity that consolidates information characteristic of both flows.<\/p>\n<p>When a packet is processed, the <strong>DPI Engine<\/strong> must associate the packet with a flow. To do this, a flow <em>key\/identifier<\/em> must be calculated based on data from the packet. The key is calculated differently depending on the structure of the packet. Flows can be of various types, but the most common ones are:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"108\" width=\"108\">\n<p align=\"left\">Type<\/p>\n<\/td>\n<td data-colwidth=\"273\" width=\"273\">\n<p align=\"left\">Description<\/p>\n<\/td>\n<td>\n<p align=\"left\">Key<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"108\" width=\"108\">\n<p align=\"left\">Tuple3<\/p>\n<\/td>\n<td data-colwidth=\"273\" width=\"273\">\n<p align=\"left\">IPv4\/IPv6 fragmented flow<\/p>\n<\/td>\n<td>\n<p align=\"left\">{ src_ip, dst_ip, id }<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"108\" width=\"108\">\n<p align=\"left\">Tuple5<\/p>\n<\/td>\n<td data-colwidth=\"273\" width=\"273\">\n<p align=\"left\">IPv4\/IPv6 transport flow<\/p>\n<\/td>\n<td>\n<p align=\"left\">{ src_ip, src_port, dst_ip, dst_port, protocol }<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"108\" width=\"108\">\n<p align=\"left\">Tuple6<\/p>\n<\/td>\n<td data-colwidth=\"273\" width=\"273\">\n<p align=\"left\">Tunnel flow (VLAN-C-TAG, GRE, \u2026)<\/p>\n<\/td>\n<td>\n<p align=\"left\">{ src_ip, src_port, dst_ip, dst_port, protocol, tag }<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>That is, to calculate the key, it is necessary to reach the IP layer, extract the IP addresses, and check that the flow is not fragmented (by verifying the offsets and the MF flag). If the IP packet is fragmented, the ID field should be used to construct a Tuple3 key. If the packet is not fragmented, the next layer after IP should be examined to extract the ports (if it is a transport layer protocol and ports are present), and a Tuple5 key should be constructed.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/250\/b75\/cbf\/250b75cbf45e1bc435e5086c00593d77.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 5: \u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043f\u043e\u0442\u043e\u043a\u043e\u0432\" title=\"Scheme 5: Flow table example\" width=\"801\" height=\"281\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/250\/b75\/cbf\/250b75cbf45e1bc435e5086c00593d77.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/250\/b75\/cbf\/250b75cbf45e1bc435e5086c00593d77.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 5: Flow table example<\/figcaption><\/div>\n<\/figure>\n<p>In the diagram above, the <em>identifier<\/em> field is shown so that its values can be referenced later in the text. In practice, however, the <em>key<\/em> field is the only key used for lookup.<\/p>\n<p>Previously, we discussed types of flows grouped by the type of key. This classification is useful for managing the flow context (buffering data, collecting statistics, etc.), but it is not the only way flows are categorized. Flows can also be divided into <a href=\"https:\/\/en.wikipedia.org\/wiki\/Control_plane\" rel=\"noopener noreferrer nofollow\">Control Plane<\/a> and <strong>User Plane<\/strong> (or <strong>Data Plane<\/strong>) flows.<\/p>\n<p>A <strong>Control Plane flow<\/strong> is a network flow where packets carry &#171;control information.&#187;<\/p>\n<p>Control information refers to data that is not related to the transmission of user content, but instead serves to negotiate transmission conditions and prepare for data transfer.<\/p>\n<p>For example, consider the FTP protocol. After establishing a TCP connection, when the user enters credentials, navigates directories, or queries file sizes \u2014 all of this constitutes control information (<em>Control Plane<\/em>). At the same time, when the user decides to download a file, within the FTP session, a message exchange takes place announcing a socket on the server side that the client must connect to in order to retrieve the file. Then the client initiates a connection to this socket, and the file download begins \u2014 but already in a separate flow. This flow is considered part of the <em>User Plane<\/em>.<\/p>\n<h3>Flow Direction<\/h3>\n<p><a class=\"anchor\" name=\"flow-direction\" id=\"flow-direction\"><\/a><\/p>\n<p>Flow direction is typically divided into <strong>Client-To-Server (CTS)<\/strong> and <strong>Server-To-Client (STC)<\/strong>. To determine which side is the client, it is necessary to identify who initiated the connection. For example, if a packet contains a TCP layer with only the SYN flag set, it indicates the first packet of a session, and the initiator is the <em>src_ip:src_port<\/em> socket. In this case, the packet\u2019s direction is <em>Client-To-Server<\/em>. By swapping the IP addresses and ports, we obtain the socket for the <em>Server-To-Client<\/em> direction.<\/p>\n<p>In Diagram 5, the forward and reverse flows are shown \u2014 identifiers 1 and 2. Here, the address 192.168.1.33 represents a server running an SSH service on port 22.<\/p>\n<h3>What is Uplink\/Downlink, and why aren&#8217;t they the same as CTS\/STC?<\/h3>\n<p><a class=\"anchor\" name=\"what-is-uplink-downlink\" id=\"what-is-uplink-downlink\"><\/a><\/p>\n<p>In networking, the terms <strong>Uplink<\/strong> and <strong>Downlink<\/strong> are also used in relation to network interfaces. Thus, all packets captured from the <em>Uplink<\/em> interface are considered to belong to the subscriber, while packets captured from the <em>Downlink<\/em> interface belong to the external network. At first glance, it may seem that the flow direction can always be easily determined based on which interface the packet was captured from (captured from <em>Uplink<\/em> \u2014 <em>CTS<\/em>, captured from <em>Downlink<\/em> \u2014 <em>STC<\/em>). However, this is not entirely correct. For example, imagine a subscriber sets up a mini-server at home (such as a media server with movies), requests a static IP address from the provider, then goes on a two-week vacation and accesses their server remotely from, say, Georgia. In this case, for the provider&#8217;s DPI system, traffic from the user&#8217;s server to the user (which is <em>STC<\/em>) will actually go through <em>Uplink<\/em>, while traffic from the user to the server (<em>CTS<\/em>) will go through <em>Downlink<\/em>.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/feb\/c1f\/50d\/febc1f50d12305343eadef7a1f000b8d.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 6: Uplink\/Downlink\" title=\"Scheme 6: Uplink\/Downlink\" width=\"459\" height=\"444\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/feb\/c1f\/50d\/febc1f50d12305343eadef7a1f000b8d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/feb\/c1f\/50d\/febc1f50d12305343eadef7a1f000b8d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 6: Uplink\/Downlink<\/figcaption><\/div>\n<\/figure>\n<p>In Diagram 6, two devices are shown connected to an access point (a home router), which in turn is connected to the <strong>ISP<\/strong> (<strong>I<\/strong>nternet <strong>S<\/strong>ervice <strong>P<\/strong>rovider) via a wired link. All traffic coming <strong>from<\/strong> the tablet and laptop is considered <strong>Uplink<\/strong> for both the router and the ISP. Conversely, all traffic going <strong>to<\/strong> these devices is considered <strong>Downlink<\/strong>.<\/p>\n<h3>What is reassembling?<\/h3>\n<p><a class=\"anchor\" name=\"what-is-reassembling\" id=\"what-is-reassembling\"><\/a><\/p>\n<p>Packets in a network can be compared to freight cars carrying coal. But not everything that needs to be sent can always fit into a single car.<\/p>\n<p>For example, if 180 tons of coal need to be transported from point A to point B, and each car can only hold 60 tons, three cars will be needed to deliver the full amount. The same idea applies to networks. For instance, when a user&#8217;s browser forms an HTTP request to YouTube that, let&#8217;s say, is 2048 bytes in size, this request is handed over to the operating system\u2019s TCP stack. The OS kernel then takes responsibility for delivering the request to YouTube\u2019s server. The request might be sent in a single packet or it might be split into multiple segments and sent in parts. This process is called <strong>TCP segmentation<\/strong>, and the process of putting the segments back together is called <strong>reassembling<\/strong>.<\/p>\n<p><strong>Reassembling<\/strong> is an essential part of how a DPI (Deep Packet Inspection) system operates. In order to extract domain names from packets or decrypt the payload, the DPI system must first reconstruct the full packet or message \u2014 and to do that, it needs to capture all of the segments, stitch them back together, and only then perform analysis.<\/p>\n<p><strong>Segmentation\/Fragmentation<\/strong> can occur at different layers of the OSI model. The most common protocols where this happens are:<\/p>\n<ul>\n<li>\n<p>IPv4\/IPv6<\/p>\n<\/li>\n<li>\n<p>TCP<\/p>\n<\/li>\n<li>\n<p>DTLS<\/p>\n<\/li>\n<li>\n<p>OpenVPN<\/p>\n<\/li>\n<li>\n<p>QUIC<\/p>\n<\/li>\n<li>\n<p>HTTP\/2<\/p>\n<\/li>\n<\/ul>\n<p>It\u2019s important to note that if IPv4\/IPv6 fragmentation is present in the network, the task for the reassembler becomes more complex. In this case, it first has to reconstruct the message at the IP (network) layer, and only after that can it reassemble the message at the transport layer \u2014 and, if necessary (depending on the protocol), even at the application layer.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/872\/9f3\/198\/8729f3198592c204fd136cf8f6b13700.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 7: \u0421\u0431\u043e\u0440\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\" title=\"Scheme 7: Message assembling\" width=\"962\" height=\"500\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/872\/9f3\/198\/8729f3198592c204fd136cf8f6b13700.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/872\/9f3\/198\/8729f3198592c204fd136cf8f6b13700.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 7: Message assembling<\/figcaption><\/div>\n<\/figure>\n<p><strong>Diagram 7<\/strong> shows a very simplified example of message reassembly (without sequence numbers, packet sizes, acknowledgments, etc.). At <strong>Stage 0<\/strong>, you can see that the user&#8217;s device sends 4 TCP segments to the <strong>AP<\/strong> (<strong>A<\/strong>ccess <strong>P<\/strong>oint), but only 3 segments leave the AP \u2014 one segment got delayed for some reason. Meanwhile, the <strong>ISP<\/strong> was also only able to forward two segments to the <strong>DPI<\/strong> at once, due to its own limitations. The DPI is deployed <strong>inline<\/strong>, meaning it must make real-time decisions about whether to allow traffic through. However, based on the information currently available for this flow, the DPI does not have enough data to make a decision about whether to let the packets into the external network.<\/p>\n<p>At <strong>Stage 2<\/strong>, the AP sends the previously delayed first segment to the ISP, and the ISP forwards the third segment that was held back in the previous step. Again, the DPI still lacks the complete message needed to make a final decision for this flow.<\/p>\n<p>At <strong>Stage 3<\/strong>, the DPI finally receives the missing first segment. With the full message now assembled, it can analyze it and make a decision. In this case, the resource is perfectly legitimate \u2014 so the flow is allowed to pass.<\/p>\n<h3>How can reassembling affect traffic classification?<\/h3>\n<p><a class=\"anchor\" name=\"how-reassembling-affects-on-flow-classification\" id=\"how-reassembling-affects-on-flow-classification\"><\/a><\/p>\n<p>Segmentation is one of the simplest ways to interfere with traffic classification (after tricks like changing the case in a domain name \u2014 for example, <a href=\"http:\/\/YoUTubE.COM\" rel=\"noopener noreferrer nofollow\"><em>YoUTubE.COM<\/em><\/a>). Why does this work? Because if a user forces their OS to set the segment size to 1 byte, and the request to a resource is 2048 bytes in size, then, in the worst case, the DPI will classify the flow only by the <strong>2048th packet<\/strong> (assuming the hostname is visible in plaintext). In practice, classification happens earlier \u2014 as soon as the DPI can extract the <em>server_name<\/em> (from the TLS protocol) or <em>host<\/em>\/<em>authority<\/em> (from HTTP\/HTTP2). For example, if the server name appears around the 100th byte, the DPI will classify the flow on the 100th packet.<\/p>\n<p>What&#8217;s happening inside the DPI: the engine gathers incoming packets, byte by byte, into a buffer and continuously checks whether a hostname has already appeared. This is very expensive for high-load systems like DPI. Not only is the final buffer size unpredictable (so it has to be stretched or preallocated generously), but the system also has to repeatedly scan the buffer after every packet, which hits performance hard. Additionally, all this buffering leads to significant memory consumption \u2014 a critical issue for DPI systems. Thus, to remain operational, a DPI engine must <strong>self-balance<\/strong>: it needs to enforce limits on buffering and the number of packets it processes before a flow is marked as <strong>unclassified<\/strong> (assigned a default policy and its buffers are dropped).<\/p>\n<p>Of course, these days there are entire clusters of IP addresses reserved for large services, so sometimes classification can happen based on IP address alone without needing the hostname at all.<\/p>\n<h3>What is a service?<\/h3>\n<p><a class=\"anchor\" name=\"what-is-service\" id=\"what-is-service\"><\/a><\/p>\n<p>In previous sections, the terms &#171;service&#187; and &#171;protocol&#187; have already been used. However, it is necessary to clarify these concepts to make everything completely clear.<\/p>\n<p>A <strong>service<\/strong> is a program running on a server (or a virtual machine) that accepts incoming connections from users and sends\/receives data. For example, Telegram is a service for instant messaging (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Instant_messaging\" rel=\"noopener noreferrer nofollow\">IM<\/a>), YouTube is a media service for uploading and watching video content, and so on. Unlike protocols, services do not have RFCs. In other words, a service is a program that sends and receives data, regardless of the format (JSON, XML, etc.).<\/p>\n<p>If the main goal of a service is to exchange data in a way that the user can read (and vice versa), the role of <strong>protocols<\/strong> is to define how these data are delivered or presented.<\/p>\n<p>For example, IPv4\/IPv6 protocols are responsible for transferring data between network devices like routers and\/or servers. Data is transmitted from one device to another based on IP addresses.<\/p>\n<details class=\"spoiler\">\n<summary>Switches<\/summary>\n<div class=\"spoiler__content\">\n<p>In addition to routers and servers, there are also switches that handle data transmission between different network segments (typically to other switches). However, switches perform this task based on VLANs (numerical identifiers) rather than IP addresses. It is important to note that VLANs are not considered during traffic classification by the DPI Engine.<\/p>\n<\/div>\n<\/details>\n<p>Transport protocols (TCP, UDP, QUIC) are responsible for delivering messages from a client to a server at the application level. The choice of transport protocol also determines how critical data loss is. For example, TCP guarantees message delivery, while UDP does not. To better understand what &#171;delivery at the application level&#187; means, let&#8217;s consider a user (with IP address 192.168.12.22) who opens WhatsApp and YouTube on their smartphone. On the user&#8217;s device, two ports are opened (let&#8217;s say 4444 and 5555). Now, packets are sent from the user to the WhatsApp server from port 4444, and to the YouTube server from port 5555. When the smartphone receives a packet with destination port 4444, the operating system forwards the received data to the WhatsApp application. Similarly, packets with destination port 5555 are delivered to YouTube.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d3b\/3ff\/cf8\/d3b3ffcf8446d5098f3b88115a49ae64.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 8: \u041f\u043e\u0440\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439\" title=\"Scheme 8: Application ports\" width=\"641\" height=\"441\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/d3b\/3ff\/cf8\/d3b3ffcf8446d5098f3b88115a49ae64.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d3b\/3ff\/cf8\/d3b3ffcf8446d5098f3b88115a49ae64.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 8: Application ports<\/figcaption><\/div>\n<\/figure>\n<p>SSL\/TLS protocols are responsible for encrypting data and verifying the server (and\/or the client, if necessary). In other words, they ensure the secure transmission of data.<\/p>\n<p>HTTP\/HTTP2 protocols (and other application-layer protocols) are directly responsible for transferring the original message. In particular, HTTP\/HTTP2 handle the task of formatting the message so that both sides of the connection (the client and the server) can understand it. For example, an HTTP request includes a URI field that helps the service understand which data the user is requesting. HTTP also has a Content-Type header that indicates the type of transmitted data (text\/html, audio\/mpeg, image\/gif, and so on).<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c2e\/f20\/4b6\/c2ef204b614acbcd99fa494d88d4d307.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 9: &quot;\u0421\u0442\u0440\u0438\u0436\u043a\u0430&quot; \u0441\u043b\u043e\u0451\u0432 \u043f\u0430\u043a\u0435\u0442\u0430\" title=\"Scheme 9: Protocol layer cutting\" width=\"791\" height=\"241\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/c2e\/f20\/4b6\/c2ef204b614acbcd99fa494d88d4d307.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c2e\/f20\/4b6\/c2ef204b614acbcd99fa494d88d4d307.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 9: Protocol layer cutting<\/figcaption><\/div>\n<\/figure>\n<p>The diagram above illustrates how packet layers are stripped off before the application receives the data. The packet first arrives at the <strong>NIC<\/strong> (<strong>N<\/strong>etwork <strong>I<\/strong>nterface <strong>C<\/strong>ard), where the Ethernet layer is removed, and the data is passed to the OS kernel. The kernel then checks the listening sockets (ip:port). If there is an application listening on the corresponding socket, the network and transport layers are also stripped, and the remaining data is delivered to the application.<\/p>\n<p>In summary, a service is a program. A protocol is a method for transferring or presenting data.<\/p>\n<h3>Running multiple services on a single server<\/h3>\n<p><a class=\"anchor\" name=\"few-services-on-single-server\" id=\"few-services-on-single-server\"><\/a><\/p>\n<p>It is quite common to run multiple services on a single server. For example, a user rents a virtual machine with the IPv4 address 90.156.176.56 and deploys YouTrack and GitLab on it. They purchase a domain (<a href=\"http:\/\/privatezone.com\" rel=\"noopener noreferrer nofollow\">privatezone.com<\/a>), an SSL certificate, and configure DNS records. As a result, two services are now running on the same IP address.<\/p>\n<p>If the services are launched with default parameters (HTTP port 80, TLS port 443), only the first service to start will run successfully, while the second one will fail to launch (and vice versa) because the default ports are already in use.<\/p>\n<p>To resolve this, the services must be started on different ports \u2014 for example, YouTrack on port 9000 and GitLab on port 9001. Now, when a user types <a href=\"http:\/\/privatezone.com\" rel=\"noopener noreferrer nofollow\">privatezone.com<\/a> into the browser, they will see an error, because no program is running on port 443 (TLS) or 80 (HTTP), which the browser uses by default to send requests.<\/p>\n<p>To access YouTrack, the user would have to enter privatezone.com:9000, and for GitLab \u2014 privatezone.com:9001. This is inconvenient since it requires remembering specific ports for each service.<\/p>\n<p>To improve this setup, you should add two more DNS records that point to the same IPv4 address (90.156.176.56), but make the service being accessed clear from the domain name itself. For example, in our case, the DNS records would look like this:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">Domain<\/p>\n<\/td>\n<td>\n<p align=\"left\">Sub-domain<\/p>\n<\/td>\n<td>\n<p align=\"left\">Type<\/p>\n<\/td>\n<td>\n<p align=\"left\">Address<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"http:\/\/privatezone.com\" rel=\"noopener noreferrer nofollow\">privatezone.com<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">@<\/p>\n<\/td>\n<td>\n<p align=\"left\">A<\/p>\n<\/td>\n<td>\n<p align=\"left\">90.156.176.56<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"http:\/\/privatezone.com\" rel=\"noopener noreferrer nofollow\">privatezone.com<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">youtrack<\/p>\n<\/td>\n<td>\n<p align=\"left\">A<\/p>\n<\/td>\n<td>\n<p align=\"left\">90.156.176.56<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><a href=\"http:\/\/privatezone.com\" rel=\"noopener noreferrer nofollow\">privatezone.com<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\">gitlab<\/p>\n<\/td>\n<td>\n<p align=\"left\">A<\/p>\n<\/td>\n<td>\n<p align=\"left\">90.156.176.56<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Thus, when a user requests <a href=\"http:\/\/gitlab.privatezone.com\" rel=\"noopener noreferrer nofollow\">gitlab.privatezone.com<\/a> in a browser, the browser sends a TLS request with the domain <a href=\"http:\/\/gitlab.privatezone.com\" rel=\"noopener noreferrer nofollow\">gitlab.privatezone.com<\/a> specified in the server_name field (SNI). However, the server still won\u2019t respond, because there is no program running on port 443. To route incoming connections between YouTrack and GitLab, you need to install <strong>Nginx<\/strong> (or any other web server) and configure it to forward requests for <a href=\"http:\/\/youtrack.privatezone.com\" rel=\"noopener noreferrer nofollow\">youtrack.privatezone.com<\/a> to YouTrack (127.0.0.1:9000) and requests for <a href=\"http:\/\/gitlab.privatezone.com\" rel=\"noopener noreferrer nofollow\">gitlab.privatezone.com<\/a> to GitLab (127.0.0.1:9001). The addresses 127.0.0.1:9000 and 127.0.0.1:9001 mean that the requests are routed locally (127.0.0.1) to ports 9000 and 9001, where they are handled by the appropriate applications.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/24d\/0a1\/f08\/24d0a1f0828502054575eff4c3707b1f.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 10: 2 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435\" title=\"Scheme 10: 2 services on one virtual machine\" width=\"601\" height=\"281\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/24d\/0a1\/f08\/24d0a1f0828502054575eff4c3707b1f.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/24d\/0a1\/f08\/24d0a1f0828502054575eff4c3707b1f.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 10: 2 services on one virtual machine<\/figcaption><\/div>\n<\/figure>\n<p>From the example above, it becomes clear that if multiple services are running on a server\/virtual machine, classification by IP address cannot be performed. Domain name checking is absolutely necessary to determine the service. This is important to understand. For example, if a hypothetical Google has a large pool of IP addresses, and there is no information (not received from the service) that, for instance, the pool 142.250.221.0\/24 is reserved exclusively for the Gmail service, then IP-based classification is impossible, and additional domain name checking is required (unless, of course, Google is considered as one service). Google can deploy YouTube, Cloud, and so on within this pool without any warning, which would break IP classification.<\/p>\n<h3>Traffic classification<\/h3>\n<p><a class=\"anchor\" name=\"traffic-classification\" id=\"traffic-classification\"><\/a><\/p>\n<p>Traffic classification is the process of determining which service a network flow belongs to. Classification consists of the following steps, some of which may be skipped depending on the protocol or classification technique:<\/p>\n<ul>\n<li>\n<p><strong>Protocol identification<\/strong> represented in the packet<\/p>\n<\/li>\n<li>\n<p><strong>Field dissection<\/strong> necessary for classification (IP addresses, ports, domain names, etc.)<\/p>\n<\/li>\n<li>\n<p><strong>Reassembling<\/strong> (IPv4, TCP, QUIC, HTTP\/2, etc.)<\/p>\n<\/li>\n<li>\n<p><strong>Field unpacking<\/strong> (e.g., DNS Name consisting of labels)<\/p>\n<\/li>\n<li>\n<p><strong>Decryption<\/strong> (e.g., QUIC Initial)<\/p>\n<\/li>\n<li>\n<p><strong>Application of techniques<\/strong> to identify the service of the network flow<\/p>\n<\/li>\n<li>\n<p><strong>Application of techniques<\/strong> to classify the nature of the network flow<\/p>\n<\/li>\n<\/ul>\n<h3>Methods for protocol identification<\/h3>\n<p><a class=\"anchor\" name=\"protocol-detection-methods\" id=\"protocol-detection-methods\"><\/a><\/p>\n<p>From the user&#8217;s perspective, who has deployed OpenVPN and Nginx on their server, everything is simple: they know that OpenVPN operates on port 1194 and Nginx serves their website on port 443. In other words, the OpenVPN server (openvpn-server), running on the user&#8217;s server on UDP port 1194, knows for sure that the data in the packet is formatted according to the OpenVPN specification. If the data does not comply with this specification, it should not be processed (an error should be reported or simply ignored). Everything is straightforward for the openvpn-server, but not for the network analyzer.<\/p>\n<p>Protocols in a packet can be represented as bricks of different colors, stacked one after another. Determining the color of the next brick can be easy: for example, when the first blue brick says that the next one is red. This example applies to protocols like Ethernet, VLAN, IPv4, IPv6, etc. In one of the fields of such protocols, there is an indication of what protocol comes after it. However, difficulties arise when trying to determine the protocol following the transport layer (TCP\/UDP). UDP and TCP protocols do not contain information about which protocol follows them, so identifying the next protocol is possible only heuristically.<\/p>\n<p>The following methods can be used to identify the protocol in a packet:<\/p>\n<ul>\n<li>\n<p><strong>Explicit<\/strong> \u2013 the next protocol is explicitly known (explicit identification).<\/p>\n<\/li>\n<li>\n<p><strong>Port-based<\/strong> \u2013 a hint indicating which protocol is most likely.<\/p>\n<\/li>\n<li>\n<p><strong>Patterns<\/strong> \u2013 specific patterns or markers whose appearance indicates the packet belongs to a certain protocol. Examples of protocols that can be identified by patterns include HTTP, SSDP, SIP, and a few others.<\/p>\n<\/li>\n<li>\n<p><strong>Try-dissect<\/strong> \u2013 checking the structure of the protocol (message size, field values, etc.). There may be collisions with other protocols if their message structures are similar.<\/p>\n<\/li>\n<\/ul>\n<p>It might seem logical to assume that identifying a protocol is an easy task: just check the port number and, based on it, parse the corresponding protocol. For example, 80 means HTTP, 443 means TLS, and so on. In reality, this assumption is wrong \u2014 the port only serves as a hint for which protocol to <em>check first<\/em> (using patterns or structural analysis). If you rely solely on the port number, services running on non-standard ports will be misidentified. For instance, imagine QUIC traffic traveling to a server not on port 443, but on port 1194 (the default port for OpenVPN). In this case, DPI would first attempt to parse QUIC as OpenVPN, fail, and then label the protocol as <em>unknown<\/em>. Simple port spoofing would interfere with correct protocol identification and, consequently, with service classification (since the first QUIC message can be reassembled, decrypted, and used to extract the TLS layer and obtain the SNI).<\/p>\n<p>An additional challenge is posed by protocols with high data entropy, such as OpenVPN or RTP\/SRTP. In such protocols, only a very small portion of the bytes can be checked against the expected protocol structure. The majority of the message consists of payload, which is essentially unpredictable and useless for analysis. For these protocols, it&#8217;s usually necessary to collect more than one packet to either correlate certain fields across multiple messages or verify that the structure of a subsequent packet no longer matches the protocol initially assumed by the <strong>DPI Engine<\/strong> (i.e., using the method of elimination).<\/p>\n<p>Thus, for a DPI Engine, it is important not only to recognize a protocol based on a single message type (for example, TLS Client Hello), which can directly influence the final service classification. It is equally important to understand the structure of every message type supported by the protocol (such as TLS Alert, Change Cipher Spec, Application Data, and others), because the ability to correctly parse any message type reduces the risk of false positives and increases the chance of identifying the protocol from the very first packet. In other words, the more protocols are supported and the more message types a DPI Engine can accurately dissect for each protocol, the more reliable the classification will be.<\/p>\n<p>There are also some edge cases where protocol identification seems straightforward at first glance, but isn&#8217;t in practice. A good example is ICMP traffic with an embedded payload. ICMP is a simple and important protocol, typically allowed across most networks and usually treated as a terminal protocol (at least in an ideal world). However, ICMP packets can carry payload data. Since payload analysis in ICMP is rarely needed (and analyzing every payload would unnecessarily burden the system in 99% of cases), it is often skipped. That said, payloads can be used to establish covert ICMP tunnels.<\/p>\n<h3>Internet service classification methods<\/h3>\n<p><a class=\"anchor\" name=\"internet-services-classification-methods\" id=\"internet-services-classification-methods\"><\/a><\/p>\n<p>The <strong>DPI Engine<\/strong> uses a variety of techniques to classify services. The main goal of classification is to identify the service as early as possible, so that the network flow can be offloaded, reducing the load on the software (packets belonging to an offloaded flow are no longer analyzed). There is even a concept called <strong>FPC<\/strong> (<strong>F<\/strong>irst <strong>P<\/strong>acket <strong>C<\/strong>lassification), although not all techniques can guarantee <em>FPC<\/em>.<\/p>\n<p>Below are some of the most common approaches to service classification:<\/p>\n<ul>\n<li>\n<p>IP Database<\/p>\n<\/li>\n<li>\n<p>Domain Name Patterns<\/p>\n<\/li>\n<li>\n<p>Data Patterns<\/p>\n<\/li>\n<li>\n<p>Data Structure<\/p>\n<\/li>\n<li>\n<p>Cache<\/p>\n<\/li>\n<li>\n<p>Domain Fronting<\/p>\n<\/li>\n<li>\n<p>SPID (<strong>S<\/strong>tatistical <strong>P<\/strong>rotocol <strong>ID<\/strong>entification)<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>Packet capture\/Packet filter<\/summary>\n<div class=\"spoiler__content\">\n<p>DPI not only analyzes traffic, but also passes, throttles, or blocks network packets. Packets from the network interface are captured by a dedicated DPI module, usually referred to as a <em>traffic capture<\/em> or <em>packet filter<\/em> module. Such a module typically operates at the <a href=\"https:\/\/en.wikipedia.org\/wiki\/User_space_and_kernel_space\" rel=\"noopener noreferrer nofollow\">Kernel space<\/a> level. It is responsible for enforcing restrictions applied to a flow. Popular libraries for traffic capture include <a href=\"https:\/\/www.dpdk.org\/\" rel=\"noopener noreferrer nofollow\">DPDK<\/a> and <a href=\"https:\/\/www.ntop.org\/products\/packet-capture\/pf_ring\/\" rel=\"noopener noreferrer nofollow\">PF_Ring<\/a>.<\/p>\n<p>Until a flow is classified, its packets are forwarded for analysis by the <strong>DPI Engine<\/strong>, whose code usually runs in <a href=\"https:\/\/en.wikipedia.org\/wiki\/User_space_and_kernel_space\" rel=\"noopener noreferrer nofollow\">User space<\/a>. Once the flow has been classified, further packet analysis becomes unnecessary \u2014 only statistics need to be collected so that they can be reported to billing once the flow ends. To achieve this, the traffic capture module is sent a <strong>policy<\/strong> (instructions on what to do with the flow\u2019s packets: pass, throttle, or block). After receiving the policy, the capture module stops queuing the flow\u2019s packets for analysis and instead either simply collects statistics or drops the packets if the flow was blocked.<\/p>\n<\/div>\n<\/details>\n<p><strong>IP Database<\/strong> is a fairly basic scenario for classification, especially in cases where an entire pool of IP addresses is reserved for a service. A good example is Telegram, which publishes a list of CIDR ranges on its website. If the packet\u2019s IP address falls within one of these CIDR intervals, the DPI can safely conclude that the traffic belongs to Telegram.<\/p>\n<p><strong>Domain Name Patterns<\/strong> is also a standard classification scenario. If the DPI Engine is able to extract the hostname from the packet (which is typical for protocols like HTTP, HTTP\/2, SSDP, SIP, TLS, QUIC+TLS), it checks the hostname against a list of known domain patterns to classify the service. There are plenty of examples for this method. For instance, for Telegram alone, at least three domains can be identified: <a href=\"http:\/\/telegram.org\" rel=\"noopener noreferrer nofollow\">telegram.org<\/a>, <a href=\"http:\/\/t.me\" rel=\"noopener noreferrer nofollow\">t.me<\/a>, and <a href=\"http:\/\/telegram.me\" rel=\"noopener noreferrer nofollow\">telegram.me<\/a>.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c8d\/13c\/2d8\/c8d13c2d87c128c2c3aba690d48bf02b.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 12: \u041a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 IP \u0430\u0434\u0440\u0435\u0441\u0430 \u0438 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043c\u0435\u043d\u0438\" title=\"Scheme 11: Classification based on IP address and domain name\" width=\"998\" height=\"334\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/c8d\/13c\/2d8\/c8d13c2d87c128c2c3aba690d48bf02b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c8d\/13c\/2d8\/c8d13c2d87c128c2c3aba690d48bf02b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 11: Classification based on IP address and domain name<\/figcaption><\/div>\n<\/figure>\n<p><strong>Data Patterns<\/strong> \u2013 a method that analyzes specific parts of the payload for which the final protocol has not been determined. For example, a packet might show the following protocol chain: ethernet.ipv4.tcp.payload. &#8216;Payload&#8217; indicates that the final (in this case, application) protocol could not be determined. Therefore, a payload analyzer is used to check its individual parts in order to make a decision. An example of this could be the search for &#8216;magic numbers&#8217; in the payload at specific offsets.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/674\/612\/d3c\/674612d3c31e4c245e6b14f15aac3096.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 13: Data patterns\" title=\"Scheme 13: Data patterns\" width=\"601\" height=\"284\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/674\/612\/d3c\/674612d3c31e4c245e6b14f15aac3096.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/674\/612\/d3c\/674612d3c31e4c245e6b14f15aac3096.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 13: Data patterns<\/figcaption><\/div>\n<\/figure>\n<p><strong>Data Structure<\/strong> \u2013 this method is conceptually very similar to the protocol (not service) identification method <strong>Try-Dissect<\/strong>, which verifies the structure of the payload according to the specification of the protocol. However, there are cases where services use their own protocols and do not share their specifications and\/or implementations with the world. In such cases, researchers (or AI) have to analyze captured dumps of such traffic to identify any patterns. For example, the first byte\/two bytes indicate the packet length, while the message size fluctuates between 124 and 256. Or, when the packet size is between 130 and 180, the first byte indicates the message length, and the 24th byte falls within the range of 0\u20138. And so on. This technique is not used frequently and is not very reliable. Any change in the protocol on the service side is not announced anywhere and may break the classification. Moreover, if the protocol is changed, it requires re-analysis by researchers and then code modifications (unlike classification based on IP addresses or domain names), which takes a lot of time.<\/p>\n<p><strong>Cache<\/strong> \u2013 ne of the most commonly used methods of classification, after the basic ones (IP, Domain Names). The essence of this method is to store information from one flow to help classify another. There are several types of caching techniques, for example:<\/p>\n<ul>\n<li>\n<p>DNS Cache<\/p>\n<\/li>\n<li>\n<p>TLS\/DTLS Session ID Cache<\/p>\n<\/li>\n<li>\n<p>QUIC Cache<\/p>\n<\/li>\n<\/ul>\n<p>For example, consider <strong>DNS Cache<\/strong>. <em>DNS Cache<\/em> allows performing <em>FPC<\/em>, meaning the service will be classified from the first packet. The essence of the DNS Cache approach is to store the IP addresses obtained from the DNS response for a specific service of a particular user. Before accessing a resource by domain name, in most cases, the client first sends a DNS query and receives a DNS response with a list of IP addresses for the requested domain. Thus, the <strong>DPI Engine<\/strong> analyzes the DNS response, checks the domain name, and if it is relevant (i.e., the domain name is in the classification lists and associated with a specific service), it caches the list of received IP addresses. After that, the client is expected to establish a new connection to one of these IP addresses, and if it appears, the <strong>DPI Engine<\/strong> makes a verdict about the classified service.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7b7\/c0c\/ebe\/7b7c0cebee4f7f5d5c0fb4df17d878ca.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 14: DNS Cache\" title=\"Scheme 14: DNS Cache\" width=\"701\" height=\"591\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/7b7\/c0c\/ebe\/7b7c0cebee4f7f5d5c0fb4df17d878ca.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7b7\/c0c\/ebe\/7b7c0cebee4f7f5d5c0fb4df17d878ca.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 14: DNS Cache<\/figcaption><\/div>\n<\/figure>\n<p>To briefly touch on <strong>TLS\/DTLS Session ID Cache<\/strong>, this technique is used to control <em>Connection Migration<\/em> (referred to as <em>Session Resumption<\/em> in TLS). TLS connection migration is a scenario in which the first connection contains an SNI in the TLS Client Hello, but the subsequent connection does not. That is, the client requests <a href=\"http:\/\/youtube.com\" rel=\"noopener noreferrer nofollow\">youtube.com<\/a> in the TLS Client Hello during the first connection, and the server responds with a Server Hello, which includes a Session ID field (connection identifier). Then, for one reason or another, the connection is closed and a new one is opened. But in the new connection, there is no SNI, and the client sends the Session ID used in the first connection, and the previous session is resumed.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/06c\/462\/49f\/06c46249f887791a8f7b946b4b419bf5.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 15: TLS Session Resumption\" title=\"Scheme 15: TLS Session Resumption\" width=\"501\" height=\"791\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/06c\/462\/49f\/06c46249f887791a8f7b946b4b419bf5.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/06c\/462\/49f\/06c46249f887791a8f7b946b4b419bf5.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 15: TLS Session Resumption<\/figcaption><\/div>\n<\/figure>\n<p>It is worth noting that caching is useful when a service uses an IP address not from a pre-known list (IP Database). DNS and TLS Cache are not the only, but the most commonly used types of caching.<\/p>\n<p><strong>Domain Fronting<\/strong> \u2013 a method to bypass blocks, which involves hiding the domain of the requested resource in the client-&gt;CDN-&gt;server chain. To briefly describe the principle \u2013 in a world where almost all traffic goes through TLS, the requested resource (host) is indicated twice: in the TLS Client Hello (unless ECH \u2013 Encrypted Client Hello \u2013 is used) and HTTP Host.<\/p>\n<p>In this scenario, the client application establishes a TLS connection with the CDN server, but the domains in the TLS Client Hello and HTTP Host differ. In the TLS Client Hello, a fake (but legitimate from the censor&#8217;s point of view) domain is used, while the encrypted TLS HTTP request is sent to a domain different from the one indicated in the Client Hello. To illustrate this more clearly, consider the following diagram:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/461\/2b8\/8c6\/4612b88c638139f6253eeff7088dab9d.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 16: Domain Fronting\" title=\"Scheme 16: Domain Fronting\" width=\"696\" height=\"438\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/461\/2b8\/8c6\/4612b88c638139f6253eeff7088dab9d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/461\/2b8\/8c6\/4612b88c638139f6253eeff7088dab9d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Scheme 16: Domain Fronting<\/figcaption><\/div>\n<\/figure>\n<p>The diagram was taken from <a href=\"https:\/\/www.hideipvpn.com\/privacy\/domain-fronting-attack\/\" rel=\"noopener noreferrer nofollow\">here<\/a>.<\/p>\n<p>As can be seen, the client queries an unblocked domain from the DNS server, whose address matches that of the blocked resource. Then the TLS connection is easily established with the server, as only the SNI is visible to the censor, and the HTTP Host domain is encrypted under the TLS layer.<\/p>\n<p>Determining Domain Fronting without decrypting TLS is quite difficult. TLS decryption can be used in cybersecurity products, but it is not feasible for telecoms. For this reason, detecting Domain Fronting for specific services (i.e., you need to know in advance which services use this technique) lies at the intersection of collecting \u201cgarbage\u201d domains (which act as a cover for the main domain) and identifying behavioral patterns typical of such sessions.<\/p>\n<p>Domain collection can be done by monitoring CDN providers used by the service, catching TLS connections where one domain was requested in the Client Hello, but the certificate from the server returns another (typical for the service being investigated). This may involve reverse engineering or semi-automated domain collection generated by the application (e.g., writing a sniffer to collect the domains accessed by the application).<\/p>\n<p>Domain Fronting has become irrelevant for service developers with large audiences (such as Telegram, WhatsApp, and others), as major CDN providers have started to control the use of their nodes to prevent bypassing blocks through their servers (Google, AWS, Cloudflare).<\/p>\n<p><strong>SPID<\/strong> (<em>Statistical Protocol Identification<\/em>) \u2013 is a method based on analyzing the statistical characteristics of the flow, such as average packet size, bitrate, IAT (Inter Arrival Time), and so on. This method is not very reliable for service identification and is mainly used to classify the flow&#8217;s nature (<em>workflow<\/em>), for example, file transfer, audio\/video call, etc.<\/p>\n<p><strong>ML\/AI<\/strong> \u2013 a method based on the analysis of various flow characteristics (including statistical ones) that classifies a service with a certain probability. This method is used when it is not possible to make a definitive verdict. Unlike SPID, the values\/ranges used for classification in ML\/AI can change during traffic processing (the model is self-learning), whereas in SPID they are always static. The main need for ML\/AI classification is to adapt to traffic variability. This method is used for classifying VPN services that cannot be identified by IP addresses or protocol verification, as well as for determining the flow&#8217;s nature (to be described in the next paragraph).<\/p>\n<p>The most popular techniques for traffic classification have been described above. There are also other techniques that may be based on specific criteria characteristic of individual services (or service groups), but these require deeper analysis, such as using AI, source code analysis, or reverse engineering.<\/p>\n<h3>Workflow classification<\/h3>\n<p><a class=\"anchor\" name=\"workflow-classification\" id=\"workflow-classification\"><\/a><\/p>\n<p>Classifying the service itself is important, but it is not always enough. For example, a mobile operator might use file transfer speed in messengers as a competitive advantage for one of its tariffs. In other words, there arises a need to determine what kind of work the flow is performing (<em>workflow<\/em>). Several of the most popular types of such work can be highlighted:<\/p>\n<ul>\n<li>\n<p>Chat<\/p>\n<\/li>\n<li>\n<p>Audio call<\/p>\n<\/li>\n<li>\n<p>Video call<\/p>\n<\/li>\n<li>\n<p>File transfer<\/p>\n<\/li>\n<\/ul>\n<p>This type of classification is usually based on the analysis of the statistical characteristics of the flow (<em>SPID<\/em>).<\/p>\n<p>Statistics-based classification is highly sensitive to changes in the service&#8217;s operation (for example, the release of a new version). For instance, consider a situation where a messaging app starts using a new audio codec, which changes the statistical metrics, affecting the classification.<\/p>\n<p>There is also the concept of \u00ab<a href=\"https:\/\/en.wikipedia.org\/wiki\/Comfort_noise\" rel=\"noopener noreferrer nofollow\">Comfort Noise<\/a>\u00bb, which can, in certain situations, affect the definition of workflow.<\/p>\n<p>In any case, <em>workflow<\/em> is very useful information both for telecom solutions and for products in the field of information security. For example, consider a scenario where a subscriber, while having an active voice call, opens a session in an online banking service. That&#8217;s an interesting combination! Or another example: during an incident investigation, one might find that several audio calls were made on a device involved in the breach, followed by a file being received, and then after N minutes, the device was compromised.<\/p>\n<h3>Why is it difficult?<\/h3>\n<p><a class=\"anchor\" name=\"why-is-difficult\" id=\"why-is-difficult\"><\/a><\/p>\n<p>The main criteria for <strong>DPI Engine<\/strong> products are classification quality and speed. Quality is especially critical for classifying services and protocols that are subject to blocking. Incorrect classification of such services (or more precisely, its absence) can lead to penalties from regulators.<\/p>\n<p>Performance is important because the load in networks using DPI is usually very high, and analyzing every packet in a stream is not feasible. Therefore, the goal is to deliver a verdict on the service as quickly as possible so that new packets no longer need to be analyzed and do not consume DPI resources.<\/p>\n<p>In terms of performance, it is crucial how quickly the <strong>DPI Engine<\/strong> extracts domain names, searches for matches in the IP and domain name database, performs flow table lookups to restore session context; how well it decides what information to cache and retrieves it quickly when needed, cleans outdated data in the cache, and much more.<\/p>\n<p>As for classification quality, it is essential to keep the list of IP addresses and domain names for services up to date, update them in a timely manner, and be able to export cached data via an API so that the DPI can pass it to other clusters in the network.<\/p>\n<h3>What else is interesting about DPI Engine?<\/h3>\n<p><a class=\"anchor\" name=\"what-else-dpi-engine-does\" id=\"what-else-dpi-engine-does\"><\/a><\/p>\n<p>The application of <strong>DPI Engine<\/strong> is quite diverse. Here are some examples of its use:<\/p>\n<ul>\n<li>\n<p><strong>Attribute Extraction<\/strong> \u2013 extracting protocol attributes is useful for many purposes. For example, within a network, protocols that do not use encryption (FTP, HTTP, POP3, etc.) can be monitored, sensitive data can be extracted from them, and reports can be generated showing which users, which nodes in the network, and the percentage of overall traffic use insecure connections. Another example is analyzing the ciphers used in TLS connections (cipher_suites; <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cipher_suite\" rel=\"noopener noreferrer nofollow\">Cipher Suite<\/a>) and\/or TLS versions to detect outdated versions of protocols or vulnerable encryption algorithms.<\/p>\n<\/li>\n<li>\n<p><strong>File Extraction<\/strong> \u2013 for unencrypted protocols, files can be extracted if a file is present in the packet. For example, extracting images from HTTP or FTP streams. Extracted files can be further analyzed, such as in DLP (Data Loss Prevention).<\/p>\n<\/li>\n<li>\n<p><strong>Dataset Producing<\/strong> \u2013 for the <strong>DPI Engine<\/strong>, a set of parameters can be configured for extraction (e.g., <em>src_ip<\/em>, <em>dst_ip<\/em>, <em>src_port<\/em>, <em>dst_port<\/em>, <em>hostname<\/em>, <em>protocol_tree<\/em>, <em>service_id<\/em>, <em>byte_count<\/em>, <em>bitrate<\/em>, etc.), after which pcap dumps can be uploaded for analysis, and the requested parameter set will be output in JSON format for each packet. This set can be used for AI training and the identification of new metrics for classification. Another example: a similar data set can be generated not per packet but per flow and used as <a href=\"https:\/\/en.wikipedia.org\/wiki\/Internet_Protocol_Detail_Record\" rel=\"noopener noreferrer nofollow\">IPDR<\/a> (IP Detail Record).<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Tethering\" rel=\"noopener noreferrer nofollow\">Tethering<\/a> Detection \u2013 detecting the use of a mobile phone as a hotspot.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/904848\/\"> https:\/\/habr.com\/ru\/articles\/904848\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\">\n<div><figcaption>DPI Engine<\/figcaption><\/div>\n<\/figure>\n<h3>Content table<\/h3>\n<ul>\n<li>\n<p><a href=\"#introduction\" rel=\"noopener noreferrer nofollow\">Introduction<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-network-protocol-packet-layer\" rel=\"noopener noreferrer nofollow\">What is a network protocol, packet, layer?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#osi\" rel=\"noopener noreferrer nofollow\">OSI<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-network-flow\" rel=\"noopener noreferrer nofollow\">What is a network flow?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#flow-direction\" rel=\"noopener noreferrer nofollow\">Flow direction<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-uplink-downlink\" rel=\"noopener noreferrer nofollow\">What is Uplink\/Downlink and why is it not the same as CTS\/STC?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-reassembling\" rel=\"noopener noreferrer nofollow\">What is reassembling?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#how-reassembling-affects-on-flow-classification\" rel=\"noopener noreferrer nofollow\">How can reassembling affect traffic classification?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-is-service\" rel=\"noopener noreferrer nofollow\">What is a service?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#few-services-on-single-server\" rel=\"noopener noreferrer nofollow\">More than one service on a single server<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#traffic-classification\" rel=\"noopener noreferrer nofollow\">Traffic classification<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#protocol-detection-methods\" rel=\"noopener noreferrer nofollow\">Methods for protocol detection<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#internet-services-classification-methods\" rel=\"noopener noreferrer nofollow\">Methods for classifying internet services<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#workflow-classification\" rel=\"noopener noreferrer nofollow\">Workflow type classification<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#why-is-difficult\" rel=\"noopener noreferrer nofollow\">Why is it difficult?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#what-else-dpi-engine-does\" rel=\"noopener noreferrer nofollow\">What else is interesting about the DPI Engine?<\/a><\/p>\n<\/li>\n<\/ul>\n<h3>Introduction<\/h3>\n<p><a class=\"anchor\" name=\"introduction\" id=\"introduction\"><\/a><\/p>\n<p>For those familiar with the term DPI (<strong>Deep Packet Inspection<\/strong>), it often evokes unpleasant associations: blocking, regulators, censorship, tightening controls, and so on. In reality, DPI is simply the name of a technology whose essence lies in the deep analysis of network traffic.<\/p>\n<p>It is important to clarify from the outset that DPI examines traffic &#171;inline&#187; \u2014 meaning it analyzes the entire packet (across all OSI model layers), not just the payload (such as the HTTP layer, which, by the way, is almost always encrypted for an in-line analyzer unless it engages in certificate substitution).<\/p>\n<p>Returning to why DPI should not be viewed negatively:<\/p>\n<ul>\n<li>\n<p>is used, in one form or another, in all information security solutions (NTA, NGFW, Network Monitors, NPF, etc.);<\/p>\n<\/li>\n<li>\n<p>helps system administrators monitor events within a network;<\/p>\n<\/li>\n<li>\n<p>enables mobile operators to create attractive plans for subscribers (since this requires traffic classification, for instance, to exclude traffic from messengers if they are unlimited under a given plan);<\/p>\n<\/li>\n<li>\n<p>allows load balancing across the network, providing subscribers with approximately equal connection speeds in high-traffic areas (such as during football matches or concerts \u2014 heavy load on cells, where it is better to provide fair access to messaging and browsing services while limiting bandwidth for platforms like YouTube).<\/p>\n<\/li>\n<\/ul>\n<p>In an operator\u2019s network, DPI must not only classify network flows but also authenticate subscribers, retrieve policies, and monitor their enforcement (throttle speeds, block prohibited resources, restrict access to internal services when the balance is zero, etc.).<\/p>\n<p>The task of traffic classification is fundamental to a full-fledged DPI solution and belongs to a distinct class known as <strong>DPI Engine<\/strong>. This is due to the constant evolution of services \u2014 names change (e.g., Twitter -&gt; X), new domain names, CDNs, new service optimization methods are developed (such as voice or video calls), and new protocols are adopted. As a result, a separate segment of tasks arises that is independent of the type of network (Mobile Core, ISP, Wi-Fi AP, etc.), yet solving these tasks remains essential for each network type. For this reason, deep traffic analysis and network flow classification are carried out specifically by <strong>DPI Engine<\/strong> solutions.<\/p>\n<details class=\"spoiler\">\n<summary>Inline vs. Mirroring<\/summary>\n<div class=\"spoiler__content\">\n<p>DPI solutions typically operate in one of two modes: inline or mirroring.<\/p>\n<p>Inline deployment means that the DPI system is positioned between the client and the external network and must make real-time decisions regarding traffic flow without delayed processing. In contrast, in mirroring mode, the DPI system receives a copy of the traffic rather than the actual live packets. Even when operating in mirroring mode, a DPI can still influence session behavior (for example, by terminating a session through sending a TCP-RST packet); however, such intervention does not require introducing delays to the rest of the packet flow.<\/p>\n<\/div>\n<\/details>\n<h3>What is Network Protocol, Packet, and Layer?<\/h3>\n<p><a class=\"anchor\" name=\"what-is-network-protocol-packet-layer\" id=\"what-is-network-protocol-packet-layer\"><\/a><\/p>\n<p>In order to explain how traffic classification works, it is necessary to introduce some basic concepts. While these may be familiar to experienced readers, it is still worth defining them.<\/p>\n<p><strong>Packet<\/strong> \u2014 a packet is a set of bytes, structured in a specific way, that is received or transmitted over a network interface.<\/p>\n<p><strong>Protocol<\/strong> \u2014 a protocol is a set of rules that govern how data is transmitted between different nodes in a network. Protocols define how data should be formatted, processed, transmitted in order, and more. Different protocols serve different roles in data transmission and are responsible for various functions.<\/p>\n<p><strong>Layer<\/strong> \u2014 a layer refers to the portion of a network packet associated with a particular protocol. This section (<em>set of bytes<\/em>) cannot belong to more than one protocol at the same time.<\/p>\n<p><strong>Field<\/strong> \u2014 a field is a part of a layer (<em>a set of bytes<\/em>) that stores information for specific, predefined purposes. For example, in an IPv4 layer, which occupies 20 bytes (without Options), the sender\u2019s address (4 bytes) is located at byte offset 12, while the receiver\u2019s address (also 4 bytes) is located at offset 16.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Scheme 1: Protocol layers inside a packet<\/figcaption><\/div>\n<\/figure>\n<h3>OSI<\/h3>\n<p><a class=\"anchor\" name=\"osi\" id=\"osi\"><\/a><\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/OSI_model\" rel=\"noopener noreferrer nofollow\">OSI<\/a> (<strong>O<\/strong>pen <strong>S<\/strong>ystems <strong>I<\/strong>nterconnection model) is a hierarchical, multi-layered framework for network protocols, where each layer plays a specific role in ensuring the successful transmission of data.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Scheme 2: OSI model<\/figcaption><\/div>\n<\/figure>\n<p>The diagram was taken from <a href=\"https:\/\/www.linkedin.com\/pulse\/what-protocol-data-unitpdu-rahima-aktar-mvp1e\" rel=\"noopener noreferrer nofollow\">here<\/a>.<\/p>\n<p>By simplifying the formal definitions of the OSI model layers, we can say the following:<\/p>\n<ul>\n<li>\n<p>Network layer protocols are responsible for data transmission based on the IP addresses of the recipients..<\/p>\n<\/li>\n<li>\n<p>Transport layer protocols ensure that, once data reaches the destination server, the correct application can process it (based on ports). In other words, they &#171;navigate&#187; data not between network nodes but between applications on a device.<\/p>\n<\/li>\n<li>\n<p>Presentation layer protocols determine how the data will be transmitted (encryption, compression, etc.).<\/p>\n<\/li>\n<li>\n<p>Application layer protocols are used to structure data between the client and server applications, so both can process it. For example, in the HTTP protocol (application layer), before the actual data payload (request or response body) is transmitted, information is provided about which resource the request is for, the format of the payload, whether compression is used, and so on. In essence, application layer protocols are what programs\/services on end devices process.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Scheme 3: Data transmission according to the OSI model<\/figcaption><\/div>\n<\/figure>\n<\/li>\n<\/ul>\n<p>The diagram was taken from <a href=\"https:\/\/www.linkedin.com\/pulse\/how-do-devices-talk-each-other-rahima-aktar-yhbbc\" rel=\"noopener noreferrer nofollow\">here<\/a>.<\/p>\n<h3>What is a network flow?<\/h3>\n<p><a class=\"anchor\" name=\"what-is-network-flow\" id=\"what-is-network-flow\"><\/a><\/p>\n<p>A <strong>network flow<\/strong> (<strong>Network flow<\/strong> or simply <strong>flow<\/strong>) is an abstraction over network packets, used to group them. For example, consider the Internet, which can be viewed as a large number of packets being transmitted between different network participants. Packets are the smallest unit of network exchange. While a packet represents a more physical abstraction (information, a set of bytes transmitted over a communication channel), a flow is more of a logical entity that helps organize packets into groups. For instance, if the sender and receiver IP addresses are the same, that would constitute an IP flow. Another example: when both the sender and receiver IP addresses, as well as the TCP ports, match. This flow could be considered as part of a specific TCP connection. There can be several TCP connections (and not just TCP) between a sender and a receiver.<\/p>\n<p>Thus, the chaos of packets within the network takes on a more structured form when the packets are divided into groups. To better understand, it is easier to imagine a flow as a pipe through which packets fly. From the sender to the receiver, they travel through one pipe (the forward flow), while the return packets go through a neighboring one (the reverse flow). In this example, the pipe represents a grouping of packets.<\/p>\n<blockquote>\n<p>It is important to distinguish between a network flow and an execution thread. A network flow is referred to as <strong>flow<\/strong>, while an execution thread is called <strong>thread<\/strong>.<\/p>\n<\/blockquote>\n<figure class=\"full-width\">\n<div><figcaption>Scheme 4: Forward and reverse flows<\/figcaption><\/div>\n<\/figure>\n<p>Packets need to be divided into flows for several reasons. For example, to keep statistics (such as the number of processed packets, bytes, timestamps, etc.), which can be useful for traffic classification or for <a href=\"https:\/\/en.wikipedia.org\/wiki\/Traffic_shaping\" rel=\"noopener noreferrer nofollow\">shaping<\/a> (speed limiting).<\/p>\n<p>The forward and reverse flows are linked to each other (referencing each other), forming a session. A <strong>session<\/strong> is a collection of shared information for related flows. For instance, for two TLS flows (forming a session) after the handshake is completed, parameters such as <em>supported_version<\/em>, <em>application_layer_protocol_negotiation<\/em>, <em>session_id<\/em>, <em>tls_cipher_suite<\/em>, and <em>compression_method<\/em> are common to both flows.<\/p>\n<p>In Diagram 4, the session context is presented as a shared entity that consolidates information characteristic of both flows.<\/p>\n<p>When a packet is processed, the <strong>DPI Engine<\/strong> must associate the packet with a flow. To do this, a flow <em>key\/identifier<\/em> must be calculated based on data from the packet. The key is calculated differently depending on the structure of the packet. Flows can be of various types, but the most common ones are:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"108\" width=\"108\">\n<p align=\"left\">Type<\/p>\n<\/td>\n<td data-colwidth=\"273\" width=\"273\">\n<p align=\"left\">Description<\/p>\n<\/td>\n<td>\n<p align=\"left\">Key<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"108\" width=\"108\">\n<p align=\"left\">Tuple3<\/p>\n<\/td>\n<td data-colwidth=\"273\" width=\"273\">\n<p align=\"left\">IPv4\/IPv6 fragmented flow<\/p>\n<\/td>\n<td>\n<p align=\"left\">{ src_ip, dst_ip, id }<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"108\" width=\"108\">\n<p align=\"left\">Tuple5<\/p>\n<\/td>\n<td data-colwidth=\"273\" width=\"273\">\n<p align=\"left\">IPv4\/IPv6 transport flow<\/p>\n<\/td>\n<td>\n<p align=\"left\">{ src_ip, src_port, dst_ip, dst_port, protocol }<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"108\" width=\"108\">\n<p align=\"left\">Tuple6<\/p>\n<\/td>\n<td data-colwidth=\"273\" width=\"273\">\n<p align=\"left\">Tunnel flow (VLAN-C-TAG, GRE, \u2026)<\/p>\n<\/td>\n<td>\n<p align=\"left\">{ src_ip, src_port, dst_ip, dst_port, protocol, tag }<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>That is, to calculate the key, it is necessary to reach the IP layer, extract the IP addresses, and check that the flow is not fragmented (by verifying the offsets and the MF flag). If the IP packet is fragmented, the ID field should be used to construct a Tuple3 key. If the packet is not fragmented, the next layer after IP should be examined to extract the ports (if it is a transport layer protocol and ports are present), and a Tuple5 key should be constructed.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Scheme 5: Flow table example<\/figcaption><\/div>\n<\/figure>\n<p>In the diagram above, the <em>identifier<\/em> field is shown so that its values can be referenced later in the text. In practice, however, the <em>key<\/em> field is the only key used for lookup.<\/p>\n<p>Previously, we discussed types of flows grouped by the type of key. This classification is useful for managing the flow context (buffering data, collecting statistics, etc.), but it is not the only way flows are categorized. Flows can also be divided into <a href=\"https:\/\/en.wikipedia.org\/wiki\/Control_plane\" rel=\"noopener noreferrer nofollow\">Control Plane<\/a> and <strong>User Plane<\/strong> (or <strong>Data Plane<\/strong>) flows.<\/p>\n<p>A <strong>Control Plane flow<\/strong> is a network flow where packets carry &#171;control information.&#187;<\/p>\n<p>Control information refers to data that is not related to the transmission of user content, but instead serves to negotiate <\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-457980","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/457980","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=457980"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/457980\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=457980"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=457980"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=457980"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}