Exemple #1
0
        UdpSendStatus SendFragmentedMessage(UdpRawMessage message, IChannel channel)
        {
            message.Position = 0;
            int    mtu     = this.Mtu;
            ushort frame   = 1;
            ushort frames  = (ushort)Math.Ceiling(message.Length / (float)(mtu - Datagram.GetHeaderSize(true)));
            ushort groupId = GetNextFragementationGroupId();

            do
            {
                Debug.Assert(frame <= frames, "frame > frames");

                Datagram datagramFrag = Datagram.CreateNew(peer.Configuration.MemoryStreamPool, mtu);
                datagramFrag.Type              = MessageType.UserData;
                datagramFrag.Channel           = channel.Descriptor.Channel;
                datagramFrag.DeliveryType      = channel.Descriptor.DeliveryType;
                datagramFrag.FragmentationInfo = new Datagram.FragmentInfo(groupId, frame, frames);
                datagramFrag.ConnectionKey     = this.EndPoint.ConnectionKey;

                int toCopy = mtu - Datagram.GetHeaderSize(true);
                if (toCopy > message.Length - message.Position)
                {
                    toCopy = message.Length - message.Position;
                }
                message.CopyTo(datagramFrag.BaseStream, toCopy);

                channel.SendDatagram(datagramFrag);
                frame++;
            } while (message.Position < message.Length);

            message.Dispose();

            return(UdpSendStatus.Enqueued);
        }
Exemple #2
0
 bool CheckCanBeSendUnfragmented(UdpRawMessage datagram)
 {
     if (datagram.Length + Datagram.GetHeaderSize(false) > Mtu)
     {
         return(false);
     }
     return(true);
 }
 protected override UdpSendStatus SendRawMessage(Networking.Udp.Messages.MessageInfo messageInfo)
 {
     using (messageInfo.Message)
     {
         UdpRawMessage encryptedMessage = messageInfo.Message.Encrypt(cipher);
         return(base.SendRawMessage(new Networking.Udp.Messages.MessageInfo(encryptedMessage, messageInfo.DeliveryType,
                                                                            messageInfo.Channel)));
     }
 }
Exemple #4
0
        void CloseInternal(DisconnectReason reason, UdpRawMessage payload)
        {
            if (Status == UdpConnectionStatus.Disconnected)
            {
                return;
            }
            ChangeStatus(UdpConnectionStatus.Disconnected);

            logger.Trace($"{this} closing with ({reason})");
            var disconnectReq_ = disconnectReq;

            if (disconnectReq_ != null)
            {
                disconnectReq_.Dispose();
                disconnectReq = null;
            }
            var args = new ConnectionClosedEventArgs(this, reason, payload);

            logger.Trace($"{this} closing pre event syncronization");
            peer.Configuration.SynchronizeSafe(() =>
            {
                logger.Trace($"{this} firing event connection OnConnectionClosed");

                try
                {
                    OnConnectionClosed(args);
                }
                catch (Exception ex)
                {
                    logger.Error($"Unhandled exception on {this.GetType().Name}.{nameof(OnConnectionClosed)}: {ex}");
                }

                logger.Trace($"{this} firing event peer OnConnectionClosed");
                peer.OnConnectionClosedInternalSynchronized(args);
                logger.Trace($"{this} events fired");
            }, logger);

            logger.Trace($"{this} closing post event syncronization");

            var connectTcs_ = this.connectTcs;

            if (connectTcs_ != null)
            {
                connectTcs_.TrySetException(new ConnectionFailed(reason));
            }
            var disconnectTcs_ = this.disconnectTcs;

            if (disconnectTcs_ != null)
            {
                disconnectTcs_.TrySetResult(null);
            }

            logger.Info($"{this} closed ({reason})");
        }
Exemple #5
0
        Datagram CreateSpecialDatagram(MessageType messageType, UdpRawMessage payload)
        {
            if (!CheckCanBeSendUnfragmented(payload))
            {
                throw new ArgumentException($"Payload can be datagram only smaller than current MTU ({Mtu})");
            }
            var datagram = Datagram.CreateNew(peer.Configuration.MemoryStreamPool, (int)payload.BaseStream.Length);

            datagram.Type = messageType;
            payload.BaseStream.Position = 0;
            payload.BaseStream.CopyTo(datagram.BaseStream);
            return(datagram);
        }
Exemple #6
0
        public virtual async Task CloseAsync(UdpRawMessage payload)
        {
            try
            {
                disconnectTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

                Close(payload);

                await disconnectTcs.Task;
            }
            finally
            {
                disconnectTcs = null;
            }
        }
Exemple #7
0
 void ReleaseMessage(UdpRawMessage message, DeliveryType deliveryType, int channel)
 {
     message.Position = 0;
     peer.Configuration.SynchronizeSafe(() =>
     {
         try
         {
             OnMessageReceived(new MessageInfo(message, deliveryType, channel));
         }
         catch (Exception ex)
         {
             logger.Error($"Unhandled exception on {this.GetType().Name}.{nameof(OnMessageReceived)}: {ex}");
         }
     }, logger);
 }
Exemple #8
0
        internal async Task Connect(UdpRawMessage payload)
        {
            try
            {
                connectTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

                StartConnect(payload);

                await connectTcs.Task;
            }
            finally
            {
                connectTcs = null;
            }
        }
Exemple #9
0
 internal void StartConnect(UdpRawMessage payload)
 {
     if (!CheckStatus(UdpConnectionStatus.Waiting))
     {
         throw new InvalidOperationException($"Couldn't connect wrong status: {Status}, expected {UdpConnectionStatus.Waiting}");
     }
     logger.Info($"Connecting to {EndPoint.EndPoint}");
     ChangeStatus(UdpConnectionStatus.Connecting);
     lastStatusPacketSent = DateTime.UtcNow;
     if (payload == null)
     {
         connectReq = CreateSpecialDatagram(MessageType.ConnectReq);
     }
     else
     {
         connectReq = CreateSpecialDatagram(MessageType.ConnectReq, payload);
         payload.Dispose();
     }
     connectReq.DontDisposeOnSend = true;
     SendDatagramAsync(connectReq);
 }
Exemple #10
0
        public virtual void Close(UdpRawMessage payload)
        {
            if (Status >= UdpConnectionStatus.Disconnecting)
            {
                return;
            }
            ChangeStatus(UdpConnectionStatus.Disconnecting);
            Datagram disconnectReq;

            if (payload == null)
            {
                disconnectReq = CreateSpecialDatagram(MessageType.DisconnectReq);
            }
            else
            {
                disconnectReq = CreateSpecialDatagram(MessageType.DisconnectReq, payload);
            }
            disconnectReq.DontDisposeOnSend = true;
            this.disconnectReq   = disconnectReq;
            lastStatusPacketSent = DateTime.UtcNow;
            SendDatagramAsync(disconnectReq);
            payload?.Dispose();
        }
 public OnAcceptConnectionEventArgs(EndPoint endpoint, UdpRawMessage payload)
 {
     this.Endpoint = endpoint;
     this.Payload  = payload;
 }
 public ConnectionClosedEventArgs(UdpConnection connection, DisconnectReason reason, UdpRawMessage payload)
 {
     this.Connection = connection;
     this.Reason     = reason;
     this.Payload    = payload;
 }