protected override void OnReceive(int nErrorCode) { byte[] buffer = new byte[5000]; byte[] pBuffer = buffer; EndPoint endpoint = null; int length = ReceiveFrom(buffer, ref endpoint); if (length != SOCKET_ERROR) { IPEndPoint ipEndPoint = endpoint as IPEndPoint; int nPayLoadLen = length; ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByIPUDP(BitConverter.ToUInt32(ipEndPoint.Address.GetAddressBytes(), 0), (ushort)IPAddress.NetworkToHostOrder(ipEndPoint.Port), true); if (pServer != null && MuleApplication.Instance.Preference.IsServerCryptLayerUDPEnabled && ((pServer.ServerKeyUDP != 0 && pServer.DoesSupportsObfuscationUDP) || (pServer.CryptPingReplyPending && pServer.Challenge != 0))) { // TODO uint dwKey = 0; if (pServer.CryptPingReplyPending && pServer.Challenge != 0 /* && pServer.GetPort() == ntohs(sockAddr.sin_port) - 12 */) { dwKey = pServer.Challenge; } else { dwKey = pServer.ServerKeyUDP; } Debug.Assert(dwKey != 0); nPayLoadLen = DecryptReceivedServer(buffer, length, out pBuffer, dwKey, BitConverter.ToUInt32(ipEndPoint.Address.GetAddressBytes(), 0)); } if (pBuffer[0] == MuleConstants.PROTOCOL_EDONKEYPROT) { ProcessPacket(pBuffer, 2, nPayLoadLen - 2, pBuffer[1], BitConverter.ToUInt32(ipEndPoint.Address.GetAddressBytes(), 0), (ushort)IPAddress.NetworkToHostOrder(ipEndPoint.Port)); } } else { IPEndPoint ipEndPoint = endpoint as IPEndPoint; if (ipEndPoint != null) { ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByIPUDP(BitConverter.ToUInt32(ipEndPoint.Address.GetAddressBytes(), 0), (ushort)IPAddress.NetworkToHostOrder(ipEndPoint.Port), true); if (pServer != null && !pServer.CryptPingReplyPending && MpdUtilities.GetTickCount() - pServer.LastPinged >= MuleConstants.ONE_SEC_MS * 30) { pServer.AddFailedCount(); } } } }
public ED2KServerImpl(ED2KServer pOld) { Port = pOld.Port; IP = pOld.IP; IsStaticMember = pOld.IsStaticMember; FileCount = pOld.FileCount; UserCount = pOld.UserCount; Priority = pOld.Priority; Ping = pOld.Ping; FailedCount = pOld.FailedCount; LastPinged = pOld.LastPinged; LastPingedTime = pOld.LastPingedTime; MaxUsers = pOld.MaxUsers; SoftFiles = pOld.SoftFiles; HardFiles = pOld.HardFiles; LastDescPingedCount = pOld.LastDescPingedCount; Description = pOld.Description; ServerName = pOld.ServerName; DynIP = pOld.DynIP; Version = pOld.Version; TCPFlags = pOld.TCPFlags; UDPFlags = pOld.UDPFlags; DescReqChallenge = pOld.DescReqChallenge; LowIDUsers = pOld.LowIDUsers; Challenge = pOld.Challenge; ServerKeyUDP = pOld.ServerKeyUDP; CryptPingReplyPending = pOld.CryptPingReplyPending; ServerKeyUDPIP = pOld.ServerKeyUDPIP; ObfuscationPortTCP = pOld.ObfuscationPortTCP; ObfuscationPortUDP = pOld.ObfuscationPortUDP; RealLastPingedTime = pOld.RealLastPingedTime; }
public ED2KServer GetNextServer(bool bOnlyObfuscated) { if (serverpos_ >= (uint)servers_.Count) { return(null); } ED2KServer nextserver = null; int i = 0; while (nextserver == null && i < servers_.Count) { uint posIndex = serverpos_; if (serverpos_ >= (uint)servers_.Count) { // check if search position is still valid (could be corrupted by server delete operation) posIndex = 0; serverpos_ = 0; } serverpos_++; i++; if (!bOnlyObfuscated || servers_[(int)posIndex].DoesSupportsObfuscationTCP) { nextserver = servers_[(int)posIndex]; } else if (serverpos_ >= (uint)servers_.Count) { return(null); } } return(nextserver); }
public bool AddServerMetToList(List <ServerAddress> list) { list.ForEach(serverAddress => { IPAddress ip = null; if (IPAddress.TryParse(serverAddress.Address, out ip)) { ED2KServer server = MuleApplication.Instance.ED2KObjectManager.CreateED2KServer((ushort)serverAddress.Port, serverAddress.Address); server.ServerName = serverAddress.Name; server.IsStaticMember = serverAddress.IsStatic; switch (serverAddress.Priority) { case (uint)ED2KServerPriorityEnum.SRV_PR_HIGH: server.Priority = ED2KServerPriorityEnum.SRV_PR_HIGH; break; case (uint)ED2KServerPriorityEnum.SRV_PR_LOW: server.Priority = ED2KServerPriorityEnum.SRV_PR_LOW; break; case (uint)ED2KServerPriorityEnum.SRV_PR_NORMAL: default: server.Priority = ED2KServerPriorityEnum.SRV_PR_NORMAL; break; } servers_.Add(server); } } ); return(true); }
public bool IsGoodServerIP(ED2KServer pServer) { if (pServer.HasDynIP) { return(true); } return(MpdUtilities.IsGoodIPPort(pServer.IP, pServer.Port)); }
public void MoveServerDown(ED2KServer pServer) { if (!servers_.Contains(pServer)) { return; } servers_.Remove(pServer); servers_.Add(pServer); }
public void RemoveServer(ED2KServer pServer) { if (!servers_.Contains(pServer)) { return; } servers_.Remove(pServer); delservercount_++; if (MuleApplication.Instance.DownloadQueue.CurrentUDPServer == pServer) { MuleApplication.Instance.DownloadQueue.CurrentUDPServer = null; } }
private void ProcessPacketError(uint size, uint opcode, uint nIP, ushort nUDPPort, Exception ex) { string strName = string.Empty; ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByIPUDP(nIP, nUDPPort); if (pServer != null) { strName = " (" + pServer.ServerName + ")"; } MpdUtilities.DebugLogWarning(false, string.Format("Error: Failed to process server UDP packet from {0}:{1}{2} opcode=0x{3} size={4} - {5}", MpdUtilities.IP2String(nIP), nUDPPort, strName, opcode, size, ex.Message), ex); }
public bool AddServer(ED2KServer pServer, bool bAddTail) { if (!IsGoodServerIP(pServer)) { // check for 0-IP, localhost and optionally for LAN addresses return(false); } if (MuleApplication.Instance.Preference.IsFilterServerByIP) { // IP-Filter: We don't need to reject dynIP-servers here. After the DN was // resolved, the IP will get filtered and the server will get removed. This applies // for TCP-connections as well as for outgoing UDP-packets because for both protocols // we resolve the DN and filter the received IP. //if (pServer.HasDynIP()) // return false; if (MuleApplication.Instance.IPFilter.IsFiltered(pServer.IP)) { return(false); } } ED2KServer pFoundServer = GetServerByAddress(pServer.Address, pServer.Port); // Avoid duplicate (dynIP) servers: If the server which is to be added, is a dynIP-server // but we don't know yet it's DN, we need to search for an already available server with // that IP. if (pFoundServer == null && pServer.IP != 0) { pFoundServer = GetServerByIPTCP(pServer.IP, pServer.Port); } if (pFoundServer != null) { pFoundServer.ResetFailedCount(); return(false); } if (bAddTail) { servers_.Add(pServer); } else { servers_.Insert(0, pServer); } return(true); }
public void RemoveDuplicatesByAddress(ED2KServer pExceptThis) { foreach (ED2KServer pServer in servers_) { if (pServer == pExceptThis) { continue; } if (string.Compare(pServer.Address, pExceptThis.Address, true) == 0 && pServer.Port == pExceptThis.Port) { servers_.Remove(pServer); return; } } }
public void RemoveDuplicatesByIP(ED2KServer pExceptThis) { foreach (ED2KServer pServer in servers_) { if (pServer == pExceptThis) { continue; } if (pServer.IP == pExceptThis.IP && pServer.Port == pExceptThis.Port) { servers_.Remove(pServer); return; } } }
public bool Disconnect() { if (IsConnected && connectedSocket_ != null) { MuleApplication.Instance.SharedFiles.ClearED2KPublishInfo(); IsConnected = false; ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByAddress(connectedSocket_.CurrentServer.Address, connectedSocket_.CurrentServer.Port); MuleApplication.Instance.PublicIP = 0; DestroySocket(connectedSocket_); connectedSocket_ = null; MuleApplication.Instance.Statistics.ServerConnectTime = 0; MuleApplication.Instance.Statistics.Add2TotalServerDuration(); return(true); } return(false); }
public void TryAnotherConnectionRequest() { if (connectionAttemps_.Count < (MuleApplication.Instance.Preference.IsSafeServerConnectEnabled ? 1 : 2)) { ED2KServer next_server = MuleApplication.Instance.ServerList.GetNextServer(tryObfuscated_); if (next_server == null) { if (connectionAttemps_.Count == 0) { if (tryObfuscated_ && !MuleApplication.Instance.Preference.IsClientCryptLayerRequired) { // try all servers on the non-obfuscated port next tryObfuscated_ = false; ConnectToAnyServer(0, true, true, true); } else if (retryTimer_ == null) { // 05-Nov-2003: If we have a very short server list, we could put serious load on those few servers // if we start the next connection tries without waiting. startAutoConnectPos_ = 0; // default: start at 0 } } return; } // Barry - Only auto-connect to static server option if (MuleApplication.Instance.Preference.DoesAutoConnectToStaticServersOnly) { if (next_server.IsStaticMember) { ConnectToServer(next_server, true, !tryObfuscated_); } } else { ConnectToServer(next_server, true, !tryObfuscated_); } } }
public override bool Equals(object obj) { if (obj is ED2KServer) { ED2KServer pServer = obj as ED2KServer; if (Port != pServer.Port) { return(false); } if (HasDynIP && pServer.HasDynIP) { return(string.Compare(DynIP, pServer.DynIP, true) == 0); } if (HasDynIP || pServer.HasDynIP) { return(false); } return(IP == pServer.IP); } return(base.Equals(obj)); }
public ED2KServer GetSuccServer(ED2KServer lastserver) { if (servers_.Count == 0) { return(null); } if (lastserver == null) { return(servers_[0]); } int index = servers_.IndexOf(lastserver); if (index < 0) { return(servers_[0]); } if (index + 1 >= servers_.Count) { return(null); } return(servers_[index + 1]); }
public ED2KServer GetNextStatServer() { ED2KServer nextserver = null; int i = 0; while (nextserver == null && i < servers_.Count) { uint posIndex = statserverpos_; if (statserverpos_ >= (uint)servers_.Count) { // check if search position is still valid (could be corrupted by server delete operation) posIndex = 0; statserverpos_ = 0; } nextserver = servers_[(int)posIndex]; statserverpos_++; i++; if (statserverpos_ == (uint)servers_.Count) { statserverpos_ = 0; } } return(nextserver); }
public ED2KServer CreateED2KServer(ED2KServer server) { return(new ED2KServerImpl(server)); }
public void ConnectToServer(ED2KServer toConnect, bool multiconnect) { ConnectToServer(toConnect, multiconnect, false); }
public void ConnectToServer(ED2KServer toConnect) { ConnectToServer(toConnect, false, false); }
public void SendPacket(Packet packet, Mule.ED2K.ED2KServer pServer, ushort nSpecialPort, byte[] pInRawPacket, uint nRawLen) { // Create raw UDP packet byte[] pRawPacket; uint uRawPacketSize; ushort nPort = 0; if (packet != null) { pRawPacket = new byte[packet.Size + 2]; Array.Copy(packet.UDPHeader, pRawPacket, 2); Array.Copy(packet.Buffer, 0, pRawPacket, 2, packet.Size); uRawPacketSize = packet.Size + 2; if (MuleApplication.Instance.Preference.IsServerCryptLayerUDPEnabled && pServer.ServerKeyUDP != 0 && pServer.DoesSupportsObfuscationUDP) { uRawPacketSize = (uint)EncryptSendServer(ref pRawPacket, (int)uRawPacketSize, pServer.ServerKeyUDP); nPort = pServer.ObfuscationPortUDP; } else { nPort = (ushort)(pServer.Port + 4); } } else if (pInRawPacket != null) { // we don't encrypt rawpackets (!) pRawPacket = new byte[nRawLen]; Array.Copy(pInRawPacket, pRawPacket, nRawLen); uRawPacketSize = nRawLen; nPort = (ushort)(pServer.Port + 4); } else { Debug.Assert(false); return; } nPort = (nSpecialPort == 0) ? nPort : nSpecialPort; Debug.Assert(nPort != 0); // Do we need to resolve the DN of this server? IPAddress ipAddr = IPAddress.None; IPAddress.TryParse(pServer.Address, out ipAddr); if (ipAddr == IPAddress.None) { IPHostEntry hostEntry = Dns.GetHostEntry(pServer.Address); // Get the IP value uint nIP = 0; if (hostEntry != null && hostEntry.AddressList.Length > 0) { nIP = BitConverter.ToUInt32(hostEntry.AddressList[0].GetAddressBytes(), 0); } if (nIP != 0) { bool bRemoveServer = false; if (!MpdUtilities.IsGoodIP(nIP)) { // However, if we are currently connected to a "not-good-ip", that IP can't // be that bad -- may only happen when debugging in a LAN. ED2KServer pConnectedServer = MuleApplication.Instance.ServerConnect.CurrentServer; if (pConnectedServer != null || pConnectedServer.IP != nIP) { bRemoveServer = true; } } if (!bRemoveServer && MuleApplication.Instance.Preference.IsFilterServerByIP && MuleApplication.Instance.IPFilter.IsFiltered(nIP)) { bRemoveServer = true; } ED2KServer pTempServer = MuleApplication.Instance.ServerList.GetServerByAddress(pServer.Address, pServer.Port); if (pTempServer != null) { pServer.IP = nIP; // If we already have entries in the server list (dynIP-servers without a DN) // with the same IP as this dynIP-server, remove the duplicates. MuleApplication.Instance.ServerList.RemoveDuplicatesByIP(pServer); } if (bRemoveServer) { return; } // Send all of the queued packets for this server. SendBuffer(nIP, nPort, pRawPacket, uRawPacketSize); } } else { // No DNS query needed for this server. Just send the packet. SendBuffer(BitConverter.ToUInt32(ipAddr.GetAddressBytes(), 0), nPort, pRawPacket, uRawPacketSize); } }
public void ServerStats() { // Update the server list even if we are connected to Kademlia only. The idea is for both networks to keep // each other up to date.. Kad network can get you back into the ED2K network.. And the ED2K network can get // you back into the Kad network.. if (MuleApplication.Instance.ServerConnect.IsConnected && MuleApplication.Instance.ServerConnect.IsUDPSocketAvailable && servers_.Count > 0) { ED2KServer ping_server = GetNextStatServer(); if (ping_server == null) { return; } uint tNow = MpdUtilities.Time(); ED2KServer test = ping_server; while (ping_server.LastPingedTime != 0 && (tNow - ping_server.LastPingedTime) < MuleConstants.UDPSERVSTATREASKTIME) { ping_server = GetNextStatServer(); if (ping_server == test) { return; } } // IP-filter: We do not need to IP-filter any servers here, even dynIP-servers are not // needed to get filtered here. See also comments in 'CServerSocket::ConnectTo'. if (ping_server.FailedCount >= MuleApplication.Instance.Preference.DeadServerRetries) { RemoveServer(ping_server); return; } Random rand = new Random((int)tNow); ping_server.RealLastPingedTime = tNow; // this is not used to calcualte the next ping, but only to ensure a minimum delay for premature pings if (!ping_server.CryptPingReplyPending && (tNow - ping_server.LastPingedTime) >= MuleConstants.UDPSERVSTATREASKTIME && MuleApplication.Instance.PublicIP != 0 && MuleApplication.Instance.Preference.IsServerCryptLayerUDPEnabled) { // we try a obfsucation ping first and wait 20 seconds for an answer // if it doesn'T get responsed, we don't count it as error but continue with a normal ping ping_server.CryptPingReplyPending = true; int nPacketLen = 4 + (byte)(rand.Next() % 16); // max padding 16 bytes byte[] pRawPacket = new byte[nPacketLen]; int dwChallenge = (rand.Next() << 17) | (rand.Next() << 2) | (rand.Next() & 0x03); if (dwChallenge == 0) { dwChallenge++; } Array.Copy(BitConverter.GetBytes(dwChallenge), pRawPacket, 4); for (uint i = 4; i < nPacketLen; i++) // fillung up the remaining bytes with random data { pRawPacket[i] = (byte)rand.Next(); } ping_server.Challenge = (uint)dwChallenge; ping_server.LastPinged = MpdUtilities.GetTickCount(); ping_server.LastPingedTime = ((tNow - (uint)MuleConstants.UDPSERVSTATREASKTIME) + 20); // give it 20 seconds to respond MuleApplication.Instance.Statistics.AddUpDataOverheadServer((uint)nPacketLen); MuleApplication.Instance.ServerConnect.SendUDPPacket(null, ping_server, true, (ushort)(ping_server.Port + 12), pRawPacket, (uint)nPacketLen); } else if (ping_server.CryptPingReplyPending || MuleApplication.Instance.PublicIP == 0 || !MuleApplication.Instance.Preference.IsServerCryptLayerUDPEnabled) { // our obfsucation ping request was not answered, so probably the server doesn'T supports obfuscation // continue with a normal request ping_server.CryptPingReplyPending = false; Packet packet = MuleApplication.Instance.NetworkObjectManager.CreatePacket(OperationCodeEnum.OP_GLOBSERVSTATREQ, 4); int uChallenge = 0x55AA0000 + MpdUtilities.GetRandomUInt16(); ping_server.Challenge = (uint)uChallenge; Array.Copy(BitConverter.GetBytes(uChallenge), packet.Buffer, 4); ping_server.LastPinged = MpdUtilities.GetTickCount(); ping_server.LastPingedTime = (uint)(tNow - (rand.Next() % MuleConstants.ONE_HOUR_SEC)); ping_server.AddFailedCount(); MuleApplication.Instance.Statistics.AddUpDataOverheadServer(packet.Size); MuleApplication.Instance.ServerConnect.SendUDPPacket(packet, ping_server, true); } else { Debug.Assert(false); } } }
public int GetPositionOfServer(ED2KServer pServer) { return(servers_.IndexOf(pServer)); }
public bool AddServer(ED2KServer pServer) { return(AddServer(pServer, true)); }
private bool ProcessPacket(byte[] buffer, int offset, int size, uint opcode, uint nIP, ushort nUDPPort) { try { MuleApplication.Instance.Statistics.AddDownDataOverheadServer((uint)size); ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByIPUDP(nIP, nUDPPort, true); if (pServer != null) { pServer.ResetFailedCount(); } switch ((OperationCodeEnum)opcode) { case OperationCodeEnum.OP_GLOBSEARCHRES: { SafeMemFile data = MpdObjectManager.CreateSafeMemFile(buffer, size); // process all search result packets int iLeft; do { uint uResultCount = MuleApplication.Instance.SearchList.ProcessUDPSearchAnswer(data, true /*pServer.GetUnicodeSupport()*/, nIP, nUDPPort - 4); // check if there is another source packet iLeft = (int)(data.Length - data.Position); if (iLeft >= 2) { byte protocol = data.ReadUInt8(); iLeft--; if (protocol != MuleConstants.PROTOCOL_EDONKEYPROT) { data.Seek(-1, System.IO.SeekOrigin.Current); iLeft += 1; break; } byte opcode1 = data.ReadUInt8(); iLeft--; if (opcode1 != (byte)OperationCodeEnum.OP_GLOBSEARCHRES) { data.Seek(-2, System.IO.SeekOrigin.Current); iLeft += 2; break; } } }while (iLeft > 0); break; } case OperationCodeEnum.OP_GLOBFOUNDSOURCES: { SafeMemFile data = MpdObjectManager.CreateSafeMemFile(buffer, size); // process all source packets int iLeft; do { byte[] fileid = new byte[16]; data.ReadHash16(fileid); PartFile file = MuleApplication.Instance.DownloadQueue.GetFileByID(fileid); if (file != null) { file.AddSources(data, nIP, (ushort)(nUDPPort - 4), false); } else { // skip sources for that file uint count = data.ReadUInt8(); data.Seek(count * (4 + 2), System.IO.SeekOrigin.Current); } // check if there is another source packet iLeft = (int)(data.Length - data.Position); if (iLeft >= 2) { byte protocol = data.ReadUInt8(); iLeft--; if (protocol != MuleConstants.PROTOCOL_EDONKEYPROT) { data.Seek(-1, System.IO.SeekOrigin.Current); iLeft += 1; break; } byte opcode1 = data.ReadUInt8(); iLeft--; if (opcode1 != (byte)OperationCodeEnum.OP_GLOBFOUNDSOURCES) { data.Seek(-2, System.IO.SeekOrigin.Current); iLeft += 2; break; } } }while (iLeft > 0); break; } case OperationCodeEnum.OP_GLOBSERVSTATRES: { if (size < 12 || pServer == null) { return(true); } uint challenge = BitConverter.ToUInt32(buffer, 0); if (challenge != pServer.Challenge) { return(true); } if (pServer != null) { pServer.Challenge = 0; pServer.CryptPingReplyPending = false; uint tNow = MpdUtilities.Time(); Random rand = new Random(); // if we used Obfuscated ping, we still need to reset the time properly pServer.LastPingedTime = Convert.ToUInt32(tNow - (rand.Next() % MuleConstants.ONE_HOUR_SEC)); } uint cur_user = BitConverter.ToUInt32(buffer, 4); uint cur_files = BitConverter.ToUInt32(buffer, 8); uint cur_maxusers = 0; uint cur_softfiles = 0; uint cur_hardfiles = 0; uint uUDPFlags = 0; uint uLowIDUsers = 0; uint dwServerUDPKey = 0; ushort nTCPObfuscationPort = 0; ushort nUDPObfuscationPort = 0; if (size >= 16) { cur_maxusers = BitConverter.ToUInt32(buffer, 12); } if (size >= 24) { cur_softfiles = BitConverter.ToUInt32(buffer, 16); cur_hardfiles = BitConverter.ToUInt32(buffer, 20); } if (size >= 28) { uUDPFlags = BitConverter.ToUInt32(buffer, 24); } if (size >= 32) { uLowIDUsers = BitConverter.ToUInt32(buffer, 28); } if (size >= 40) { // TODO debug check if this packet was encrypted if it has a key nUDPObfuscationPort = BitConverter.ToUInt16(buffer, 32); nTCPObfuscationPort = BitConverter.ToUInt16(buffer, 34);; dwServerUDPKey = BitConverter.ToUInt32(buffer, 36); } if (pServer != null) { pServer.Ping = MpdUtilities.GetTickCount() - pServer.LastPinged; pServer.UserCount = cur_user; pServer.FileCount = cur_files; pServer.MaxUsers = cur_maxusers; pServer.SoftFiles = cur_softfiles; pServer.HardFiles = cur_hardfiles; pServer.ServerKeyUDP = dwServerUDPKey; pServer.ObfuscationPortTCP = nTCPObfuscationPort; pServer.ObfuscationPortUDP = nUDPObfuscationPort; // if the received UDP flags do not match any already stored UDP flags, // reset the server version string because the version (which was determined by last connecting to // that server) is most likely not accurat any longer. // this may also give 'false' results because we don't know the UDP flags when connecting to a server // with TCP. //if (pServer.GetUDPFlags() != uUDPFlags) // pServer.Version(_T = ""); pServer.UDPFlags = (ED2KServerUdpFlagsEnum)uUDPFlags; pServer.LowIDUsers = uLowIDUsers; pServer.SetLastDescPingedCount(false); if (pServer.LastDescPingedCount < 2) { // eserver 16.45+ supports a new OP_SERVER_DESC_RES answer, if the OP_SERVER_DESC_REQ contains a uint // challenge, the server returns additional info with OP_SERVER_DESC_RES. To properly distinguish the // old and new OP_SERVER_DESC_RES answer, the challenge has to be selected carefully. The first 2 bytes // of the challenge (in network byte order) MUST NOT be a valid string-len-int16! Packet packet1 = MuleApplication.Instance.NetworkObjectManager.CreatePacket(OperationCodeEnum.OP_SERVER_DESC_REQ, 4); uint uDescReqChallenge = ((uint)MpdUtilities.GetRandomUInt16() << 16) + MuleConstants.INV_SERV_DESC_LEN; // 0xF0FF = an 'invalid' string length. pServer.DescReqChallenge = uDescReqChallenge; Array.Copy(BitConverter.GetBytes(uDescReqChallenge), packet1.Buffer, 4); MuleApplication.Instance.Statistics.AddUpDataOverheadServer(packet1.Size); MuleApplication.Instance.ServerConnect.SendUDPPacket(packet1, pServer, true); } else { pServer.SetLastDescPingedCount(true); } } break; } case OperationCodeEnum.OP_SERVER_DESC_RES: { if (pServer == null) { return(true); } // old packet: <name_len 2><name name_len><desc_len 2 desc_en> // new packet: <challenge 4><taglist> // // NOTE: To properly distinguish between the two packets which are both useing the same opcode... // the first two bytes of <challenge> (in network byte order) have to be an invalid <name_len> at least. SafeMemFile srvinfo = MpdObjectManager.CreateSafeMemFile(buffer, size); if (size >= 8 && BitConverter.ToUInt16(buffer, 0) == MuleConstants.INV_SERV_DESC_LEN) { if (pServer.DescReqChallenge != 0 && BitConverter.ToUInt32(buffer, 0) == pServer.DescReqChallenge) { pServer.DescReqChallenge = 0; srvinfo.ReadUInt32(); // skip challenge uint uTags = srvinfo.ReadUInt32(); for (uint i = 0; i < uTags; i++) { Tag tag = MpdObjectManager.CreateTag(srvinfo, true /*pServer.GetUnicodeSupport()*/); if (tag.NameID == MuleConstants.ST_SERVERNAME && tag.IsStr) { pServer.ServerName = tag.Str; } else if (tag.NameID == MuleConstants.ST_DESCRIPTION && tag.IsStr) { pServer.Description = tag.Str; } else if (tag.NameID == MuleConstants.ST_DYNIP && tag.IsStr) { // Verify that we really received a DN. IPAddress address; if (!IPAddress.TryParse(tag.Str, out address) || address == IPAddress.None) { string strOldDynIP = pServer.DynIP; pServer.DynIP = tag.Str; // If a dynIP-server changed its address or, if this is the // first time we get the dynIP-address for a server which we // already have as non-dynIP in our list, we need to remove // an already available server with the same 'dynIP:port'. if (string.Compare(strOldDynIP, pServer.DynIP, true) != 0) { MuleApplication.Instance.ServerList.RemoveDuplicatesByAddress(pServer); } } } else if (tag.NameID == MuleConstants.ST_VERSION && tag.IsStr) { pServer.Version = tag.Str; } else if (tag.NameID == MuleConstants.ST_VERSION && tag.IsInt) { pServer.Version = string.Format("{0}.{1}", tag.Int >> 16, tag.Int & 0xFFFF); } } } else { // A server sent us a new server description packet (including a challenge) although we did not // ask for it. This may happen, if there are multiple servers running on the same machine with // multiple IPs. If such a server is asked for a description, the server will answer 2 times, // but with the same IP. } } else { string strName = srvinfo.ReadString(true /*pServer.GetUnicodeSupport()*/); string strDesc = srvinfo.ReadString(true /*pServer.GetUnicodeSupport()*/); pServer.Description = strDesc; pServer.ServerName = strName; } break; } default: return(false); } return(true); } catch (Exception error) { ProcessPacketError((uint)size, (uint)opcode, nIP, nUDPPort, error); if (opcode == (byte)OperationCodeEnum.OP_GLOBSEARCHRES || opcode == (byte)OperationCodeEnum.OP_GLOBFOUNDSOURCES) { return(true); } } return(false); }
public void ConnectionEstablished(Mule.Network.ServerSocket sender) { if (!IsConnecting) { // we are already IsConnected to another server DestroySocket(sender); return; } InitLocalIP(); if (sender.ConnectionState == ConnectionStateEnum.CS_WAITFORLOGIN) { ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByAddress(sender.CurrentServer.Address, sender.CurrentServer.Port); if (pServer != null) { pServer.ResetFailedCount(); } // Send login packet SafeMemFile data = MpdObjectManager.CreateSafeMemFile(256); data.WriteHash16(MuleApplication.Instance.Preference.UserHash); data.WriteUInt32(ClientID); data.WriteUInt16(MuleApplication.Instance.Preference.Port); uint tagcount = 4; data.WriteUInt32(tagcount); Tag tagName = MpdObjectManager.CreateTag(TagTypeEnum.CT_NAME, MuleApplication.Instance.Preference.UserNick); tagName.WriteTagToFile(data); Tag tagVersion = MpdObjectManager.CreateTag(TagTypeEnum.CT_VERSION, VersionsEnum.EDONKEYVERSION); tagVersion.WriteTagToFile(data); ServerFlagsEnum dwCryptFlags = 0; if (MuleApplication.Instance.Preference.IsClientCryptLayerSupported) { dwCryptFlags |= ServerFlagsEnum.SRVCAP_SUPPORTCRYPT; } if (MuleApplication.Instance.Preference.IsClientCryptLayerRequested) { dwCryptFlags |= ServerFlagsEnum.SRVCAP_REQUESTCRYPT; } if (MuleApplication.Instance.Preference.IsClientCryptLayerRequired) { dwCryptFlags |= ServerFlagsEnum.SRVCAP_REQUIRECRYPT; } Tag tagFlags = MpdObjectManager.CreateTag(TagTypeEnum.CT_SERVER_FLAGS, ServerFlagsEnum.SRVCAP_ZLIB | ServerFlagsEnum.SRVCAP_NEWTAGS | ServerFlagsEnum.SRVCAP_LARGEFILES | ServerFlagsEnum.SRVCAP_UNICODE | dwCryptFlags); tagFlags.WriteTagToFile(data); // eMule Version (14-Mar-2004: requested by lugdunummaster (need for LowID clients which have no chance // to send an Hello packet to the server during the callback test)) Tag tagMuleVersion = MpdObjectManager.CreateTag(TagTypeEnum.CT_EMULE_VERSION, (MuleApplication.Instance.Version.Major << 17) | (MuleApplication.Instance.Version.Minor << 10) | (MuleApplication.Instance.Version.Build << 7)); tagMuleVersion.WriteTagToFile(data); Packet packet = MuleApplication.Instance.NetworkObjectManager.CreatePacket(data); packet.OperationCode = OperationCodeEnum.OP_LOGINREQUEST; MuleApplication.Instance.Statistics.AddUpDataOverheadServer(packet.Size); SendPacket(packet, true, sender); } else if (sender.ConnectionState == ConnectionStateEnum.CS_CONNECTED) { MuleApplication.Instance.Statistics.Reconnects++; MuleApplication.Instance.Statistics.ServerConnectTime = MpdUtilities.GetTickCount(); IsConnected = true; connectedSocket_ = sender; StopConnectionTry(); MuleApplication.Instance.SharedFiles.ClearED2KPublishInfo(); MuleApplication.Instance.SharedFiles.SendListToServer(); if (MuleApplication.Instance.Preference.DoesAddServersFromServer) { Packet packet = MuleApplication.Instance.NetworkObjectManager.CreatePacket( OperationCodeEnum.OP_GETSERVERLIST, 0); MuleApplication.Instance.Statistics.AddUpDataOverheadServer(packet.Size); SendPacket(packet, true); } } }
public bool IsEqual(ED2KServer pServer) { return(Equals(pServer)); }
public void ConnectionFailed(Mule.Network.ServerSocket sender) { if (!IsConnecting && sender != connectedSocket_) { // just return, cleanup is done by the socket itself return; } ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByAddress(sender.CurrentServer.Address, sender.CurrentServer.Port); switch (sender.ConnectionState) { case ConnectionStateEnum.CS_FATALERROR: //TODO:Log break; case ConnectionStateEnum.CS_DISCONNECTED: MuleApplication.Instance.SharedFiles.ClearED2KPublishInfo(); break; case ConnectionStateEnum.CS_SERVERDEAD: if (pServer != null) { pServer.AddFailedCount(); } break; case ConnectionStateEnum.CS_ERROR: break; case ConnectionStateEnum.CS_SERVERFULL: break; case ConnectionStateEnum.CS_NOTCONNECTED: break; } // IMPORTANT: mark this socket not to be deleted in StopConnectionTry(), // because it will delete itself after this function! sender.IsDeleting = true; switch (sender.ConnectionState) { case ConnectionStateEnum.CS_FATALERROR: { bool autoretry = !IsSingleConnect; StopConnectionTry(); if (MuleApplication.Instance.Preference.IsReconnect && autoretry && retryTimer_ == null) { // There are situations where we may get Winsock error codes which indicate // that the network is down, although it is not. Those error codes may get // thrown only for particular IPs. If the first server in our list has such // an IP and will therefor throw such an error we would never connect to // any server at all. To circumvent that, start the next auto-connection // attempt with a different server (use the next server in the list). startAutoConnectPos_ = 0; // default: start at 0 if (pServer != null) { // If possible, use the "next" server. int iPosInList = MuleApplication.Instance.ServerList.GetPositionOfServer(pServer); if (iPosInList >= 0) { startAutoConnectPos_ = (uint)((iPosInList + 1) % MuleApplication.Instance.ServerList.ServerCount); } } retryTimer_ = new Timer(new TimerCallback(RetryConnectTimer), this, 0, MuleConstants.ONE_SEC_MS * MuleConstants.CS_RETRYCONNECTTIME); } break; } case ConnectionStateEnum.CS_DISCONNECTED: { MuleApplication.Instance.SharedFiles.ClearED2KPublishInfo(); IsConnected = false; if (connectedSocket_ != null) { connectedSocket_.Close(); connectedSocket_ = null; } MuleApplication.Instance.Statistics.ServerConnectTime = 0; MuleApplication.Instance.Statistics.Add2TotalServerDuration(); if (MuleApplication.Instance.Preference.IsReconnect && !IsConnecting) { ConnectToAnyServer(); } break; } case ConnectionStateEnum.CS_ERROR: case ConnectionStateEnum.CS_NOTCONNECTED: { if (!IsConnecting) { break; } } goto case ConnectionStateEnum.CS_SERVERDEAD; case ConnectionStateEnum.CS_SERVERDEAD: case ConnectionStateEnum.CS_SERVERFULL: { if (!IsConnecting) { break; } if (IsSingleConnect) { if (pServer != null && sender.IsServerCryptEnabledConnection && !MuleApplication.Instance.Preference.IsClientCryptLayerRequired) { // try reconnecting without obfuscation ConnectToServer(pServer, false, true); break; } StopConnectionTry(); break; } Dictionary <ulong, ServerSocket> .Enumerator pos = connectionAttemps_.GetEnumerator(); while (pos.MoveNext()) { if (pos.Current.Value == sender) { connectionAttemps_.Remove(pos.Current.Key); break; } } TryAnotherConnectionRequest(); } break; } }