mirror of
https://github.com/znc/znc.git
synced 2026-08-07 17:33:34 +02:00
Added ipv6 support and multiple listen ports
git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@641 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
+3
-1
@@ -1,11 +1,12 @@
|
||||
#include "main.h"
|
||||
#include "Server.h"
|
||||
|
||||
CServer::CServer(const CString& sName, unsigned short uPort, const CString& sPass, bool bSSL) {
|
||||
CServer::CServer(const CString& sName, unsigned short uPort, const CString& sPass, bool bSSL, bool bIPV6) {
|
||||
m_sName = sName;
|
||||
m_uPort = (uPort) ? uPort : 6667;
|
||||
m_sPass = sPass;
|
||||
m_bSSL = bSSL;
|
||||
m_bIPV6 = bIPV6;
|
||||
}
|
||||
|
||||
CServer::~CServer() {}
|
||||
@@ -30,6 +31,7 @@ const CString& CServer::GetName() const { return m_sName; }
|
||||
unsigned short CServer::GetPort() const { return m_uPort; }
|
||||
const CString& CServer::GetPass() const { return m_sPass; }
|
||||
bool CServer::IsSSL() const { return m_bSSL; }
|
||||
bool CServer::IsIPV6() const { return m_bIPV6; }
|
||||
|
||||
CString CServer::GetString() const {
|
||||
return m_sName + " " + CString(m_bSSL ? "+" : "") + CString::ToString(m_uPort) + CString(m_sPass.empty() ? CString("") : " " + m_sPass);
|
||||
|
||||
@@ -5,13 +5,14 @@
|
||||
|
||||
class CServer {
|
||||
public:
|
||||
CServer(const CString& sName, unsigned short uPort = 6667, const CString& sPass = "", bool bSSL = false);
|
||||
CServer(const CString& sName, unsigned short uPort = 6667, const CString& sPass = "", bool bSSL = false, bool bIPV6 = false);
|
||||
virtual ~CServer();
|
||||
|
||||
const CString& GetName() const;
|
||||
unsigned short GetPort() const;
|
||||
const CString& GetPass() const;
|
||||
bool IsSSL() const;
|
||||
bool IsIPV6() const;
|
||||
CString GetString() const;
|
||||
static bool IsValidHostName(const CString& sHostName);
|
||||
private:
|
||||
@@ -20,6 +21,7 @@ protected:
|
||||
unsigned short m_uPort;
|
||||
CString m_sPass;
|
||||
bool m_bSSL;
|
||||
bool m_bIPV6;
|
||||
};
|
||||
|
||||
#endif // !_SERVER_H
|
||||
|
||||
@@ -597,7 +597,7 @@ bool CUser::DelServer(const CString& sName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CUser::AddServer(const CString& sName) {
|
||||
bool CUser::AddServer(const CString& sName, bool bIPV6) {
|
||||
if (sName.empty()) {
|
||||
return false;
|
||||
}
|
||||
@@ -617,15 +617,22 @@ bool CUser::AddServer(const CString& sName) {
|
||||
unsigned short uPort = strtoul(sPort.c_str(), NULL, 10);
|
||||
CString sPass = sLine.Token(2, true);
|
||||
|
||||
return AddServer(sHost, uPort, sPass, bSSL);
|
||||
return AddServer(sHost, uPort, sPass, bSSL, bIPV6);
|
||||
}
|
||||
|
||||
bool CUser::AddServer(const CString& sName, unsigned short uPort, const CString& sPass, bool bSSL) {
|
||||
bool CUser::AddServer(const CString& sName, unsigned short uPort, const CString& sPass, bool bSSL, bool bIPV6) {
|
||||
#ifndef HAVE_LIBSSL
|
||||
if (bSSL) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_IPV6
|
||||
if (bIPV6) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sName.empty()) {
|
||||
return false;
|
||||
}
|
||||
@@ -634,7 +641,7 @@ bool CUser::AddServer(const CString& sName, unsigned short uPort, const CString&
|
||||
uPort = 6667;
|
||||
}
|
||||
|
||||
CServer* pServer = new CServer(sName, uPort, sPass, bSSL);
|
||||
CServer* pServer = new CServer(sName, uPort, sPass, bSSL, bIPV6);
|
||||
m_vServers.push_back(pServer);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -39,8 +39,8 @@ public:
|
||||
void JoinChans();
|
||||
CServer* FindServer(const CString& sName);
|
||||
bool DelServer(const CString& sName);
|
||||
bool AddServer(const CString& sName);
|
||||
bool AddServer(const CString& sName, unsigned short uPort, const CString& sPass = "", bool bSSL = false);
|
||||
bool AddServer(const CString& sName, bool bIPV6 = false);
|
||||
bool AddServer(const CString& sName, unsigned short uPort, const CString& sPass = "", bool bSSL = false, bool bIPV6 = false);
|
||||
CServer* GetNextServer();
|
||||
CServer* GetCurrentServer();
|
||||
bool CheckPass(const CString& sPass);
|
||||
|
||||
@@ -161,8 +161,8 @@ int main(int argc, char** argv, char** envp) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!pZNC->GetListenPort()) {
|
||||
CUtils::PrintError("You must supply a ListenPort in your config.");
|
||||
if (!pZNC->GetListeners().size()) {
|
||||
CUtils::PrintError("You must supply at least one Listen port in your config.");
|
||||
delete pZNC;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ CZNC::CZNC() {
|
||||
#ifdef _MODULES
|
||||
m_pModules = new CGlobalModules();
|
||||
#endif
|
||||
m_uListenPort = 0;
|
||||
m_bISpoofLocked = false;
|
||||
SetISpoofFormat(""); // Set ISpoofFormat to default
|
||||
}
|
||||
@@ -32,6 +31,10 @@ CZNC::~CZNC() {
|
||||
}
|
||||
#endif
|
||||
|
||||
for (size_t b = 0; b < m_vpListeners.size(); b++) {
|
||||
delete m_vpListeners[b];
|
||||
}
|
||||
|
||||
m_Manager.Cleanup();
|
||||
DeleteUsers();
|
||||
}
|
||||
@@ -142,20 +145,26 @@ int CZNC::Loop() {
|
||||
m_bISpoofLocked = true;
|
||||
}
|
||||
|
||||
DEBUG_ONLY( cout << "User [" << pUser->GetUserName() << "] is connecting to [" << pServer->GetName() << ":" << pServer->GetPort() << "] ..." << endl);
|
||||
DEBUG_ONLY(cout << "User [" << pUser->GetUserName() << "] is connecting to [" << pServer->GetName() << ":" << pServer->GetPort() << "] ..." << endl);
|
||||
pUser->PutStatus("Attempting to connect to [" + pServer->GetName() + ":" + CString::ToString(pServer->GetPort()) + "] ...");
|
||||
|
||||
pIRCSock = new CIRCSock(pUser);
|
||||
pIRCSock->SetPass(pServer->GetPass());
|
||||
|
||||
bool bSSL = false;
|
||||
bool bIPV6 = false;
|
||||
#ifdef HAVE_LIBSSL
|
||||
if (pServer->IsSSL()) {
|
||||
bSSL = true;
|
||||
pIRCSock->SetPemLocation(GetPemLocation());
|
||||
}
|
||||
#endif
|
||||
if (!m_Manager.Connect(pServer->GetName(), pServer->GetPort(), sSockName, 20, bSSL, pUser->GetVHost(), pIRCSock)) {
|
||||
#ifdef HAVE_IPV6
|
||||
if (pServer->IsIPV6()) {
|
||||
bIPV6 = true;
|
||||
}
|
||||
#endif
|
||||
if (!m_Manager.Connect(pServer->GetName(), pServer->GetPort(), sSockName, 20, bSSL, pUser->GetVHost(), pIRCSock, bIPV6)) {
|
||||
ReleaseISpoof();
|
||||
pUser->PutStatus("Unable to connect. (Bad host?)");
|
||||
}
|
||||
@@ -253,24 +262,6 @@ Csock* CZNC::FindSockByName(const CString& sSockName) {
|
||||
return m_Manager.FindSockByName(sSockName);
|
||||
}
|
||||
|
||||
bool CZNC::Listen() {
|
||||
if (!m_uListenPort) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CClient* pClient = new CClient;
|
||||
|
||||
bool bSSL = false;
|
||||
#ifdef HAVE_LIBSSL
|
||||
if (IsSSL()) {
|
||||
bSSL = true;
|
||||
pClient->SetPemLocation(GetPemLocation());
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_Manager.ListenHost(m_uListenPort, "_LISTENER", m_sListenHost, bSSL, SOMAXCONN, pClient);
|
||||
}
|
||||
|
||||
bool CZNC::IsHostAllowed(const CString& sHostMask) {
|
||||
for (map<CString,CUser*>::iterator a = m_msUsers.begin(); a != m_msUsers.end(); a++) {
|
||||
if (a->second->IsHostAllowed(sHostMask)) {
|
||||
@@ -339,12 +330,18 @@ bool CZNC::WriteConfig() {
|
||||
return false;
|
||||
}
|
||||
|
||||
CString sHostPortion;
|
||||
if (!m_sListenHost.empty()) {
|
||||
sHostPortion = m_sListenHost + ":";
|
||||
}
|
||||
for (size_t l = 0; l < m_vpListeners.size(); l++) {
|
||||
CListener* pListener = m_vpListeners[l];
|
||||
CString sHostPortion = pListener->GetBindHost();
|
||||
|
||||
File.Write("Listen = " + sHostPortion + CString((m_bSSL) ? "+" : "") + CString::ToString(m_uListenPort) + "\r\n");
|
||||
if (!sHostPortion.empty()) {
|
||||
sHostPortion += " ";
|
||||
}
|
||||
|
||||
CString s6 = (pListener->IsIPV6()) ? "6" : " ";
|
||||
|
||||
File.Write("Listen" + s6 + " = " + sHostPortion + CString((pListener->IsSSL()) ? "+" : "") + CString::ToString(pListener->GetPort()) + "\r\n");
|
||||
}
|
||||
|
||||
if (!m_sISpoofFile.empty()) {
|
||||
File.Write("ISpoofFile = " + m_sISpoofFile + "\r\n");
|
||||
@@ -400,7 +397,6 @@ bool CZNC::WriteNewConfig(const CString& sConfig) {
|
||||
CString sConfigFile = ExpandConfigPath((sConfig.empty()) ? "znc.conf" : sConfig);
|
||||
CString sAnswer, sUser;
|
||||
vector<CString> vsLines;
|
||||
bool bAnswer = false;
|
||||
|
||||
if (CFile::Exists(sConfigFile)) {
|
||||
if (!m_LockFile.TryExLock(sConfigFile, 50)) {
|
||||
@@ -423,18 +419,29 @@ bool CZNC::WriteNewConfig(const CString& sConfig) {
|
||||
// Listen
|
||||
unsigned int uPort = 0;
|
||||
while(!CUtils::GetNumInput("What port would you like ZNC to listen on?", uPort, 1, 65535));
|
||||
|
||||
CString sSSL;
|
||||
#ifdef HAVE_LIBSSL
|
||||
bAnswer = CUtils::GetBoolInput("Would you like ZNC to listen using SSL?", false);
|
||||
if (CUtils::GetBoolInput("Would you like ZNC to listen using SSL?", false)) {
|
||||
sSSL = "+";
|
||||
}
|
||||
#endif
|
||||
|
||||
CString s6 = " ";
|
||||
#ifdef HAVE_IPV6
|
||||
if (CUtils::GetBoolInput("Would you like ZNC to listen using ipv6?", false)) {
|
||||
s6 = "6";
|
||||
}
|
||||
#endif
|
||||
|
||||
CString sListenHost;
|
||||
CUtils::GetInput("Listen Host", sListenHost, "", "Blank for all ips");
|
||||
|
||||
if (!sListenHost.empty()) {
|
||||
sListenHost += ":";
|
||||
sListenHost += " ";
|
||||
}
|
||||
|
||||
vsLines.push_back("Listen = " + sListenHost + CString((bAnswer) ? "+" : "") + CString::ToString(uPort));
|
||||
vsLines.push_back("Listen" + s6 + " = " + sListenHost + sSSL + CString::ToString(uPort));
|
||||
// !Listen
|
||||
|
||||
#ifdef _MODULES
|
||||
@@ -925,6 +932,14 @@ bool CZNC::ParseConfig(const CString& sConfig) {
|
||||
} else if (sName.CaseCmp("Allow") == 0) {
|
||||
pUser->AddAllowedHost(sValue);
|
||||
continue;
|
||||
} else if (sName.CaseCmp("Server6") == 0) {
|
||||
CUtils::PrintAction("Adding ipv6 Server [" + sValue + "]");
|
||||
#ifdef HAVE_IPV6
|
||||
CUtils::PrintStatus(pUser->AddServer(sValue, true));
|
||||
#else
|
||||
CUtils::PrintStatus(false, "ZNC was not compiled with ipv6 support");
|
||||
#endif
|
||||
continue;
|
||||
} else if (sName.CaseCmp("Server") == 0) {
|
||||
CUtils::PrintAction("Adding Server [" + sValue + "]");
|
||||
CUtils::PrintStatus(pUser->AddServer(sValue));
|
||||
@@ -956,41 +971,60 @@ bool CZNC::ParseConfig(const CString& sConfig) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (sName.CaseCmp("Listen") == 0 || sName.CaseCmp("ListenPort") == 0) {
|
||||
m_bSSL = false;
|
||||
if (sName.CaseCmp("Listen") == 0 || sName.CaseCmp("ListenPort") == 0 || sName.CaseCmp("Listen6") == 0) {
|
||||
bool bSSL = false;
|
||||
bool bIPV6 = (sName.CaseCmp("Listen6") == 0);
|
||||
CString sPort;
|
||||
|
||||
if (sValue.find(":") != CString::npos) {
|
||||
m_sListenHost = sValue.Token(0, false, ":");
|
||||
sPort = sValue.Token(1, true, ":");
|
||||
CString sBindHost;
|
||||
|
||||
if (!bIPV6) {
|
||||
sValue.Replace(":", " ");
|
||||
}
|
||||
|
||||
if (sValue.find(" ") != CString::npos) {
|
||||
sBindHost = sValue.Token(0, false, " ");
|
||||
sPort = sValue.Token(1, true, " ");
|
||||
} else {
|
||||
m_sListenHost = "";
|
||||
sPort = sValue;
|
||||
}
|
||||
|
||||
if (sPort.Left(1) == "+") {
|
||||
sPort.LeftChomp();
|
||||
m_bSSL = true;
|
||||
bSSL = true;
|
||||
}
|
||||
|
||||
CString sHostComment;
|
||||
|
||||
if (!m_sListenHost.empty()) {
|
||||
sHostComment = " on host [" + m_sListenHost + "]";
|
||||
if (!sBindHost.empty()) {
|
||||
sHostComment = " on host [" + sBindHost + "]";
|
||||
}
|
||||
|
||||
m_uListenPort = strtol(sPort.c_str(), NULL, 10);
|
||||
CUtils::PrintAction("Binding to port [" + CString((m_bSSL) ? "+" : "") + CString::ToString(m_uListenPort) + "]" + sHostComment);
|
||||
CString sIPV6Comment;
|
||||
|
||||
if (bIPV6) {
|
||||
sIPV6Comment = " using ipv6";
|
||||
}
|
||||
|
||||
unsigned short uPort = strtol(sPort.c_str(), NULL, 10);
|
||||
CUtils::PrintAction("Binding to port [" + CString((bSSL) ? "+" : "") + CString::ToString(uPort) + "]" + sHostComment + sIPV6Comment);
|
||||
|
||||
#ifndef HAVE_IPV6
|
||||
if (bIPV6) {
|
||||
CUtils::PrintStatus(false, "IPV6 is not enabled");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_LIBSSL
|
||||
if (m_bSSL) {
|
||||
if (bSSL) {
|
||||
CUtils::PrintStatus(false, "SSL is not enabled");
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
CString sPemFile = GetPemLocation();
|
||||
|
||||
if ((m_bSSL) && (!CFile::Exists(sPemFile))) {
|
||||
if (bSSL && !CFile::Exists(sPemFile)) {
|
||||
CUtils::PrintStatus(false, "Unable to locate pem file: [" + sPemFile + "]");
|
||||
|
||||
if (CUtils::GetBoolInput("Would you like to create a new pem file?", true)) {
|
||||
@@ -999,19 +1033,23 @@ bool CZNC::ParseConfig(const CString& sConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CUtils::PrintAction("Binding to port [" + CString((m_bSSL) ? "+" : "") + CString::ToString(m_uListenPort) + "]");
|
||||
CUtils::PrintAction("Binding to port [+" + CString::ToString(uPort) + "]" + sHostComment + sIPV6Comment);
|
||||
}
|
||||
#endif
|
||||
if (!m_uListenPort) {
|
||||
if (!uPort) {
|
||||
CUtils::PrintStatus(false, "Invalid port");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Listen()) {
|
||||
CListener* pListener = new CListener(uPort, sBindHost, bSSL, bIPV6);
|
||||
|
||||
if (!pListener->Listen()) {
|
||||
CUtils::PrintStatus(false, "Unable to bind");
|
||||
delete pListener;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_vpListeners.push_back(pListener);
|
||||
CUtils::PrintStatus(true);
|
||||
|
||||
continue;
|
||||
|
||||
@@ -13,6 +13,7 @@ using std::set;
|
||||
|
||||
class CUser;
|
||||
class CClient;
|
||||
class CListener;
|
||||
|
||||
class CZNC {
|
||||
public:
|
||||
@@ -25,7 +26,6 @@ public:
|
||||
bool WritePidFile(int iPid);
|
||||
CUser* GetUser(const CString& sUser);
|
||||
Csock* FindSockByName(const CString& sSockName);
|
||||
bool Listen();
|
||||
bool ParseConfig(const CString& sConfig);
|
||||
bool IsHostAllowed(const CString& sHostMask);
|
||||
void InitDirs(const CString& sArgvPath);
|
||||
@@ -51,8 +51,6 @@ public:
|
||||
#ifdef _MODULES
|
||||
CGlobalModules& GetModules() { return *m_pModules; }
|
||||
#endif
|
||||
unsigned short GetListenPort() const { return m_uListenPort; }
|
||||
const CString& GetListenHost() const { return m_sListenHost; }
|
||||
const CString& GetStatusPrefix() const { return m_sStatusPrefix; }
|
||||
const CString& GetCurPath() const { if (!CFile::Exists(m_sCurPath)) { CUtils::MakeDir(m_sCurPath); } return m_sCurPath; }
|
||||
const CString& GetModPath() const { if (!CFile::Exists(m_sModPath)) { CUtils::MakeDir(m_sModPath); } return m_sModPath; }
|
||||
@@ -66,13 +64,7 @@ public:
|
||||
const CString& GetISpoofFile() const { return m_sISpoofFile; }
|
||||
const CString& GetISpoofFormat() const { return m_sISpoofFormat; }
|
||||
const VCString& GetVHosts() const { return m_vsVHosts; }
|
||||
|
||||
bool IsSSL() const {
|
||||
#ifdef HAVE_LIBSSL
|
||||
return m_bSSL;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
const vector<CListener*>& GetListeners() const { return m_vpListeners; }
|
||||
// !Getters
|
||||
|
||||
// Static allocator
|
||||
@@ -91,8 +83,7 @@ public:
|
||||
|
||||
private:
|
||||
protected:
|
||||
unsigned short m_uListenPort;
|
||||
CString m_sListenHost;
|
||||
vector<CListener*> m_vpListeners;
|
||||
map<CString,CUser*> m_msUsers;
|
||||
set<CUser*> m_ssDelUsers;
|
||||
TSocketManager<Csock> m_Manager;
|
||||
@@ -115,11 +106,60 @@ protected:
|
||||
VCString m_vsMotd;
|
||||
CLockFile m_LockFile;
|
||||
bool m_bISpoofLocked;
|
||||
bool m_bSSL;
|
||||
map<CString,CUser*>::iterator m_itUserIter; // This needs to be reset to m_msUsers.begin() if anything is added or removed to the map
|
||||
#ifdef _MODULES
|
||||
CGlobalModules* m_pModules;
|
||||
#endif
|
||||
};
|
||||
|
||||
class CListener {
|
||||
public:
|
||||
CListener(unsigned short uPort, const CString& sBindHost, bool bSSL, bool bIPV6) {
|
||||
m_uPort = uPort;
|
||||
m_sBindHost = sBindHost;
|
||||
m_bSSL = bSSL;
|
||||
m_bIPV6 = bIPV6;
|
||||
}
|
||||
|
||||
virtual ~CListener() {}
|
||||
|
||||
// Setters
|
||||
void SetSSL(bool b) { m_bSSL = b; }
|
||||
void SetIPV6(bool b) { m_bIPV6 = b; }
|
||||
void SetPort(unsigned short u) { m_uPort = u; }
|
||||
void SetBindHost(const CString& s) { m_sBindHost = s; }
|
||||
// !Setters
|
||||
|
||||
// Getters
|
||||
bool IsSSL() const { return m_bSSL; }
|
||||
bool IsIPV6() const { return m_bIPV6; }
|
||||
unsigned short GetPort() const { return m_uPort; }
|
||||
const CString& GetBindHost() const { return m_sBindHost; }
|
||||
// !Getters
|
||||
|
||||
bool Listen() const {
|
||||
if (!m_uPort) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CClient* pClient = new CClient;
|
||||
|
||||
bool bSSL = false;
|
||||
#ifdef HAVE_LIBSSL
|
||||
if (IsSSL()) {
|
||||
bSSL = true;
|
||||
pClient->SetPemLocation(CZNC::Get().GetPemLocation());
|
||||
}
|
||||
#endif
|
||||
|
||||
return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", m_sBindHost, bSSL, SOMAXCONN, pClient, m_bIPV6);
|
||||
}
|
||||
private:
|
||||
protected:
|
||||
bool m_bSSL;
|
||||
bool m_bIPV6;
|
||||
unsigned short m_uPort;
|
||||
CString m_sBindHost;
|
||||
};
|
||||
|
||||
#endif // !_ZNC_H
|
||||
|
||||
Reference in New Issue
Block a user