Пример #1
0
        // Constructor for unmarshaling.
        private protected IPEndpoint(InputStream istr, Communicator communicator, Protocol protocol)
            : base(communicator, protocol)
        {
            Host = istr.ReadString();

            if (protocol == Protocol.Ice1)
            {
                checked
                {
                    Port = (ushort)istr.ReadInt();
                }
            }
            else
            {
                Port = istr.ReadUShort();
            }
        }
Пример #2
0
        // Constructor for unmarshaling.
        private protected IPEndpoint(InputStream istr, Communicator communicator, Protocol protocol)
            : base(communicator, protocol)
        {
            Debug.Assert(protocol == Protocol.Ice1 || protocol == Protocol.Ice2);
            Host = istr.ReadString();

            if (protocol == Protocol.Ice1)
            {
                checked
                {
                    Port = (ushort)istr.ReadInt();
                }
            }
            else
            {
                Port = istr.ReadUShort();
            }
            SourceAddress = communicator.DefaultSourceAddress;
        }
Пример #3
0
        internal override async ValueTask InitializeAsync(Action heartbeatCallback, CancellationToken cancel)
        {
            HeartbeatCallback = heartbeatCallback;

            // Initialize the transport
            await _transceiver.InitializeAsync(cancel).ConfigureAwait(false);

            if (IsIncoming)
            {
                (FrameType type, ArraySegment <byte> data) = await ReceiveFrameAsync(cancel);

                if (type != FrameType.Initialize)
                {
                    throw new InvalidDataException($"unexpected Slic frame with frame type `{type}'");
                }

                // Check that the Slic version is supported (we only support version 1 for now)
                var istr = new InputStream(data, Encoding);
                if (istr.ReadUShort() != 1)
                {
                    // If unsupported Slic version, we stop reading there and reply with a VERSION frame to provide
                    // the client the supported Slic versions.
                    await PrepareAndSendFrameAsync(FrameType.Version, ostr =>
                    {
                        ostr.WriteSequence(new ArraySegment <short>(new short[] { 1 }).AsReadOnlySpan());
                    }, cancel).ConfigureAwait(false);

                    (type, data) = await ReceiveFrameAsync(cancel);

                    if (type != FrameType.Initialize)
                    {
                        throw new InvalidDataException($"unexpected Slic frame with frame type `{type}'");
                    }

                    istr = new InputStream(data, Encoding);
                    ushort version = istr.ReadUShort();
                    if (version != 1)
                    {
                        throw new InvalidDataException($"unsupported Slic version `{version}'");
                    }
                }

                string protocol = istr.ReadString();
                if (ProtocolExtensions.Parse(protocol) != Protocol.Ice2)
                {
                    throw new NotSupportedException($"application protocol `{protocol}' is not supported with Slic");
                }

                // TODO: transport parameters

                // Send back an INITIALIZE_ACK frame.
                await PrepareAndSendFrameAsync(FrameType.InitializeAck, istr =>
                {
                    // TODO: transport parameters
                }, cancel).ConfigureAwait(false);
            }
            else
            {
                // Send the INITIALIZE frame.
                await PrepareAndSendFrameAsync(FrameType.Initialize, ostr =>
                {
                    ostr.WriteUShort(1);                       // Slic V1
                    ostr.WriteString(Protocol.Ice2.GetName()); // Ice protocol name
                    // TODO: transport parameters
                }, cancel).ConfigureAwait(false);

                // Read the INITIALIZE_ACK or VERSION frame from the server
                (FrameType type, ArraySegment <byte> data) = await ReceiveFrameAsync(cancel);

                // If we receive a VERSION frame, there isn't much we can do as we only support V1 so we throw
                // with an appropriate message to abort the connection.
                if (type == FrameType.Version)
                {
                    // Read the version sequence provided by the server.
                    short[] versions = new InputStream(data, Encoding).ReadArray <short>();
                    throw new InvalidDataException(
                              $"unsupported Slic version, server supports Slic `{string.Join(", ", versions)}'");
                }
                else if (type != FrameType.InitializeAck)
                {
                    throw new InvalidDataException($"unexpected Slic frame with frame type `{type}'");
                }

                // TODO: transport parameters
            }

            if (Endpoint.Communicator.TraceLevels.Transport >= 1)
            {
                var s = new StringBuilder();
                s.Append(IsIncoming ? "accepted" : "established");
                s.Append(' ');
                s.Append(Endpoint.TransportName);
                s.Append(" connection\n");
                s.Append(ToString());
                Endpoint.Communicator.Logger.Trace(Endpoint.Communicator.TraceLevels.TransportCategory, s.ToString());
            }
        }