summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-03-10 11:50:03 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-03-10 11:50:03 +0000
commitda2ad810d29d16446adf5b88f8371704c1c88786 (patch)
treec2f34c7e5120ba9c22e06ae282d709e3005d3d91
parentbaa9673d291b9b9a2d7ad0d3aab56487de434502 (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.h2
-rw-r--r--src/dns.cpp35
-rw-r--r--src/inspircd_io.cpp51
-rw-r--r--src/message.cpp15
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 != "");
}