示例#1
0
            public static void writeChId(NaiveMultiplexing m, BytesView bv, int id, ref int cur)
            {
                int idLen = m.sendChannelIdLength;

                if (idLen == 1)
                {
                    var i = id == ReservedId ? (sbyte.MinValue) : (sbyte)id;
                    bv[cur++] = (byte)i;
                }
                else if (idLen == 2)
                {
                    var i = id == ReservedId ? (short.MinValue) : (short)id;
                    bv[cur++] = (byte)(i >> 8);
                    bv[cur++] = (byte)(i);
                }
                else if (idLen == 4)
                {
                    for (int i = 4 - 1; i >= 0; i--)
                    {
                        bv[cur++] = (byte)(id >> (i * 8));
                    }
                }
                else
                {
                    string message = $"BUG?: unexpected recvChannelIdLength ({m.recvChannelIdLength})";
                    Logging.error($"{m}: " + message);
                    throw new Exception(message);
                }
            }
示例#2
0
        public async Task <int> ReadAsync(BytesSegment bs)
        {
            var pos     = 0;
            var curnode = latestMsg;

            if (curnode == null || curnode.tlen == 0)
            {
                curnode = (await MsgStream.RecvMsgR(null)).Data;
                if (curnode == null)
                {
                    return(0);
                }
            }
            do
            {
                if (curnode.len > 0)
                {
                    var size = Math.Min(bs.Len, curnode.len);
                    Buffer.BlockCopy(curnode.bytes, curnode.offset, bs.Bytes, bs.Offset + pos, size);
                    curnode.SubSelf(size);
                    pos += size;
                }
            } while (pos < bs.Len && (curnode = curnode.nextNode) != null);
            if (curnode == null || curnode.tlen == 0)
            {
                latestMsg = null;
            }
            else
            {
                latestMsg = curnode;
            }
            return(pos);
        }
示例#3
0
        private async Task SendImpl(Msg msg, byte flags)
        {
            var header = BufferPool.GlobalGetBs(4);
            int hPos   = 0;
            int len    = msg.Data.len;

            if (len > 0x00ffffff)
            {
                throw new ArgumentOutOfRangeException("msg", "msg is too long!");
            }
            for (int i = 3 - 1; i >= 0; i--)
            {
                header[hPos++] = (byte)((len >> (i * 8)) & (0xff));
            }
            header[hPos++] = flags;

            var bv = new BytesView(header.Bytes, header.Offset, header.Len);

            Filters.OnWrite(bv);
            if (bv.len != hPos)
            {
                throw new Exception("filters are not allowed to change data size");
            }

            Filters.OnWrite(msg.Data);
            if (msg.Data.len != len)
            {
                throw new Exception("filters are not allowed to change data size");
            }

            bv.nextNode = msg.Data;

            await BaseStream.WriteMultipleAsyncR(bv);
        }
示例#4
0
 public AwaitableWrapper <Msg> RecvMsgR(BytesView buf)
 {
     if (readEOF)
     {
         ThrowInvalidOperation();
     }
     raR.Reset();
     raR_deq = recvQueue.DequeueAsync(out raR_noWaiting);
     if (raR_continuation == null)
     {
         raR_continuation = () => {
             Msg m;
             var tmp = raR_deq;
             raR_deq = null;
             if (!tmp.TryGetResult(out m, out var ex))
             {
                 raR.SetException(ex);
             }
             else
             {
                 try {
                     m = rar_continuation2(m);
                 } catch (Exception e) {
                     raR.SetException(e);
                     return;
                 }
                 raR.SetResult(m);
             }
         };
示例#5
0
        private Task WriteMultipleAsyncImpl(BytesView bv)
        {
            if (bv.nextNode == null)
            {
                return(WriteAsync(new BytesSegment(bv)));
            }
            var e     = writeArgPool.GetValue();
            int count = 0;

            foreach (var cur in bv)
            {
                if (cur.len > 0)
                {
                    count++;
                }
            }
            var bufList = new ArraySegment <byte> [count];
            var index   = 0;

            foreach (var cur in bv)
            {
                if (cur.len > 0)
                {
                    bufList[index++] = new ArraySegment <byte>(cur.bytes, cur.offset, cur.len);
                }
            }
            e.BufferList = bufList;
            return(SendAsync(e));
        }
示例#6
0
            public static Frame unpack(NaiveMultiplexing m, BytesView bv)
            {
                var cur = 0;
                int id  = getChId(m, bv, ref cur);

                bv.SubSelf(cur);
                return(new Frame {
                    Id = id, Data = bv
                });
            }
示例#7
0
 public AwaitableWrapper WriteMultipleAsyncR(BytesView bv)
 {
     if (raWm == null)
     {
         raWm = new ReusableAwaiter <VoidType> .BeginEndStateMachine <SocketStream1>(this, WriteMultipleEnd);
     }
     raWm.Reset();
     ArraySegment <byte>[] bufList = PrepareWriteMultiple(bv);
     WriteMultipleBegin(this, bufList, raWm.ArgCallback, raWm.ArgState);
     return(new AwaitableWrapper(raWm));
 }
示例#8
0
        public static byte[] EncryptOrDecryptBytes(bool isEncrypting, byte[] key, byte[] buf)
        {
            var bv = new BytesView(buf);

            if (key.Length > 16)
            {
                key = key.Take(16).ToArray();
            }
            WebSocket.GetAesFilter2(isEncrypting, key)(bv);
            return(bv.GetBytes());
        }
示例#9
0
        internal async Task SendOpcode(Channel ch, byte opcode)
        {
            BytesView bv   = new BytesView(new byte[4 + 1]);
            Task      task = null;

            lock (_sendLock) {
                int cur = 0;
                Frame.writeChId(this, bv, ch.Id, ref cur);
                bv[cur++] = opcode;
                task      = this.SendMsg_NoLock(ReservedChannel, bv);
            }
            await task.CAF();
        }
示例#10
0
            public BytesView pack(NaiveMultiplexing m, BytesView headerBv = null)
            {
                Debug.Assert(Id <= m.currentMaxId, $"Id > currentMaxId ({m})");
                if (headerBv == null)
                {
                    headerBv = new BytesView(new byte[getSendChIdLen(m)]);
                }
                var cur = 0;

                writeChId(m, headerBv, Id, ref cur);
                headerBv.len      = cur;
                headerBv.nextNode = Data;
                return(headerBv);
            }
示例#11
0
        public static uint Append(BytesView bv, uint initial)
        {
            uint crc = initial;

            while (bv != null)
            {
                if (bv.len > 0)
                {
                    crc = Crc32CAlgorithm.Append(crc, bv.bytes, bv.offset, bv.len);
                }
                bv = bv.nextNode;
            }
            return(crc);
        }
示例#12
0
        public async Task <Msg> RecvMsg(BytesView buf)
        {
            while (true)
            {
                Msg msg = Msg.EOF;
                await WaitBaseStream();

                try {
                    msg = await BaseStream.RecvMsg(buf);
                } catch (Exception) {
                }
                if (msg.IsEOF)
                {
                    OnBaseStreamFailed();
                    continue;
                }
                var data   = msg.Data;
                var opcode = (Opcode)data[0];
                if (opcode == Opcode.Data)
                {
                    ReceivedPacketsCount++;
                    SendAck();
                    return(msg);
                }
                else if (opcode == Opcode.AckOneMessage)
                {
                    AckedPacketsCount++;
                    var acked = unackedPackets.Dequeue();
                    SendingWindowAdd(acked.Len);
                }
                else if (opcode == Opcode.AckMessages)
                {
                    int seq      = BitConverter.ToInt32(data.bytes, data.offset + 1);
                    int totalLen = 0;
                    while (unackedPackets.Peek().Seq <= seq)
                    {
                        AckedPacketsCount++;
                        var acked = unackedPackets.Dequeue();
                        totalLen += acked.Len;
                    }
                    SendingWindowAdd(totalLen);
                }
                else
                {
                    throw new Exception("unknown opcode: " + opcode);
                }
            }
        }
示例#13
0
 public Task <Msg> RecvMsg(BytesView buf)
 {
     lock (_syncRoot) {
         if (MState.HasRemoteShutdown)
         {
             throw new InvalidOperationException("remote shutdown");
         }
         if (lastRecv?.IsCompleted == false)
         {
             throw new Exception("another RecvMsg() task is running");
         }
         var t = _RecvMsg(buf);
         lastRecv = t;
         return(t);
     }
 }
示例#14
0
                public async Task <Msg> _RecvMsg(BytesView buf)
                {
                    if (!_conn.ivReceived)
                    {
                        _conn.ivReceived = true;
                        var recvEnc = _conn.enc(false);
                        recvEnc.IV = (await ws.ReadAsync()).payload;
                        ws.AddReadFilter(FilterBase.GetStreamFilterFromIVEncryptor(false, recvEnc, true));
                    }
                    var frame = await ws.ReadAsync();

                    if (frame.opcode == 0x01)
                    {
                        OnFinReceived();
                        return(Msg.EOF);
                    }
                    return(frame.payload);
                }
示例#15
0
 public static AwaitableWrapper WriteMultipleAsyncR(this IMyStream myStream, BytesView bv)
 {
     if (myStream is IMyStreamMultiBuffer bvs)
     {
         return(bvs.WriteMultipleAsyncR(bv));
     }
     else
     {
         return(new AwaitableWrapper(NaiveUtils.RunAsyncTask(async() => {
             foreach (var item in bv)
             {
                 if (item.len > 0)
                 {
                     await myStream.WriteAsync(new BytesSegment(item));
                 }
             }
         })));
     }
 }
示例#16
0
        private static ArraySegment <byte>[] PrepareWriteMultiple(BytesView bv)
        {
            int count = 0;

            foreach (var cur in bv)
            {
                if (cur.len > 0)
                {
                    count++;
                }
            }
            var bufList = new ArraySegment <byte> [count];
            var index   = 0;

            foreach (var cur in bv)
            {
                if (cur.len > 0)
                {
                    bufList[index++] = new ArraySegment <byte>(cur.bytes, cur.offset, cur.len);
                }
            }

            return(bufList);
        }
示例#17
0
            public static int getChId(NaiveMultiplexing m, BytesView bv, ref int cur)
            {
                int id    = 0;
                int idLen = m.recvChannelIdLength;

                if (idLen == 1)
                {
                    id = (sbyte)bv[cur++];
                    if (id == sbyte.MinValue)
                    {
                        id = ReservedId;
                    }
                }
                else if (idLen == 2)
                {
                    id = (short)(bv[cur++] << 8 | bv[cur++]);
                    if (id == short.MinValue)
                    {
                        id = ReservedId;
                    }
                }
                else if (idLen == 4)
                {
                    for (int i = 4 - 1; i >= 0; i--)
                    {
                        id |= (bv[cur++] << (i * 8));
                    }
                }
                else
                {
                    string message = $"BUG?: unexpected recvChannelIdLength ({idLen})";
                    Logging.error($"{m}: " + message);
                    throw new Exception(message);
                }
                return(id);
            }
示例#18
0
        public Task <Msg> RecvMsg(BytesView buf)
        {
            if (PreReadEnabled && recvTasks == null)
            {
                recvTasks = new Task <Msg> [recvStreams.Length];
                for (int i = 0; i < recvStreams.Length; i++)
                {
                    var i2 = i;
                    recvTasks[i] = Task.Run(() => recvStreams[i2].RecvMsg(null));
                }
            }
            if (nextRecv == recvStreams.Length)
            {
                nextRecv = 0;
            }
            var curRecv2 = nextRecv++;

            if (recvTasks != null)
            {
                var task = recvTasks[curRecv2];
                recvTasks[curRecv2] = (!task.IsCompleted)
                    ? NaiveUtils.RunAsyncTask(async(s) => {
                    await s.prevTask;
                    return(await s.curStream.RecvMsg(null));
                }, new recvArgs {
                    prevTask = task, curStream = recvStreams[curRecv2]
                })
                                      //? task.ContinueWith((t, s) => s.CastTo<IMsgStream>().RecvMsg(null), recvStreams[curRecv2], TaskContinuationOptions.ExecuteSynchronously).Unwrap()
                    : recvStreams[curRecv2].RecvMsg(null);
                return(task);
            }
            else
            {
                return(recvStreams[curRecv2].RecvMsg(buf));
            }
        }
示例#19
0
 public AwaitableWrapper WriteMultipleAsyncR(BytesView bv)
 {
     return(new AwaitableWrapper(MsgStream.SendMsg(new Msg(bv))));
 }
示例#20
0
 public static uint Compute(BytesView bv)
 {
     return(Append(bv, 0));
 }
示例#21
0
 public Task WriteMultipleAsync(BytesView bv)
 {
     ArraySegment <byte>[] bufList = PrepareWriteMultiple(bv);
     return(TaskHelper.FromAsyncTrim(this, bufList, WriteMultipleBegin, WriteMultipleEnd));
 }
示例#22
0
 public async Task <Msg> RecvMsg(BytesView buf)
 {
     return(await RecvMsgR(buf));
 }
示例#23
0
        public async Task <Msg> RecvMsg(BytesView buf)
        {
            var frame = await RecvImpl();

            return(new Msg(frame.Payload));
        }
示例#24
0
 public AwaitableWrapper WriteMultipleAsyncR(BytesView bv)
 {
     return(new AwaitableWrapper(WriteMultipleAsyncImpl(bv)));
 }
示例#25
0
 public Frame(int id, BytesView data)
 {
     Id   = id;
     Data = data;
 }