diff options
-rw-r--r-- | data/anope.example.conf | 8 | ||||
-rw-r--r-- | data/stats.standalone.example.conf | 8 | ||||
-rw-r--r-- | docs/Changes.conf | 1 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | include/sockets.h | 26 | ||||
-rw-r--r-- | modules/extra/m_ssl_gnutls.cpp | 2 | ||||
-rw-r--r-- | modules/extra/m_ssl_openssl.cpp | 2 | ||||
-rw-r--r-- | modules/m_dns.cpp | 2 | ||||
-rw-r--r-- | modules/m_httpd.cpp | 2 | ||||
-rw-r--r-- | modules/m_proxyscan.cpp | 2 | ||||
-rw-r--r-- | src/config.cpp | 30 | ||||
-rw-r--r-- | src/sockets.cpp | 33 | ||||
-rw-r--r-- | src/uplink.cpp | 4 |
13 files changed, 84 insertions, 42 deletions
diff --git a/data/anope.example.conf b/data/anope.example.conf index 03ba73109..79bee85ec 100644 --- a/data/anope.example.conf +++ b/data/anope.example.conf @@ -161,7 +161,8 @@ define uplink { /* - * The IP or hostname of the IRC server you wish to connect Anope to. + * The IP address, hostname, or UNIX socket path of the IRC server you wish + * to connect Anope to. * Usually, you will want to connect over 127.0.0.1 (aka localhost). * * NOTE: On some shell providers, this will not be an option. @@ -169,9 +170,10 @@ uplink host = "127.0.0.1" /* - * Enable if Anope should connect using IPv6. + * The protocol that Anope should use when connecting to the uplink. Can + * be set to "ipv4" (the default), "ipv6", or "unix". */ - ipv6 = no + protocol = "ipv4" /* * Enable if Anope should connect using SSL. diff --git a/data/stats.standalone.example.conf b/data/stats.standalone.example.conf index 835101fee..bd40723e8 100644 --- a/data/stats.standalone.example.conf +++ b/data/stats.standalone.example.conf @@ -158,7 +158,8 @@ define uplink { /* - * The IP or hostname of the IRC server you wish to connect Anope to. + * The IP address, hostname, or UNIX socket path of the IRC server you wish + * to connect Anope to. * Usually, you will want to connect over 127.0.0.1 (aka localhost). * * NOTE: On some shell providers, this will not be an option. @@ -166,9 +167,10 @@ uplink host = "127.0.0.1" /* - * Enable if Anope should connect using IPv6. + * The protocol that Anope should use when connecting to the uplink. Can + * be set to "ipv4" (the default), "ipv6", or "unix". */ - ipv6 = no + protocol = "ipv4" /* * Enable if Anope should connect using SSL. diff --git a/docs/Changes.conf b/docs/Changes.conf index e79c6729f..cb1d77313 100644 --- a/docs/Changes.conf +++ b/docs/Changes.conf @@ -3,6 +3,7 @@ Anope Version 2.1.0-git Added nickserv:minpasslen for configuring the minimum password length. Removed nickserv:strictpasswords as it is obsolete now nickserv:minpasslen exists. Renamed nickserv:passlen to nickserv:maxpasslen. +Replaced uplink:ipv6 with uplink:protocol. Anope Version 2.0.11 -------------------- diff --git a/include/config.h b/include/config.h index 8b8cb65ca..48f334cff 100644 --- a/include/config.h +++ b/include/config.h @@ -150,10 +150,10 @@ namespace Configuration Anope::string host; unsigned port; Anope::string password; - bool ipv6; + int protocol; - Uplink(const Anope::string &_host, int _port, const Anope::string &_password, bool _ipv6) : host(_host), port(_port), password(_password), ipv6(_ipv6) { } - inline bool operator==(const Uplink &other) const { return host == other.host && port == other.port && password == other.password && ipv6 == other.ipv6; } + Uplink(const Anope::string &_host, int _port, const Anope::string &_password, int _protocol) : host(_host), port(_port), password(_password), protocol(_protocol) { } + inline bool operator==(const Uplink &other) const { return host == other.host && port == other.port && password == other.password && protocol == other.protocol; } inline bool operator!=(const Uplink &other) const { return !(*this == other); } }; } diff --git a/include/sockets.h b/include/sockets.h index 24e580902..641800b6d 100644 --- a/include/sockets.h +++ b/include/sockets.h @@ -15,10 +15,16 @@ #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> +#include <sys/un.h> #endif #include "anope.h" +// This has to be after anope.h +#ifdef _WIN32 +# include <afunix.h> +#endif + #define NET_BUFSIZE 65535 /** A sockaddr union used to combine IPv4 and IPv6 sockaddrs @@ -28,6 +34,7 @@ union CoreExport sockaddrs sockaddr sa; sockaddr_in sa4; sockaddr_in6 sa6; + sockaddr_un saun; /** Construct the object, sets everything to 0 */ @@ -203,8 +210,9 @@ class CoreExport Socket protected: /* Socket FD */ int sock; - /* Is this an IPv6 socket? */ - bool ipv6; + + /* The family of this socket FD */ + int family; public: std::bitset<SF_SIZE> flags; @@ -221,25 +229,25 @@ class CoreExport Socket /** Constructor, possibly creates the socket and adds it to the engine * @param sock The socket to use, -1 if we need to create our own - * @param ipv6 true if using ipv6 + * @param family The family of the socket * @param type The socket type, defaults to SOCK_STREAM */ - Socket(int sock, bool ipv6 = false, int type = SOCK_STREAM); + Socket(int sock, bool family = AF_INET, int type = SOCK_STREAM); /** Destructor, closes the socket and removes it from the engine */ virtual ~Socket(); + /** Get the socket family for this socket + * @return the family + */ + int GetFamily() const; + /** Get the socket FD for this socket * @return the fd */ int GetFD() const; - /** Check if this socket is IPv6 - * @return true or false - */ - bool IsIPv6() const; - /** Mark a socket as (non)blocking * @param state true to enable blocking, false to disable blocking * @return true if the socket is now blocking diff --git a/modules/extra/m_ssl_gnutls.cpp b/modules/extra/m_ssl_gnutls.cpp index aba7c99f4..ba42ad603 100644 --- a/modules/extra/m_ssl_gnutls.cpp +++ b/modules/extra/m_ssl_gnutls.cpp @@ -533,7 +533,7 @@ void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int s->flags[SF_CONNECTING] = s->flags[SF_CONNECTED] = false; - s->conaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, target, port); + s->conaddr.pton(s->GetFamily(), target, port); int c = connect(s->GetFD(), &s->conaddr.sa, s->conaddr.size()); if (c == -1) { diff --git a/modules/extra/m_ssl_openssl.cpp b/modules/extra/m_ssl_openssl.cpp index d89aaa490..642f4f2e5 100644 --- a/modules/extra/m_ssl_openssl.cpp +++ b/modules/extra/m_ssl_openssl.cpp @@ -334,7 +334,7 @@ void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int s->flags[SF_CONNECTING] = s->flags[SF_CONNECTED] = false; - s->conaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, target, port); + s->conaddr.pton(s->GetFamily(), target, port); int c = connect(s->GetFD(), &s->conaddr.sa, s->conaddr.size()); if (c == -1) { diff --git a/modules/m_dns.cpp b/modules/m_dns.cpp index 45e2a1530..0306abe61 100644 --- a/modules/m_dns.cpp +++ b/modules/m_dns.cpp @@ -473,7 +473,7 @@ class TCPSocket : public ListenSocket int length = 0; public: - Client(Manager *m, TCPSocket *l, int fd, const sockaddrs &addr) : Socket(fd, l->IsIPv6()), ClientSocket(l, addr), Timer(5), + Client(Manager *m, TCPSocket *l, int fd, const sockaddrs &addr) : Socket(fd, l->GetFamily()), ClientSocket(l, addr), Timer(5), manager(m) { Log(LOG_DEBUG_2) << "Resolver: New client from " << addr.addr(); diff --git a/modules/m_httpd.cpp b/modules/m_httpd.cpp index 4ce4ba945..33fe475ea 100644 --- a/modules/m_httpd.cpp +++ b/modules/m_httpd.cpp @@ -94,7 +94,7 @@ class MyHTTPClient : public HTTPClient public: time_t created; - MyHTTPClient(HTTPProvider *l, int f, const sockaddrs &a) : Socket(f, l->IsIPv6()), HTTPClient(l, f, a), provider(l), ip(a.addr()), created(Anope::CurTime) + MyHTTPClient(HTTPProvider *l, int f, const sockaddrs &a) : Socket(f, l->GetFamily()), HTTPClient(l, f, a), provider(l), ip(a.addr()), created(Anope::CurTime) { Log(LOG_DEBUG, "httpd") << "Accepted connection " << f << " from " << a.addr(); } diff --git a/modules/m_proxyscan.cpp b/modules/m_proxyscan.cpp index c849d696e..d29645cf5 100644 --- a/modules/m_proxyscan.cpp +++ b/modules/m_proxyscan.cpp @@ -26,7 +26,7 @@ class ProxyCallbackListener : public ListenSocket class ProxyCallbackClient : public ClientSocket, public BufferedSocket { public: - ProxyCallbackClient(ListenSocket *l, int f, const sockaddrs &a) : Socket(f, l->IsIPv6()), ClientSocket(l, a), BufferedSocket() + ProxyCallbackClient(ListenSocket *l, int f, const sockaddrs &a) : Socket(f, l->GetFamily()), ClientSocket(l, a), BufferedSocket() { } diff --git a/src/config.cpp b/src/config.cpp index 0d1900268..0503340b0 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -193,19 +193,33 @@ Conf::Conf() : Block(""), EmptyBlock("") { Block *uplink = this->GetBlock("uplink", i); - const Anope::string &host = uplink->Get<const Anope::string>("host"); - bool ipv6 = uplink->Get<bool>("ipv6"); - int port = uplink->Get<int>("port"); - const Anope::string &password = uplink->Get<const Anope::string>("password"); + int protocol; + const Anope::string &protocolstr = uplink->Get<const Anope::string>("protocol", "ipv4"); + if (protocolstr == "ipv4") + protocol = AF_INET; + else if (protocolstr == "ipv6") + protocol = AF_INET6; + else if (protocolstr == "unix") + protocol = AF_UNIX; + else + throw ConfigException("uplink:protocol must be set to ipv4, ipv6, or unix"); + const Anope::string &host = uplink->Get<const Anope::string>("host"); ValidateNotEmptyOrSpaces("uplink", "host", host); - ValidateNotZero("uplink", "port", port); - ValidateNotEmptyOrSpaces("uplink", "password", password); - if (password.find(' ') != Anope::string::npos || password[0] == ':') + int port = 0; + if (protocol != AF_UNIX) + { + ValidateNotZero("uplink", "port", port); + port = uplink->Get<int>("port"); + } + + const Anope::string &password = uplink->Get<const Anope::string>("password"); + ValidateNotEmptyOrSpaces("uplink", "password", password); + if (password[0] == ':') throw ConfigException("uplink:password is not valid"); - this->Uplinks.emplace_back(host, port, password, ipv6); + this->Uplinks.emplace_back(host, port, password, protocol); } for (int i = 0; i < this->CountBlock("module"); ++i) diff --git a/src/sockets.cpp b/src/sockets.cpp index 061a8eb10..34aa946ba 100644 --- a/src/sockets.cpp +++ b/src/sockets.cpp @@ -52,6 +52,8 @@ size_t sockaddrs::size() const return sizeof(sa4); case AF_INET6: return sizeof(sa6); + case AF_UNIX: + return sizeof(saun); default: break; } @@ -67,6 +69,8 @@ int sockaddrs::port() const return ntohs(sa4.sin_port); case AF_INET6: return ntohs(sa6.sin6_port); + case AF_UNIX: + return 0; default: break; } @@ -88,6 +92,8 @@ Anope::string sockaddrs::addr() const if (inet_ntop(AF_INET6, &sa6.sin6_addr, address, sizeof(address))) return address; break; + case AF_UNIX: + return saun.sun_path; default: break; } @@ -187,6 +193,15 @@ void sockaddrs::pton(int type, const Anope::string &address, int pport) } break; } + case AF_UNIX: + { + if (address.length() < sizeof(saun.sun_path)) + { + saun.sun_family = AF_UNIX; + memcpy(&saun.sun_path, address.c_str(), address.length() + 1); + } + break; + } default: break; } @@ -432,7 +447,7 @@ SocketFlag SocketIO::FinishAccept(ClientSocket *cs) void SocketIO::Bind(Socket *s, const Anope::string &ip, int port) { - s->bindaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, ip, port); + s->bindaddr.pton(s->GetFamily(), ip, port); if (bind(s->GetFD(), &s->bindaddr.sa, s->bindaddr.size()) == -1) throw SocketException("Unable to bind to address: " + Anope::LastError()); } @@ -440,7 +455,7 @@ void SocketIO::Bind(Socket *s, const Anope::string &ip, int port) void SocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int port) { s->flags[SF_CONNECTING] = s->flags[SF_CONNECTED] = false; - s->conaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, target, port); + s->conaddr.pton(s->GetFamily(), target, port); int c = connect(s->GetFD(), &s->conaddr.sa, s->conaddr.size()); if (c == -1) { @@ -488,12 +503,12 @@ Socket::Socket() throw CoreException("Socket::Socket() ?"); } -Socket::Socket(int s, bool i, int type) +Socket::Socket(int s, bool f, int type) { this->io = &NormalSocketIO; - this->ipv6 = i; + this->family = f; if (s == -1) - this->sock = socket(this->ipv6 ? AF_INET6 : AF_INET, type, 0); + this->sock = socket(this->family, type, 0); else this->sock = s; this->SetBlocking(false); @@ -510,14 +525,14 @@ Socket::~Socket() SocketEngine::Sockets.erase(this->sock); } -int Socket::GetFD() const +int Socket::GetFamily() const { - return sock; + return family; } -bool Socket::IsIPv6() const +int Socket::GetFD() const { - return ipv6; + return sock; } bool Socket::SetBlocking(bool state) diff --git a/src/uplink.cpp b/src/uplink.cpp index 03d8d99f1..db58d71b0 100644 --- a/src/uplink.cpp +++ b/src/uplink.cpp @@ -52,12 +52,12 @@ void Uplink::Connect() if (!Config->GetBlock("serverinfo")->Get<const Anope::string>("localhost").empty()) UplinkSock->Bind(Config->GetBlock("serverinfo")->Get<const Anope::string>("localhost")); FOREACH_MOD(OnPreServerConnect, ()); - Anope::string ip = Anope::Resolve(u.host, u.ipv6 ? AF_INET6 : AF_INET); + Anope::string ip = Anope::Resolve(u.host, u.protocol); Log(LOG_TERMINAL) << "Attempting to connect to uplink #" << (Anope::CurrentUplink + 1) << " " << u.host << " (" << ip << '/' << u.port << ") with protocol " << IRCD->GetProtocolName(); UplinkSock->Connect(ip, u.port); } -UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink].ipv6), ConnectionSocket(), BufferedSocket() +UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink].protocol), ConnectionSocket(), BufferedSocket() { error = false; UplinkSock = this; |