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:
prozacx
2006-02-11 10:06:45 +00:00
parent 7c52a7862e
commit ca8247058f
7 changed files with 158 additions and 69 deletions
+3 -1
View File
@@ -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);
+3 -1
View File
@@ -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
+11 -4
View File
@@ -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;
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -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;
}
+84 -46
View File
@@ -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;
+53 -13
View File
@@ -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