Add "Listen4" config option

"Listen6" and "Listen4" now do what the name implies and "Listen" listens on
both ipv4 and ipv6 (unless a bind host was set which forces something
different).

This also changes webadmin appropriately.

Thanks to DarthGandalf for the idea and the patch.


git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1816 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
psychon
2010-03-08 17:23:53 +00:00
parent 0d42ded787
commit cbca0d7dc0
5 changed files with 85 additions and 26 deletions
+32 -10
View File
@@ -20,12 +20,18 @@ public:
~CZNCSock() {}
};
enum EAddrType {
ADDR_IPV4ONLY,
ADDR_IPV6ONLY,
ADDR_ALL
};
class CSockManager : public TSocketManager<CZNCSock> {
public:
CSockManager() {}
virtual ~CSockManager() {}
bool ListenHost(u_short iPort, const CString& sSockName, const CString& sBindHost, bool bSSL = false, int iMaxConns = SOMAXCONN, CZNCSock *pcSock = NULL, u_int iTimeout = 0, bool bIsIPv6 = false) {
bool ListenHost(u_short iPort, const CString& sSockName, const CString& sBindHost, bool bSSL = false, int iMaxConns = SOMAXCONN, CZNCSock *pcSock = NULL, u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
CSListener L(iPort, sBindHost);
L.SetSockName(sSockName);
@@ -34,19 +40,27 @@ public:
L.SetMaxConns(iMaxConns);
#ifdef HAVE_IPV6
if (bIsIPv6) {
L.SetAFRequire(CSSockAddr::RAF_INET6);
switch (eAddr) {
case ADDR_IPV4ONLY:
L.SetAFRequire(CSSockAddr::RAF_INET);
break;
case ADDR_IPV6ONLY:
L.SetAFRequire(CSSockAddr::RAF_INET6);
break;
case ADDR_ALL:
L.SetAFRequire(CSSockAddr::RAF_ANY);
break;
}
#endif
return Listen(L, pcSock);
}
bool ListenAll(u_short iPort, const CString& sSockName, bool bSSL = false, int iMaxConns = SOMAXCONN, CZNCSock *pcSock = NULL, u_int iTimeout = 0, bool bIsIPv6 = false) {
return ListenHost(iPort, sSockName, "", bSSL, iMaxConns, pcSock, iTimeout, bIsIPv6);
bool ListenAll(u_short iPort, const CString& sSockName, bool bSSL = false, int iMaxConns = SOMAXCONN, CZNCSock *pcSock = NULL, u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
return ListenHost(iPort, sSockName, "", bSSL, iMaxConns, pcSock, iTimeout, eAddr);
}
u_short ListenRand(const CString& sSockName, const CString& sBindHost, bool bSSL = false, int iMaxConns = SOMAXCONN, CZNCSock *pcSock = NULL, u_int iTimeout = 0, bool bIsIPv6 = false) {
u_short ListenRand(const CString& sSockName, const CString& sBindHost, bool bSSL = false, int iMaxConns = SOMAXCONN, CZNCSock *pcSock = NULL, u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
unsigned short uPort = 0;
CSListener L(0, sBindHost);
@@ -56,8 +70,16 @@ public:
L.SetMaxConns(iMaxConns);
#ifdef HAVE_IPV6
if (bIsIPv6) {
L.SetAFRequire(CSSockAddr::RAF_INET6);
switch (eAddr) {
case ADDR_IPV4ONLY:
L.SetAFRequire(CSSockAddr::RAF_INET);
break;
case ADDR_IPV6ONLY:
L.SetAFRequire(CSSockAddr::RAF_INET6);
break;
case ADDR_ALL:
L.SetAFRequire(CSSockAddr::RAF_ANY);
break;
}
#endif
@@ -66,8 +88,8 @@ public:
return uPort;
}
u_short ListenAllRand(const CString& sSockName, bool bSSL = false, int iMaxConns = SOMAXCONN, CZNCSock *pcSock = NULL, u_int iTimeout = 0, bool bIsIPv6 = false) {
return(ListenRand(sSockName, "", bSSL, iMaxConns, pcSock, iTimeout, bIsIPv6));
u_short ListenAllRand(const CString& sSockName, bool bSSL = false, int iMaxConns = SOMAXCONN, CZNCSock *pcSock = NULL, u_int iTimeout = 0, EAddrType eAddr = ADDR_ALL) {
return(ListenRand(sSockName, "", bSSL, iMaxConns, pcSock, iTimeout, eAddr));
}
bool Connect(const CString& sHostname, u_short iPort , const CString& sSockName, int iTimeout = 60, bool bSSL = false, const CString& sBindHost = "", CZNCSock *pcSock = NULL) {
+13 -2
View File
@@ -735,9 +735,20 @@ public:
#endif
#ifdef HAVE_IPV6
if (pListener->IsIPV6()) {
l["IsIPV6"] = "true";
switch (pListener->GetAddrType()) {
case ADDR_IPV4ONLY:
l["IsIPV4"] = "true";
break;
case ADDR_IPV6ONLY:
l["IsIPV6"] = "true";
break;
case ADDR_ALL:
l["IsIPV4"] = "true";
l["IsIPV6"] = "true";
break;
}
#else
l["IsIPV4"] = "true";
#endif
}
+2
View File
@@ -14,6 +14,7 @@
<td>Port</td>
<td>BindHost</td>
<td>SSL</td>
<td>IPv4</td>
<td>IPv6</td>
</tr>
</thead>
@@ -24,6 +25,7 @@
<td><? VAR Port ?></td>
<td><? VAR BindHost DEFAULT=** ?></td>
<td><? IF IsSSL ?>True<? ELSE ?>False<? ENDIF ?></td>
<td><? IF IsIPV4 ?>True<? ELSE ?>False<? ENDIF ?></td>
<td><? IF IsIPV6 ?>True<? ELSE ?>False<? ENDIF ?></td>
</tr>
<? ENDLOOP ?>
+32 -8
View File
@@ -549,7 +549,18 @@ bool CZNC::WriteConfig() {
sHostPortion = sHostPortion.FirstLine() + " ";
}
CString s6 = (pListener->IsIPV6()) ? "6" : " ";
CString s6;
switch (pListener->GetAddrType()) {
case ADDR_IPV4ONLY:
s6 = "4";
break;
case ADDR_IPV6ONLY:
s6 = "6";
break;
case ADDR_ALL:
s6 = " ";
break;
}
m_LockFile.Write("Listen" + s6 + " = " + sHostPortion + CString((pListener->IsSSL()) ? "+" : "") + CString(pListener->GetPort()) + "\n");
}
@@ -1426,14 +1437,20 @@ bool CZNC::DoRehash(CString& sError)
}
}
} else {
if (sName.Equals("Listen") || sName.Equals("ListenPort") || sName.Equals("Listen6")) {
if (sName.Equals("Listen") || sName.Equals("ListenPort") || sName.Equals("Listen6") || sName.Equals("Listen4")) {
bool bSSL = false;
bool bIPV6 = sName.Equals("Listen6");
EAddrType eAddr = ADDR_ALL;
if (sName.Equals("Listen4")) {
eAddr = ADDR_IPV4ONLY;
}
if (sName.Equals("Listen6")) {
eAddr = ADDR_IPV6ONLY;
}
CString sPort;
CString sBindHost;
if (!bIPV6) {
if (ADDR_IPV4ONLY == eAddr) {
sValue.Replace(":", " ");
}
@@ -1457,15 +1474,22 @@ bool CZNC::DoRehash(CString& sError)
CString sIPV6Comment;
if (bIPV6) {
sIPV6Comment = " using ipv6";
switch (eAddr) {
case ADDR_ALL:
sIPV6Comment = "";
break;
case ADDR_IPV4ONLY:
sIPV6Comment = " using ipv4";
break;
case ADDR_IPV6ONLY:
sIPV6Comment = " using ipv6";
}
unsigned short uPort = sPort.ToUShort();
CUtils::PrintAction("Binding to port [" + CString((bSSL) ? "+" : "") + CString(uPort) + "]" + sHostComment + sIPV6Comment);
#ifndef HAVE_IPV6
if (bIPV6) {
if (ADDR_IPV6ONLY == eAddr) {
sError = "IPV6 is not enabled";
CUtils::PrintStatus(false, sError);
return false;
@@ -1503,7 +1527,7 @@ bool CZNC::DoRehash(CString& sError)
return false;
}
CListener* pListener = new CListener(uPort, sBindHost, bSSL, bIPV6);
CListener* pListener = new CListener(uPort, sBindHost, bSSL, eAddr);
if (!pListener->Listen()) {
sError = "Unable to bind [" + CString(strerror(errno)) + "]";
+6 -6
View File
@@ -207,11 +207,11 @@ public:
class CListener {
public:
CListener(unsigned short uPort, const CString& sBindHost, bool bSSL, bool bIPV6) {
CListener(unsigned short uPort, const CString& sBindHost, bool bSSL, EAddrType eAddr) {
m_uPort = uPort;
m_sBindHost = sBindHost;
m_bSSL = bSSL;
m_bIPV6 = bIPV6;
m_eAddr = eAddr;
m_pListener = NULL;
}
@@ -222,14 +222,14 @@ public:
// Setters
void SetSSL(bool b) { m_bSSL = b; }
void SetIPV6(bool b) { m_bIPV6 = b; }
void SetAddrType(EAddrType eAddr) { m_eAddr = eAddr; }
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; }
EAddrType GetAddrType() const { return m_eAddr; }
unsigned short GetPort() const { return m_uPort; }
const CString& GetBindHost() const { return m_sBindHost; }
CRealListener* GetRealListener() const { return m_pListener; }
@@ -251,12 +251,12 @@ public:
#endif
return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", m_sBindHost, bSSL, SOMAXCONN,
m_pListener, 0, m_bIPV6);
m_pListener, 0, m_eAddr);
}
private:
protected:
bool m_bSSL;
bool m_bIPV6;
EAddrType m_eAddr;
unsigned short m_uPort;
CString m_sBindHost;
CRealListener* m_pListener;