mirror of
https://github.com/znc/znc.git
synced 2026-08-06 08:52:57 +02:00
Avoid a possibly expensive FindSockByName() for finding IRC socks
While a user is connecting to an IRC server, the CUser instance didn't know about the CIRCSock instance (due to historic reasons). This meant that we needed to use FindSockByName() when we had to check if there is any CIRCSock associated with this user. However, this is a bad idea since FindSockByName() is O(n) on the number of sockets that the socket manager is managing. Instead, we now already set CUser::m_pIRCSock when the CIRCSock is created so that checking for an irc socket becomes O(1). This was inspired by the results of profiling a znc instance with 900 users. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@2171 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
+5
-14
@@ -245,13 +245,11 @@ void CClient::UserCommand(CString& sLine) {
|
|||||||
}
|
}
|
||||||
m_pUser->SetNextServer(pServer);
|
m_pUser->SetNextServer(pServer);
|
||||||
|
|
||||||
if (!GetIRCSock()) {
|
// If we are already connecting to some server,
|
||||||
// If we are already connecting to some server,
|
// we have to abort that attempt
|
||||||
// we have to abort that attempt
|
Csock *pIRCSock = GetIRCSock();
|
||||||
Csock *pIRCSock = CZNC::Get().GetManager()
|
if (pIRCSock && !pIRCSock->IsConnected()) {
|
||||||
.FindSockByName("IRC::" + m_pUser->GetUserName());
|
pIRCSock->Close();
|
||||||
if (pIRCSock)
|
|
||||||
pIRCSock->Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,13 +276,6 @@ void CClient::UserCommand(CString& sLine) {
|
|||||||
if (GetIRCSock()) {
|
if (GetIRCSock()) {
|
||||||
CString sQuitMsg = sLine.Token(1, true);
|
CString sQuitMsg = sLine.Token(1, true);
|
||||||
GetIRCSock()->Quit(sQuitMsg);
|
GetIRCSock()->Quit(sQuitMsg);
|
||||||
} else {
|
|
||||||
Csock* pIRCSock;
|
|
||||||
CString sSockName = "IRC::" + m_pUser->GetUserName();
|
|
||||||
// This is *slow*, we try to avoid doing this
|
|
||||||
pIRCSock = CZNC::Get().GetManager().FindSockByName(sSockName);
|
|
||||||
if (pIRCSock)
|
|
||||||
pIRCSock->Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pUser->SetIRCConnectEnabled(false);
|
m_pUser->SetIRCConnectEnabled(false);
|
||||||
|
|||||||
+6
-1
@@ -38,6 +38,8 @@ CIRCSock::CIRCSock(CUser* pUser) : CZNCSock() {
|
|||||||
m_mueChanModes['i'] = NoArg;
|
m_mueChanModes['i'] = NoArg;
|
||||||
m_mueChanModes['n'] = NoArg;
|
m_mueChanModes['n'] = NoArg;
|
||||||
|
|
||||||
|
pUser->SetIRCSocket(this);
|
||||||
|
|
||||||
// RFC says a line can have 512 chars max, but we don't care ;)
|
// RFC says a line can have 512 chars max, but we don't care ;)
|
||||||
SetMaxBufferThreshold(1024);
|
SetMaxBufferThreshold(1024);
|
||||||
}
|
}
|
||||||
@@ -65,6 +67,10 @@ CIRCSock::~CIRCSock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CIRCSock::Quit(const CString& sQuitMsg) {
|
void CIRCSock::Quit(const CString& sQuitMsg) {
|
||||||
|
if (!m_bAuthed) {
|
||||||
|
Close(CLT_NOW);
|
||||||
|
return;
|
||||||
|
}
|
||||||
CString sMsg = (!sQuitMsg.empty()) ? sQuitMsg : m_pUser->GetQuitMsg();
|
CString sMsg = (!sQuitMsg.empty()) ? sQuitMsg : m_pUser->GetQuitMsg();
|
||||||
PutIRC("QUIT :" + sMsg);
|
PutIRC("QUIT :" + sMsg);
|
||||||
Close(CLT_AFTERWRITE);
|
Close(CLT_AFTERWRITE);
|
||||||
@@ -920,7 +926,6 @@ void CIRCSock::SetNick(const CString& sNick) {
|
|||||||
|
|
||||||
void CIRCSock::Connected() {
|
void CIRCSock::Connected() {
|
||||||
DEBUG(GetSockName() << " == Connected()");
|
DEBUG(GetSockName() << " == Connected()");
|
||||||
m_pUser->IRCConnected(this);
|
|
||||||
|
|
||||||
CString sPass = m_sPass;
|
CString sPass = m_sPass;
|
||||||
CString sNick = m_pUser->GetNick();
|
CString sNick = m_pUser->GetNick();
|
||||||
|
|||||||
@@ -131,11 +131,15 @@ const CString& CNick::GetNick() const { return m_sNick; }
|
|||||||
const CString& CNick::GetIdent() const { return m_sIdent; }
|
const CString& CNick::GetIdent() const { return m_sIdent; }
|
||||||
const CString& CNick::GetHost() const { return m_sHost; }
|
const CString& CNick::GetHost() const { return m_sHost; }
|
||||||
CString CNick::GetNickMask() const {
|
CString CNick::GetNickMask() const {
|
||||||
if (m_sNick.find('.') != CString::npos) {
|
CString sRet = m_sNick;
|
||||||
return m_sNick;
|
|
||||||
|
if (!m_sHost.empty()) {
|
||||||
|
if (!m_sIdent.empty())
|
||||||
|
sRet += "!" + m_sIdent;
|
||||||
|
sRet += "@" + m_sHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (m_sNick + "!" + m_sIdent + "@" + m_sHost);
|
return sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
CString CNick::GetHostMask() const {
|
CString CNick::GetHostMask() const {
|
||||||
|
|||||||
@@ -157,10 +157,23 @@ void CUser::DelServers()
|
|||||||
m_vServers.clear();
|
m_vServers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUser::IRCConnected(CIRCSock* pIRCSock) {
|
void CUser::SetIRCSocket(CIRCSock* pIRCSock) {
|
||||||
m_pIRCSock = pIRCSock;
|
m_pIRCSock = pIRCSock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CUser::IsIRCConnected() const
|
||||||
|
{
|
||||||
|
const CIRCSock* pSock = GetIRCSock();
|
||||||
|
|
||||||
|
if (!pSock)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!pSock->IsConnected())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void CUser::IRCDisconnected() {
|
void CUser::IRCDisconnected() {
|
||||||
m_pIRCSock = NULL;
|
m_pIRCSock = NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ public:
|
|||||||
|
|
||||||
CString GetLocalIP();
|
CString GetLocalIP();
|
||||||
CString GetLocalDCCIP();
|
CString GetLocalDCCIP();
|
||||||
bool IsIRCConnected() const { return GetIRCSock() != NULL; }
|
bool IsIRCConnected() const;
|
||||||
void IRCConnected(CIRCSock* pIRCSock);
|
void SetIRCSocket(CIRCSock* pIRCSock);
|
||||||
void IRCDisconnected();
|
void IRCDisconnected();
|
||||||
void CheckIRCConnect();
|
void CheckIRCConnect();
|
||||||
|
|
||||||
|
|||||||
@@ -111,9 +111,7 @@ bool CZNC::OnBoot() {
|
|||||||
|
|
||||||
bool CZNC::ConnectUser(CUser *pUser) {
|
bool CZNC::ConnectUser(CUser *pUser) {
|
||||||
CString sSockName = "IRC::" + pUser->GetUserName();
|
CString sSockName = "IRC::" + pUser->GetUserName();
|
||||||
// Don't use pUser->GetIRCSock(), as that only returns something if the
|
CIRCSock* pIRCSock = pUser->GetIRCSock();
|
||||||
// CIRCSock is already connected, not when it's still connecting!
|
|
||||||
CIRCSock* pIRCSock = (CIRCSock*) m_Manager.FindSockByName(sSockName);
|
|
||||||
|
|
||||||
if (m_pISpoofLockFile != NULL) {
|
if (m_pISpoofLockFile != NULL) {
|
||||||
return false;
|
return false;
|
||||||
@@ -192,9 +190,7 @@ bool CZNC::HandleUserDeletion()
|
|||||||
}
|
}
|
||||||
m_msUsers.erase(pUser->GetUserName());
|
m_msUsers.erase(pUser->GetUserName());
|
||||||
|
|
||||||
// Don't use pUser->GetIRCSock(), as that only returns something if the
|
CIRCSock* pIRCSock = pUser->GetIRCSock();
|
||||||
// CIRCSock is already connected, not when it's still connecting!
|
|
||||||
CIRCSock* pIRCSock = (CIRCSock*) m_Manager.FindSockByName("IRC::" + pUser->GetUserName());
|
|
||||||
|
|
||||||
if (pIRCSock) {
|
if (pIRCSock) {
|
||||||
m_Manager.DelSockByAddr(pIRCSock);
|
m_Manager.DelSockByAddr(pIRCSock);
|
||||||
@@ -401,10 +397,6 @@ void CZNC::DeleteUsers() {
|
|||||||
DisableConnectUser();
|
DisableConnectUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
Csock* CZNC::FindSockByName(const CString& sSockName) {
|
|
||||||
return m_Manager.FindSockByName(sSockName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CZNC::IsHostAllowed(const CString& sHostMask) const {
|
bool CZNC::IsHostAllowed(const CString& sHostMask) const {
|
||||||
for (map<CString,CUser*>::const_iterator a = m_msUsers.begin(); a != m_msUsers.end(); ++a) {
|
for (map<CString,CUser*>::const_iterator a = m_msUsers.begin(); a != m_msUsers.end(); ++a) {
|
||||||
if (a->second->IsHostAllowed(sHostMask)) {
|
if (a->second->IsHostAllowed(sHostMask)) {
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ public:
|
|||||||
bool WritePidFile(int iPid);
|
bool WritePidFile(int iPid);
|
||||||
bool DeletePidFile();
|
bool DeletePidFile();
|
||||||
bool WaitForChildLock();
|
bool WaitForChildLock();
|
||||||
Csock* FindSockByName(const CString& sSockName);
|
|
||||||
bool IsHostAllowed(const CString& sHostMask) const;
|
bool IsHostAllowed(const CString& sHostMask) const;
|
||||||
// This returns false if there are too many anonymous connections from this ip
|
// This returns false if there are too many anonymous connections from this ip
|
||||||
bool AllowConnectionFrom(const CString& sIP) const;
|
bool AllowConnectionFrom(const CString& sIP) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user