private ReConfigChunk makeSSNResets() { ReConfigChunk reply = new ReConfigChunk(); // create a new thing //logger.LogDebug($"SCTP closing {listOfStreamsToReset.Count} stream."); List <int> streamsL = new List <int>(); lock (listOfStreamsToReset) { foreach (var s in listOfStreamsToReset) { if (s.InboundIsOpen()) { streamsL.Add(s.getNum()); } } } int[] streams = streamsL.ToArray(); if (streams.Length > 0) { OutgoingSSNResetRequestParameter rep = new OutgoingSSNResetRequestParameter(nextNearNo(), farSeqno - 1, assoc.getNearTSN()); rep.setStreams(streams); reply.addParam(rep); } streamsL.Clear(); lock (listOfStreamsToReset) { foreach (var s in listOfStreamsToReset) { if (s.OutboundIsOpen()) { streamsL.Add(s.getNum()); } } } streams = streamsL.ToArray(); if (streams.Length > 0) { IncomingSSNResetRequestParameter rep = new IncomingSSNResetRequestParameter(nextNearNo()); rep.setStreams(streams); reply.addParam(rep); } //logger.LogDebug("reconfig chunk is " + reply.ToString()); return(reply); }
public bool sameAs(OutgoingSSNResetRequestParameter other) { return(this.reqSeqNo == other.reqSeqNo); }
protected VariableParam readVariable() { int type = _body.GetUShort(); int len = _body.GetUShort(); int blen = len - 4; //byte[] data; Unknown var; switch (type) { case 1: var = new HeartbeatInfo(1, "HeartbeatInfo"); break; // 2-4 Unassigned case 5: var = new IPv4Address(5, "IPv4Address"); break; case 6: var = new IPv6Address(6, "IPv6Address"); break; case 7: var = new StateCookie(7, "StateCookie"); break; case 8: var = new UnrecognizedParameters(8, "UnrecognizedParameters"); break; case 9: var = new CookiePreservative(9, "CookiePreservative"); break; // 10 Unassigned case 11: var = new HostNameAddress(11, "HostNameAddress"); break; case 12: var = new SupportedAddressTypes(12, "SupportedAddressTypes"); break; case 13: var = new OutgoingSSNResetRequestParameter(13, "OutgoingSSNResetRequestParameter"); break; case 14: var = new IncomingSSNResetRequestParameter(14, "IncomingSSNResetRequestParameter"); break; case 15: var = new SSNTSNResetRequestParameter(15, "SSNTSNResetRequestParameter"); break; case 16: var = new ReconfigurationResponseParameter(16, "ReconfigurationResponseParameter"); break; case 17: var = new AddOutgoingStreamsRequestParameter(17, "AddOutgoingStreamsRequestParameter"); break; case 18: var = new AddIncomingStreamsRequestParameter(18, "AddIncomingStreamsRequestParameter"); break; // 19-32767 Unassigned case 32768: var = new Unknown(32768, "ReservedforECNCapable"); break; case 32770: var = new RandomParam(32770, "Random"); break; case 32771: var = new ChunkListParam(32771, "ChunkList"); break; case 32772: var = new RequestedHMACAlgorithmParameter(32772, "RequestedHMACAlgorithmParameter"); break; case 32773: var = new Unknown(32773, "Padding"); break; case 32776: var = new SupportedExtensions(32776, "SupportedExtensions"); break; // 32777-49151 Unassigned case 49152: var = new ForwardTSNsupported(49152, "ForwardTSNsupported"); break; case 49153: var = new Unknown(49153, "AddIPAddress"); break; case 49154: var = new Unknown(49154, "DeleteIPAddress"); break; case 49155: var = new Unknown(49155, "ErrorCauseIndication"); break; case 49156: var = new Unknown(49156, "SetPrimaryAddress"); break; case 49157: var = new Unknown(49157, "SuccessIndication"); break; case 49158: var = new Unknown(49158, "AdaptationLayerIndication"); break; default: var = new Unknown(-1, "Unknown"); break; } try { var.readBody(_body, blen); //logger.LogDebug("variable type " + var.getType() + " name " + var.getName()); } catch (SctpPacketFormatException ex) { logger.LogError(ex.ToString()); } if (_body.hasRemaining()) { int mod = blen % 4; if (mod != 0) { for (int pad = mod; pad < 4; pad++) { _body.GetByte(); } } } return(var); }
/* * https://tools.ietf.org/html/rfc6525 */ public Chunk[] deal(ReConfigChunk rconf) { Chunk[] ret = new Chunk[1]; ReConfigChunk reply = null; //logger.LogDebug("Got a reconfig message to deal with"); if (haveSeen(rconf)) { // if not - is this a repeat reply = getPrevious(rconf); // then send the same reply } if (reply == null) { // not a repeat then reply = new ReConfigChunk(); // create a new thing if (rconf.hasOutgoingReset()) { OutgoingSSNResetRequestParameter oreset = rconf.getOutgoingReset(); int[] streams = oreset.getStreams(); if (streams.Length == 0) { streams = assoc.allStreams(); } if (timerIsRunning()) { markAsAcked(rconf); } // if we are behind, we are supposed to wait until we catch up. if (oreset.getLastAssignedTSN() > assoc.getCumAckPt()) { //logger.LogDebug("Last assigned > farTSN " + oreset.getLastAssignedTSN() + " v " + assoc.getCumAckPt()); foreach (int s in streams) { SCTPStream defstr = assoc.getStream(s); // AC: All this call did was set an unused local variable. Removed for now. //defstr.setDeferred(true); } ReconfigurationResponseParameter rep = new ReconfigurationResponseParameter(); rep.setSeq(oreset.getReqSeqNo()); rep.setResult(ReconfigurationResponseParameter.IN_PROGRESS); reply.addParam(rep); } else { // somehow invoke this when TSN catches up ?!?! ToDo //logger.LogDebug("we are up-to-date "); ReconfigurationResponseParameter rep = new ReconfigurationResponseParameter(); rep.setSeq(oreset.getReqSeqNo()); int result = streams.Length > 0 ? ReconfigurationResponseParameter.SUCCESS_PERFORMED : ReconfigurationResponseParameter.SUCCESS_NOTHING_TO_DO; rep.setResult((uint)result); // assume all good foreach (int s in streams) { SCTPStream cstrm = assoc.delStream(s); if (cstrm == null) { //logger.LogError("Close a non existant stream"); rep.setResult(ReconfigurationResponseParameter.ERROR_WRONG_SSN); break; // bidriectional might be a problem here... } else { cstrm.reset(); } } reply.addParam(rep); } } // ponder putting this in a second chunk ? if (rconf.hasIncomingReset()) { IncomingSSNResetRequestParameter ireset = rconf.getIncomingReset(); /*The Re-configuration * Response Sequence Number of the Outgoing SSN Reset Request * Parameter MUST be the Re-configuration Request Sequence Number * of the Incoming SSN Reset Request Parameter. */ OutgoingSSNResetRequestParameter rep = new OutgoingSSNResetRequestParameter(nextNearNo(), ireset.getReqNo(), assoc.getNearTSN()); int[] streams = ireset.getStreams(); rep.setStreams(streams); if (streams.Length == 0) { streams = assoc.allStreams(); } foreach (int s in streams) { SCTPStream st = assoc.getStream(s); if (st != null) { st.setClosing(true); } } reply.addParam(rep); // set outbound timer running here ??? //logger.LogDebug("Ireset " + ireset); } } if (reply.hasParam()) { ret[0] = reply; // todo should add sack here //logger.LogDebug("about to reply with " + reply.ToString()); } else { ret = null; } return(ret); }