diff --git a/tunnels/client/http2/helpers.h b/tunnels/client/http2/helpers.h index e14a64a0..fd299634 100644 --- a/tunnels/client/http2/helpers.h +++ b/tunnels/client/http2/helpers.h @@ -5,6 +5,13 @@ #define MAX_CONCURRENT_STREAMS 0xffffffffu #define MAX_CHILD_PER_STREAM 200 + +#define STATE(x) ((http2_client_state_t *)((x)->state)) +#define CSTATE(x) ((void *)((((x)->line->chains_state)[self->chain_index]))) +#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] +#define ISALIVE(x) (CSTATE(x) != NULL) + + static nghttp2_nv make_nv(const char *name, const char *value) { nghttp2_nv nv; @@ -147,9 +154,6 @@ static http2_client_con_state_t *create_http2_connection(tunnel_t *self, int tid con->method = HTTP_POST; } - context_t *init_ctx = newInitContext(con->line); - self->up->upStream(self->up, init_ctx); - return con; } static void delete_http2_connection(http2_client_con_state_t *con) diff --git a/tunnels/client/http2/http2_client.c b/tunnels/client/http2/http2_client.c index fff978d0..3a9fdf27 100644 --- a/tunnels/client/http2/http2_client.c +++ b/tunnels/client/http2/http2_client.c @@ -112,7 +112,7 @@ static bool trySendRequest(tunnel_t *self, http2_client_con_state_t *con, size_t static void flush_write_queue(http2_client_con_state_t *con) { tunnel_t *self = con->tunnel; - + context_t *g = newContext(con->line); while (contextQueueLen(con->queue) > 0) { context_t *stream_context = contextQueuePop(con->queue); @@ -124,9 +124,10 @@ static void flush_write_queue(http2_client_con_state_t *con) while (trySendRequest(self, con, stream->stream_id, stream->io, stream_context->payload)) ; - if (con->line->chains_state[self->chain_index] == NULL) - return; + if (!ISALIVE(g)) + break; } + destroyContext(g); } static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id, uint32_t error_code, void *userdata) @@ -283,6 +284,7 @@ static int on_frame_recv_callback(nghttp2_session *session, http2_client_child_con_state_t *stream = nghttp2_session_get_stream_user_data(con->session, frame->hd.stream_id); con->handshake_completed = true; flush_write_queue(con); + stream->tunnel->downStream(stream->tunnel, newEstContext(stream->line)); } else if ((frame->hd.flags & HTTP2_FLAG_END_STREAM) == HTTP2_FLAG_END_STREAM) { @@ -324,17 +326,32 @@ static inline void upStream(tunnel_t *self, context_t *c) if (c->init) { http2_client_con_state_t *con = take_http2_connection(self, c->line->tid, NULL); - if (con->line->chains_state[self->chain_index] == NULL) + context_t *g = newContext(con->line); + + if (!con->init_sent) { - destroyContext(c); - return; + con->init_sent = true; + self->up->upStream(self->up, newInitContext(con->line)); + if (!ISALIVE(g)) + { + destroyContext(g); + destroyContext(c); + return; + } } while (trySendRequest(self, con, 0, NULL, NULL)) ; + if (!ISALIVE(g)) + { + destroyContext(g); + destroyContext(c); + return; + } http2_client_child_con_state_t *stream = create_http2_stream(con, c->line, c->src_io); CSTATE_MUT(c) = stream; + destroyContext(g); if (!ISALIVE(c)) { diff --git a/tunnels/client/http2/types.h b/tunnels/client/http2/types.h index 11a59385..71f92680 100644 --- a/tunnels/client/http2/types.h +++ b/tunnels/client/http2/types.h @@ -7,11 +7,6 @@ #include "grpc_def.h" #include "loggers/network_logger.h" -#define STATE(x) ((http2_client_state_t *)((x)->state)) -#define CSTATE(x) ((void *)((((x)->line->chains_state)[self->chain_index]))) -#define CSTATE_MUT(x) ((x)->line->chains_state)[self->chain_index] -#define ISALIVE(x) (CSTATE(x) != NULL) - typedef enum { H2_SEND_MAGIC,