Example #1
0
        /// <summary>Constructs an incoming request frame.</summary>
        /// <param name="protocol">The Ice protocol.</param>
        /// <param name="data">The frame data as an array segment.</param>
        /// <param name="maxSize">The maximum payload size, checked during decompression.</param>
        /// <param name="socketStream">The optional socket stream. The stream is non-null if there's still data to
        /// read on the stream after the reading the request frame.</param>
        internal IncomingRequestFrame(
            Protocol protocol,
            ArraySegment <byte> data,
            int maxSize,
            SocketStream?socketStream)
            : base(protocol, maxSize)
        {
            SocketStream = socketStream;

            var istr = new InputStream(data, Protocol.GetEncoding());

            if (Protocol == Protocol.Ice1)
            {
                var requestHeader = new Ice1RequestHeader(istr);
                Identity     = requestHeader.Identity;
                Facet        = Ice1Definitions.GetFacet(requestHeader.FacetPath);
                Location     = Array.Empty <string>();
                Operation    = requestHeader.Operation;
                IsIdempotent = requestHeader.OperationMode != OperationMode.Normal;
                Context      = requestHeader.Context;
                Priority     = default;
                Deadline     = DateTime.MaxValue;
            }
            else
            {
                int headerSize = istr.ReadSize();
                int startPos   = istr.Pos;

                // We use the generated code for the header body and read the rest of the header "by hand".
                var requestHeaderBody = new Ice2RequestHeaderBody(istr);
                Identity     = requestHeaderBody.Identity;
                Facet        = requestHeaderBody.Facet ?? "";
                Location     = requestHeaderBody.Location ?? Array.Empty <string>();
                Operation    = requestHeaderBody.Operation;
                IsIdempotent = requestHeaderBody.Idempotent ?? false;
                Priority     = requestHeaderBody.Priority ?? default;
                if (requestHeaderBody.Deadline < -1 || requestHeaderBody.Deadline == 0)
                {
                    throw new InvalidDataException($"received invalid deadline value {requestHeaderBody.Deadline}");
                }
                // The infinite deadline is encoded as -1 and converted to DateTime.MaxValue
                Deadline = requestHeaderBody.Deadline == -1 ?
                           DateTime.MaxValue : DateTime.UnixEpoch + TimeSpan.FromMilliseconds(requestHeaderBody.Deadline);
                Context = requestHeaderBody.Context ?? new SortedDictionary <string, string>();

                BinaryContext = istr.ReadBinaryContext();

                if (istr.Pos - startPos != headerSize)
                {
                    throw new InvalidDataException(
                              @$ "received invalid request header: expected {headerSize} bytes but read {istr.Pos - startPos
                        } bytes");
                }

                if (Location.Any(segment => segment.Length == 0))
                {
                    throw new InvalidDataException("received request with an empty location segment");
                }
            }
Example #2
0
        internal virtual async ValueTask ReceiveInitializeFrameAsync(CancellationToken cancel)
        {
            byte frameType = _socket.Endpoint.Protocol == Protocol.Ice1 ?
                             (byte)Ice1FrameType.ValidateConnection : (byte)Ice2FrameType.Initialize;

            ArraySegment <byte> data = await ReceiveFrameAsync(frameType, cancel).ConfigureAwait(false);

            if (ReceivedEndOfStream)
            {
                throw new InvalidDataException($"received unexpected end of stream after initialize frame");
            }

            if (_socket.Endpoint.Communicator.TraceLevels.Protocol >= 1)
            {
                TraceFrame(data, frameType);
            }

            if (_socket.Endpoint.Protocol == Protocol.Ice1)
            {
                if (data.Count > 0)
                {
                    throw new InvalidDataException(
                              @$ "received an ice1 frame with validate connection type and a size of `{data.Count}' bytes");
                }
            }
            else
            {
                // Read the protocol parameters which are encoded with the binary context encoding.
                var istr           = new InputStream(data, Ice2Definitions.Encoding);
                int dictionarySize = istr.ReadSize();
                for (int i = 0; i < dictionarySize; ++i)
                {
                    (int key, ReadOnlyMemory <byte> value) = istr.ReadBinaryContextEntry();
                    if (key == (int)Ice2ParameterKey.IncomingFrameMaxSize)
                    {
                        checked
                        {
                            _socket.PeerIncomingFrameMaxSize = (int)value.Span.ReadVarULong().Value;
                        }

                        if (_socket.PeerIncomingFrameMaxSize < 1024)
                        {
                            throw new InvalidDataException($@"the peer's IncomingFrameMaxSize ({
                                _socket.PeerIncomingFrameMaxSize} bytes) value is inferior to 1KB");
                        }
                    }
                    else
                    {
                        // Ignore unsupported parameters.
                    }
                }

                if (_socket.PeerIncomingFrameMaxSize == null)
                {
                    throw new InvalidDataException("missing IncomingFrameMaxSize Ice2 connection parameter");
                }
            }
        }
Example #3
0
 // Constructor for unmarshaling.
 internal WSEndpoint(InputStream istr, Transport transport, Protocol protocol)
     : base(istr, transport, protocol, mostDerived: false)
 {
     if (protocol == Protocol.Ice1)
     {
         _resource = istr.ReadString();
     }
     else
     {
         int optionCount = istr.ReadSize();
         if (optionCount > 0)
         {
             _resource = istr.ReadString();
             optionCount--;
             SkipUnknownOptions(istr, optionCount);
         }
     }
 }
Example #4
0
 // Constructor for unmarshaling
 internal TcpEndpoint(
     InputStream istr,
     Communicator communicator,
     Transport transport,
     Protocol protocol,
     bool mostDerived = true)
     : base(istr, communicator, protocol)
 {
     Transport = transport;
     if (protocol == Protocol.Ice1)
     {
         Timeout            = TimeSpan.FromMilliseconds(istr.ReadInt());
         HasCompressionFlag = istr.ReadBool();
     }
     else if (mostDerived)
     {
         SkipUnknownOptions(istr, istr.ReadSize());
     }
 }
Example #5
0
        /// <summary>Reads a binary context from the stream.</summary>
        /// <param name="istr">The input stream.</param>
        /// <returns>The binary context as an immutable dictionary.</returns>
        /// <remarks>The values of the dictionary reference memory in the stream's underlying buffer.</remarks>
        public static ImmutableDictionary <int, ReadOnlyMemory <byte> > ReadBinaryContext(this InputStream istr)
        {
            Debug.Assert(istr.Encoding == Encoding.V20);

            int size = istr.ReadSize();

            if (size == 0)
            {
                return(ImmutableDictionary <int, ReadOnlyMemory <byte> > .Empty);
            }
            else
            {
                var builder = ImmutableDictionary.CreateBuilder <int, ReadOnlyMemory <byte> >();
                for (int i = 0; i < size; ++i)
                {
                    (int key, ReadOnlyMemory <byte> value) = istr.ReadBinaryContextEntry();
                    builder.Add(key, value);
                }
                return(builder.ToImmutable());
            }
        }