private void Initialize(ChannelHandlerContext ctx)
        {
            switch (_state)
            {
                case 1:
                    return;
                case 2:
                    return;
            }
            _state = 1;

            // .NET-specific:
            if (_executor == null)
            {
                _executor = new ExecutorService();
            }
            var currentMillis = Convenient.CurrentTimeMillis();
            _lastReadTime.Set(currentMillis);
            _lastWriteTime.Set(currentMillis);

            if (AllIdleTimeMillis > 0)
            {
                _cts = _executor.Schedule(AllIdleTimeoutTask, ctx, AllIdleTimeMillis);
            }
        }
        /// <summary>
        /// .NET-specific decoding handler for incoming UDP messages.
        /// </summary>
        public override void Read(ChannelHandlerContext ctx, object msg)
        {
            var dgram = msg as DatagramPacket;
            if (dgram == null)
            {
                ctx.FireRead(msg);
                return;
            }

            var buf = dgram.Content;
            var sender = dgram.Sender;
            var recipient = dgram.Recipient;

            try
            {
                var decoder = new Decoder(_signatureFactory);
                bool finished = decoder.Decode(ctx, buf, recipient, sender);
                if (finished)
                {
                    // prepare finish
                    ctx.FireRead(decoder.PrepareFinish());
                }
                else
                {
                    Logger.Warn("Did not get the complete packet!");
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Error in UDP decoding.", ex);
                throw;
            }
        }
示例#3
0
 public DirectResponder(Dispatcher dispatcher, PeerBean peerBeanMaster, ChannelHandlerContext ctx, Message.Message requestMessage)
 {
     _dispatcher = dispatcher;
     _peerBeanMaster = peerBeanMaster;
     _ctx = ctx;
     _requestMessage = requestMessage;
 }
示例#4
0
 public PipelineSession(IChannel channel, Pipeline pipeline, IEnumerable <IInboundHandler> inboundHandlers,
                        IEnumerable <IOutboundHandler> outboundHandlers)
 {
     _channel         = channel;
     _pipeline        = pipeline;
     InboundHandlers  = new LinkedList <IInboundHandler>(inboundHandlers);
     OutboundHandlers = new LinkedList <IOutboundHandler>(outboundHandlers);
     _ctx             = new ChannelHandlerContext(channel, this);
 }
示例#5
0
 public PipelineSession(IChannel channel, Pipeline pipeline, IEnumerable<IInboundHandler> inboundHandlers,
     IEnumerable<IOutboundHandler> outboundHandlers)
 {
     _channel = channel;
     _pipeline = pipeline;
     InboundHandlers = new LinkedList<IInboundHandler>(inboundHandlers);
     OutboundHandlers = new LinkedList<IOutboundHandler>(outboundHandlers);
     _ctx = new ChannelHandlerContext(channel, this);
 }
 public override void ChannelActive(ChannelHandlerContext ctx)
 {
     base.ChannelActive(ctx);
     int current;
     if ((current = _counter.IncrementAndGet()) > _limit)
     {
         ctx.Channel.Close();
         Logger.Warn("Dropped connection because {0} > {1} connections active.", current, _limit);
     }
     // fireChannelActive // TODO needed?
 }
示例#7
0
 public static void RemoveTimeout(ChannelHandlerContext ctx)
 {
     if (ctx.Channel.Pipeline.Names.Contains("timeout0"))
     {
         ctx.Channel.Pipeline.Remove("timeout0");
     }
     if (ctx.Channel.Pipeline.Names.Contains("timeout1"))
     {
         ctx.Channel.Pipeline.Remove("timeout1");
     }
 }
示例#8
0
 public override void ExceptionCaught(ChannelHandlerContext ctx, Exception cause)
 {
     if (_encoder.Message == null)
     {
         Logger.Error("Exception in encoding when starting.", cause);
         Console.WriteLine(cause.StackTrace);
     }
     else if (_encoder.Message != null && !_encoder.Message.IsDone)
     {
         Logger.Error("Exception in encoding when started.", cause);
         Console.WriteLine(cause.StackTrace);
     }
 }
示例#9
0
        public bool Decode(ChannelHandlerContext ctx, AlternativeCompositeByteBuf buffer, IPEndPoint recipient, IPEndPoint sender)
        {
            Logger.Debug("Decoding of TomP2P starts now. Readable: {0}.", buffer.ReadableBytes);

            try
            {
                long readerBefore = buffer.ReaderIndex;
                // set the sender of this message for handling timeout
                var attrInetAddr = ctx.Attr(InetAddressKey);
                attrInetAddr.Set(sender);

                if (Message == null)
                {
                    bool doneHeader = DecodeHeader(buffer, recipient, sender);
                    if (doneHeader)
                    {
                        // store the sender as an attribute
                        var attrPeerAddr = ctx.Attr(PeerAddressKey);
                        attrPeerAddr.Set(Message.Sender);

                        Message.SetIsUdp(ctx.Channel.IsUdp);
                        if (Message.IsFireAndForget() && Message.IsUdp)
                        {
                            TimeoutFactory.RemoveTimeout(ctx);
                        }
                    }
                    else
                    {
                        return false;
                    }
                }

                bool donePayload = DecodePayload(buffer);
                //DecodeSignature(buffer, readerBefore, donePayload);

                // TODO discardSomeReadBytes -> performance improvement
                return donePayload;
            }
            catch (Exception ex)
            {
                ctx.FireExceptionCaught(ex);
                Console.WriteLine(ex.ToString());
                return true;
            }
        }
示例#10
0
        public void Write(ChannelHandlerContext ctx, object msg)
        {
            try
            {
                AlternativeCompositeByteBuf buf;
                bool done;
                var message = msg as Message;
                if (message != null)
                {
                    buf = _preferDirect ? _alloc.CompDirectBuffer() : _alloc.CompBuffer();
                    // null means create signature
                    done = _encoder.Write(buf, message, null);
                }
                else
                {
                    ctx.FireWrite(msg); // TODO ok? Java uses ctx.write() (3x)
                    return;
                }

                message = _encoder.Message;

                // send buffer
                if (buf.IsReadable)
                {
                    // sender/recipient information is extracted in MyUdpClient.SendAsync()
                    ctx.FireWrite(buf);

                    if (done)
                    {
                        message.SetDone(true);
                        // we wrote the complete message, reset state
                        _encoder.Reset();
                    }
                }
                else
                {
                    ctx.FireWrite(Unpooled.EmptyBuffer);
                }
            }
            catch (Exception ex)
            {
                ctx.FireExceptionCaught(ex);
            }
        }
示例#11
0
        public override void Read(ChannelHandlerContext ctx, object msg)
        {
            // .NET-specific: use a content wrapper for TCP, similar to TomP2PSinglePacketUdp
            var piece = msg as StreamPiece;
            if (piece == null)
            {
                //ctx.FireRead(msg);
                return;
            }

            var buf = piece.Content;
            var sender = piece.Sender;
            var recipient = piece.Recipient;
            Logger.Debug("{0}: Cumulating TCP stream piece.", this);
            try
            {
                if (_cumulation == null)
                {
                    _cumulation = AlternativeCompositeByteBuf.CompBuffer(buf);
                }
                else
                {
                    // add to overhead from last TCP packet
                    _cumulation.AddComponent(buf);
                }
                Decoding(ctx, sender, recipient);
            }
            catch (Exception)
            {
                Logger.Error("Error in TCP decoding.");
                throw;
            }
            finally
            {
                // If the currently read buffer is read, it can be deallocated.
                // In case another TCP packet follows, a new buffer is created.
                if (_cumulation != null && !_cumulation.IsReadable)
                {
                    _cumulation = null;
                    // Java: no need to discard bytes as this was done in the decoder already
                }
            }
        }
示例#12
0
        private void Decoding(ChannelHandlerContext ctx, IPEndPoint sender, IPEndPoint receiver)
        {
            bool finished = true;
            bool moreData = true;
            while (finished && moreData)
            {
                finished = _decoder.Decode(ctx, _cumulation, receiver, sender);
                if (finished)
                {
                    _lastId = _decoder.Message.MessageId;
                    moreData = _cumulation.ReadableBytes > 0;
                    ctx.FireRead(_decoder.PrepareFinish());
                }
                else
                {
                    if (_decoder.Message == null)
                    {
                        // Wait for more data. This may happen if we don't get the first
                        // 58 bytes, which is the size of the header.
                        return;
                    }

                    if (_lastId == _decoder.Message.MessageId)
                    {
                        // This ID was the same as the last and the last message already
                        // finished the parsing. So this message is finished as well, although
                        // it may send only partial content.
                        finished = true;
                        moreData = _cumulation.ReadableBytes > 0;
                        ctx.FireRead(_decoder.PrepareFinish());
                    }
                    else if (_decoder.Message.IsStreaming())
                    {
                        ctx.FireRead(_decoder.Message);
                    }
                    // arriving here, the next handler must not be called since another
                    // current architecture -> skip rest of handlers
                    // TCP packet needs to be cumulated
                    ctx.SkipRestRead();
                }
            }
        }
示例#13
0
        public override void Read(ChannelHandlerContext ctx, object msg)
        {
            // Java uses a SimpleChannelInboundHandler that only expects Message objects
            var responseMessage = msg as Message.Message;
            if (responseMessage == null)
            {
                return;
            }

            if (responseMessage.Command == Rpc.Rpc.Commands.Rcon.GetNr() &&
                responseMessage.Type == Message.Message.MessageType.Ok)
            {
                Logger.Debug("Successfully set up the reverse connection to peer {0}.", responseMessage.Recipient.PeerId);
                _tcsRconResponse.SetResult(responseMessage);
            }
            else
            {
                Logger.Debug("Could not acquire a reverse connection to peer {0}.", responseMessage.Recipient.PeerId);
                var ex = new TaskFailedException("Could not acquire a reverse connection. Got: " + responseMessage);
                _tcsRconResponse.SetException(ex);
                _tcsResponse.SetException(ex);
            }
        }
示例#14
0
 public virtual void ChannelInactive(ChannelHandlerContext ctx)
 {
     _isActivated = false;
 }
示例#15
0
        private void Initialize(ChannelHandlerContext ctx)
        {
            switch (_state)
            {
                case 1:
                    return;
                case 2:
                    return;
            }
            _state = 1;

            // .NET-specific:
            if (_executor == null)
            {
                _executor = new ExecutorService();
            }
            var currentMillis = Convenient.CurrentTimeMillis();
            _lastReadTime.Set(currentMillis);
            _lastWriteTime.Set(currentMillis);

            _timer = _executor.ScheduleAtFixedRate(Heartbeating, ctx, TimeToHeartBeatMillis, TimeToHeartBeatMillis);
        }
示例#16
0
 /// <summary>
 /// Set the result as soon as the channel is closed.
 /// </summary>
 /// <param name="tcs"></param>
 /// <param name="result"></param>
 /// <param name="ctx"></param>
 public static void ResponseLater(this TaskCompletionSource<Message.Message> tcs, Message.Message result, ChannelHandlerContext ctx)
 {
     ctx.Channel.Closed += channel => tcs.SetResult(result);
 }
示例#17
0
            public override void UserEventTriggered(ChannelHandlerContext ctx, object evt)
            {
                if (evt is IdleStateHandlerTomP2P)
                {
                    Logger.Warn("Channel timeout for channel {0} {1}.", _name, ctx.Channel);
                    PeerAddress recipient;
                    if (_tcsResponse != null)
                    {
                        // client-side
                        var requestMessage = (Message.Message)_tcsResponse.Task.AsyncState;

                        Logger.Warn("Request status is {0}.", requestMessage);
                        ctx.Channel.Closed +=
                            channel =>
                                _tcsResponse.SetException(
                                    new TaskFailedException(String.Format("{0} is idle: {1}.", ctx.Channel, evt)));
                        ctx.FireTimeout();
                        ctx.Channel.Close();

                        recipient = requestMessage.Recipient;
                    }
                    else
                    {
                        // server-side

                        // .NET-specific: 
                        // Don't close the channel, as this would close all service loops on a server.
                        // instead, set the session to be timed out.
                        ctx.FireTimeout();

                        // check if we have set an attribute at least
                        // (if we have already decoded the header)
                        var attrPeerAddr = ctx.Attr(Decoder.PeerAddressKey);
                        recipient = attrPeerAddr.Get();
                    }

                    if (_peerStatusListeners == null)
                    {
                        return;
                    }

                    var socketAddr = ctx.Channel.RemoteEndPoint;
                    if (socketAddr == null)
                    {
                        var attrInetAddr = ctx.Attr(Decoder.InetAddressKey);
                        socketAddr = attrInetAddr.Get();
                    }

                    lock (_peerStatusListeners)
                    {
                        foreach (var listener in _peerStatusListeners)
                        {
                            if (recipient != null)
                            {
                                listener.PeerFailed(recipient,
                                    new PeerException(PeerException.AbortCauseEnum.Timeout, "Timeout!"));
                            }
                            else
                            {
                                if (socketAddr != null)
                                {
                                    listener.PeerFailed(new PeerAddress(Number160.Zero, socketAddr.Address),
                                        new PeerException(PeerException.AbortCauseEnum.Timeout, "Timeout!"));
                                }
                                else
                                {
                                    Logger.Warn("Cannot determine the sender's address.");
                                }
                            }
                        }
                    }
                }
            }
示例#18
0
 public override void Write(ChannelHandlerContext ctx, object msg)
 {
     ctx.Channel.WriteCompleted += channel => _lastWriteTime.Set(Convenient.CurrentTimeMillis());
     //ctx.FireWrite(msg); // TODO needed?
 }
示例#19
0
 /// <summary>
 /// Responds within a session. Keeps the connection open if told to do so.
 /// Connection is only kept alive for TCP content.
 /// </summary>
 /// <param name="ctx">The channel context.</param>
 /// <param name="responseMessage">The response message to send.</param>
 internal void Respond(ChannelHandlerContext ctx, Message.Message responseMessage)
 {
     // TODO if/else can be tied together
     if (ctx.Channel is IUdpChannel)
     {
         // Check, if channel is still open. If not, then do not send anything
         // because this will cause an exception that will be logged.
         var channel = ctx.Channel as IUdpChannel;
         if (!channel.IsOpen)
         {
             Logger.Debug("Channel UDP is not open. Do not reply {0}.", responseMessage);
             return;
         }
         Logger.Debug("Response UDP message {0}.", responseMessage);
     }
     else if (ctx.Channel is ITcpChannel)
     {
         // Check, if channel is still open. If not, then do not send anything
         // because this will cause an exception that will be logged.
         var channel = ctx.Channel as ITcpChannel;
         if (!channel.IsOpen)
         {
             Logger.Debug("Channel TCP is not open. Do not reply {0}.", responseMessage);
             return;
         }
         Logger.Debug("Response TCP message {0} to {1}.", responseMessage, "TODO"); // TODO find way to log TCP remoteEndpoint
     }
     ctx.FireRead(responseMessage);
 }
示例#20
0
        public override void ExceptionCaught(ChannelHandlerContext ctx, Exception cause)
        {
            Logger.Debug("Error originating from {0}. Cause: {1}", _message, cause);
            if (_tcsResponse.Task.IsCompleted)
            {
                Logger.Warn("Got exception, but ignored it. (Task completed.): {0}.", _tcsResponse.Task.Exception);
            }
            else
            {
                Logger.Debug("Exception caught, but handled properly: {0}.", cause.Message);
                var pe = cause as PeerException;
                if (pe != null)
                {
                    if (pe.AbortCause != PeerException.AbortCauseEnum.UserAbort)
                    {
                        // do not force if we ran into a timeout, the peer may be busy
                        lock (PeerBean.PeerStatusListeners)
                        {
                            foreach (IPeerStatusListener listener in PeerBean.PeerStatusListeners)
                            {
                                listener.PeerFailed(_message.Recipient, pe);
                            }
                        }
                        Logger.Debug("Removed from map. Cause: {0}. Message: {1}.", pe, _message);
                    }
                    else
                    {
                        Logger.Warn("Error in request.", cause);
                    }
                }
                else
                {
                    lock (PeerBean.PeerStatusListeners)
                    {
                        foreach (IPeerStatusListener listener in PeerBean.PeerStatusListeners)
                        {
                            listener.PeerFailed(_message.Recipient, new PeerException(cause));
                        }
                    }
                }
            }

            Logger.Debug("Report failure: ", cause);
            _tcsResponse.SetException(cause);
            // TODO channel not already closed in Sender?
            ctx.Close(); // TODO used?
        }
 //.NET-specific: use channel inactivation instead of close
 public override void ChannelInactive(ChannelHandlerContext ctx)
 {
     _counterCurrent.Decrement();
 }
 public void Write(ChannelHandlerContext ctx, object msg)
 {
     // nothing to do
 }
示例#23
0
 public virtual void ExceptionCaught(ChannelHandlerContext ctx, Exception cause)
 {
     // do nothing by default
     // can be overridden
 }
 //.NET-specific: use channel activation instead of connection
 public override void ChannelActive(ChannelHandlerContext ctx)
 {
     _counterCurrent.IncrementAndGet();
     _counterTotal.IncrementAndGet();
 }
示例#25
0
 public virtual void HandlerRemoved(ChannelHandlerContext ctx)
 {
     // do nothing by default
     // can be overridden
 }
示例#26
0
 public virtual void ChannelInactive(ChannelHandlerContext ctx)
 {
     _isActivated = false;
 }
示例#27
0
 public virtual void ChannelActive(ChannelHandlerContext ctx)
 {
     _isActivated = true;
 }
示例#28
0
 public virtual void ChannelActive(ChannelHandlerContext ctx)
 {
     _isActivated = true;
 }
示例#29
0
 /*public override void HandlerAdded(ChannelHandlerContext ctx)
 {
     if (ctx.Channel.IsActive)
     {
         Initialize(ctx);
     }
 }
 
 public override void HandlerRemoved(ChannelHandlerContext ctx)
 {
     Destroy();
 }*/
 
 public override void ChannelActive(ChannelHandlerContext ctx)
 {
     base.ChannelActive(ctx);
     Initialize(ctx);
 }
 public override void ChannelInactive(ChannelHandlerContext ctx)
 {
     _counter.Decrement();
     // fireChannelInactive // TODO needed?
 }
示例#31
0
 public override void ChannelInactive(ChannelHandlerContext ctx)
 {
     base.ChannelInactive(ctx);
     Destroy();
 }
示例#32
0
        public override void Read(ChannelHandlerContext ctx, object msg)
        {
            // server-side:
            // message comes (over network) from sender
            // -> correct DispatchHandler handles response

            // Java uses a SimpleChannelInboundHandler that only expects Message objects
            var requestMessage = msg as Message.Message;
            if (requestMessage == null)
            {
                return;
            }
            
            Logger.Debug("Received request message {0} from channel {1}.", requestMessage, ctx.Channel);
            if (requestMessage.Version != _p2PId)
            {
                Logger.Error("Wrong version. We are looking for {0}, but we got {1}. Received: {2}.", _p2PId, requestMessage.Version, requestMessage);
                ctx.Close(); // TODO used?
                lock (_peerBeanMaster.PeerStatusListeners)
                {
                    foreach (IPeerStatusListener listener in _peerBeanMaster.PeerStatusListeners)
                    {
                        listener.PeerFailed(requestMessage.Sender,
                            new PeerException(PeerException.AbortCauseEnum.PeerError, "Wrong P2P version."));
                    }
                }
                return;
            }
            if (!requestMessage.IsRequest())
            {
                Logger.Debug("Handing request message to the next handler. {0}", requestMessage);
                ctx.FireRead(msg);
                return;
            }

            IResponder responder = new DirectResponder(this, _peerBeanMaster, ctx, requestMessage);
            DispatchHandler myHandler = AssociatedHandler(requestMessage);
            if (myHandler != null)
            {
                bool isUdp = ctx.Channel.IsUdp;
                bool isRelay = requestMessage.Sender.IsRelayed;
                if (!isRelay && requestMessage.PeerSocketAddresses.Count != 0)
                {
                    PeerAddress sender =
                        requestMessage.Sender.ChangePeerSocketAddresses(requestMessage.PeerSocketAddresses);
                    requestMessage.SetSender(sender);
                }
                Logger.Debug("About to respond to request message {0}.", requestMessage);

                // handle the request message
                PeerConnection peerConnection = null;
                if (!isUdp)
                {
                    var tcpChannel = ctx.Channel as ITcpChannel;
                    peerConnection = new PeerConnection(requestMessage.Sender, tcpChannel, _heartBeatMillis);
                }
                myHandler.ForwardMessage(requestMessage, peerConnection, responder);
            }
            else
            {
                // do better error handling
                // if a handler is not present at all, print a warning
                if (_ioHandlers.Count == 0)
                {
                    Logger.Debug("No handler found for request message {0}. This peer has probably been shut down.", requestMessage);
                }
                else
                {
                    var knownCommands = KnownCommands();
                    if (knownCommands.Contains(Convert.ToInt32(requestMessage.Command)))
                    {
                        var sb = new StringBuilder();
                        foreach (int cmd in knownCommands)
                        {
                            sb.Append((Rpc.Rpc.Commands) cmd + "; ");
                        }
                        Logger.Warn("No handler found for request message {0}. Is the RPC command {1} registered? Found registered: {2}.", requestMessage, (Rpc.Rpc.Commands) requestMessage.Command, sb);
                    }
                    else
                    {
                        Logger.Debug("No handler found for request message {0}. This peer has probably been partially shut down.", requestMessage);
                    }
                }

                // return response that states that no handler was found
                var responseMessage = DispatchHandler.CreateResponseMessage(requestMessage,
                    Message.Message.MessageType.UnknownId, _peerBeanMaster.ServerPeerAddress);

                Respond(ctx, responseMessage);
            }
        }
示例#33
0
 public override void Read(ChannelHandlerContext ctx, object msg)
 {
     _lastReadTime.Set(Convenient.CurrentTimeMillis());
     ctx.FireRead(msg);
 }
示例#34
0
 public virtual void HandlerRemoved(ChannelHandlerContext ctx)
 {
     // do nothing by default
     // can be overridden
 }
示例#35
0
 public virtual void ExceptionCaught(ChannelHandlerContext ctx, Exception cause)
 {
     // do nothing by default
     // can be overridden
 }