/// <summary> /// UDP event handler. Called when a UDP packet is waiting to be read /// </summary> /// <param name="ar"></param> protected void RecvFromCallback(IAsyncResult ar) { if (m_status != eGameServerStatus.GSS_Open) return; if (ar == null) return; var server = (GameServer) ar.AsyncState; Socket s = server.UDPSocket; GameClient client = null; if (s != null) { //Creates a temporary EndPoint to pass to EndReceiveFrom. EndPoint tempRemoteEP = new IPEndPoint(IPAddress.Any, 0); bool receiving = false; try { // Handle the packet int read = s.EndReceiveFrom(ar, ref tempRemoteEP); if (read == 0) { log.Debug("UDP received bytes = 0"); } else { int pakCheck = (server.UDPBuffer[read - 2] << 8) | server.UDPBuffer[read - 1]; int calcCheck = PacketProcessor.CalculateChecksum(server.UDPBuffer, 0, read - 2); if (calcCheck != pakCheck) { if (log.IsWarnEnabled) log.WarnFormat("Bad UDP packet checksum (packet:0x{0:X4} calculated:0x{1:X4}) -> ignored", pakCheck, calcCheck); if (log.IsDebugEnabled) log.Debug(Marshal.ToHexDump("UDP buffer dump, received " + read + "bytes", server.UDPBuffer)); } else { var sender = (IPEndPoint) (tempRemoteEP); var pakin = new GSPacketIn(read - GSPacketIn.HDR_SIZE); pakin.Load(server.UDPBuffer, 0, read); //Get the next message BeginReceiveUDP(s, server); receiving = true; client = WorldMgr.GetClientFromID(pakin.SessionID); if (client != null) { //If this is the first message from the client, we //save the endpoint! if (client.UdpEndPoint == null) { client.UdpEndPoint = sender; client.UdpConfirm = false; } //Only handle the packet if it comes from a valid client if (client.UdpEndPoint.Equals(sender)) { client.PacketProcessor.HandlePacket(pakin); } } else if (log.IsErrorEnabled) { log.Error( string.Format("Got an UDP packet from invalid client id or ip: client id = {0}, ip = {1}, code = {2:x2}", pakin.SessionID, sender, pakin.ID)); } } } } catch (SocketException) { } catch (ObjectDisposedException) { } catch (Exception e) { if (log.IsErrorEnabled) log.Error("RecvFromCallback", e); } finally { if (!receiving) { //Get the next message //Even if we have errors, we need to continue with UDP BeginReceiveUDP(s, server); } } } }