diff options
author | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-03-10 11:50:03 +0000 |
---|---|---|
committer | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-03-10 11:50:03 +0000 |
commit | da2ad810d29d16446adf5b88f8371704c1c88786 (patch) | |
tree | c2f34c7e5120ba9c22e06ae282d709e3005d3d91 | |
parent | baa9673d291b9b9a2d7ad0d3aab56487de434502 (diff) |
Support for hostnames in <bind> tag (so long as the hostname resolves to a locally bindable ip)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@3621 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/message.h | 2 | ||||
-rw-r--r-- | src/dns.cpp | 35 | ||||
-rw-r--r-- | src/inspircd_io.cpp | 51 | ||||
-rw-r--r-- | src/message.cpp | 15 |
4 files changed, 78 insertions, 25 deletions
diff --git a/include/message.h b/include/message.h index af904df92..2c85de6f6 100644 --- a/include/message.h +++ b/include/message.h @@ -33,7 +33,7 @@ void chop(char* str); void tidystring(char* str); void Blocking(int s); void NonBlocking(int s); -int CleanAndResolve (char *resolvedHost, const char *unresolvedHost); +int CleanAndResolve (char *resolvedHost, const char *unresolvedHost, bool forward); int c_count(userrec* u); bool hasumode(userrec* user, char mode); void ChangeName(userrec* user, const char* gecos); diff --git a/src/dns.cpp b/src/dns.cpp index 3b8f8cc95..ef3eb704e 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -162,7 +162,8 @@ inline void dns_empty_header(unsigned char *output, const s_header *header, cons void dns_close(int fd) { #ifndef THREADED_DNS - ServerInstance->SE->DelFd(fd); + if (ServerInstance && ServerInstance->SE) + ServerInstance->SE->DelFd(fd); #endif log(DEBUG,"DNS: dns_close on fd %d",fd); if (fd == lastcreate) @@ -686,7 +687,7 @@ DNS::DNS() DNS::DNS(std::string dnsserver) { dns_init_2(dnsserver.c_str()); - log(DEBUG,"Create DNS"); + log(DEBUG,"Create DNS with server '%s'",dnsserver.c_str()); } void DNS::SetNS(std::string dnsserver) @@ -701,7 +702,8 @@ DNS::~DNS() bool DNS::ReverseLookup(std::string ip) { - ServerInstance->stats->statsDns++; + if (ServerInstance && ServerInstance->stats) + ServerInstance->stats->statsDns++; binip = dns_aton4(ip.c_str()); if (binip == NULL) { @@ -715,14 +717,16 @@ bool DNS::ReverseLookup(std::string ip) } log(DEBUG,"DNS: ReverseLookup, fd=%d",this->myfd); #ifndef THREADED_DNS - ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_DNS); + if (ServerInstance && ServerInstance->SE) + ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_DNS); #endif return true; } bool DNS::ForwardLookup(std::string host) { - ServerInstance->stats->statsDns++; + if (ServerInstance && ServerInstance->stats) + ServerInstance->stats->statsDns++; this->myfd = dns_getip4(host.c_str()); if (this->myfd == -1) { @@ -730,14 +734,16 @@ bool DNS::ForwardLookup(std::string host) } log(DEBUG,"DNS: ForwardLookup, fd=%d",this->myfd); #ifndef THREADED_DNS - ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_DNS); + if (ServerInstance && ServerInstance->SE) + ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_DNS); #endif return true; } bool DNS::ForwardLookupWithFD(std::string host, int &fd) { - ServerInstance->stats->statsDns++; + if (ServerInstance && ServerInstance->stats) + ServerInstance->stats->statsDns++; this->myfd = dns_getip4(host.c_str()); fd = this->myfd; if (this->myfd == -1) @@ -745,7 +751,8 @@ bool DNS::ForwardLookupWithFD(std::string host, int &fd) } log(DEBUG,"DNS: ForwardLookupWithFD, fd=%d",this->myfd); - ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_MODULE); + if (ServerInstance && ServerInstance->SE) + ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_MODULE); return true; } @@ -780,13 +787,15 @@ std::string DNS::GetResult() result = dns_getresult(this->myfd); if (result) { - ServerInstance->stats->statsDnsGood++; + if (ServerInstance && ServerInstance->stats) + ServerInstance->stats->statsDnsGood++; dns_close(this->myfd); return result; } else { - ServerInstance->stats->statsDnsBad++; + if (ServerInstance && ServerInstance->stats) + ServerInstance->stats->statsDnsBad++; if (this->myfd != -1) { dns_close(this->myfd); @@ -806,7 +815,8 @@ std::string DNS::GetResultIP() } if (result) { - ServerInstance->stats->statsDnsGood++; + if (ServerInstance && ServerInstance->stats) + ServerInstance->stats->statsDnsGood++; unsigned char a = (unsigned)result[0]; unsigned char b = (unsigned)result[1]; unsigned char c = (unsigned)result[2]; @@ -816,7 +826,8 @@ std::string DNS::GetResultIP() } else { - ServerInstance->stats->statsDnsBad++; + if (ServerInstance && ServerInstance->stats) + ServerInstance->stats->statsDnsBad++; log(DEBUG,"DANGER WILL ROBINSON! NXDOMAIN for forward lookup, but we got a reverse lookup!"); return ""; } diff --git a/src/inspircd_io.cpp b/src/inspircd_io.cpp index 53f58c4f1..4fa87a5f1 100644 --- a/src/inspircd_io.cpp +++ b/src/inspircd_io.cpp @@ -25,6 +25,7 @@ using namespace std; #include <sstream> #include <iostream> #include <fstream> +#include "message.h" #include "inspircd.h" #include "inspircd_io.h" #include "inspstring.h" @@ -1303,25 +1304,57 @@ int BindSocket (int sockfd, struct sockaddr_in client, struct sockaddr_in server { memset((char *)&server,0,sizeof(server)); struct in_addr addy; - inet_aton(addr,&addy); - server.sin_family = AF_INET; - if (!*addr) + bool resolved = false; + char resolved_addr[128]; + + if (*addr == '*') + *addr = 0; + + if (*addr && !inet_aton(addr,&addy)) { - server.sin_addr.s_addr = htonl(INADDR_ANY); + /* If they gave a hostname, bind to the IP it resolves to */ + if (CleanAndResolve(resolved_addr, addr, true)) + { + inet_aton(resolved_addr,&addy); + log(DEFAULT,"Resolved binding '%s' -> '%s'",addr,resolved_addr); + server.sin_addr = addy; + resolved = true; + } + else + { + log(DEFAULT,"WARNING: Could not resolve '%s' to an IP for binding to on port %d",addr,port); + return(FALSE); + } } - else + server.sin_family = AF_INET; + if (!resolved) { - server.sin_addr = addy; + if (!*addr) + { + server.sin_addr.s_addr = htonl(INADDR_ANY); + } + else + { + server.sin_addr = addy; + } } server.sin_port = htons(port); - if (bind(sockfd,(struct sockaddr*)&server,sizeof(server))<0) + if (bind(sockfd,(struct sockaddr*)&server,sizeof(server)) < 0) { return(ERROR); } else { - listen(sockfd, Config->MaxConn); - return(TRUE); + log(DEBUG,"Bound port %s:%d",*addr ? addr : "*",port); + if (listen(sockfd, Config->MaxConn) == -1) + { + log(DEFAULT,"ERROR in listen(): %s",strerror(errno)); + return(FALSE); + } + else + { + return(TRUE); + } } } diff --git a/src/message.cpp b/src/message.cpp index 29a4ae998..39c321f42 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -166,15 +166,24 @@ void NonBlocking(int s) fcntl(s, F_SETFL, flags | O_NONBLOCK); } -int CleanAndResolve (char *resolvedHost, const char *unresolvedHost) +int CleanAndResolve (char *resolvedHost, const char *unresolvedHost, bool forward) { + int fd; + std::string ipaddr; + DNS d(Config->DNSServer); - int fd = d.ReverseLookup(unresolvedHost); + if (forward) + fd = d.ForwardLookup(unresolvedHost); + else + fd = d.ReverseLookup(unresolvedHost); if (fd < 0) return 0; time_t T = time(NULL)+1; while ((!d.HasResult()) && (time(NULL)<T)); - std::string ipaddr = d.GetResult(); + if (forward) + ipaddr = d.GetResultIP(); + else + ipaddr = d.GetResult(); strlcpy(resolvedHost,ipaddr.c_str(),MAXBUF); return (ipaddr != ""); } |