Skip to content

Comments

QUIC Frame Encoding and Decoding Functions#18795

Closed
hlandau wants to merge 9 commits intoopenssl:masterfrom
hlandau:quic-wire-frames
Closed

QUIC Frame Encoding and Decoding Functions#18795
hlandau wants to merge 9 commits intoopenssl:masterfrom
hlandau:quic-wire-frames

Conversation

@hlandau
Copy link
Member

@hlandau hlandau commented Jul 13, 2022

Note that this is built on top of the ACKM PR.

I'm holding off on including packet header functions for now until I can ask @mattcaswell if he wants them, since he owns the record layer.

This is done/ready for review so I'm not marking it as a draft, but it shouldn't be merged until ACKM is merged.

@hlandau hlandau added branch: master Applies to master branch approval: review pending This pull request needs review by a committer approval: otc review pending triaged: feature The issue/pr requests/adds a feature labels Jul 13, 2022
@hlandau hlandau requested review from paulidale and t8m July 13, 2022 17:21
@hlandau hlandau self-assigned this Jul 13, 2022
@hlandau hlandau force-pushed the quic-wire-frames branch from 1739ace to 30f4fe9 Compare July 13, 2022 17:24
@github-actions github-actions bot added the severity: fips change The pull request changes FIPS provider sources label Jul 13, 2022
Copy link
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice code!

* |*data|
*/
__owur static ossl_inline int PACKET_peek_net_8(const PACKET *pkt,
uint64_t *data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our existing use of unsigned long for the net_4/net_3 versions of these functions seems dubious. We probably should use fixed width types instead. But that is for another PR.

* e.g. multiple packets).
*
* Note also that this means f->len is always valid after this function returns
* successfully, regardless of the value of f->has_len.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that f->len is always set anyway - I'm wondering why f->has_len is useful when decoding.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

has_len specifies whether the length field is or was included in the encoding. If it isn't, the frame runs to the end of the packet. Maybe could be named less confusingly (has_explicit_len?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand what it does. My question really was why we care how it was encoded. Surely the presence or otherwise of the length field is only useful during the decoding itself? i.e. not something we need to pass around and remember after we've decoded it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need a way to tell the encoder whether to include the length field. Keeping it symmetrical on the decode side seems the least surprising thing to do, as I see it.

0x01
};

/* 3. ACK */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like there are perhaps more test cases required here:

E.g. ack frame with no gaps, maximal/minimal ack delay values, no ecn data, etc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ACK frames are definitely the hairiest frames to encode and decode. There are more tests specifically for ACK below, but more would probably be good.

ACKs with and without ECN are tested, but we can probably test ACK delays more. I'll take this as an action item.

BUF_MEM_free(buf);
return testresult;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't seem to have any test cases for decoding illegal frame encodings?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'll add some.

Copy link
Member

@levitte levitte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a number of places where I'd expect size_t to be used, rather than uint64_t. All the maxes, primarily...

uint64_t len; /* Length of data in bytes */
const uint8_t *data;

char has_len; /* 1 if len field is valid */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the comment right? Below we say that len is always valid on decoding and has_len indicates it was in the frame.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comment, and renamed to has_explicit_len since the current naming is confusing.

* frame consumes one byte; num_bytes specifies the number of bytes of padding
* to write.
*/
int ossl_quic_wire_encode_frame_padding(WPACKET *pkt, size_t num_bytes);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be named ossl_quic_wire_encode_frames_padding when it creates potentially multiple frames.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just ossl_wire_encode_padding? I'll change it.

@hlandau
Copy link
Member Author

hlandau commented Jul 22, 2022

Updated. Rebased, and no longer based on top of ACKM. Some small definitions in ACKM this relied on are now incorporated in this PR. ACKM will be rebased on top of this soon.

I've added testing for malformed frame decoding. Testing of ACK frames with no gaps is already tested.

@hlandau hlandau force-pushed the quic-wire-frames branch from 30f4fe9 to f6949e9 Compare July 22, 2022 14:58
@hlandau
Copy link
Member Author

hlandau commented Jul 25, 2022

Updated.

Copy link
Contributor

@paulidale paulidale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Mostly nits but a couple of more meaningful comments.

I've not gone through comparing the produced output to the formal frame definitions.

typedef struct ossl_quic_frame_new_conn_id_st {
uint64_t seq_num;
uint64_t retire_prior_to;
const unsigned char *conn_id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a fixed array appropriate here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be equally valid. Any preference?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ID cache proposal now uses fixed arrays. We might as well be consistent and use them everywhere (and pray the standard doesn't increase the size soon). Not that I'm against length + pointer. The reduction in mallocs is probably a good thing.

BTW: I'm currently proposing an array 21 long, with the size in the first byte and the up to 20 octets in the remaining (zero filled). That way one memcmp is enough to compare two. It's a bit kludgy but workable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a bit obtuse. Since we will be representing connection IDs all over the place, I'll introduce a structure:

#define OSSL_QUIC_MAX_CONN_ID_LEN       20
typedef struct ossl_quic_conn_id_st {
    unsigned char   id_len;
    unsigned char   id[OSSL_QUIC_MAX_CONN_ID_LEN];
} OSSL_QUIC_CONN_ID;

|| !PACKET_get_quic_vlint(pkt, &len_))
return NULL;

if (len_ > SIZE_MAX
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prediction: some compilers will complain about a guaranteed true condition and we'll need to change this in the future...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any ideas?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly, nothing comes to mind except preprocessor lines :(

Reversing the condition and excluding equality len_ < SIZE_MAX sort of circumvents this but is really ugly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we shouldn't reduce the correctness of the code to satisfy compiler warnings since this is putting the cart before the horse. I'll leave this as it is for now...

If compilers start complaining about this it will definitely happen elsewhere in the codebase too, and it will probably be more productive to figure out a general strategy for it at this time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this. I wasn't expecting a resolution -- I couldn't think of one.
Once we get warnings, we can address them.

We've had some previously BTW which we've managed to avoid.

@paulidale paulidale added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Jul 28, 2022
@openssl-machine openssl-machine added approval: ready to merge The 24 hour grace period has passed, ready to merge and removed approval: done This pull request has the required number of approvals labels Jul 29, 2022
@openssl-machine
Copy link
Collaborator

This pull request is ready to merge

@paulidale
Copy link
Contributor

Merged.

@paulidale paulidale closed this Jul 29, 2022
openssl-machine pushed a commit that referenced this pull request Jul 29, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from #18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Jul 31, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Jul 31, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Jul 31, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Jul 31, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 3, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 3, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 3, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
JeffroMF pushed a commit to JeffroMF/openssl.1.55555 that referenced this pull request Aug 5, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl/openssl#18795)
sftcd pushed a commit to sftcd/openssl that referenced this pull request Sep 24, 2022
This adds functions for encoding and decoding QUIC frames.

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl#18795)
pr000000f added a commit to pr000000f/tongsuo-dev that referenced this pull request Dec 8, 2025
From OpenSSL commit dffafaf48174497a724d546c3483d2493fc9b64c,
openssl/openssl#18795

This adds functions for encoding and decoding QUIC frames.
Modify the existing include/internal/packet.h with additional
PACKET_peek_quic_vlint and PACKET_skip_quic_vlint functions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: ready to merge The 24 hour grace period has passed, ready to merge branch: master Applies to master branch severity: fips change The pull request changes FIPS provider sources triaged: feature The issue/pr requests/adds a feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants