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);
- if (--conn->length >= 0)
+ if (--conn->length > 0)
break;
muxdebug("Server LWS_EXT_XGM_STATE__ADDCHANNEL_HEADERS done\n");
/* reply with ADDCHANNEL to ack it */
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,
// conn->block_subchannel, "url-parsing-not-done-yet");
case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY:
case LWS_CONNMODE_WS_CLIENT:
// 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;
default:
// fprintf(stderr, " server\n");
- if (libwebsocket_rx_sm(wsi_child, c) < 0)
+ if (libwebsocket_rx_sm(wsi_child, c) < 0) {
fprintf(stderr, "probs\n");
-
+ libwebsocket_close_and_free_session(
+ context,
+ wsi_child,
+ LWS_CLOSE_STATUS_GOINGAWAY);
+ }
break;
}
break;
* connection
*/
- conn->wsi_parent = wsi_parent;
- parent_conn->wsi_children[
- parent_conn->count_children] = wsi;
+ wsi->candidate_children_list = wsi_parent->candidate_children_list;
+ wsi_parent->candidate_children_list = wsi;
+ wsi->mode = LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD;
- /*
- * and now we have to ask the server to allow us to do
- * this
- */
+ fprintf(stderr, "attaching to existing mux\n");
- if (lws_ext_x_google_mux__send_addchannel(context,
- wsi_parent, wsi, parent_conn->count_children,
- (const char *)in) < 0) {
- fprintf(stderr, "Addchannel failed\n");
- continue;
- }
+ conn = parent_conn;
+ wsi = wsi_parent;
- parent_conn->count_children++;
+ goto handle_additions;
- fprintf(stderr, "!x-google-mux: muxing connection! CHILD ADD %d to %p\n", parent_conn->count_children - 1, (void *)wsi);
-
- done = 1;
- n = mux_ctx->active_conns;
}
/*
case LWS_EXT_CALLBACK_DESTROY:
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;
case LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING:
case LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED:
muxdebug("LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED\n");
+handle_additions:
/*
* did this putative parent get x-google-mux authorized in the
* end?
wsi_parent = wsi_temp;
}
- break;
+ return 1;
}
/*
wsi_parent = wsi_temp;
}
wsi->candidate_children_list = NULL;
- break;
+ return 1;
/*
* whenever we receive something on a muxed link
* 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;
+ }
/*
* get parent / transport mux context
* 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;
+ }
/*
* otherwise we need to take care of the sending action using
if (old_state == WSI_STATE_ESTABLISHED &&
reason != LWS_CLOSE_STATUS_NOSTATUS) {
+
+ fprintf(stderr, "sending close indication...\n");
+
n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING],
0, LWS_WRITE_CLOSE);
if (!n) {
}
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
* remove this fd from wsi mapping hashtable
/* tell the user it's all over for this guy */
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->user_space, NULL, 0);
+ } else {
+ fprintf(stderr, "not calling back closed due to old_state=%d\n", old_state);
+ }
/* deallocate any active extension contexts */
#endif
shutdown(wsi->sock, SHUT_RDWR);
#ifdef WIN32
- closesocket(wsi->sock);
+ if (wsi->sock)
+ closesocket(wsi->sock);
#else
- close(wsi->sock);
+ if (wsi->sock)
+ close(wsi->sock);
#endif
#ifdef LWS_OPENSSL_SUPPORT
}