quic: Make follow stream respect server direction

For QUIC, we explicitly know the server direction. Use that
in order to correctly mark which packets are from the server
verus from the client, instead of assuming that the first packets
in a stream are from the client (which is true for a connection
generally but not necessarily a stream). This also allows us to track
direction across connection migration instead of marking all
packets after migration as from the server.
This commit is contained in:
John Thacker 2022-07-29 07:25:14 -04:00 committed by A Wireshark GitLab Utility
parent 6f6d53be78
commit 72703582d5
1 changed files with 42 additions and 7 deletions

View File

@ -393,6 +393,7 @@ typedef struct _quic_follow_stream {
typedef struct quic_follow_tap_data {
tvbuff_t *tvb;
guint64 stream_id;
gboolean from_server;
} quic_follow_tap_data_t;
/**
@ -2344,6 +2345,7 @@ dissect_quic_frame_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tree
follow_data->tvb = tvb_new_subset_remaining(tvb, offset);
follow_data->stream_id = stream_id;
follow_data->from_server = from_server;
tap_queue_packet(quic_follow_tap, pinfo, follow_data);
}
@ -4447,8 +4449,9 @@ quic_follow_address_filter(address *src_addr _U_, address *dst_addr _U_, int src
}
static tap_packet_status
follow_quic_tap_listener(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data, tap_flags_t flags)
follow_quic_tap_listener(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data, tap_flags_t flags _U_)
{
follow_record_t *follow_record;
follow_info_t *follow_info = (follow_info_t *)tapdata;
const quic_follow_tap_data_t *follow_data = (const quic_follow_tap_data_t *)data;
@ -4457,12 +4460,44 @@ follow_quic_tap_listener(void *tapdata, packet_info *pinfo, epan_dissect_t *edt
return TAP_PACKET_DONT_REDRAW;
}
// XXX: follow_tvb_tap_listener sets follow_info->is_server based on
// the initial client_port and client_ip, and is not correct after
// connection migration. QUIC should implement its own function
// here. Ideally, such function should also deal with stream
// fragmentation in a similar manner to the TCP dissector.
return follow_tvb_tap_listener(tapdata, pinfo, NULL, follow_data->tvb, flags);
follow_record = g_new(follow_record_t, 1);
// XXX: Ideally, we should also deal with stream retransmission
// and out of order packets in a similar manner to the TCP dissector,
// using the offset, plus ACKs and other information.
follow_record->data = g_byte_array_sized_new(tvb_captured_length(follow_data->tvb));
follow_record->data = g_byte_array_append(follow_record->data, tvb_get_ptr(follow_data->tvb, 0, -1), tvb_captured_length(follow_data->tvb));
follow_record->packet_num = pinfo->fd->num;
follow_record->abs_ts = pinfo->fd->abs_ts;
/* This sets the address and port information the first time this
* stream is tapped. It will no longer be true after migration, but
* as it seems it's only used for display, using the initial values
* is the best we can do.
*/
if (follow_data->from_server) {
follow_record->is_server = TRUE;
if (follow_info->client_port == 0) {
follow_info->server_port = pinfo->srcport;
copy_address(&follow_info->server_ip, &pinfo->src);
follow_info->client_port = pinfo->destport;
copy_address(&follow_info->client_ip, &pinfo->dst);
}
} else {
follow_record->is_server = FALSE;
if (follow_info->client_port == 0) {
follow_info->client_port = pinfo->srcport;
copy_address(&follow_info->client_ip, &pinfo->src);
follow_info->server_port = pinfo->destport;
copy_address(&follow_info->server_ip, &pinfo->dst);
}
}
follow_info->bytes_written[follow_record->is_server] += follow_record->data->len;
follow_info->payload = g_list_prepend(follow_info->payload, follow_record);
return TAP_PACKET_DONT_REDRAW;
}
guint32 get_quic_connections_count(void)