diff --git a/Client.cpp b/Client.cpp index b16442b5..e697fda6 100644 --- a/Client.cpp +++ b/Client.cpp @@ -395,7 +395,7 @@ void CClient::ReadLine(const CString& sData) { unsigned long uLongIP = sCTCP.Token(3).ToULong(); unsigned short uPort = sCTCP.Token(4).ToUShort(); unsigned long uFileSize = sCTCP.Token(5).ToULong(); - CString sIP = (m_pIRCSock) ? m_pIRCSock->GetLocalIP() : GetLocalIP(); + CString sIP = m_pUser->GetLocalDCCIP(); if (!m_pUser->UseClientIP()) { uLongIP = CUtils::GetLongIP(GetRemoteIP()); @@ -403,7 +403,7 @@ void CClient::ReadLine(const CString& sData) { if (sType.Equals("CHAT")) { if (!sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) { - unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, "", true, m_pUser, (m_pIRCSock) ? m_pIRCSock->GetLocalIP() : GetLocalIP(), ""); + unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, "", true, m_pUser, ""); if (uBNCPort) { PutIRC("PRIVMSG " + sTarget + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + "\001"); } @@ -434,7 +434,7 @@ void CClient::ReadLine(const CString& sData) { MODULECALL(OnDCCUserSend(CString(m_pUser->GetStatusPrefix() + sTarget), uLongIP, uPort, sFile, uFileSize), m_pUser, this, return); } } else { - unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, sFile, false, m_pUser, (m_pIRCSock) ? m_pIRCSock->GetLocalIP() : GetLocalIP(), ""); + unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, sFile, false, m_pUser, ""); if (uBNCPort) { PutIRC("PRIVMSG " + sTarget + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001"); } diff --git a/DCCBounce.cpp b/DCCBounce.cpp index b2f43f7f..3eb93a01 100644 --- a/DCCBounce.cpp +++ b/DCCBounce.cpp @@ -17,7 +17,7 @@ const unsigned int CDCCBounce::m_uiMinDCCBuffer = 2 * 1024; CDCCBounce::CDCCBounce(CUser* pUser, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, const CString& sRemoteNick, - const CString& sRemoteIP, CString sLocalIP, bool bIsChat) : CZNCSock() { + const CString& sRemoteIP, bool bIsChat) : CZNCSock() { m_uRemotePort = uPort; m_sConnectIP = CUtils::GetIP(uLongIP); m_sRemoteIP = sRemoteIP; @@ -25,7 +25,7 @@ CDCCBounce::CDCCBounce(CUser* pUser, unsigned long uLongIP, unsigned short uPort m_sRemoteNick = sRemoteNick; m_pUser = pUser; m_bIsChat = bIsChat; - m_sLocalIP = sLocalIP; + m_sLocalIP = pUser->GetLocalDCCIP(); m_pPeer = NULL; m_bIsRemote = false; @@ -205,9 +205,10 @@ void CDCCBounce::PutPeer(const CString& sLine) { } } -unsigned short CDCCBounce::DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CUser* pUser, const CString& sLocalIP, const CString& sRemoteIP) { - CDCCBounce* pDCCBounce = new CDCCBounce(pUser, uLongIP, uPort, sFileName, sNick, sRemoteIP, sLocalIP, bIsChat); - unsigned short uListenPort = CZNC::Get().GetManager().ListenRand("DCC::" + CString((bIsChat) ? "Chat" : "Xfer") + "::Local::" + sNick, sLocalIP, false, SOMAXCONN, pDCCBounce, 120); +unsigned short CDCCBounce::DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CUser* pUser, const CString& sRemoteIP) { + CDCCBounce* pDCCBounce = new CDCCBounce(pUser, uLongIP, uPort, sFileName, sNick, sRemoteIP, bIsChat); + unsigned short uListenPort = CZNC::Get().GetManager().ListenRand("DCC::" + CString((bIsChat) ? "Chat" : "Xfer") + "::Local::" + sNick, + pUser->GetLocalDCCIP(), false, SOMAXCONN, pDCCBounce, 120); return uListenPort; } diff --git a/DCCBounce.h b/DCCBounce.h index 67c0b563..4d522a14 100644 --- a/DCCBounce.h +++ b/DCCBounce.h @@ -17,13 +17,13 @@ class CDCCBounce : public CZNCSock { public: CDCCBounce(CUser* pUser, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, const CString& sRemoteNick, - const CString& sRemoteIP, CString sLocalIP, bool bIsChat = false); + const CString& sRemoteIP, bool bIsChat = false); CDCCBounce(const CString& sHostname, unsigned short uPort, CUser* pUser, const CString& sRemoteNick, const CString& sRemoteIP, const CString& sFileName, int iTimeout = 60, bool bIsChat = false); virtual ~CDCCBounce(); - static unsigned short DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CUser* pUser, const CString& sLocalIP, const CString& sRemoteIP); + static unsigned short DCCRequest(const CString& sNick, unsigned long uLongIP, unsigned short uPort, const CString& sFileName, bool bIsChat, CUser* pUser, const CString& sRemoteIP); void ReadLine(const CString& sData); virtual void ReadData(const char* data, int len); diff --git a/IRCSock.cpp b/IRCSock.cpp index cd18b30d..6dbaa2ed 100644 --- a/IRCSock.cpp +++ b/IRCSock.cpp @@ -650,15 +650,17 @@ bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) { if (sType.Equals("CHAT")) { CNick FromNick(Nick.GetNickMask()); - unsigned short uBNCPort = CDCCBounce::DCCRequest(FromNick.GetNick(), uLongIP, uPort, "", true, m_pUser, GetLocalIP(), CUtils::GetIP(uLongIP)); + unsigned short uBNCPort = CDCCBounce::DCCRequest(FromNick.GetNick(), uLongIP, uPort, "", true, m_pUser, CUtils::GetIP(uLongIP)); if (uBNCPort) { - m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(GetLocalIP())) + " " + CString(uBNCPort) + "\001"); + CString sIP = m_pUser->GetLocalDCCIP(); + m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + "\001"); } } else if (sType.Equals("SEND")) { // DCC SEND readme.txt 403120438 5550 1104 - unsigned short uBNCPort = CDCCBounce::DCCRequest(Nick.GetNick(), uLongIP, uPort, sFile, false, m_pUser, GetLocalIP(), CUtils::GetIP(uLongIP)); + unsigned short uBNCPort = CDCCBounce::DCCRequest(Nick.GetNick(), uLongIP, uPort, sFile, false, m_pUser, CUtils::GetIP(uLongIP)); if (uBNCPort) { - m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(GetLocalIP())) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001"); + CString sIP = m_pUser->GetLocalDCCIP(); + m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + GetNick() + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001"); } } else if (sType.Equals("RESUME")) { // Need to lookup the connection by port, filter the port, and forward to the user diff --git a/User.cpp b/User.cpp index 1b51e4ab..f026669c 100644 --- a/User.cpp +++ b/User.cpp @@ -330,6 +330,7 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneChans) { SetRealName(User.GetRealName()); SetStatusPrefix(User.GetStatusPrefix()); SetVHost(User.GetVHost()); + SetDCCVHost(User.GetDCCVHost()); SetQuitMsg(User.GetQuitMsg()); SetDefaultChanModes(User.GetDefaultChanModes()); SetBufferCount(User.GetBufferCount()); @@ -614,6 +615,7 @@ bool CUser::WriteConfig(CFile& File) { PrintLine(File, "Ident", GetIdent()); PrintLine(File, "RealName", GetRealName()); PrintLine(File, "VHost", GetVHost()); + PrintLine(File, "DCCVHost", GetDCCVHost()); PrintLine(File, "QuitMsg", GetQuitMsg()); if (CZNC::Get().GetStatusPrefix() != GetStatusPrefix()) PrintLine(File, "StatusPrefix", GetStatusPrefix()); @@ -933,6 +935,12 @@ CString CUser::GetLocalIP() { return ""; } +CString CUser::GetLocalDCCIP() { + if (!GetDCCVHost().empty()) + return GetDCCVHost(); + return GetLocalIP(); +} + bool CUser::PutIRC(const CString& sLine) { CIRCSock* pIRCSock = GetIRCSock(); @@ -1032,13 +1040,13 @@ bool CUser::SendFile(const CString& sRemoteNick, const CString& sFileName, const return false; } - unsigned short uPort = CZNC::Get().GetManager().ListenRand("DCC::LISTEN::" + sRemoteNick, GetLocalIP(), false, SOMAXCONN, pSock, 120); + unsigned short uPort = CZNC::Get().GetManager().ListenRand("DCC::LISTEN::" + sRemoteNick, GetLocalDCCIP(), false, SOMAXCONN, pSock, 120); if (GetNick().Equals(sRemoteNick)) { - PutUser(":" + GetStatusPrefix() + "status!znc@znc.in PRIVMSG " + sRemoteNick + " :\001DCC SEND " + pFile->GetShortName() + " " + CString(CUtils::GetLongIP(GetLocalIP())) + " " + PutUser(":" + GetStatusPrefix() + "status!znc@znc.in PRIVMSG " + sRemoteNick + " :\001DCC SEND " + pFile->GetShortName() + " " + CString(CUtils::GetLongIP(GetLocalDCCIP())) + " " + CString(uPort) + " " + CString(pFile->GetSize()) + "\001"); } else { - PutIRC("PRIVMSG " + sRemoteNick + " :\001DCC SEND " + pFile->GetShortName() + " " + CString(CUtils::GetLongIP(GetLocalIP())) + " " + PutIRC("PRIVMSG " + sRemoteNick + " :\001DCC SEND " + pFile->GetShortName() + " " + CString(CUtils::GetLongIP(GetLocalDCCIP())) + " " + CString(uPort) + " " + CString(pFile->GetSize()) + "\001"); } @@ -1059,7 +1067,7 @@ bool CUser::GetFile(const CString& sRemoteNick, const CString& sRemoteIP, unsign return false; } - if (!CZNC::Get().GetManager().Connect(sRemoteIP, uRemotePort, "DCC::GET::" + sRemoteNick, 60, false, GetLocalIP(), pSock)) { + if (!CZNC::Get().GetManager().Connect(sRemoteIP, uRemotePort, "DCC::GET::" + sRemoteNick, 60, false, GetLocalDCCIP(), pSock)) { PutModule(sModuleName, "DCC <- [" + sRemoteNick + "][" + sFileName + "] - Unable to connect."); return false; } @@ -1106,6 +1114,7 @@ void CUser::SetAltNick(const CString& s) { m_sAltNick = s; } void CUser::SetIdent(const CString& s) { m_sIdent = s; } void CUser::SetRealName(const CString& s) { m_sRealName = s; } void CUser::SetVHost(const CString& s) { m_sVHost = s; } +void CUser::SetDCCVHost(const CString& s) { m_sDCCVHost = s; } void CUser::SetPass(const CString& s, eHashType eHash, const CString& sSalt) { m_sPass = s; m_eHashType = eHash; @@ -1165,6 +1174,7 @@ const CString& CUser::GetAltNick(bool bAllowDefault) const { return (bAllowDefau const CString& CUser::GetIdent(bool bAllowDefault) const { return (bAllowDefault && m_sIdent.empty()) ? GetCleanUserName() : m_sIdent; } const CString& CUser::GetRealName() const { return m_sRealName.empty() ? m_sUserName : m_sRealName; } const CString& CUser::GetVHost() const { return m_sVHost; } +const CString& CUser::GetDCCVHost() const { return m_sDCCVHost; } const CString& CUser::GetPass() const { return m_sPass; } CUser::eHashType CUser::GetPassHashType() const { return m_eHashType; } const CString& CUser::GetPassSalt() const { return m_sPassSalt; } diff --git a/User.h b/User.h index c3e692db..cc9dc769 100644 --- a/User.h +++ b/User.h @@ -111,6 +111,7 @@ public: void UserDisconnected(CClient* pClient); CString GetLocalIP(); + CString GetLocalDCCIP(); bool IsIRCConnected() const { return GetIRCSock() != NULL; } void IRCConnected(CIRCSock* pIRCSock); void IRCDisconnected(); @@ -144,6 +145,7 @@ public: void SetIdent(const CString& s); void SetRealName(const CString& s); void SetVHost(const CString& s); + void SetDCCVHost(const CString& s); void SetPass(const CString& s, eHashType eHash, const CString& sSalt = ""); void SetBounceDCCs(bool b); void SetMultiClients(bool b); @@ -181,6 +183,7 @@ public: const CString& GetIdent(bool bAllowDefault = true) const; const CString& GetRealName() const; const CString& GetVHost() const; + const CString& GetDCCVHost() const; const CString& GetPass() const; eHashType GetPassHashType() const; const CString& GetPassSalt() const; @@ -230,6 +233,7 @@ protected: CString m_sIdent; CString m_sRealName; CString m_sVHost; + CString m_sDCCVHost; CString m_sPass; CString m_sPassSalt; CString m_sStatusPrefix; diff --git a/znc.cpp b/znc.cpp index e7a9329f..54ef1cdd 100644 --- a/znc.cpp +++ b/znc.cpp @@ -1312,6 +1312,9 @@ bool CZNC::DoRehash(CString& sError) } else if (sName.Equals("VHost")) { pUser->SetVHost(sValue); continue; + } else if (sName.Equals("DCCVHost")) { + pUser->SetDCCVHost(sValue); + continue; } else if (sName.Equals("Allow")) { pUser->AddAllowedHost(sValue); continue;