@@ -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 (
0 commit comments