Skip to content

Commit aebf994

Browse files
author
Damir Zainullin
committed
++
1 parent 96adb1b commit aebf994

File tree

13 files changed

+435
-146
lines changed

13 files changed

+435
-146
lines changed

process-plugin-api/process/http/src/http.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,54 +73,67 @@ FlowAction HTTPPlugin::parseHTTP(
7373
if (parser.requestParsed && m_requestParsed) {
7474
return FlowAction::FlushWithReinsert;
7575
}
76+
m_requestParsed |= parser.requestParsed;
77+
7678
if (parser.responseParsed && m_responseParsed) {
7779
return FlowAction::FlushWithReinsert;
7880
}
81+
m_responseParsed |= parser.responseParsed;
7982

8083
if (parser.method.has_value()) {
8184
std::ranges::copy(*parser.method |
8285
std::views::take(m_exportData.method.capacity()),
8386
std::back_inserter(m_exportData.method));
87+
m_fieldHandlers[HTTPFields::HTTP_REQUEST_METHOD].setAsAvailable(flowRecord);
8488
}
8589
if (parser.uri.has_value()) {
8690
std::ranges::copy(*parser.uri |
8791
std::views::take(m_exportData.uri.capacity()),
8892
std::back_inserter(m_exportData.uri));
93+
m_fieldHandlers[HTTPFields::HTTP_REQUEST_URI].setAsAvailable(flowRecord);
8994
}
9095
if (parser.host.has_value()) {
9196
std::ranges::copy(*parser.host |
9297
std::views::take(m_exportData.host.capacity()),
9398
std::back_inserter(m_exportData.host));
99+
m_fieldHandlers[HTTPFields::HTTP_REQUEST_HOST].setAsAvailable(flowRecord);
94100
}
95101
if (parser.userAgent.has_value()) {
96102
std::ranges::copy(*parser.userAgent |
97103
std::views::take(m_exportData.userAgent.capacity()),
98104
std::back_inserter(m_exportData.userAgent));
105+
m_fieldHandlers[HTTPFields::HTTP_REQUEST_AGENT].setAsAvailable(flowRecord);
99106
}
100107
if (parser.referer.has_value()) {
101108
std::ranges::copy(*parser.referer |
102109
std::views::take(m_exportData.referer.capacity()),
103110
std::back_inserter(m_exportData.referer));
111+
m_fieldHandlers[HTTPFields::HTTP_REQUEST_REFERER].setAsAvailable(flowRecord);
104112
}
105113
if (parser.statusCode.has_value()) {
106114
m_exportData.statusCode = *parser.statusCode;
115+
m_fieldHandlers[HTTPFields::HTTP_RESPONSE_STATUS_CODE].setAsAvailable(flowRecord);
107116
}
108117
if (parser.contentType.has_value()) {
109118
std::ranges::copy(*parser.contentType |
110119
std::views::take(m_exportData.contentType.capacity()),
111120
std::back_inserter(m_exportData.contentType));
121+
m_fieldHandlers[HTTPFields::HTTP_RESPONSE_CONTENT_TYPE].setAsAvailable(flowRecord);
112122
}
113123
if (parser.server.has_value()) {
114124
std::ranges::copy(*parser.server |
115125
std::views::take(m_exportData.server.capacity()),
116126
std::back_inserter(m_exportData.server));
127+
m_fieldHandlers[HTTPFields::HTTP_RESPONSE_SERVER].setAsAvailable(flowRecord);
117128
}
118129
if (parser.cookies.has_value()) {
119130
std::ranges::copy(*parser.cookies |
120131
std::views::take(m_exportData.cookies.capacity()),
121132
std::back_inserter(m_exportData.cookies));
133+
m_fieldHandlers[HTTPFields::HTTP_RESPONSE_SET_COOKIE_NAMES].setAsAvailable(flowRecord);
122134
}
123135

136+
124137
if (m_requestParsed && m_responseParsed) {
125138
return FlowAction::RequestNoData;
126139
}

process-plugin-api/process/passiveDns/src/passivedns.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ std::optional<IPAddress> getIPFromPTR(const std::string& ptrName) noexcept
101101
ipAsString.erase(ipAsString.size() - ip4Postfix.size());
102102
struct in_addr addr;
103103
inet_pton(AF_INET, ipAsString.c_str(), &addr);
104-
return addr.s_addr;
104+
return ntohl(addr.s_addr);
105105
}
106106

107107
std::string_view ip6Postfix = ".ip6.arpa";

process-plugin-api/process/quic/src/quic.cpp

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,136 @@ int QUICPlugin::process_quic(
7373
const Packet& pkt,
7474
bool new_quic_flow)
7575
{
76-
QUICParser process_quic;
76+
QUICParser quicParser;
77+
78+
quicParser.parse(payload, initialDestConnectionId);
79+
80+
if (quicParser.headerView.has_value() &&
81+
quicParser.packetTypesCumulative.bits.zeroRTT) {
82+
m_exportData.version = quicParser.headerView->versionId;
83+
}
84+
85+
if (!m_exportData.packetTypes.full()) {
86+
m_exportData.packetTypes.push_back(
87+
static_cast<uint8_t>(quicParser.packetTypesCumulative.raw));
88+
}
89+
90+
// TODO get direction ?
91+
92+
m_exportData.zeroRTTPacket = std::min<uint16_t>(
93+
m_exportData.zeroRTTPacket + quicParser.zeroRTTPackets,
94+
std::numeric_limits<uint8_t>::max()
95+
);
96+
97+
if (quicParser.initialHeaderView.has_value()) {
98+
m_exportData.clientHelloParsed
99+
= quicParser.initialHeaderView->clientHelloParsed;
100+
}
101+
102+
switch (quicParser.packetType) {
103+
case QUICParser::PACKET_TYPE::INITIAL:
104+
if (!quicParser.initialHeaderView.has_value()) {
105+
break; //??
106+
}
107+
process_quic.quic_get_parsed_initial(parsed_initial);
108+
m_initialDestinationConnectionId.clear();
109+
std::ranges::copy(quicParser.initialHeaderView->destinationConnectionId |
110+
std::views::take(m_initialDestinationConnectionId.capacity()),
111+
std::back_inserter(m_initialDestinationConnectionId));
112+
// Store DCID from first observed Initial packet. This is used in the crypto operations.
113+
// Check length works because the first Initial must have a non-zero DCID.
114+
if (quic_data->initial_dcid_length == 0) {
115+
process_quic.quic_get_dcid_len(quic_data->initial_dcid_length);
116+
process_quic.quic_get_dcid(quic_data->initial_dcid);
117+
// Once established it can only be changed by a retry packet.
118+
}
119+
if (quicParser.initialHeaderView.has_value() &&
120+
quicParser.initialHeaderView->clientHelloParsed) {
121+
122+
if (m_exportData.sourceConnectionId.empty() &&
123+
quicParser.packetDirection.has_value() &&
124+
m_tempConnectionIdBuffer[*quicParser.packetDirection].has_value()) {
125+
std::ranges::copy(
126+
m_tempConnectionIdBuffer[*quicParser.packetDirection].destinationConnectionId |
127+
std::views::take(m_exportData.sourceConnectionId.capacity()),
128+
std::back_inserter(m_exportData.sourceConnectionId)
129+
);
130+
}
131+
set_stored_cid_fields(quic_data, new_quic_flow);
132+
set_client_hello_fields(&process_quic, rec, quic_data, pkt, new_quic_flow);
133+
quic_data->client_hello_seen = true;
134+
135+
if (!quic_data->tls_ext_type_set) {
136+
process_quic.quic_get_tls_ext_type(quic_data->tls_ext_type);
137+
process_quic.quic_get_tls_ext_type_len(quic_data->tls_ext_type_len);
138+
quic_data->tls_ext_type_set = true;
139+
}
140+
141+
if (!quic_data->tls_ext_len_set) {
142+
process_quic.quic_get_tls_extension_lengths(quic_data->tls_ext_len);
143+
process_quic.quic_get_tls_extension_lengths_len(quic_data->tls_ext_len_len);
144+
quic_data->tls_ext_len_set = true;
145+
}
146+
147+
if (!quic_data->tls_ext_set) {
148+
process_quic.quic_get_tls_ext(quic_data->tls_ext);
149+
process_quic.quic_get_tls_ext_len(quic_data->tls_ext_length);
150+
quic_data->tls_ext_set = true;
151+
}
152+
break;
153+
}
154+
155+
// Update accounting for information from CH, SH.
156+
toServer = get_direction_to_server_and_set_port(
157+
&process_quic,
158+
quic_data,
159+
process_quic.quic_get_server_port(),
160+
pkt,
161+
new_quic_flow);
162+
// fallthrough to set cids
163+
[[fallthrough]];
164+
case QUICParser::PACKET_TYPE::HANDSHAKE:
165+
// -1 sets stores intermediately.
166+
set_cid_fields(quic_data, rec, &process_quic, toServer, new_quic_flow, pkt);
167+
break;
168+
case QUICParser::PACKET_TYPE::RETRY:
169+
quic_data->cnt_retry_packets += 1;
170+
/*
171+
* A client MUST accept and process at most one Retry packet for each connection
172+
* attempt. After the client has received and processed an Initial or Retry packet from
173+
* the server, it MUST discard any subsequent Retry packets that it receives.
174+
*/
175+
if (quic_data->cnt_retry_packets == 1) {
176+
// Additionally set token len
177+
process_quic.quic_get_scid(quic_data->retry_scid);
178+
process_quic.quic_get_scid_len(quic_data->retry_scid_length);
179+
// Update DCID for decryption
180+
process_quic.quic_get_dcid_len(quic_data->initial_dcid_length);
181+
process_quic.quic_get_scid(quic_data->initial_dcid);
182+
183+
process_quic.quic_get_token_length(quic_data->quic_token_length);
184+
}
185+
186+
if (!quic_data->occid_set) {
187+
process_quic.quic_get_dcid(quic_data->occid);
188+
process_quic.quic_get_dcid_len(quic_data->occid_length);
189+
quic_data->occid_set = true;
190+
}
191+
192+
break;
193+
case QUICParser::PACKET_TYPE::ZERO_RTT:
194+
// Connection IDs are identical to Client Initial CH. The DCID might be OSCID at first
195+
// and change to SCID later. We ignore the DCID.
196+
if (!quic_data->occid_set) {
197+
process_quic.quic_get_scid(quic_data->occid);
198+
process_quic.quic_get_scid_len(quic_data->occid_length);
199+
quic_data->occid_set = true;
200+
}
201+
break;
202+
}
203+
204+
return QUIC_DETECTED;
205+
77206

78207
// Test for QUIC LH packet in UDP payload
79208
if (process_quic.quic_check_quic_long_header_packet(

process-plugin-api/process/quic/src/quic.hpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
#include <processPlugin.hpp>
1818
#include <fieldManager.hpp>
1919

20-
#include "burstStatsExport.hpp"
21-
#include "burstStatsFields.hpp"
20+
#include "quicExport.hpp"
21+
#include "quicFields.hpp"
2222

2323
namespace ipxp {
2424

@@ -47,9 +47,16 @@ class QUICPlugin : public ProcessPlugin {
4747
QUICPlugin(QUICPlugin&& other) = delete;
4848

4949
private:
50-
BurstStatsExport m_exportData;
51-
FieldHandlers<BurstStatsFields> m_fieldHandlers;
52-
50+
QUICExport m_exportData;
51+
FieldHandlers<QUICFields> m_fieldHandlers;
52+
53+
struct TemporaryConnectionIdBuffer {
54+
boost::static_string<QUICExport::MAX_CONNECTION_ID_LENGTH> sourceConnectionId;
55+
boost::static_string<QUICExport::MAX_CONNECTION_ID_LENGTH> destinationConnectionId;
56+
};
57+
58+
DirectionalField<std::optional<TemporaryConnectionIdBuffer>> m_tempConnectionIdBuffer;
59+
boost::static_string<QUICExport::MAX_CONNECTION_ID_LENGTH> m_initialConnectionId;
5360
};
5461

5562
} // namespace ipxp
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
5+
#include <directionalField.hpp>
6+
7+
namespace ipxp
8+
{
9+
enum class QUICDirection : uint8_t {
10+
CLIENT_TO_SERVER = static_cast<uint8_t>(Direction::Forward),
11+
SERVER_TO_CLIENT = static_cast<uint8_t>(Direction::Reverse),
12+
};
13+
14+
} // namespace ipxp

process-plugin-api/process/quic/src/quicExport.hpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#include <array>
44
#include <optional>
55
#include <span>
6-
#include <boost/static_string/static_string.hpp>
6+
#include <boost/static_string.hpp>
7+
#include <boost/container/static_vector.hpp>
78

89

910
#include "burst.hpp"
@@ -14,41 +15,50 @@ namespace ipxp
1415
struct QUICExport {
1516
constexpr static std::size_t BUFFER_SIZE = 255;
1617
constexpr static std::size_t MAX_CONNECTION_ID_LENGTH = 20;
18+
constexpr static std::size_t MAX_PACKETS = 30;
19+
constexpr static std::size_t MAX_TLS_EXTENSIONS = 30;
1720

1821
boost::static_string<BUFFER_SIZE> sni;
1922
boost::static_string<BUFFER_SIZE> userAgent;
2023
uint32_t quicVersion;
2124
uint32_t quicClientVersion;
2225
uint64_t quicTokenLength;
26+
boost::static_string<MAX_CONNECTION_ID_LENGTH> occid;
27+
boost::static_string<MAX_CONNECTION_ID_LENGTH> oscid;
28+
boost::static_string<MAX_CONNECTION_ID_LENGTH> scid;
29+
boost::static_string<MAX_CONNECTION_ID_LENGTH> retryScid;
30+
uint8_t quicMultiplexed;
31+
uint8_t quicZeroRTTCount;
32+
uint8_t clientHelloParsed;
33+
uint16_t serverPort;
34+
boost::container::static_vector<uint8_t, MAX_PACKETS> packetTypes;
35+
boost::container::static_vector<uint16_t, MAX_TLS_EXTENSIONS> tlsExtensionTypes;
36+
boost::container::static_vector<uint16_t, MAX_TLS_EXTENSIONS> tlsExtensionLengths;
37+
38+
39+
2340
// We use a char as a buffer.
2441
uint8_t occidLength;
2542
uint8_t oscidLength;
2643
uint8_t scidLength;
2744
//uint8_t initial_dcid_length;
28-
boost::static_string<MAX_CONNECTION_ID_LENGTH> occid;
29-
boost::static_string<MAX_CONNECTION_ID_LENGTH> oscid;
30-
boost::static_string<MAX_CONNECTION_ID_LENGTH> scid;
45+
3146
boost::static_string<MAX_CONNECTION_ID_LENGTH> initialDestConnectionId;
32-
boost::static_string<MAX_CONNECTION_ID_LENGTH> retryScid;
3347
// Intermediate storage when direction is not clear
34-
char dir_scid[MAX_CONNECTION_ID_LENGTH] = {0};
35-
char dir_dcid[MAX_CONNECTION_ID_LENGTH] = {0};
36-
char dir_scid2[MAX_CONNECTION_ID_LENGTH] = {0};
37-
char dir_dcid2[MAX_CONNECTION_ID_LENGTH] = {0};
38-
uint16_t dir_dport;
39-
uint16_t dir_dport2;
40-
uint16_t server_port;
41-
uint8_t cnt_retry_packets;
42-
43-
uint8_t quic_multiplexed;
44-
uint8_t quic_zero_rtt;
45-
uint8_t pkt_types[QUIC_MAX_ELEMCOUNT];
46-
47-
uint16_t tls_ext_type[MAX_QUIC_TLS_EXT_LEN];
48+
boost::static_string<MAX_CONNECTION_ID_LENGTH> dirScid;
49+
boost::static_string<MAX_CONNECTION_ID_LENGTH> dirDcid;
50+
boost::static_string<MAX_CONNECTION_ID_LENGTH> dirScid2;
51+
boost::static_string<MAX_CONNECTION_ID_LENGTH> dirDcid2;
52+
uint16_t dirDport;
53+
uint16_t dirDport2;
54+
uint8_t cntRetryPackets;
55+
56+
57+
58+
4859
uint16_t tls_ext_type_len;
4960
bool tls_ext_type_set;
5061

51-
uint16_t tls_ext_len[MAX_QUIC_TLS_EXT_LEN];
5262
uint8_t tls_ext_len_len;
5363
bool tls_ext_len_set;
5464

@@ -58,7 +68,6 @@ struct QUICExport {
5868

5969
uint8_t last_pkt_type;
6070

61-
uint8_t parsed_ch;
6271

6372
// Flags to ease decisions
6473
bool occid_set;

process-plugin-api/process/quic/src/quicHeaderView.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ class QUICHeaderView {
1616
constexpr static std::size_t QUIC_MIN_PACKET_LENGTH = 8;
1717

1818
enum class PacketType {
19-
INITIAL,
19+
INITIAL = 0,
2020
ZERO_RTT,
2121
HANDSHAKE,
2222
RETRY,
23-
VERSION_NEGOTIATION
23+
VERSION_NEGOTIATION = 7
2424
};
2525

2626
std::byte headerForm;
2727
QUICVersionId versionId;
28-
uint8_t destConnectionIdLength;
28+
//uint8_t destConnectionIdLength;
2929
std::span<const uint8_t> destConnectionId;
30-
uint8_t srcConnectionIdLength;
30+
//uint8_t srcConnectionIdLength;
3131
std::span<const uint8_t> srcConnectionId;
3232

3333
constexpr static

0 commit comments

Comments
 (0)