Example #1
0
        /**
         * <code>
         * 2)  Authenticate the State Cookie as one that it previously generated
         * by comparing the computed MAC against the one carried in the
         * State Cookie.  If this comparison fails, the SCTP packet,
         * including the COOKIE ECHO and any DATA chunks, should be silently
         * discarded,
         *
         * 3)  Compare the port numbers and the Verification Tag contained
         * within the COOKIE ECHO chunk to the actual port numbers and the
         * Verification Tag within the SCTP common header of the received
         * packet.  If these values do not match, the packet MUST be
         * silently discarded.
         *
         * 4)  Compare the creation timestamp in the State Cookie to the current
         * local time.  If the elapsed time is longer than the lifespan
         * carried in the State Cookie, then the packet, including the
         * COOKIE ECHO and any attached DATA chunks, SHOULD be discarded,
         * and the endpoint MUST transmit an ERROR chunk with a "Stale
         * Cookie" error cause to the peer endpoint.
         *
         * 5)  If the State Cookie is valid, create an association to the sender
         * of the COOKIE ECHO chunk with the information in the TCB data
         * carried in the COOKIE ECHO and enter the ESTABLISHED state.
         *
         * 6)  Send a COOKIE ACK chunk to the peer acknowledging receipt of the
         * COOKIE ECHO.  The COOKIE ACK MAY be bundled with an outbound DATA
         * chunk or SACK chunk; however, the COOKIE ACK MUST be the first
         * chunk in the SCTP packet.
         *
         * 7)  Immediately acknowledge any DATA chunk bundled with the COOKIE
         * ECHO with a SACK (subsequent DATA chunk acknowledgement should
         * follow the rules defined in Section 6.2).  As mentioned in step
         * 6, if the SACK is bundled with the COOKIE ACK, the COOKIE ACK
         * MUST appear first in the SCTP packet.
         * </code>
         */
        private Chunk[] cookieEchoDeal(CookieEchoChunk echo)
        {
            Chunk[] reply = new Chunk[0];
            if (_state == State.CLOSED || _state == State.COOKIEWAIT || _state == State.COOKIEECHOED)
            {
                // Authenticate the State Cookie
                CookieHolder cookie;
                if (null != (cookie = checkCookieEcho(echo.getCookieData())))
                {
                    // Compare the creation timestamp in the State Cookie to the current local time.
                    uint howStale = howStaleIsMyCookie(cookie);
                    if (howStale == 0)
                    {
                        //enter the ESTABLISHED state
                        _state = State.ESTABLISHED;

                        /*
                         *                       Send a COOKIE ACK chunk to the peer acknowledging receipt of the
                         *                       COOKIE ECHO.  The COOKIE ACK MAY be bundled with an outbound DATA
                         *                       chunk or SACK chunk; however, the COOKIE ACK MUST be the first
                         *                       chunk in the SCTP packet.
                         */
                        reply    = new Chunk[1];
                        reply[0] = new CookieAckChunk();
                    }
                    else
                    {
                        reply = new Chunk[1];

                        /* If the elapsed time is longer than the lifespan
                         * carried in the State Cookie, then the packet, including the
                         * COOKIE ECHO and any attached DATA chunks, SHOULD be discarded,
                         * and the endpoint MUST transmit an ERROR chunk with a "Stale
                         * Cookie" error cause to the peer endpoint.*/
                        StaleCookieError sce = new StaleCookieError();
                        sce.setMeasure(howStale * 1000);
                        ErrorChunk ec = new ErrorChunk(sce);
                        reply[0] = ec;
                    }
                }
                else
                {
                    logger.LogError("Got a COOKIE_ECHO that doesn't match any we sent. ?!?");
                }
            }
            else
            {
                logger.LogDebug("Got an COOKIE_ECHO when not closed - ignoring it");
            }

            return(reply);
        }
Example #2
0
        public static Chunk mkChunk(ByteBuffer pkt)
        {
            Chunk ret = null;

            if (pkt.remaining() >= 4)
            {
                ChunkType type   = (ChunkType)pkt.GetByte();
                byte      flags  = pkt.GetByte();
                int       length = pkt.GetUShort();
                switch (type)
                {
                case ChunkType.DATA:
                    ret = new DataChunk(flags, length, pkt);
                    break;

                case ChunkType.INIT:
                    ret = new InitChunk(type, flags, length, pkt);
                    break;

                case ChunkType.SACK:
                    ret = new SackChunk(type, flags, length, pkt);
                    break;

                case ChunkType.INITACK:
                    ret = new InitAckChunk(type, flags, length, pkt);
                    break;

                case ChunkType.COOKIE_ECHO:
                    ret = new CookieEchoChunk(type, flags, length, pkt);
                    break;

                case ChunkType.COOKIE_ACK:
                    ret = new CookieAckChunk(type, flags, length, pkt);
                    break;

                case ChunkType.ABORT:
                    ret = new AbortChunk(type, flags, length, pkt);
                    break;

                case ChunkType.HEARTBEAT:
                    ret = new HeartBeatChunk(type, flags, length, pkt);
                    break;

                case ChunkType.RE_CONFIG:
                    ret = new ReConfigChunk(type, flags, length, pkt);
                    break;

                case ChunkType.ERROR:
                    ret = new ErrorChunk(type, flags, length, pkt);
                    break;

                default:
                    logger.LogWarning($"SCTP unknown chunk type received {type}.");
                    ret = new FailChunk(type, flags, length, pkt);
                    break;
                }
                if (ret != null)
                {
                    if (pkt.hasRemaining())
                    {
                        int mod = ret.getLength() % 4;
                        if (mod != 0)
                        {
                            for (int pad = mod; pad < 4; pad++)
                            {
                                pkt.GetByte();
                            }
                        }
                    }
                }
            }
            return(ret);
        }