// 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(); } }
// 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; }
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()); } }