Example #1
0
        private bool HandleReceiveQueue()
        {
            TunnelDataMessage[] tdmsgs = null;

            lock ( ReceiveQueue )
            {
                if (ReceiveQueue.Count == 0)
                {
                    return(true);
                }

                if (ReceiveQueue.Any(mq => mq.MessageType == I2NPMessage.MessageTypes.TunnelData))
                {
                    var removelist = ReceiveQueue.Where(mq => mq.MessageType == I2NPMessage.MessageTypes.TunnelData);
                    tdmsgs = removelist.Select(mq => (TunnelDataMessage)mq.Message).ToArray();
                }

                ReceiveQueue.Clear(); // Just drop the non-TunnelData
            }

            if (tdmsgs != null)
            {
                return(HandleTunnelData(tdmsgs));
            }

            return(true);
        }
        /// <summary>
        /// Receive from one of the contained streams
        /// </summary>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task ReceiveAsync(CancellationToken ct)
        {
            if (!Links.Any())
            {
                throw new SocketException(SocketError.Closed);
            }

            // Fill receive queue from any of the link's receive queue.  If queue is empty
            // replenish it from all streams...
            Message message;

            while (true)
            {
                foreach (var link in Links)
                {
                    while (link.ReceiveQueue.TryDequeue(out message))
                    {
                        if (message.TypeId == MessageContent.Close)
                        {
                            // Remote side closed, close link
                            Links.Remove(link);
                            try {
                                await link.CloseAsync(CancellationToken.None).ConfigureAwait(false);
                            }
                            catch { }

                            if (!Links.Any())
                            {
                                throw new SocketException("Remote side closed",
                                                          null, SocketError.Closed);
                            }
                        }
                        else
                        {
                            ReceiveQueue.Enqueue(message);
                        }
                    }
                }
                if (ReceiveQueue.Any())
                {
                    return;
                }
                else
                {
                    try {
                        var tasks = Links.Select(i => i.ReceiveAsync(ct));
                        await Task.WhenAny(tasks).ConfigureAwait(false);
                    }
                    catch (AggregateException ae) {
                        throw new SocketException("Receive await failed",
                                                  ae, ae.GetSocketError());
                    }
                }
            }
        }
Example #3
0
 private void ReceiveFromQueue()
 {
     if (FirmwareVersion == 2)
     {
         if (ReceiveQueue.Any() && !HasRegValue(_RECEIVE))
         {
             SetRegValue(_RECEIVE, ReceiveQueue.Dequeue());
             RemoveRegValue(_WAITING);
         }
     }
 }
Example #4
0
        /// <summary>
        /// Receive from one of the contained streams
        /// </summary>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task ReceiveAsync(CancellationToken ct)
        {
            if (!Links.Any())
            {
                throw new SocketException(SocketError.Closed);
            }

            // Fill receive queue from any of the link's receive queue.  If queue is empty
            // replenish it from all streams...
            while (true)
            {
                foreach (var link in Links)
                {
                    Message message;
                    var     queue = link.ReceiveQueue;
                    if (queue == null)
                    {
                        Links.Remove(link);
                    }
                    else
                    {
                        while (queue.TryDequeue(out message))
                        {
                            if (message.TypeId == MessageContent.Close)
                            {
                                // Remote side closed, close link
                                Links.Remove(link);
                                try {
                                    await link.CloseAsync(ct).ConfigureAwait(false);
                                }
                                catch { }
                            }
                            else
                            {
                                ReceiveQueue.Enqueue(message);
                            }
                        }
                    }
                    if (!Links.Any())
                    {
                        throw new SocketException("Remote side closed",
                                                  null, SocketError.Closed);
                    }
                }
                if (ReceiveQueue.Any())
                {
                    return;
                }
                else
                {
                    try {
                        var tasks    = Links.Select(i => i.ReceiveAsync(ct));
                        var selected = await Task.WhenAny(tasks).ConfigureAwait(false);

                        await selected.ConfigureAwait(false);
                    }
                    catch (OperationCanceledException) {
                        throw;
                    }
                    catch (Exception e) {
                        ct.ThrowIfCancellationRequested();
                        throw new SocketException("Receive await failed",
                                                  e, e.GetSocketError());
                    }
                }
            }
        }
Example #5
0
        private bool HandleReceiveQueue()
        {
            II2NPHeader msg = null;
            List <TunnelDataMessage> tdmsgs = null;

            lock ( ReceiveQueue )
            {
                if (ReceiveQueue.Count == 0)
                {
                    return(true);
                }

                if (ReceiveQueue.Any(mq => mq.MessageType == I2NPMessage.MessageTypes.TunnelData))
                {
                    var removelist = ReceiveQueue.Where(mq => mq.MessageType == I2NPMessage.MessageTypes.TunnelData);
                    tdmsgs = removelist.Select(mq => (TunnelDataMessage)mq.Message).ToList();
                    foreach (var one in removelist.ToArray())
                    {
                        ReceiveQueue.Remove(one);
                    }
                }
                else
                {
                    msg = ReceiveQueue.Last.Value;
                    ReceiveQueue.RemoveLast();
                }
            }

            if (tdmsgs != null)
            {
                HandleTunnelData(tdmsgs);
                return(true);
            }

            DebugUtils.LogDebug("InboundTunnel " + TunnelDebugTrace + " HandleReceiveQueue: " + msg.MessageType.ToString());

            switch (msg.MessageType)
            {
            case I2NPMessage.MessageTypes.TunnelData:
                throw new NotImplementedException("Should not happen " + TunnelDebugTrace);

            case I2NPMessage.MessageTypes.TunnelBuildReply:
                ThreadPool.QueueUserWorkItem(cb =>
                {
                    TunnelProvider.Inst.HandleTunnelBuildReply((II2NPHeader16)msg, (TunnelBuildReplyMessage)msg.Message);
                });
                return(true);

            case I2NPMessage.MessageTypes.VariableTunnelBuildReply:
                ThreadPool.QueueUserWorkItem(cb =>
                {
                    TunnelProvider.Inst.HandleVariableTunnelBuildReply((II2NPHeader16)msg, (VariableTunnelBuildReplyMessage)msg.Message);
                });
                return(true);

            case I2NPMessage.MessageTypes.DeliveryStatus:
#if LOG_ALL_TUNNEL_TRANSFER
                DebugUtils.LogDebug("InboundTunnel " + TunnelDebugTrace + ": DeliveryStatus: " + msg.Message.ToString());
#endif

                ThreadPool.QueueUserWorkItem(cb => {
                    lock (DeliveryStatusReceivedLock) if (DeliveryStatusReceived != null)
                        {
                            DeliveryStatusReceived((DeliveryStatusMessage)msg.Message);
                        }
                });
                break;

            case I2NPMessage.MessageTypes.DatabaseStore:
                var ds = (DatabaseStoreMessage)msg.Message;
                ThreadPool.QueueUserWorkItem(cb =>
                {
                    TunnelProvider.HandleDatabaseStore(ds);
                });
                break;

            case I2NPMessage.MessageTypes.Garlic:
#if LOG_ALL_TUNNEL_TRANSFER
                DebugUtils.Log("InboundTunnel " + TunnelDebugTrace + ": Garlic: " + msg.Message.ToString());
#endif

                ThreadPool.QueueUserWorkItem(cb =>
                {
                    lock (GarlicMessageReceivedLock) if (GarlicMessageReceived != null)
                        {
                            GarlicMessageReceived((GarlicMessage)msg.Message);
                        }
                });
                break;

            default:
                DebugUtils.LogWarning("InboundTunnel " + TunnelDebugTrace + " HandleReceiveQueue: Dropped " + msg.ToString());
                break;
            }

            return(true);
        }