/// <summary> /// This method is used to receive data from anyone /// The main function of this method is establishing udp-hole connections /// </summary> private void UdpAsyncSocketCallback(object o, SocketAsyncEventArgs e) { if (e.LastOperation == SocketAsyncOperation.ReceiveFrom) { try { if (e.BytesTransferred >= 21) { PayloadReader pr = new PayloadReader(e.Buffer); decimal ClientId = pr.ReadDecimal(); lock (Clients) { if (Clients.ContainsKey(ClientId)) { SSPClient client = Clients[ClientId]; client.AsyncSocketCallback(o, e); } } } } catch { } if (!UdpServer.ReceiveFromAsync(udpAsyncSocket)) { UdpAsyncSocketCallback(null, udpAsyncSocket); } } }
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 { } }
public IMessage DeCacheMessage(IMessage message, PayloadReader pr, ref bool isCached, ref IMessage CachedMessage, MessageHandler msgHandler) { lock (Messages) { uint Id = msgHandler.GetMessageId(message.GetType()); isCached = pr.ReadBool(); if (!Messages.TryGetValue(Id, out CachedMessage) && !isCached) { CachedMessage = (IMessage)Activator.CreateInstance(message.GetType()); Messages.Add(Id, (IMessage)Activator.CreateInstance(message.GetType())); FieldInfo[] _fields = message.GetType().GetFields(); FieldInfo[] _cachedFields = CachedMessage.GetType().GetFields(); for (int i = 0; i < _fields.Length; i++) { //de-serialize objects int oldPos = pr.Offset; _fields[i].SetValue(message, pr.ReadObject()); pr.Offset = oldPos; _fields[i].SetValue(Messages[Id], pr.ReadObject()); } return(message); } FieldInfo[] fields = message.GetType().GetFields(); FieldInfo[] cacheFields = CachedMessage.GetType().GetFields(); for (int i = 0; i < fields.Length; i++) { MessageCacheType CacheType = (MessageCacheType)pr.ReadByte(); object NewValue = null; switch (CacheType) { case MessageCacheType.Bool: { NewValue = pr.ReadBool(); break; } case MessageCacheType.Byte: { NewValue = pr.ReadByte(); break; } case MessageCacheType.ByteArray: { uint size = pr.ReadUInteger(); NewValue = pr.ReadBytes((int)size); break; } case MessageCacheType.Decimal: { NewValue = pr.ReadDecimal(); break; } case MessageCacheType.Double: { NewValue = pr.ReadDouble(); break; } case MessageCacheType.Float: { NewValue = pr.ReadFloat(); break; } case MessageCacheType.Long: { NewValue = pr.ReadLong(); break; } case MessageCacheType.NULL: { NewValue = null; break; } case MessageCacheType.OtherObject: { NewValue = pr.ReadObject(); break; } case MessageCacheType.Short: { NewValue = pr.ReadShort(); break; } case MessageCacheType.String: { NewValue = pr.ReadString(); break; } case MessageCacheType.Integer: { NewValue = pr.ReadInteger(); break; } case MessageCacheType.UInteger: { NewValue = pr.ReadUInteger(); break; } case MessageCacheType.ULong: { NewValue = pr.ReadULong(); break; } case MessageCacheType.UShort: { NewValue = pr.ReadUShort(); break; } case MessageCacheType.NotUpdated: { NewValue = cacheFields[i].GetValue(CachedMessage); break; } } fields[i].SetValue(message, NewValue); } } return(message); }