public MuxChannel getChannel(long channelId, boolean create) { if (channelId == CONTROL_CHANNEL_ID) { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"Invalid Channel ID"); } MuxChannel channel = channels.get(channelId); if (channel == null) { if (create) { channel = new MuxChannel(channelId,this); channels.put(channelId,channel); } else { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"Unknown Channel ID"); } } return channel; }
/** * Per spec, the physical connection must be failed. * <p> * <a href="https://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-08#section-18">Section 18. Fail the Physical Connection.</a> * * <blockquote> To _Fail the Physical Connection_, an endpoint MUST send a DropChannel multiplex control block with objective channel ID of 0 and drop * reason code in the range of 2000-2999, and then _Fail the WebSocket Connection_ on the physical connection with status code of 1011. </blockquote> */ private void mustFailPhysicalConnection(MuxPhysicalConnectionException muxe) { // TODO: stop muxer from receiving incoming sub-channel traffic. MuxDropChannel drop = muxe.getMuxDropChannel(); LOG.warn(muxe); try { generator.generate(null,drop); } catch (IOException ioe) { LOG.warn("Unable to send mux DropChannel",ioe); } String reason = "Mux[MUST FAIL]" + drop.getPhrase(); reason = StringUtil.truncate(reason,WebSocketFrame.MAX_CONTROL_PAYLOAD); this.physicalConnection.close(StatusCode.SERVER_ERROR,reason); // TODO: trigger abnormal close for all sub-channels. }
/** * Per spec, the physical connection must be failed. * <p> * <a href="https://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-08#section-18">Section 18. Fail the Physical Connection.</a> * * <blockquote> To _Fail the Physical Connection_, an endpoint MUST send a DropChannel multiplex control block with objective channel ID of 0 and drop * reason code in the range of 2000-2999, and then _Fail the WebSocket Connection_ on the physical connection with status code of 1011. </blockquote> */ private void mustFailPhysicalConnection(MuxPhysicalConnectionException muxe) { // TODO: stop muxer from receiving incoming sub-channel traffic. MuxDropChannel drop = muxe.getMuxDropChannel(); LOG.warn(muxe); try { generator.generate(null,drop); } catch (IOException ioe) { LOG.warn("Unable to send mux DropChannel",ioe); } String reason = "Mux[MUST FAIL]" + drop.getPhrase(); reason = StringUtil.truncate(reason,WebSocketFrame.MAX_CONTROL_PAYLOAD); this.physicalConnection.close(StatusCode.SERVER_ERROR,reason); // TODO: trigger abnormal close for all sub-channels. }
public MuxChannel getChannel(long channelId, boolean create) { if (channelId == CONTROL_CHANNEL_ID) { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"Invalid Channel ID"); } MuxChannel channel = channels.get(channelId); if (channel == null) { if (create) { channel = new MuxChannel(channelId,this); channels.put(channelId,channel); } else { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"Unknown Channel ID"); } } return channel; }
/** * Incoming parser errors */ @Override public void incomingError(WebSocketException e) { MuxDropChannel.Reason reason = MuxDropChannel.Reason.PHYSICAL_CONNECTION_FAILED; String phrase = String.format("%s: %s", e.getClass().getName(), e.getMessage()); mustFailPhysicalConnection(new MuxPhysicalConnectionException(reason,phrase)); }
/** * Incoming parser errors */ @Override public void incomingError(WebSocketException e) { MuxDropChannel.Reason reason = MuxDropChannel.Reason.PHYSICAL_CONNECTION_FAILED; String phrase = String.format("%s: %s", e.getClass().getName(), e.getMessage()); mustFailPhysicalConnection(new MuxPhysicalConnectionException(reason,phrase)); }
/** * Incoming mux control block, destined for the control channel (id 0) */ @Override public void onMuxNewChannelSlot(MuxNewChannelSlot slot) { if (policy.getBehavior() == WebSocketBehavior.SERVER) { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"NewChannelSlot not allowed per spec"); } if (slot.isFallback()) { if (slot.getNumberOfSlots() == 0) { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"Cannot have 0 number of slots during fallback"); } if (slot.getInitialSendQuota() == 0) { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"Cannot have 0 initial send quota during fallback"); } } // TODO: handle channel slot }
/** * Incoming mux control block, destined for the control channel (id 0) */ @Override public void onMuxNewChannelSlot(MuxNewChannelSlot slot) { if (policy.getBehavior() == WebSocketBehavior.SERVER) { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"NewChannelSlot not allowed per spec"); } if (slot.isFallback()) { if (slot.getNumberOfSlots() == 0) { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"Cannot have 0 number of slots during fallback"); } if (slot.getInitialSendQuota() == 0) { throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"Cannot have 0 initial send quota during fallback"); } } // TODO: handle channel slot }
throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"AddChannelResponse not allowed per spec"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_RESPONSE_ENCODING,"RSV Not allowed to be set"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.BAD_RESPONSE,"Unable to parse response",t);
throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"AddChannelResponse not allowed per spec"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_RESPONSE_ENCODING,"RSV Not allowed to be set"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.BAD_RESPONSE,"Unable to parse response",t);
throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"AddChannelRequest not allowed per spec"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_REQUEST_ENCODING,"RSV Not allowed to be set"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.BAD_REQUEST,"Unrecognized request encoding"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.BAD_REQUEST,"Unable to parse request",t);
throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_MUX_CONTROL_BLOCK,"AddChannelRequest not allowed per spec"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.UNKNOWN_REQUEST_ENCODING,"RSV Not allowed to be set"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.BAD_REQUEST,"Unrecognized request encoding"); throw new MuxPhysicalConnectionException(MuxDropChannel.Reason.BAD_REQUEST,"Unable to parse request",t);