Skip to content

Commit

Permalink
h2: Send GOAWAY frames in a dedicated function
Browse files Browse the repository at this point in the history
And after issuing or receiving a goaway, stop processing frames when
there are no streams left.

Initially submitted as part of listen sockets management.

Refs #3959

Conflicts:
	bin/varnishd/http2/cache_http2_proto.c
  • Loading branch information
dridi authored and simonvik committed Mar 18, 2024
1 parent 5ffa8a7 commit cd48ced
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
1 change: 1 addition & 0 deletions bin/varnishd/http2/cache_http2.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ struct h2_sess {
struct sess *sess;
int refcnt;
uint32_t highest_stream;
int goaway;
int bogosity;
int do_sweep;

Expand Down
31 changes: 25 additions & 6 deletions bin/varnishd/http2/cache_http2_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ h2_rx_goaway(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC);
assert(r2 == h2->req0);

h2->goaway = 1;
h2->goaway_last_stream = vbe32dec(h2->rxf_data);
h2->error = h2_connectionerror(vbe32dec(h2->rxf_data + 4));
Lck_Lock(&h2->sess->mtx);
Expand All @@ -389,6 +390,25 @@ h2_rx_goaway(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2)
return (h2->error);
}

static void
h2_tx_goaway(struct worker *wrk, struct h2_sess *h2, h2_error h2e)
{
char b[8];

ASSERT_RXTHR(h2);
AN(h2e);

if (h2->goaway)
return;

h2->goaway = 1;
vbe32enc(b, h2->highest_stream);
vbe32enc(b + 4, h2e->val);
H2_Send_Get(wrk, h2, h2->req0);
H2_Send_Frame(wrk, h2, H2_F_GOAWAY, 0, 8, 0, b);
H2_Send_Rel(h2, h2->req0);
}

/**********************************************************************
*/

Expand Down Expand Up @@ -1410,9 +1430,12 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2)
enum htc_status_e hs;
h2_frame h2f;
h2_error h2e;
char b[8];

ASSERT_RXTHR(h2);

if (h2->goaway && h2->open_streams == 0)
return (0);

VTCP_blocking(*h2->htc->rfd);
h2->sess->t_idle = VTIM_real();
hs = HTC_RxStuff(h2->htc, h2_frame_complete,
Expand Down Expand Up @@ -1484,11 +1507,7 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2)
h2e = h2_procframe(wrk, h2, h2f);
if (h2->error == NULL && h2e != NULL) {
h2->error = h2e;
vbe32enc(b, h2->highest_stream);
vbe32enc(b + 4, h2e->val);
H2_Send_Get(wrk, h2, h2->req0);
H2_Send_Frame(wrk, h2, H2_F_GOAWAY, 0, 8, 0, b);
H2_Send_Rel(h2, h2->req0);
h2_tx_goaway(wrk, h2, h2e);
}

return (h2->error != NULL ? 0 : 1);
Expand Down

0 comments on commit cd48ced

Please sign in to comment.