Ejemplo n.º 1
0
        /// <summary>
        /// Requests a new association be created.
        /// </summary>
        /// <param name="destination">The UDP endpoint to attempt to create the association with.</param>
        /// <param name="sourcePort">The SCTP source port.</param>
        /// <param name="destinationPort">The SCTP destination port.</param>
        /// <returns>An SCTP association.</returns>
        public SctpAssociation Associate(
            IPEndPoint destination,
            ushort sourcePort,
            ushort destinationPort,
            ushort numberOutboundStreams = SctpAssociation.DEFAULT_NUMBER_OUTBOUND_STREAMS,
            ushort numberInboundStreams  = SctpAssociation.DEFAULT_NUMBER_INBOUND_STREAMS)
        {
            var association = new SctpAssociation(
                this,
                destination,
                sourcePort,
                destinationPort,
                DEFAULT_UDP_MTU,
                numberOutboundStreams,
                numberInboundStreams);

            if (_associations.TryAdd(association.ID, association))
            {
                association.Init();
                return(association);
            }
            else
            {
                logger.LogWarning("SCTP transport failed to add association.");
                association.Shutdown();
                return(null);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Event handler for a packet receive on the UDP encapsulation socket.
        /// </summary>
        /// <param name="receiver">The UDP receiver that received the packet.</param>
        /// <param name="localPort">The local port the packet was received on.</param>
        /// <param name="remoteEndPoint">The remote end point the packet was received from.</param>
        /// <param name="packet">A buffer containing the packet.</param>
        private void OnEncapsulationSocketPacketReceived(UdpReceiver receiver, int localPort, IPEndPoint remoteEndPoint, byte[] packet)
        {
            try
            {
                if (!SctpPacket.VerifyChecksum(packet, 0, packet.Length))
                {
                    logger.LogWarning($"SCTP packet from UDP {remoteEndPoint} dropped due to invalid checksum.");
                }
                else
                {
                    var sctpPacket = SctpPacket.Parse(packet, 0, packet.Length);

                    // Process packet.
                    if (sctpPacket.Header.VerificationTag == 0)
                    {
                        GotInit(sctpPacket, remoteEndPoint);
                    }
                    else if (sctpPacket.Chunks.Any(x => x.KnownType == SctpChunkType.COOKIE_ECHO))
                    {
                        // The COOKIE ECHO chunk is the 3rd step in the SCTP handshake when the remote party has
                        // requested a new association be created.
                        var cookie = base.GetCookie(sctpPacket);

                        if (cookie.IsEmpty())
                        {
                            logger.LogWarning($"SCTP error acquiring handshake cookie from COOKIE ECHO chunk.");
                        }
                        else
                        {
                            logger.LogDebug($"SCTP creating new association for {remoteEndPoint}.");

                            var association = new SctpAssociation(this, cookie, localPort);

                            if (_associations.TryAdd(association.ID, association))
                            {
                                if (sctpPacket.Chunks.Count > 1)
                                {
                                    // There could be DATA chunks after the COOKIE ECHO chunk.
                                    association.OnPacketReceived(sctpPacket);
                                }
                            }
                            else
                            {
                                logger.LogError($"SCTP failed to add new association to dictionary.");
                            }
                        }
                    }
                    else
                    {
                        // TODO: Lookup the existing association for the packet.
                        _associations.Values.First().OnPacketReceived(sctpPacket);
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError($"Exception SctpTransport.OnEncapsulationSocketPacketReceived. {excp}");
            }
        }