public override int Send(byte[] lpBuf, int offset, int nBufLen, SocketFlags nFlags) { if (!IsEncryptionLayerReady) { Debug.Assert(false); // must be a bug return(0); } else if (serverCrypt_ && streamCryptState_ == StreamCryptStateEnum.ECS_ENCRYPTING && fiSendBuffer_ != null) { Debug.Assert(negotiatingState_ == NegotiatingStateEnum.ONS_BASIC_SERVER_DELAYEDSENDING); // handshakedata was delayed to put it into one frame with the first paypload to the server // do so now with the payload attached int nRes = SendNegotiatingData(lpBuf, Convert.ToUInt32(nBufLen), Convert.ToUInt32(offset + nBufLen)); Debug.Assert(nRes != SOCKET_ERROR); return(nBufLen); // report a full send, even if we didn't for some reason - the data is know in our buffer and will be handled later } else if (negotiatingState_ == NegotiatingStateEnum.ONS_BASIC_SERVER_DELAYEDSENDING) { Debug.Assert(false); } if (streamCryptState_ == StreamCryptStateEnum.ECS_UNKNOWN) { //this happens when the encryption option was not set on a outgoing connection //or if we try to send before receiving on a incoming connection - both shouldn't happen streamCryptState_ = StreamCryptStateEnum.ECS_NONE; MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Overwriting State ECS_UNKNOWN with ECS_NONE because of premature Send() (%s)"), DbgGetIPString()); } return(base.Send(lpBuf, offset, nBufLen, nFlags)); }
public void StartUp() { if (IsRunning) { return; } IsRunning = false; try { ServerList.Init(); UploadBandwidthThrottler.Start(); DownloadQueue.Init(); ListenSocket.StartListening(); ClientUDP.Create(); if (Preference.DoesAutoConnect) { StartConnection(); } IsRunning = true; } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication StartUp Fail", ex); } }
protected void InitalizeCrypting() { publicKeyLen_ = 0; Array.Clear(publicKey_, 0, 80); // not really needed; better for debugging tho signkey_ = null; if (!MuleApplication.Instance.Preference.IsSecureIdentEnabled) { return; } // check if keyfile is there bool bCreateNewKey = false; string filename = System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR), "crytkey.dat"); if (System.IO.File.Exists(filename)) { FileInfo info = new FileInfo(filename); if (info.Length == 0) { bCreateNewKey = true; } } else { bCreateNewKey = true; } if (bCreateNewKey) { CreateKeyPair(); } // load key try { string keyText = System.IO.File.ReadAllText(filename); byte[] key = Convert.FromBase64String(keyText); // load private key signkey_ = MpdObjectManager.CreateRSAPKCS1V15SHA1Signer(key); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider((int)MuleConstants.RSAKEYSIZE); rsa.ImportCspBlob(key); byte[] tmp = rsa.ExportCspBlob(false); Array.Copy(tmp, publicKey_, tmp.Length); publicKeyLen_ = (byte)tmp.Length; } catch (Exception ex) { signkey_ = null; MpdUtilities.DebugLogError(ex); } }
public byte CreateSignature(ClientCredits pTarget, byte[] pachOutput, byte nMaxSize, uint ChallengeIP, byte byChaIPKind, RSAPKCS1SignatureFormatter sigkey) { // sigkey param is used for debug only if (sigkey == null) { sigkey = signkey_; } // create a signature of the public key from pTarget byte nResult; if (!IsCryptoAvailable) { return(0); } try { byte[] abyBuffer = new byte[CreditStruct.MAXPUBKEYSIZE + 9]; uint keylen = pTarget.SecIDKeyLen; Array.Copy(pTarget.SecureIdent, abyBuffer, keylen); // 4 additional bytes random data send from this client uint challenge = pTarget.CryptRndChallengeFrom; Array.Copy(BitConverter.GetBytes(challenge), 0, abyBuffer, keylen, 4); ushort ChIpLen = 0; if (byChaIPKind != 0) { ChIpLen = 5; Array.Copy(BitConverter.GetBytes(ChallengeIP), 0, abyBuffer, keylen + 4, 4); abyBuffer[keylen + 4 + 4] = byChaIPKind; } byte[] tmpBuf = new byte[keylen + 4 + ChIpLen]; Array.Copy(abyBuffer, tmpBuf, keylen + 4 + ChIpLen); byte[] outBuf = sigkey.CreateSignature(tmpBuf); nResult = (byte)outBuf.Length; if (outBuf.Length > nMaxSize) { nResult = nMaxSize; } Array.Copy(outBuf, pachOutput, nResult); } catch (Exception ex) { MpdUtilities.DebugLogError(ex); nResult = 0; } return(nResult); }
public override bool Connect(string lpszHostAddress, uint nHostPort) { InitProxySupport(); try { base.Connect(lpszHostAddress, nHostPort); return(base.Connected); } catch (Exception ex) { MpdUtilities.DebugLogError("Connect Fail", ex); return(base.Connected); } }
public virtual int Receive(byte[] pBuffer, int offset, int nBufLen, SocketFlags nFlags) { SocketErrorCode = SocketError.Success; try { return(socket_.Receive(pBuffer, offset, nBufLen, nFlags)); } catch (SocketException ex) { SocketErrorCode = ex.SocketErrorCode; MpdUtilities.DebugLogError(string.Format("Socket Exception:{0},{1}", ex.ErrorCode, ex.SocketErrorCode), ex); return(SOCKET_ERROR); } }
public AsyncSocket Accept() { SocketErrorCode = SocketError.Success; try { return(CreateAsyncSocket(socket_.Accept())); } catch (SocketException ex) { SocketErrorCode = ex.SocketErrorCode; MpdUtilities.DebugLogError(string.Format("Socket Exception:{0},{1}", ex.ErrorCode, ex.SocketErrorCode), ex); return(null); } }
protected void CryptPrepareSendData(byte[] pBuffer, uint nLen) { if (!IsEncryptionLayerReady) { Debug.Assert(false); // must be a bug return; } if (streamCryptState_ == StreamCryptStateEnum.ECS_UNKNOWN) { //this happens when the encryption option was not set on a outgoing connection //or if we try to send before receiving on a incoming connection - both shouldn't happen streamCryptState_ = StreamCryptStateEnum.ECS_NONE; MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Overwriting State ECS_UNKNOWN with ECS_NONE because of premature Send() (%s)"), DbgGetIPString()); } if (streamCryptState_ == StreamCryptStateEnum.ECS_ENCRYPTING) { MuleUtilities.RC4Crypt(pBuffer, pBuffer, nLen, rc4SendKey_); } }
public void InitLocalIP() { LocalIP = 0; // Using 'gethostname/gethostbyname' does not solve the problem when we have more than // one IP address. Using 'gethostname/gethostbyname' even seems to return the last IP // address which we got. e.g. if we already got an IP from our ISP, // 'gethostname/gethostbyname' will returned that (primary) IP, but if we add another // IP by opening a VPN connection, 'gethostname' will still return the same hostname, // but 'gethostbyname' will return the 2nd IP. // To weaken that problem at least for users which are binding eMule to a certain IP, // we use the explicitly specified bind address as our local IP address. if (MuleApplication.Instance.Preference.BindAddr != null) { IPAddress ulBindAddr = null; if (IPAddress.TryParse(MuleApplication.Instance.Preference.BindAddr, out ulBindAddr)) { LocalIP = BitConverter.ToUInt32(ulBindAddr.GetAddressBytes(), 0); return; } } // Don't use 'gethostbyname(null)'. The winsock DLL may be replaced by a DLL from a third party // which is not fully compatible to the original winsock DLL. ppl reported crash with SCORSOCK.DLL // when using 'gethostbyname(null)'. try { string hostName = Dns.GetHostName(); IPHostEntry hostEntry = Dns.GetHostEntry(hostName); if (hostEntry.AddressList != null && hostEntry.AddressList.Length > 0) { LocalIP = BitConverter.ToUInt32(hostEntry.AddressList[0].GetAddressBytes(), 0); } } catch (Exception ex) { MpdUtilities.DebugLogError(ex); } }
protected void SaveList() { lastSaved_ = MpdUtilities.GetTickCount(); string name = System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR), CLIENTS_MET_FILENAME); try { using (FileStream file = new FileStream(name, FileMode.Create, FileAccess.Write, FileShare.None)) { int count = clients_.Count; SafeMemFile memfile = MpdObjectManager.CreateSafeMemFile(count * (16 + 5 * 4 + 1 * 2 + 1 + CreditStruct.MAXPUBKEYSIZE)); memfile.WriteUInt8((byte)VersionsEnum.CREDITFILE_VERSION); Dictionary <MapCKey, ClientCredits> .Enumerator pos = clients_.GetEnumerator(); count = 0; while (pos.MoveNext()) { ClientCredits cur_credit = pos.Current.Value; if (cur_credit.GetUploadedTotal() != 0 || cur_credit.GetDownloadedTotal() != 0) { WriteCreditStruct(memfile, cur_credit.DataStruct); count++; } } memfile.WriteUInt32((uint)count); file.Write(memfile.Buffer, 0, (int)memfile.Length); file.Flush(); file.Close(); memfile.Close(); } } catch (Exception error) { MpdUtilities.DebugLogError(error); } }
private void RetryConnectTimer(object state) { // NOTE: Always handle all type of MFC exceptions in TimerProcs - otherwise we'll get mem leaks try { StopConnectionTry(); if (IsConnected) { return; } if (startAutoConnectPos_ >= MuleApplication.Instance.ServerList.ServerCount) { startAutoConnectPos_ = 0; } ConnectToAnyServer(startAutoConnectPos_, true, true); } catch (Exception ex) { MpdUtilities.DebugLogError(ex); } }
public bool StartListening() { try { if (!base.CreateSocket(new IPEndPoint(0, 0).AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { return(false); } IPAddress address = IPAddress.Any; if (MuleApplication.Instance.Preference.BindAddr != null && MuleApplication.Instance.Preference.BindAddr.Length > 0) { IPAddress.TryParse(MuleApplication.Instance.Preference.BindAddr, out address); } IPEndPoint endpoint = new IPEndPoint(address, MuleApplication.Instance.Preference.Port); Bind(endpoint); Listen(); port_ = MuleApplication.Instance.Preference.Port; bListening_ = true; return(true); } catch (Exception ex) { MpdUtilities.DebugLogError("Start Listening Error", ex); return(false); } }
protected bool CreateKeyPair() { try { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider((int)MuleConstants.RSAKEYSIZE); byte[] key = rsa.ExportCspBlob(true); string keyText = Convert.ToBase64String(key); string filename = System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR), "crytkey.dat"); System.IO.File.WriteAllText(filename, keyText); return(true); } catch (Exception ex) { MpdUtilities.DebugLogError(ex); return(false); } }
public bool Create() { try { if (!CreateSocket(new IPEndPoint(IPAddress.Any, 0).AddressFamily, SocketType.Dgram, ProtocolType.Udp)) { return(false); } if (MuleApplication.Instance.Preference.UDPPort != 0) { Bind(new IPEndPoint(IPAddress.Parse(MuleApplication.Instance.Preference.BindAddr), MuleApplication.Instance.Preference.UDPPort)); // the default socket size seems to be not enough for this UDP socket // because we tend to drop packets if several flow in at the same time int val = 64 * 1024; SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.ReceiveBuffer, val); } else { return(false); } port_ = MuleApplication.Instance.Preference.UDPPort; return(true); } catch (Exception ex) { MpdUtilities.DebugLogError("ClientUDPSocket Create Fail", ex); return(false); } }
public virtual int DecryptReceivedClient(byte[] pbyBufIn, int nBufLen, out byte[] ppbyBufOut, uint dwIP, out uint nReceiverVerifyKey, out uint nSenderVerifyKey) { int nResult = nBufLen; ppbyBufOut = pbyBufIn; nReceiverVerifyKey = 0; nSenderVerifyKey = 0; if (nResult <= CRYPT_HEADER_WITHOUTPADDING /*|| !MuleApplication.Instance.Preference.IsClientCryptLayerSupported()*/) { return(nResult); } switch (pbyBufIn[0]) { case MuleConstants.PROTOCOL_EMULEPROT: case MuleConstants.PROTOCOL_KADEMLIAPACKEDPROT: case MuleConstants.PROTOCOL_KADEMLIAHEADER: case MuleConstants.PROTOCOL_UDPRESERVEDPROT1: case MuleConstants.PROTOCOL_UDPRESERVEDPROT2: case MuleConstants.PROTOCOL_PACKEDPROT: return(nResult); // no encrypted packet (see description on top) } // might be an encrypted packet, try to decrypt RC4Key keyReceiveKey = null; uint dwValue = 0; // check the marker bit which type this packet could be and which key to test first, this is only an indicator since old clients have it set random // see the header for marker bits explanation byte byCurrentTry = (byte)(((pbyBufIn[0] & 0x03) == 3) ? 1 : (pbyBufIn[0] & 0x03)); byte byTries; if (MuleApplication.Instance.KadEngine.Preference == null) { // if kad never run, no point in checking anything except for ed2k encryption byTries = 1; byCurrentTry = 1; } else { byTries = 3; } bool bKadRecvKeyUsed = false; bool bKad = false; do { byTries--; MD5 md5 = MD5.Create(); byte[] rawHash = null; if (byCurrentTry == 0) { // kad packet with NodeID as key bKad = true; bKadRecvKeyUsed = false; if (MuleApplication.Instance.KadEngine.Preference != null) { byte[] achKeyData = new byte[18]; Array.Copy(MuleApplication.Instance.KadEngine.Preference.KadID.Bytes, 0, achKeyData, 0, 16); Array.Copy(pbyBufIn, 1, achKeyData, 16, 2); // random key part sent from remote client rawHash = md5.ComputeHash(achKeyData); } } else if (byCurrentTry == 1) { // ed2k packet bKad = false; bKadRecvKeyUsed = false; byte[] achKeyData = new byte[23]; MpdUtilities.Md4Cpy(achKeyData, MuleApplication.Instance.Preference.UserHash); achKeyData[20] = MAGICVALUE_UDP; Array.Copy(BitConverter.GetBytes(dwIP), 0, achKeyData, 16, 4); Array.Copy(pbyBufIn, 1, achKeyData, 21, 2); // random key part sent from remote client rawHash = md5.ComputeHash(achKeyData); } else if (byCurrentTry == 2) { // kad packet with ReceiverKey as key bKad = true; bKadRecvKeyUsed = true; if (MuleApplication.Instance.KadEngine.Preference != null) { byte[] achKeyData = new byte[6]; Array.Copy(BitConverter.GetBytes(MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP)), achKeyData, 4); Array.Copy(pbyBufIn, 1, achKeyData, 4, 2); // random key part sent from remote client rawHash = md5.ComputeHash(achKeyData); } } else { Debug.Assert(false); } MuleUtilities.RC4CreateKey(rawHash, 16, ref keyReceiveKey, true); byte[] outBuf = new byte[4]; MuleUtilities.RC4Crypt(pbyBufIn, 3, outBuf, 0, 4, keyReceiveKey); dwIP = BitConverter.ToUInt32(outBuf, 0); byCurrentTry = (byte)((byCurrentTry + 1) % 3); } while (dwValue != MAGICVALUE_UDP_SYNC_CLIENT && byTries > 0); // try to decrypt as ed2k as well as kad packet if needed (max 3 rounds) if (dwValue == MAGICVALUE_UDP_SYNC_CLIENT) { // yup this is an encrypted packet // debugoutput notices // the following cases are "allowed" but shouldn't happen given that there is only our implementation yet if (bKad && (pbyBufIn[0] & 0x01) != 0) { MpdUtilities.DebugLog( string.Format("Received obfuscated UDP packet from clientIP: {0} with wrong key marker bits (kad packet, ed2k bit)", MpdUtilities.IP2String(dwIP))); } else if (bKad && !bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) != 0) { MpdUtilities.DebugLog( string.Format("Received obfuscated UDP packet from clientIP: {0} with wrong key marker bits (kad packet, nodeid key, recvkey bit)", MpdUtilities.IP2String(dwIP))); } else if (bKad && bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) == 0) { MpdUtilities.DebugLog( string.Format("Received obfuscated UDP packet from clientIP: {0} with wrong key marker bits (kad packet, recvkey key, nodeid bit)", MpdUtilities.IP2String(dwIP))); } byte byPadLen; byte[] outBuf = new byte[1]; MuleUtilities.RC4Crypt(pbyBufIn, 7, outBuf, 0, 1, keyReceiveKey); byPadLen = outBuf[0]; nResult -= CRYPT_HEADER_WITHOUTPADDING; if (nResult <= byPadLen) { MpdUtilities.DebugLogError( string.Format("Invalid obfuscated UDP packet from clientIP: {0}, Paddingsize ({1}) larger than received bytes", MpdUtilities.IP2String(dwIP), byPadLen)); return(nBufLen); // pass through, let the Receivefunction do the errorhandling on this junk } if (byPadLen > 0) { MuleUtilities.RC4Crypt(null, null, byPadLen, keyReceiveKey); } nResult -= byPadLen; if (bKad) { if (nResult <= 8) { MpdUtilities.DebugLogError( string.Format("Obfuscated Kad packet with mismatching size (verify keys missing) received from clientIP: {0}", MpdUtilities.IP2String(dwIP))); return(nBufLen); // pass through, let the Receivefunction do the errorhandling on this junk; } // read the verify keys outBuf = new byte[4]; MuleUtilities.RC4Crypt(pbyBufIn, (int)(CRYPT_HEADER_WITHOUTPADDING + byPadLen), outBuf, 0, 4, keyReceiveKey); nReceiverVerifyKey = BitConverter.ToUInt32(outBuf, 0); MuleUtilities.RC4Crypt(pbyBufIn, (int)(CRYPT_HEADER_WITHOUTPADDING + byPadLen + 4), outBuf, 0, 4, keyReceiveKey); nSenderVerifyKey = BitConverter.ToUInt32(outBuf, 0); nResult -= 8; } ppbyBufOut = new byte[nResult]; Array.Copy(pbyBufIn, (nBufLen - nResult), ppbyBufOut, 0, nResult); MuleUtilities.RC4Crypt(ppbyBufOut, ppbyBufOut, (uint)nResult, keyReceiveKey); MuleApplication.Instance.Statistics.AddDownDataOverheadCrypt((uint)(nBufLen - nResult)); //DEBUG_ONLY( MpdUtilities.DebugLog(("Received obfuscated UDP packet from clientIP: %s, Key: %s, RKey: %u, SKey: %u"), MpdUtilities.IP2String(dwIP), bKad ? (bKadRecvKeyUsed ? ("ReceiverKey") : ("NodeID")) : ("UserHash") // , nReceiverVerifyKey != 0 ? *nReceiverVerifyKey : 0, nSenderVerifyKey != 0 ? *nSenderVerifyKey : 0) ); return(nResult); // done } else { MpdUtilities.DebugLogWarning( string.Format("Obfuscated packet expected but magicvalue mismatch on UDP packet from clientIP: {0}, Possible RecvKey: {1}", MpdUtilities.IP2String(dwIP), MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP))); return(nBufLen); // pass through, let the Receivefunction do the errorhandling on this junk } }
public override int Receive(byte[] lpBuf, int offset, int nBufLen, SocketFlags nFlags) { obfuscationBytesReceived_ = base.Receive(lpBuf, offset, nBufLen, nFlags); fullReceive_ = obfuscationBytesReceived_ == (uint)nBufLen; if (obfuscationBytesReceived_ == SOCKET_ERROR || obfuscationBytesReceived_ <= 0) { return(obfuscationBytesReceived_); } switch (streamCryptState_) { case StreamCryptStateEnum.ECS_NONE: // disabled, just pass it through return(obfuscationBytesReceived_); case StreamCryptStateEnum.ECS_PENDING: case StreamCryptStateEnum.ECS_PENDING_SERVER: Debug.Assert(false); MpdUtilities.DebugLogError(("CEncryptedStreamSocket Received data before sending on outgoing connection")); streamCryptState_ = StreamCryptStateEnum.ECS_NONE; return(obfuscationBytesReceived_); case StreamCryptStateEnum.ECS_UNKNOWN: { int nRead = 1; bool bNormalHeader = false; switch (lpBuf[offset]) { case MuleConstants.PROTOCOL_EDONKEYPROT: case MuleConstants.PROTOCOL_PACKEDPROT: case MuleConstants.PROTOCOL_EMULEPROT: bNormalHeader = true; break; } if (!bNormalHeader) { StartNegotiation(false); int nNegRes = Negotiate(lpBuf, offset + nRead, obfuscationBytesReceived_ - nRead); if (nNegRes == (-1)) { return(0); } nRead += nNegRes; if (nRead != obfuscationBytesReceived_) { // this means we have more data then the current negotiation step required (or there is a bug) and this should never happen // (note: even if it just finished the handshake here, there still can be no data left, since the other client didnt received our response yet) MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Client %s sent more data then expected while negotiating, disconnecting (1)"), DbgGetIPString()); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); } return(0); } else { // doesn't seems to be encrypted streamCryptState_ = StreamCryptStateEnum.ECS_NONE; // if we require an encrypted connection, cut the connection here. This shouldn't happen that often // at least with other up-to-date eMule clients because they check for incompability before connecting if possible if (MuleApplication.Instance.Preference.IsClientCryptLayerRequired) { // TODO: Remove me when i have been solved // Even if the Require option is enabled, we currently have to accept unencrypted connection which are made // for lowid/firewall checks from servers and other from us selected client. Otherwise, this option would // always result in a lowid/firewalled status. This is of course not nice, but we can't avoid this walkarround // untill servers and kad completely support encryption too, which will at least for kad take a bit // only exception is the .ini option ClientCryptLayerRequiredStrict which will even ignore test connections // Update: New server now support encrypted callbacks IPEndPoint remote = RemoteEndPoint as IPEndPoint; uint address = BitConverter.ToUInt32(remote.Address.GetAddressBytes(), 0); if (MuleApplication.Instance.Preference.IsClientCryptLayerRequiredStrict || (!MuleApplication.Instance.ServerConnect.AwaitingTestFromIP(address) && !MuleApplication.Instance.ClientList.IsKadFirewallCheckIP(address))) { MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_DEFAULT, false, ("Rejected incoming connection because Obfuscation was required but not used %s"), DbgGetIPString()); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION_NOTALLOWED)); return(0); } else { MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_DEFAULT, false, ("Incoming unencrypted firewallcheck connection permitted despite RequireEncryption setting - %s"), DbgGetIPString()); } } return(obfuscationBytesReceived_); // buffer was unchanged, we can just pass it through } } case StreamCryptStateEnum.ECS_ENCRYPTING: // basic obfuscation enabled and set, so decrypt and pass along MuleUtilities.RC4Crypt(lpBuf, offset, lpBuf, offset, Convert.ToUInt32(obfuscationBytesReceived_), rc4ReceiveKey_); return(obfuscationBytesReceived_); case StreamCryptStateEnum.ECS_NEGOTIATING: { int nRead = Negotiate(lpBuf, offset, obfuscationBytesReceived_); if (nRead == (-1)) { return(0); } else if (nRead != obfuscationBytesReceived_ && streamCryptState_ != StreamCryptStateEnum.ECS_ENCRYPTING) { // this means we have more data then the current negotiation step required (or there is a bug) and this should never happen MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Client %s sent more data then expected while negotiating, disconnecting (2)"), DbgGetIPString()); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); return(0); } else if (nRead != (uint)obfuscationBytesReceived_ && streamCryptState_ == StreamCryptStateEnum.ECS_ENCRYPTING) { // we finished the handshake and if we this was an outgoing connection it is allowed (but strange and unlikely) that the client sent payload MpdUtilities.DebugLogWarning(("CEncryptedStreamSocket: Client %s has finished the handshake but also sent payload on a outgoing connection"), DbgGetIPString()); Array.Copy(lpBuf, offset + nRead, lpBuf, offset + 0, obfuscationBytesReceived_ - nRead); return(obfuscationBytesReceived_ - nRead); } else { return(0); } } default: Debug.Assert(false); return(obfuscationBytesReceived_); } }
protected void LoadList() { string strFileName = System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR), CLIENTS_MET_FILENAME); if (!System.IO.File.Exists(strFileName)) { return; } SafeBufferedFile file = null; try { file = MpdObjectManager.CreateSafeBufferedFile(strFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None); byte version = file.ReadUInt8(); if (version != (byte)VersionsEnum.CREDITFILE_VERSION && version != (byte)VersionsEnum.CREDITFILE_VERSION_29) { file.Close(); return; } // everything is ok, lets see if the backup exist... string strBakFileName = System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR), string.Format("{0}{1}", CLIENTS_MET_FILENAME, ".bak")); uint dwBakFileSize = 0; bool bCreateBackup = true; if (System.IO.File.Exists(strBakFileName)) { FileInfo fInfo = new FileInfo(strBakFileName); dwBakFileSize = (uint)fInfo.Length; if (dwBakFileSize > (uint)file.Length) { // the size of the backup was larger then the org. file, something is wrong here, don't overwrite old backup.. bCreateBackup = false; } } //else: the backup doesn't exist, create it if (bCreateBackup) { file.Close(); // close the file before copying System.IO.File.Copy(strFileName, strBakFileName, true); file = MpdObjectManager.CreateSafeBufferedFile(strFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None); file.Seek(1, SeekOrigin.Begin); //set filepointer behind file version byte } uint count = file.ReadUInt32(); uint dwExpired = MpdUtilities.Time() - 12960000; // today - 150 day uint cDeleted = 0; for (uint i = 0; i < count; i++) { CreditStruct newcstruct = new CreditStruct(); if (version == (byte)VersionsEnum.CREDITFILE_VERSION_29) { ReadCreditStruct29a(file, newcstruct); } else { ReadCreditStruct(file, newcstruct); } if (newcstruct.nLastSeen < dwExpired) { cDeleted++; continue; } ClientCredits newcredits = MuleApplication.Instance.CoreObjectManager.CreateClientCredits(newcstruct); clients_[new MapCKey(newcredits.Key)] = newcredits; } file.Close(); } catch (Exception error) { MpdUtilities.DebugLogError(error); file.Close(); } }
public bool VerifyIdent(ClientCredits pTarget, byte[] pachSignature, byte nInputSize, uint dwForIP, byte byChaIPKind) { if (!IsCryptoAvailable) { pTarget.IdentState = IdentStateEnum.IS_NOTAVAILABLE; return(false); } bool bResult; try { RSAPKCS1SignatureDeformatter pubkey = MpdObjectManager.CreateRSAPKCS1V15SHA1Verifier(pTarget.SecureIdent, pTarget.SecIDKeyLen); // 4 additional bytes random data send from this client +5 bytes v2 byte[] abyBuffer = new byte[CreditStruct.MAXPUBKEYSIZE + 9]; Array.Copy(publicKey_, abyBuffer, publicKeyLen_); uint challenge = pTarget.CryptRndChallengeFor; Array.Copy(BitConverter.GetBytes(challenge), 0, abyBuffer, publicKeyLen_, 4); // v2 security improvments (not supported by 29b, not used as default by 29c) byte nChIpSize = 0; if (byChaIPKind != 0) { nChIpSize = 5; uint ChallengeIP = 0; switch (byChaIPKind) { case CRYPT_CIP_LOCALCLIENT: ChallengeIP = dwForIP; break; case CRYPT_CIP_REMOTECLIENT: if (MuleApplication.Instance.ServerConnect.ClientID == 0 || MuleApplication.Instance.ServerConnect.IsLowID) { ChallengeIP = MuleApplication.Instance.ServerConnect.LocalIP; } else { ChallengeIP = MuleApplication.Instance.ServerConnect.ClientID; } break; case CRYPT_CIP_NONECLIENT: // maybe not supported in future versions ChallengeIP = 0; break; } Array.Copy(BitConverter.GetBytes(ChallengeIP), 0, abyBuffer, publicKeyLen_ + 4, 4); abyBuffer[publicKeyLen_ + 4 + 4] = byChaIPKind; } //v2 end byte[] hash = new byte[publicKeyLen_ + 4 + nChIpSize]; Array.Copy(abyBuffer, hash, publicKeyLen_ + 4 + nChIpSize); byte[] sign = new byte[nInputSize]; Array.Copy(pachSignature, sign, nInputSize); bResult = pubkey.VerifySignature(hash, sign); } catch (Exception ex) { MpdUtilities.DebugLogError(ex); bResult = false; } if (!bResult) { if (pTarget.IdentState == IdentStateEnum.IS_IDNEEDED) { pTarget.IdentState = IdentStateEnum.IS_IDFAILED; } } else { pTarget.Verified(dwForIP); } return(bResult); }
private void SocketManagerThreadFunc() { while (!shutDown_) { List <Socket> readSockets = new List <Socket>(); List <Socket> writeSockets = new List <Socket>(); List <Socket> errorSockets = new List <Socket>(); lock (locker_) { sockets_.Keys.ToList().ForEach(s => { readSockets.Add(s); writeSockets.Add(s); errorSockets.Add(s); }); } if (readSockets.Count == 0) { Thread.Sleep(TIMEOUT); continue; } try { Socket.Select(readSockets, writeSockets, errorSockets, TIMEOUT * 1000); if (shutDown_) { return; } lock (locker_) { readSockets.ForEach(s => { if (!sockets_.ContainsKey(s)) { return; } AsyncSocketImpl socket = sockets_[s]; if (socket.listen_called_) { socket.FireOnAcceptEvent(); } else { socket.FireOnReceiveEvent(); } }); writeSockets.ForEach(s => { if (!sockets_.ContainsKey(s)) { return; } AsyncSocketImpl socket = sockets_[s]; if (socket.Connected && socket.connect_event_fired_) { socket.FireOnSendEvent(); } else { socket.connect_event_fired_ = true; socket.FireOnConnectEvent(); } }); errorSockets.ForEach(s => { if (!sockets_.ContainsKey(s)) { return; } AsyncSocketImpl socket = sockets_[s]; socket.FireOnErrorEvent(10061); }); } } catch (SocketException ex) { MpdUtilities.DebugLogError(string.Format("Socket Exception:{0},{1}", ex.ErrorCode, ex.SocketErrorCode), ex); } catch (Exception ex) { MpdUtilities.DebugLogError(ex); } }//while }
private int Negotiate(byte[] pBuffer, int offset, int nLen) { int nRead = 0; Debug.Assert(receiveBytesWanted_ > 0); try { while (negotiatingState_ != NegotiatingStateEnum.ONS_COMPLETE && receiveBytesWanted_ > 0) { if (receiveBytesWanted_ > 512) { Debug.Assert(false); return(0); } if (fiReceiveBuffer_ == null) { byte[] pReceiveBuffer = new byte[512]; // use a fixed size buffer fiReceiveBuffer_ = MpdObjectManager.CreateSafeMemFile(pReceiveBuffer); } int nToRead = Math.Min(Convert.ToInt32(nLen) - nRead, Convert.ToInt32(receiveBytesWanted_)); fiReceiveBuffer_.Write(pBuffer, nRead, nToRead); nRead += nToRead; receiveBytesWanted_ -= Convert.ToUInt32(nToRead); if (receiveBytesWanted_ > 0) { return(nRead); } uint nCurrentBytesLen = (uint)fiReceiveBuffer_.Position; if (negotiatingState_ != NegotiatingStateEnum.ONS_BASIC_CLIENTA_RANDOMPART && negotiatingState_ != NegotiatingStateEnum.ONS_BASIC_SERVER_DHANSWER) { // don't have the keys yet byte[] pCryptBuffer = fiReceiveBuffer_.Buffer; MuleUtilities.RC4Crypt(pCryptBuffer, pCryptBuffer, nCurrentBytesLen, rc4ReceiveKey_); } fiReceiveBuffer_.SeekToBegin(); switch (negotiatingState_) { case NegotiatingStateEnum.ONS_NONE: // would be a bug Debug.Assert(false); return(0); case NegotiatingStateEnum.ONS_BASIC_CLIENTA_RANDOMPART: { Debug.Assert(rc4ReceiveKey_ == null); byte[] achKeyData = new byte[21]; MpdUtilities.Md4Cpy(achKeyData, MuleApplication.Instance.Preference.UserHash); achKeyData[16] = Convert.ToByte(MuleConstants.MAGICVALUE_REQUESTER); fiReceiveBuffer_.Read(achKeyData, 17, 4); // random key part sent from remote client MD5 md5 = MD5.Create(); rc4ReceiveKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(achKeyData), 16); achKeyData[16] = Convert.ToByte(MuleConstants.MAGICVALUE_SERVER); rc4SendKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(achKeyData), 16); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTA_MAGICVALUE; receiveBytesWanted_ = 4; break; } case NegotiatingStateEnum.ONS_BASIC_CLIENTA_MAGICVALUE: { uint dwValue = fiReceiveBuffer_.ReadUInt32(); if (dwValue == MuleConstants.MAGICVALUE_SYNC) { // yup, the one or the other way it worked, this is an encrypted stream //DEBUG_ONLY( MpdUtilities.DebugLog(("Received proper magic value, clientIP: %s"), DbgGetIPString()) ); // set the receiver key negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTA_METHODTAGSPADLEN; receiveBytesWanted_ = 3; } else { MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Received wrong magic value from clientIP %s on a supposly encrytped stream / Wrong Header"), DbgGetIPString()); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); return(-1); } break; } case NegotiatingStateEnum.ONS_BASIC_CLIENTA_METHODTAGSPADLEN: DbgByEncryptionSupported = fiReceiveBuffer_.ReadUInt8(); DbgByEncryptionRequested = fiReceiveBuffer_.ReadUInt8(); if (DbgByEncryptionRequested != Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION)) { MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_LOW, false, ("CEncryptedStreamSocket: Client %s preffered unsupported encryption method (%i)"), DbgGetIPString(), DbgByEncryptionRequested); } receiveBytesWanted_ = fiReceiveBuffer_.ReadUInt8(); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTA_PADDING; if (receiveBytesWanted_ > 0) { break; } else { goto case NegotiatingStateEnum.ONS_BASIC_CLIENTA_PADDING; } case NegotiatingStateEnum.ONS_BASIC_CLIENTA_PADDING: { // ignore the random bytes, send the response, set status complete SafeMemFile fileResponse = MpdObjectManager.CreateSafeMemFile(26); fileResponse.WriteUInt32(MuleConstants.MAGICVALUE_SYNC); byte bySelectedEncryptionMethod = Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION); // we do not support any further encryption in this version, so no need to look which the other client preferred fileResponse.WriteUInt8(bySelectedEncryptionMethod); IPEndPoint remoteEp = RemoteEndPoint as IPEndPoint; byte byPaddingLen = MuleApplication.Instance.ServerConnect.AwaitingTestFromIP(BitConverter.ToUInt32(remoteEp.Address.GetAddressBytes(), 0)) ? Convert.ToByte(16) : Convert.ToByte(MuleApplication.Instance.Preference.CryptTCPPaddingLength + 1); byte byPadding = Convert.ToByte(MpdUtilities.GetRandomUInt8() % byPaddingLen); fileResponse.WriteUInt8(byPadding); for (int i = 0; i < byPadding; i++) { fileResponse.WriteUInt8(MpdUtilities.GetRandomUInt8()); } SendNegotiatingData(fileResponse.Buffer, (uint)fileResponse.Length); negotiatingState_ = NegotiatingStateEnum.ONS_COMPLETE; streamCryptState_ = StreamCryptStateEnum.ECS_ENCRYPTING; //DEBUG_ONLY( MpdUtilities.DebugLog(("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (incoming)"), DbgGetIPString()) ); break; } case NegotiatingStateEnum.ONS_BASIC_CLIENTB_MAGICVALUE: { if (fiReceiveBuffer_.ReadUInt32() != MuleConstants.MAGICVALUE_SYNC) { MpdUtilities.DebugLogError(("CEncryptedStreamSocket: EncryptedstreamSyncError: Client sent wrong Magic Value as answer, cannot complete handshake (%s)"), DbgGetIPString()); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); return(-1); } negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTB_METHODTAGSPADLEN; receiveBytesWanted_ = 2; break; } case NegotiatingStateEnum.ONS_BASIC_CLIENTB_METHODTAGSPADLEN: { DbgByEncryptionMethodSet = fiReceiveBuffer_.ReadUInt8(); if (DbgByEncryptionMethodSet != Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION)) { MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Client %s set unsupported encryption method (%i), handshake failed"), DbgGetIPString(), DbgByEncryptionMethodSet); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); return(-1); } receiveBytesWanted_ = fiReceiveBuffer_.ReadUInt8(); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_CLIENTB_PADDING; if (receiveBytesWanted_ > 0) { break; } else { goto case NegotiatingStateEnum.ONS_BASIC_CLIENTB_PADDING; } } case NegotiatingStateEnum.ONS_BASIC_CLIENTB_PADDING: // ignore the random bytes, the handshake is complete negotiatingState_ = NegotiatingStateEnum.ONS_COMPLETE; streamCryptState_ = StreamCryptStateEnum.ECS_ENCRYPTING; //DEBUG_ONLY( MpdUtilities.DebugLog(("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (outgoing)"), DbgGetIPString()) ); break; case NegotiatingStateEnum.ONS_BASIC_SERVER_DHANSWER: { Debug.Assert(cryptDHA_ != new BigInteger(0)); byte[] aBuffer = new byte[MuleConstants.PRIMESIZE_BYTES + 1]; fiReceiveBuffer_.Read(aBuffer, 0, Convert.ToInt32(MuleConstants.PRIMESIZE_BYTES)); BigInteger cryptDHAnswer = new BigInteger(aBuffer, (int)MuleConstants.PRIMESIZE_BYTES); BigInteger cryptDHPrime = new BigInteger(dh768_p_, (int)MuleConstants.PRIMESIZE_BYTES); // our fixed prime BigInteger cryptResult = cryptDHAnswer.modPow(cryptDHA_, cryptDHPrime); cryptDHA_ = 0; Array.Clear(aBuffer, 0, aBuffer.Length); // create the keys Array.Copy(cryptResult.getBytes(), aBuffer, MuleConstants.PRIMESIZE_BYTES); aBuffer[MuleConstants.PRIMESIZE_BYTES] = Convert.ToByte(MuleConstants.MAGICVALUE_REQUESTER); MD5 md5 = MD5.Create(); rc4SendKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(aBuffer), 16); aBuffer[MuleConstants.PRIMESIZE_BYTES] = Convert.ToByte(MuleConstants.MAGICVALUE_SERVER); rc4ReceiveKey_ = MuleUtilities.RC4CreateKey(md5.ComputeHash(aBuffer), 16); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_SERVER_MAGICVALUE; receiveBytesWanted_ = 4; break; } case NegotiatingStateEnum.ONS_BASIC_SERVER_MAGICVALUE: { uint dwValue = fiReceiveBuffer_.ReadUInt32(); if (dwValue == MuleConstants.MAGICVALUE_SYNC) { // yup, the one or the other way it worked, this is an encrypted stream MpdUtilities.DebugLog(("Received proper magic value after DH-Agreement from Serverconnection IP: %s"), DbgGetIPString()); // set the receiver key negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_SERVER_METHODTAGSPADLEN; receiveBytesWanted_ = 3; } else { MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Received wrong magic value after DH-Agreement from Serverconnection"), DbgGetIPString()); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); return(-1); } break; } case NegotiatingStateEnum.ONS_BASIC_SERVER_METHODTAGSPADLEN: DbgByEncryptionSupported = fiReceiveBuffer_.ReadUInt8(); DbgByEncryptionRequested = fiReceiveBuffer_.ReadUInt8(); if (DbgByEncryptionRequested != Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION)) { MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_LOW, false, ("CEncryptedStreamSocket: Server %s preffered unsupported encryption method (%i)"), DbgGetIPString(), DbgByEncryptionRequested); } receiveBytesWanted_ = fiReceiveBuffer_.ReadUInt8(); negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_SERVER_PADDING; if (receiveBytesWanted_ > 16) { MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_LOW, false, ("CEncryptedStreamSocket: Server %s sent more than 16 (%i) padding bytes"), DbgGetIPString(), receiveBytesWanted_); } if (receiveBytesWanted_ > 0) { break; } else { goto case NegotiatingStateEnum.ONS_BASIC_SERVER_PADDING; } case NegotiatingStateEnum.ONS_BASIC_SERVER_PADDING: { // ignore the random bytes (they are decrypted already), send the response, set status complete SafeMemFile fileResponse = MpdObjectManager.CreateSafeMemFile(26); fileResponse.WriteUInt32(MuleConstants.MAGICVALUE_SYNC); byte bySelectedEncryptionMethod = Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION); // we do not support any further encryption in this version, so no need to look which the other client preferred fileResponse.WriteUInt8(bySelectedEncryptionMethod); byte byPadding = (byte)(MpdUtilities.GetRandomUInt8() % 16); fileResponse.WriteUInt8(byPadding); for (int i = 0; i < byPadding; i++) { fileResponse.WriteUInt8(MpdUtilities.GetRandomUInt8()); } negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_SERVER_DELAYEDSENDING; SendNegotiatingData(fileResponse.Buffer, (uint)fileResponse.Length, 0, true); // don't actually send it right now, store it in our sendbuffer streamCryptState_ = StreamCryptStateEnum.ECS_ENCRYPTING; MpdUtilities.DebugLog(("CEncryptedStreamSocket: Finished DH Obufscation handshake with Server %s"), DbgGetIPString()); break; } default: Debug.Assert(false); break; } fiReceiveBuffer_.SeekToBegin(); } fiReceiveBuffer_ = null; return(nRead); } catch (Exception) { Debug.Assert(false); OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION)); fiReceiveBuffer_ = null; return(-1); } }
public void Stop() { try { CloseConnection(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { ServerConnect.Stop(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { ClientUDP.Close(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { ListenSocket.StopListening(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { LastCommonRouteFinder.StopFinder(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { UploadBandwidthThrottler.Stop(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { Preference.Save(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { ClientCredits.CleanUp(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } if (ShutDownMuleApplication != null) { ShutDownMuleApplication(this, new EventArgs()); } }
protected override void OnReceive(int nErrorCode) { byte[] buffer = new byte[5000]; EndPoint endPoint = null; int nRealLen = ReceiveFrom(buffer, ref endPoint); IPEndPoint ipEndPoint = endPoint as IPEndPoint; uint dwIP = 0; if (ipEndPoint != null) { dwIP = BitConverter.ToUInt32(ipEndPoint.Address.GetAddressBytes(), 0); } if (ipEndPoint != null && !(MuleApplication.Instance.IPFilter.IsFiltered(dwIP) || MuleApplication.Instance.ClientList.IsBannedClient(dwIP))) { byte[] pBuffer; uint nReceiverVerifyKey; uint nSenderVerifyKey; int nPacketLen = DecryptReceivedClient(buffer, nRealLen, out pBuffer, dwIP, out nReceiverVerifyKey, out nSenderVerifyKey); if (nPacketLen >= 1) { try { switch (pBuffer[0]) { case MuleConstants.PROTOCOL_EMULEPROT: { if (nPacketLen >= 2) { ProcessPacket(pBuffer, 2, (uint)nPacketLen - 2, pBuffer[1], dwIP, (ushort)IPAddress.NetworkToHostOrder(ipEndPoint.Port)); } else { throw new MuleException("eMule packet too short"); } break; } case MuleConstants.PROTOCOL_KADEMLIAPACKEDPROT: { MuleApplication.Instance.Statistics.AddDownDataOverheadKad((uint)nPacketLen); if (nPacketLen >= 2) { byte[] unpack = null; byte[] unpackTmp = null; if (MpdUtilities.Decompress(pBuffer, 2, (uint)nPacketLen - 2, out unpackTmp)) { unpack = new byte[unpackTmp.Length + 2]; Array.Copy(unpackTmp, 0, unpack, 2, unpackTmp.Length); unpack[0] = MuleConstants.PROTOCOL_KADEMLIAHEADER; unpack[1] = pBuffer[1]; try { MuleApplication.Instance.KadEngine.ProcessPacket(unpack, (uint)unpack.Length, dwIP, (ushort)IPAddress.NetworkToHostOrder(ipEndPoint.Port), MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP) == nReceiverVerifyKey, MuleApplication.Instance.KadObjectManager.CreateKadUDPKey(nSenderVerifyKey, (uint)MuleApplication.Instance.GetPublicIP(false))); } catch { throw; } } else { throw new MuleException("Failed to uncompress Kad packet!"); } } else { throw new MuleException("Kad packet (compressed) too short"); } break; } case MuleConstants.PROTOCOL_KADEMLIAHEADER: { MuleApplication.Instance.Statistics.AddDownDataOverheadKad((uint)nPacketLen); if (nPacketLen >= 2) { MuleApplication.Instance.KadEngine.ProcessPacket(pBuffer, (uint)nPacketLen, dwIP, (ushort)ipEndPoint.Port, MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP) == nReceiverVerifyKey, MuleApplication.Instance.KadObjectManager.CreateKadUDPKey(nSenderVerifyKey, (uint)MuleApplication.Instance.GetPublicIP(false))); } else { throw new MuleException("Kad packet too short"); } break; } default: { throw new MuleException(string.Format("Unknown protocol 0x{0}", pBuffer[0])); } } } catch (Exception error) { MpdUtilities.DebugLogError(error); } } } }