Ejemplo n.º 1
0
        internal void SendCommand(UdpCommandType cmd)
        {
            if (CheckCanSend(true) == UdpSendFailReason.None)
            {
                UdpStream stream = socket.GetWriteStream(mtu << 3, UdpSocket.HeaderBitSize);
                stream.WriteByte((byte)cmd, 8);

                UdpHeader header = MakeHeader(false);
                header.Pack(stream, socket);

                UdpHandle handle = MakeHandle(ref header);
                handle.Object = null;

                if (SendStream(stream, handle, false))
                {
                    // track stats
                    stats.PacketSent((uint)stream.Ptr >> 3);
                    socket.Statistics.PacketSent((uint)stream.Ptr >> 3);
                }
                else
                {
                    // should we do something here?????
                }
            }
        }
Ejemplo n.º 2
0
        internal void SendObject(object o)
        {
            serializer.SendNext(o);

            while (serializer.HasQueuedObjects)
            {
                UdpSendFailReason reason = CheckCanSend(false);

                if (reason != UdpSendFailReason.None)
                {
                    while (serializer.HasQueuedObjects)
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, serializer.NextObject(), reason);
                    }

                    break;
                }

                UdpStream stream     = socket.GetWriteStream(mtu << 3, UdpSocket.HeaderBitSize);
                var       initialPtr = stream.Ptr; // Erhune: added info
                object    obj        = serializer.NextObject();

                if (serializer.Pack(stream, ref obj))
                {
                    if (stream.Overflowing && (socket.Config.AllowPacketOverflow == false))
                    {
                        UdpLog.Error("Stream to {0} is overflowing (InitialPtr={1} Ptr={2} Len={3}), not sending {4}",
                                     endpoint.ToString(), initialPtr, stream.Ptr, stream.Length, obj); // Erhune: added info
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.StreamOverflow);
                        return;
                    }

                    UdpHeader header = MakeHeader(true);
                    header.Pack(stream, socket, shouldSendClock);

                    UdpHandle handle = MakeHandle(ref header);
                    handle.Object = obj;

                    if (SendStream(stream, handle, alwaysSendMtu))
                    {
                        // track stats
                        stats.PacketSent((uint)stream.Ptr >> 3);
                        socket.Statistics.PacketSent((uint)stream.Ptr >> 3);

                        // push object to user thread
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SENT, this, obj);
                    }
                    else
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.SocketError);
                    }
                }
                else
                {
                    socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.SerializerReturnedFalse);
                }
            }
        }
Ejemplo n.º 3
0
        UdpHandle MakeHandle(ref UdpHeader header)
        {
            UdpHandle handle = new UdpHandle();

            handle.IsObject    = header.IsObject;
            handle.ObjSequence = header.ObjSequence;
            handle.SendTime    = header.Now;
            return(handle);
        }
Ejemplo n.º 4
0
        void AckHandles(UdpHeader header, bool updateRtt)
        {
            while (!sendWindow.Empty)
            {
                UdpHandle handle = sendWindow.Peek();

                int seqDistance = UdpMath.SeqDistance(handle.ObjSequence, header.AckSequence, UdpHeader.SEQ_PADD);
                if (seqDistance > 0)
                {
                    break;
                }

                if (handle.IsObject)
                {
                    if (seqDistance <= -UdpSocket.AckRedundancy)
                    {
                        // track stats
                        stats.PacketLost();
                        socket.Statistics.PacketLost();

                        // handle lost
                        ObjectLost(handle.Object);
                    }
                    else
                    {
                        if ((header.AckHistory & (1UL << -seqDistance)) != 0UL)
                        {
                            // track stats
                            stats.PacketDelivered();
                            socket.Statistics.PacketDelivered();

                            // handle delivered objects
                            ObjectDelivered(handle.Object);
                        }
                        else
                        {
                            // track stats
                            stats.PacketLost();
                            socket.Statistics.PacketLost();

                            // handle
                            ObjectLost(handle.Object);
                        }
                    }
                }

                if (seqDistance == 0 && header.AckTime > 0)
                {
                    UpdatePing(recvTime, handle.SendTime, header.AckTime);
                }

                sendWindow.Dequeue();
            }
        }
Ejemplo n.º 5
0
        bool SendStream(UdpStream stream, UdpHandle handle, bool expandToMtu)
        {
            int bytesToSend = UdpMath.BytesRequired(stream.Ptr);

            if (bytesToSend < mtu && expandToMtu)
            {
                bytesToSend = mtu;
            }

            sendTime     = handle.SendTime;
            sendSequence = handle.ObjSequence;
            sendWindow.Enqueue(handle);
            recvSinceLastSend = 0;

            return(socket.Send(endpoint, stream.Data, bytesToSend));
        }
Ejemplo n.º 6
0
        void OnStateDisconnected(UdpConnectionState oldState)
        {
            if (oldState == UdpConnectionState.Connected)
            {
                while (sendWindow.Empty == false)
                {
                    UdpHandle handle = sendWindow.Dequeue();

                    if (handle.IsObject)
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_LOST, this, handle.Object);
                    }
                }

                socket.Raise(UdpEvent.PUBLIC_DISCONNECTED, this);
            }
        }
Ejemplo n.º 7
0
        internal void StartReceiver()
        {
            this.Connection.StartNetworkStream();

            if (UdpHandle != null)
            {
                this.UdpAsyncReceiveEvent = new SocketAsyncEventArgs();
                this.UdpAsyncReceiveEvent.SetBuffer(new byte[70000], 0, 70000);
                this.UdpAsyncReceiveEvent.RemoteEndPoint = this.UdpEndPoint;
                this.UdpAsyncReceiveEvent.Completed     += AsyncSocketCallback;
                this.UdpAsyncReceiveEvent.AcceptSocket   = this.UdpHandle;

                if (!UdpHandle.ReceiveFromAsync(UdpAsyncReceiveEvent))
                {
                    AsyncSocketCallback(null, UdpAsyncReceiveEvent);
                }
            }
        }
Ejemplo n.º 8
0
        bool SendStream(UdpStream stream, UdpHandle handle, bool expandToMtu)
        {
            int bytesToSend = UdpMath.BytesRequired(stream.Ptr);
            if (bytesToSend < mtu && expandToMtu) {
                bytesToSend = mtu;
            }

            sendTime = handle.SendTime;
            sendSequence = handle.ObjSequence;
            sendWindow.Enqueue(handle);
            recvSinceLastSend = 0;

            return socket.Send(endpoint, stream.Data, bytesToSend);
        }
Ejemplo n.º 9
0
 UdpHandle MakeHandle(ref UdpHeader header)
 {
     UdpHandle handle = new UdpHandle();
     handle.IsObject = header.IsObject;
     handle.ObjSequence = header.ObjSequence;
     handle.SendTime = header.Now;
     return handle;
 }
Ejemplo n.º 10
0
        internal unsafe void AsyncSocketCallback(object o, SocketAsyncEventArgs e)
        {
            if (e.LastOperation == SocketAsyncOperation.ReceiveFrom)
            {
                try
                {
                    if (e.BytesTransferred >= 21)
                    {
                        if (!Connected)
                        {
                            return; //TCP Client is disconnected so don't process UDP packets
                        }
                        //before we process the packet, does the IP/LocalPort match ?
                        if (UdpHandshaked && BitConverter.ToUInt32(this.UdpEndPoint.Address.GetAddressBytes(), 0) !=
                            BitConverter.ToUInt32(((IPEndPoint)e.RemoteEndPoint).Address.GetAddressBytes(), 0))
                        {
                            //simply skip and don't disconnect TCP
                            //I'll add later a option to the server to disconnect or not just for safety reasons ;)
                            return;
                        }

                        //decrypt traffic here
                        PayloadReader pr       = new PayloadReader(e.Buffer);
                        decimal       clientId = pr.ReadDecimal();

                        //extra check
                        if (this.ClientId != clientId)
                        {
                            return;
                        }

                        UdpPAcketId packetId  = (UdpPAcketId)pr.ReadByte();
                        uint        MessageId = pr.ReadUInteger();

                        IMessage message = null;
                        try
                        {
                            message = Connection.messageHandler.HandleUdpMessage(pr, MessageId);

                            if (message != null)
                            {
                                message.RawSize = e.BytesTransferred;
                            }
                        }
                        catch (Exception ex)
                        {
                            return;
                        }


                        //process packet
                        if (UdpHandshaked)
                        {
                            switch (packetId)
                            {
                            case UdpPAcketId.Payload:
                            {
                                //onReceiveUdpMessage(message);
                                break;
                            }
                            }
                        }
                        else
                        {
                            MsgUdpHandshake HandshakeMsg = message as MsgUdpHandshake;
                            if (HandshakeMsg != null)
                            {
                                fixed(byte *ptr = HandshakeMsg.HandshakeCode, ptr2 = this.UdpHandshakeCode)
                                {
                                    if (NativeMethods.memcmp(ptr, ptr2, (uint)this.UdpHandshakeCode.Length) == 0)
                                    {
                                        this.UdpEndPoint = e.RemoteEndPoint as IPEndPoint;
                                        Connection.SendPayload(new MsgUdpValidation(new byte[] { 0x8F, 0xFF, 0x46, 0x4F, 0x37 }), PacketId.Unknown);
                                        UdpHandshaked       = true;
                                        UdpSyncObject.Value = true;
                                        UdpSyncObject.Pulse();
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    onException(ex, ErrorType.Core);
                }

                if (PeerSide == SecureSocketProtocol2.PeerSide.Client)
                {
                    if (!UdpHandle.ReceiveFromAsync(UdpAsyncReceiveEvent))
                    {
                        AsyncSocketCallback(null, UdpAsyncReceiveEvent);
                    }
                }
            }
            else
            {
            }
        }
Ejemplo n.º 11
0
        internal void Disconnect(DisconnectReason Reason)
        {
            //disconnect all plugins
            try
            {
                for (int i = 0; i < Plugins.Plugins.Length; i++)
                {
                    if (Plugins.Plugins[i].AllowPluginHooks() && Plugins.Plugins[i].Hooks.Count > 0)
                    {
                        foreach (IPluginHook hook in Plugins.Plugins[i].Hooks)
                        {
                            hook.onClientDisconnected();
                        }
                    }

                    try { Plugins.Plugins[i].onClientDisconnected(); } catch { }
                }
            }
            catch (Exception ex)
            {
                onException(ex, ErrorType.UserLand);
            }

            try
            {
                lock (Connection)
                {
                    if (this.Connected && !ConnectionClosedNormal)
                    {
                        Connection.SendPayload(new MsgDisconnected(Reason), PacketId.Disconnected);
                        ConnectionClosedNormal = true;
                    }
                }
            }
            catch (Exception ex)
            {
                onException(ex, ErrorType.Core);
            }

            try
            {
                Handle.Close();
            }
            catch { }

            try
            {
                if (UdpHandle != null)
                {
                    UdpHandle.Close();
                }
            }
            catch (Exception ex)
            {
                onException(ex, ErrorType.Core);
            }

            this.Connection.State = ConnectionState.Closed;

            try
            {
                onDisconnect(Reason);
            }
            catch (Exception ex)
            {
                onException(ex, ErrorType.UserLand);
            }
        }