Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworked HTTP1 -> HTTP2 message transformation #1820

Merged
merged 10 commits into from
Apr 6, 2023

Conversation

const-t
Copy link
Contributor

@const-t const-t commented Feb 15, 2023

This patch introduce another approach to HTTP1 -> HTTP2 message transformation. We had following problems with inplace transformation: Each added header was added to new skb fragment, that caused skb fragmentation. Appending value to existing in message header was limited by size which remains after transformation. We could use mixed approach, encode headers inplace while message has room and then expand skb by new fragments, but maintain both approaches and code complexity not worth it.

Now transformation consist of following steps:

  1. Find skb and fragment contains body or last crlf, if body not exists.
  2. Delete found data from skb. Keep skb.
  3. Hpack encode headers then add to skb from previous step. Headers adds as paged fragments, now we don't use headroom. HTTP2_MAX_OFFSET not used anymore during HTTP1 -> HTTP2 transformation without cache. All paged data in skb allocates from response's TfwPool.
  4. Forward message to client.
  5. Cleanup all data that was deleted from skbs in first step.

TfwPool was patched to statisfy new requirments. Now we use compound pages for order above zero and put_page insted of free_pages, because during free pages might be still used by skbs.

Fixed CONTINUATION frame.

@const-t const-t force-pushed the kt-1103-h2-msg-trasform branch 8 times, most recently from 3e9ec31 to 1b5cfaa Compare February 17, 2023 15:06
@const-t const-t force-pushed the kt-1103-h2-msg-trasform branch 5 times, most recently from 6468634 to 461c529 Compare February 23, 2023 15:12
@const-t const-t force-pushed the kt-1103-h2-msg-trasform branch 2 times, most recently from 026f948 to e653d84 Compare February 24, 2023 10:18
@const-t const-t marked this pull request as ready for review February 27, 2023 09:36
@const-t const-t force-pushed the kt-1103-h2-msg-trasform branch 2 times, most recently from 8df8606 to f66aedb Compare March 1, 2023 15:19
Copy link
Contributor

@krizhanovsky krizhanovsky left a comment

Choose a reason for hiding this comment

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

I didn't notice any severe issue with the pull request, but there are still some things to do and fix.

Please make all the following changes by new separate patches, do not rewrite the current patches, to simplify next reviews. Later, on the merge time, you can squash senseless patches.

fw/cache.c Outdated Show resolved Hide resolved
fw/http.h Outdated Show resolved Hide resolved
fw/hpack.c Outdated Show resolved Hide resolved
fw/hpack.c Outdated Show resolved Hide resolved
fw/http_msg.c Outdated Show resolved Hide resolved
ss_skb_unlink(&it->skb_head, skb);
ss_skb_queue_tail(&cleanup->skb_head, skb);

} while (it->skb != NULL);
Copy link
Contributor

Choose a reason for hiding this comment

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

@RomanBelozerov I'm wondering if we have a test, which sends an HTTP response to Tempesta with very small chunks, especially headers, and Tempesta forwards the response to a client via HTTP/2? I believe we have some test for this, but I'm not sure about HTTP/2 client in this scenario...

Copy link
Contributor

Choose a reason for hiding this comment

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

We have test for small TCP chunks in h2 request. Should I add for responses?

Copy link
Contributor

Choose a reason for hiding this comment

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

fw/http.h Outdated Show resolved Hide resolved
fw/http_msg.c Outdated Show resolved Hide resolved
fw/http_msg.c Show resolved Hide resolved
fw/ss_skb.h Outdated Show resolved Hide resolved
@EvgeniiMekhanik
Copy link
Contributor

There are several tests which doesn't work on this branch tempesta-tech/tempesta-test@59db00a#diff-46cbe3acf14e83bddf0360bdc9ab952e6673ea0360c67f246da3cbdae49a6eb1R493 (test_big_header_after_setting_header_table_size, test_big_body_after_setting_header_table_size) (very big body or very big header)

return -ENOENT;
T_WARN("Appending to singular header '%.*s'\n",
PR_TFW_STR(TFW_STR_CHUNK(hdr, 0)));
return 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why we don't drop response in this case now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We shouldn't, it is a legit case. Just print a warning.

fw/hpack.c Outdated Show resolved Hide resolved
fw/hpack.c Outdated Show resolved Hide resolved
fw/http.c Outdated Show resolved Hide resolved
fw/http_msg.c Show resolved Hide resolved
fw/http_msg.c Show resolved Hide resolved
fw/http_msg.c Show resolved Hide resolved
@EvgeniiMekhanik
Copy link
Contributor

Please see tempesta-tech/tempesta-test@465eecf i add several tests, which doesn't work. Also test_flow_control_window_with_long_headers_and_body_FOR_1820 crash on this branch

Copy link
Contributor

@krizhanovsky krizhanovsky left a comment

Choose a reason for hiding this comment

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

LGTM. I created a new issue for a non addressed comment about copying.

Please also update the copyright year in the modified files (e.g. pool.[ch])

fw/ss_skb.h Outdated Show resolved Hide resolved
fw/http_msg.c Show resolved Hide resolved
fw/http_msg.c Outdated Show resolved Hide resolved
Copy link
Contributor

@s0nx s0nx left a comment

Choose a reason for hiding this comment

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

LGTM

fw/hpack.c Outdated Show resolved Hide resolved
fw/http_msg.c Outdated Show resolved Hide resolved
Copy link
Contributor

@EvgeniiMekhanik EvgeniiMekhanik left a comment

Choose a reason for hiding this comment

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

LGTM, but please squash all fixes in appropriate commits

@const-t const-t force-pushed the kt-1103-h2-msg-trasform branch 2 times, most recently from df99fad to ca26930 Compare April 5, 2023 11:16
This patch introduce another approach to HTTP1 -> HTTP2 message
transformation. We had following problems with inplace transformation:
Each added header was added to new skb fragment, that caused skb
fragmentation. Appending value to existing in message header
was limited by size which remains after transformation. We could
use mixed approach, encode headers inplace while message has room
and then expand skb by new fragments, but maintain both approaches
and code complexity not worth it.

Now transformation consist of following steps:
1. Find skb and fragment contains body or last crlf, if body not exists.
2. Delete found data from skb. Keep skb.
3. Hpack encode headers then add to skb from previous step. Headers adds
as paged fragments, now we don't use headroom. HTTP2_MAX_OFFSET not used
anymore during HTTP1 -> HTTP2 transformation without cache. All paged
data in skb allocates from response's TfwPool.
4. Forward message to client.
5. Cleanup all data that was deleted from skbs in first step.

TfwPool was patched to statisfy new requirments. Now we use compound
pages for order above zero and `put_page` insted of `free_pages`,
because during free pages might be still used by skbs.

Fixed CONTINUATION frame.
tfw_http_msg_resp|req_spec_hid expects header name with colon
or even without it, however whole header was passed that
cause incorrect "hid" finding
duplicated singular header. Warning message changed to human
readable. (SQUASH ME)
Current behaviour:
 -resp_hdr_add adds header only if it doesn't exists in message.
 Except special non-singular headers e.g set-cookie, forwarded.
 These headers can be added anyway. Appending to header NOT
 IMPLEMENTED for http2.

 -resp_hdr_set adds headers anyway, even if such header already
 exists in message. Existed header will be removed.
…coding headers.

Now we don't need to have many operations such as "expand" or "substitute".
We only need to decide to use or not pool(must not be used for cache and local
messages) and what format of header we will encode, http1 raw or http2 ready.

added @tfw_hpack_transform that used during HTTP1 -> HTTP2
transformation.
everywhere and avoids unneccessary calls tfw_hpack_hdr_add/expand
There was a case when we exhaust all available room in skb
and tso_fragment couldn't correctly split such skb.

Now max size of skb data is:
SS_SKB_MAX_DATA_LEN (SKB_MAX_HEADER + MAX_SKB_FRAGS * PAGE_SIZE)
@const-t const-t changed the title Reworked HTTP1 -> HTTP2 message transformation. Reworked HTTP1 -> HTTP2 message transformation Apr 5, 2023
@const-t const-t closed this Apr 5, 2023
@const-t const-t reopened this Apr 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants