Skip to content
Snippets Groups Projects
Commit 66a16f39 authored by Andy Green's avatar Andy Green
Browse files

x google mux implement child close


This implements clean client and server close for mux child connections,
and deals with accounting for parent child lists.

The mux link can then survive constant connection bringup and teardown
found in the new test client.

Signed-off-by: default avatarAndy Green <andy@warmcat.com>
parent 7448c7ee
No related branches found
No related tags found
No related merge requests found
...@@ -40,6 +40,8 @@ struct libwebsocket * __libwebsocket_client_connect_2( ...@@ -40,6 +40,8 @@ struct libwebsocket * __libwebsocket_client_connect_2(
* prepare the actual connection (to the proxy, if any) * prepare the actual connection (to the proxy, if any)
*/ */
fprintf(stderr, "__libwebsocket_client_connect_2: address %s", wsi->c_address);
server_hostent = gethostbyname(wsi->c_address); server_hostent = gethostbyname(wsi->c_address);
if (server_hostent == NULL) { if (server_hostent == NULL) {
fprintf(stderr, "Unable to get host name from %s\n", fprintf(stderr, "Unable to get host name from %s\n",
... ...
......
...@@ -342,11 +342,11 @@ bail2: ...@@ -342,11 +342,11 @@ bail2:
wsi_child = conn->wsi_children[conn->block_subchannel]; wsi_child = conn->wsi_children[conn->block_subchannel];
muxdebug("Server LWS_EXT_XGM_STATE__ADDCHANNEL_HEADERS in\n"); muxdebug("Server LWS_EXT_XGM_STATE__ADDCHANNEL_HEADERS in %d\n", conn->length);
libwebsocket_read(context, wsi_child, &c, 1); libwebsocket_read(context, wsi_child, &c, 1);
if (--conn->length >= 0) if (--conn->length > 0)
break; break;
muxdebug("Server LWS_EXT_XGM_STATE__ADDCHANNEL_HEADERS done\n"); muxdebug("Server LWS_EXT_XGM_STATE__ADDCHANNEL_HEADERS done\n");
...@@ -359,7 +359,10 @@ bail2: ...@@ -359,7 +359,10 @@ bail2:
/* reply with ADDCHANNEL to ack it */ /* reply with ADDCHANNEL to ack it */
wsi->xor_mask = xor_no_mask; wsi->xor_mask = xor_no_mask;
child_conn = lws_get_extension_user_matching_ext(wsi_child, this_ext);
child_conn->wsi_parent = wsi;
muxdebug("Setting child conn parent to %p\n", (void *)wsi);
// lws_ext_x_google_mux__send_addchannel(context, wsi, wsi_child, // lws_ext_x_google_mux__send_addchannel(context, wsi, wsi_child,
// conn->block_subchannel, "url-parsing-not-done-yet"); // conn->block_subchannel, "url-parsing-not-done-yet");
...@@ -450,7 +453,12 @@ bail2: ...@@ -450,7 +453,12 @@ bail2:
case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY: case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY:
case LWS_CONNMODE_WS_CLIENT: case LWS_CONNMODE_WS_CLIENT:
// fprintf(stderr, " client\n"); // fprintf(stderr, " client\n");
libwebsocket_client_rx_sm(wsi_child, c); if (libwebsocket_client_rx_sm(wsi_child, c) < 0) {
libwebsocket_close_and_free_session(
context,
wsi_child,
LWS_CLOSE_STATUS_GOINGAWAY);
}
return 0; return 0;
...@@ -458,9 +466,13 @@ bail2: ...@@ -458,9 +466,13 @@ bail2:
default: default:
// fprintf(stderr, " server\n"); // fprintf(stderr, " server\n");
if (libwebsocket_rx_sm(wsi_child, c) < 0) if (libwebsocket_rx_sm(wsi_child, c) < 0) {
fprintf(stderr, "probs\n"); fprintf(stderr, "probs\n");
libwebsocket_close_and_free_session(
context,
wsi_child,
LWS_CLOSE_STATUS_GOINGAWAY);
}
break; break;
} }
break; break;
...@@ -611,28 +623,17 @@ int lws_extension_callback_x_google_mux( ...@@ -611,28 +623,17 @@ int lws_extension_callback_x_google_mux(
* connection * connection
*/ */
conn->wsi_parent = wsi_parent; wsi->candidate_children_list = wsi_parent->candidate_children_list;
parent_conn->wsi_children[ wsi_parent->candidate_children_list = wsi;
parent_conn->count_children] = wsi; wsi->mode = LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD;
/*
* and now we have to ask the server to allow us to do
* this
*/
if (lws_ext_x_google_mux__send_addchannel(context, fprintf(stderr, "attaching to existing mux\n");
wsi_parent, wsi, parent_conn->count_children,
(const char *)in) < 0) {
fprintf(stderr, "Addchannel failed\n");
continue;
}
parent_conn->count_children++; conn = parent_conn;
wsi = wsi_parent;
fprintf(stderr, "!x-google-mux: muxing connection! CHILD ADD %d to %p\n", parent_conn->count_children - 1, (void *)wsi); goto handle_additions;
done = 1;
n = mux_ctx->active_conns;
} }
/* /*
...@@ -663,6 +664,28 @@ int lws_extension_callback_x_google_mux( ...@@ -663,6 +664,28 @@ int lws_extension_callback_x_google_mux(
case LWS_EXT_CALLBACK_DESTROY: case LWS_EXT_CALLBACK_DESTROY:
muxdebug("LWS_EXT_CALLBACK_DESTROY\n"); muxdebug("LWS_EXT_CALLBACK_DESTROY\n");
/*
* remove us from parent if noted in parent
*/
if (conn->wsi_parent) {
parent_conn = lws_get_extension_user_matching_ext(conn->wsi_parent, ext);
if (parent_conn == 0) {
fprintf(stderr, "failed to get parent conn\n");
break;
}
for (n = 0; n < parent_conn->count_children; n++)
if (parent_conn->wsi_children[n] == wsi) {
parent_conn->count_children--;
while (n < parent_conn->count_children) {
parent_conn->wsi_children[n] = parent_conn->wsi_children[n + 1];
n++;
}
}
}
break; break;
case LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING: case LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING:
...@@ -694,6 +717,7 @@ int lws_extension_callback_x_google_mux( ...@@ -694,6 +717,7 @@ int lws_extension_callback_x_google_mux(
case LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED: case LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED:
muxdebug("LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED\n"); muxdebug("LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED\n");
handle_additions:
/* /*
* did this putative parent get x-google-mux authorized in the * did this putative parent get x-google-mux authorized in the
* end? * end?
...@@ -716,7 +740,7 @@ int lws_extension_callback_x_google_mux( ...@@ -716,7 +740,7 @@ int lws_extension_callback_x_google_mux(
wsi_parent = wsi_temp; wsi_parent = wsi_temp;
} }
break; return 1;
} }
/* /*
...@@ -741,7 +765,7 @@ int lws_extension_callback_x_google_mux( ...@@ -741,7 +765,7 @@ int lws_extension_callback_x_google_mux(
wsi_parent = wsi_temp; wsi_parent = wsi_temp;
} }
wsi->candidate_children_list = NULL; wsi->candidate_children_list = NULL;
break; return 1;
/* /*
* whenever we receive something on a muxed link * whenever we receive something on a muxed link
...@@ -776,8 +800,10 @@ int lws_extension_callback_x_google_mux( ...@@ -776,8 +800,10 @@ int lws_extension_callback_x_google_mux(
* he's not a child connection of a mux * he's not a child connection of a mux
*/ */
if (!conn->wsi_parent) if (!conn->wsi_parent) {
// fprintf(stderr, "conn %p has no parent\n", (void *)conn);
return 0; return 0;
}
/* /*
* get parent / transport mux context * get parent / transport mux context
...@@ -794,8 +820,10 @@ int lws_extension_callback_x_google_mux( ...@@ -794,8 +820,10 @@ int lws_extension_callback_x_google_mux(
* no more muxified than it already is * no more muxified than it already is
*/ */
if (parent_conn->count_children == 0) if (parent_conn->count_children == 0) {
// fprintf(stderr, "parent in singular mode\n");
return 0; return 0;
}
/* /*
* otherwise we need to take care of the sending action using * otherwise we need to take care of the sending action using
... ...
......
...@@ -721,7 +721,8 @@ libwebsocket_read(struct libwebsocket_context *context, struct libwebsocket *wsi ...@@ -721,7 +721,8 @@ libwebsocket_read(struct libwebsocket_context *context, struct libwebsocket *wsi
switch (wsi->mode) { switch (wsi->mode) {
case LWS_CONNMODE_WS_CLIENT: case LWS_CONNMODE_WS_CLIENT:
for (n = 0; n < len; n++) for (n = 0; n < len; n++)
libwebsocket_client_rx_sm(wsi, *buf++); if (libwebsocket_client_rx_sm(wsi, *buf++) < 0)
goto bail;
return 0; return 0;
default: default:
... ...
......
...@@ -222,6 +222,9 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, ...@@ -222,6 +222,9 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context,
if (old_state == WSI_STATE_ESTABLISHED && if (old_state == WSI_STATE_ESTABLISHED &&
reason != LWS_CLOSE_STATUS_NOSTATUS) { reason != LWS_CLOSE_STATUS_NOSTATUS) {
fprintf(stderr, "sending close indication...\n");
n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING],
0, LWS_WRITE_CLOSE); 0, LWS_WRITE_CLOSE);
if (!n) { if (!n) {
...@@ -246,6 +249,9 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context, ...@@ -246,6 +249,9 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context,
} }
just_kill_connection: just_kill_connection:
fprintf(stderr, "libwebsocket_close_and_free_session: just_kill_connection\n");
/* /*
* we won't be servicing or receiving anything further from this guy * we won't be servicing or receiving anything further from this guy
* remove this fd from wsi mapping hashtable * remove this fd from wsi mapping hashtable
...@@ -278,9 +284,15 @@ just_kill_connection: ...@@ -278,9 +284,15 @@ just_kill_connection:
/* tell the user it's all over for this guy */ /* tell the user it's all over for this guy */
if (wsi->protocol && wsi->protocol->callback && if (wsi->protocol && wsi->protocol->callback &&
old_state == WSI_STATE_ESTABLISHED) ((old_state == WSI_STATE_ESTABLISHED) ||
(old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) ||
(old_state == WSI_STATE_AWAITING_CLOSE_ACK))) {
fprintf(stderr, "calling back CLOSED\n");
wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED, wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED,
wsi->user_space, NULL, 0); wsi->user_space, NULL, 0);
} else {
fprintf(stderr, "not calling back closed due to old_state=%d\n", old_state);
}
/* deallocate any active extension contexts */ /* deallocate any active extension contexts */
...@@ -334,8 +346,10 @@ just_kill_connection: ...@@ -334,8 +346,10 @@ just_kill_connection:
#endif #endif
shutdown(wsi->sock, SHUT_RDWR); shutdown(wsi->sock, SHUT_RDWR);
#ifdef WIN32 #ifdef WIN32
if (wsi->sock)
closesocket(wsi->sock); closesocket(wsi->sock);
#else #else
if (wsi->sock)
close(wsi->sock); close(wsi->sock);
#endif #endif
#ifdef LWS_OPENSSL_SUPPORT #ifdef LWS_OPENSSL_SUPPORT
... ...
......
...@@ -1409,9 +1409,15 @@ int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len) ...@@ -1409,9 +1409,15 @@ int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
fprintf(stderr, "Extension reports fatal error\n"); fprintf(stderr, "Extension reports fatal error\n");
return -1; return -1;
} }
if (m) /* handled */ if (m) /* handled */ {
// fprintf(stderr, "ext sent it\n");
return 0; return 0;
} }
}
if (!wsi->sock) {
fprintf(stderr, "** error 0 sock but expected to send\n");
}
/* /*
* nope, send it on the socket directly * nope, send it on the socket directly
... ...
......
...@@ -192,6 +192,7 @@ dump_handshake_info(struct lws_tokens *lwst) ...@@ -192,6 +192,7 @@ dump_handshake_info(struct lws_tokens *lwst)
[WSI_TOKEN_ACCEPT] = "Accept", [WSI_TOKEN_ACCEPT] = "Accept",
[WSI_TOKEN_NONCE] = "Nonce", [WSI_TOKEN_NONCE] = "Nonce",
[WSI_TOKEN_HTTP] = "Http", [WSI_TOKEN_HTTP] = "Http",
[WSI_TOKEN_MUXURL] = "MuxURL",
}; };
for (n = 0; n < WSI_TOKEN_COUNT; n++) { for (n = 0; n < WSI_TOKEN_COUNT; n++) {
... ...
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment