summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/inspsocket.h14
-rw-r--r--include/message.h1
-rw-r--r--src/inspsocket.cpp20
-rw-r--r--src/message.cpp5
-rw-r--r--src/modules/m_spanningtree.cpp54
-rw-r--r--src/socket.cpp41
6 files changed, 51 insertions, 84 deletions
diff --git a/include/inspsocket.h b/include/inspsocket.h
index 077f20a65..b644151dc 100644
--- a/include/inspsocket.h
+++ b/include/inspsocket.h
@@ -59,10 +59,6 @@ class InspSocket : public Extensible
int fd;
/**
- * The resolver for this socket
- */
-
- /**
* The hostname connected to
*/
char host[MAXBUF];
@@ -184,15 +180,15 @@ class InspSocket : public Extensible
/**
* This constructor is used to create a new
* socket, either listening for connections, or an outbound connection to another host.
- * Note that if you specify a hostname in the 'host' parameter, then there will be an extra
- * step involved (a nonblocking DNS lookup) which will cause your connection to be established
- * slower than if it was an IP. Therefore, use an IP address where it is available instead.
- * @param host The hostname to connect to, or bind to
+ * Note that if you specify a hostname in the 'ipaddr' parameter, this class will not
+ * connect. You must resolve your hostnames before passing them to InspSocket. To do so,
+ * you should use the nonblocking class 'Resolver'.
+ * @param ipaddr The IP to connect to, or bind to
* @param port The port number to connect to, or bind to
* @param listening true to listen on the given host:port pair, or false to connect to them
* @param maxtime Number of seconds to wait, if connecting, before the connection times out and an OnTimeout() event is generated
*/
- InspSocket(const std::string &host, int port, bool listening, unsigned long maxtime);
+ InspSocket(const std::string &ipaddr, int port, bool listening, unsigned long maxtime);
/**
* This method is called when an outbound
diff --git a/include/message.h b/include/message.h
index fd9d47ff2..f7fcba278 100644
--- a/include/message.h
+++ b/include/message.h
@@ -31,7 +31,6 @@
int common_channels(userrec *u, userrec *u2);
void Blocking(int s);
void NonBlocking(int s);
-int CleanAndResolve(char *resolvedHost, const char *unresolvedHost, bool forward, unsigned long timeout);
int c_count(userrec* u);
void ChangeName(userrec* user, const char* gecos);
void ChangeDisplayedHost(userrec* user, const char* host);
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp
index f443873e5..f738835a8 100644
--- a/src/inspsocket.cpp
+++ b/src/inspsocket.cpp
@@ -57,9 +57,9 @@ InspSocket::InspSocket(int newfd, const char* ip)
}
}
-InspSocket::InspSocket(const std::string &ahost, int aport, bool listening, unsigned long maxtime) : fd(-1)
+InspSocket::InspSocket(const std::string &ipaddr, int aport, bool listening, unsigned long maxtime) : fd(-1)
{
- strlcpy(host,ahost.c_str(),MAXBUF);
+ strlcpy(host,ipaddr.c_str(),MAXBUF);
this->ClosePending = false;
if (listening) {
if ((this->fd = OpenTCPSocket()) == ERROR)
@@ -73,7 +73,7 @@ InspSocket::InspSocket(const std::string &ahost, int aport, bool listening, unsi
}
else
{
- if (!BindSocket(this->fd,this->client,this->server,aport,(char*)ahost.c_str()))
+ if (!BindSocket(this->fd,this->client,this->server,aport,(char*)ipaddr.c_str()))
{
log(DEBUG,"BindSocket() error %s",strerror(errno));
this->Close();
@@ -98,7 +98,7 @@ InspSocket::InspSocket(const std::string &ahost, int aport, bool listening, unsi
}
else
{
- strlcpy(this->host,ahost.c_str(),MAXBUF);
+ strlcpy(this->host,ipaddr.c_str(),MAXBUF);
this->port = aport;
if (insp_aton(host,&addy) < 1)
@@ -170,18 +170,6 @@ bool InspSocket::BindAddr()
if ((IP != "*") && (IP != "127.0.0.1") && (IP != ""))
{
insp_sockaddr s;
- char resolved_addr[MAXBUF];
-
- if (insp_aton(IP.c_str(),&n) < 1)
- {
- /* If they gave a hostname, bind to the IP it resolves to */
- log(DEBUG,"Resolving host %s",IP.c_str());
- if (CleanAndResolve(resolved_addr, IP.c_str(), true, 1))
- {
- log(DEBUG,"Resolved host %s to %s",IP.c_str(),resolved_addr);
- IP = resolved_addr;
- }
- }
if (insp_aton(IP.c_str(),&n) > 0)
{
diff --git a/src/message.cpp b/src/message.cpp
index 96b540db4..268cc6554 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -95,11 +95,6 @@ void NonBlocking(int s)
fcntl(s, F_SETFL, flags | O_NONBLOCK);
}
-int CleanAndResolve (char *resolvedHost, const char *unresolvedHost, bool forward, unsigned long timeout)
-{
- return 0;
-}
-
int c_count(userrec* u)
{
int z = 0;
diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp
index d4bc5360e..3a811d1fa 100644
--- a/src/modules/m_spanningtree.cpp
+++ b/src/modules/m_spanningtree.cpp
@@ -139,6 +139,8 @@ extern std::vector<ZLine> pzlines;
extern std::vector<QLine> pqlines;
extern std::vector<ELine> pelines;
+std::vector<std::string> ValidIPs;
+
class UserManager : public classbase
{
uid_hash uids;
@@ -3032,27 +3034,8 @@ class TreeSocket : public InspSocket
* IPs for which we don't have a link block.
*/
bool found = false;
- char resolved_host[MAXBUF];
vector<Link>::iterator i;
- for (i = LinkBlocks.begin(); i != LinkBlocks.end(); i++)
- {
- if (i->IPAddr == ip)
- {
- found = true;
- break;
- }
- /* XXX: Fixme: blocks for a very short amount of time,
- * we should cache these on rehash/startup
- */
- if (CleanAndResolve(resolved_host,i->IPAddr.c_str(),true,1))
- {
- if (std::string(resolved_host) == ip)
- {
- found = true;
- break;
- }
- }
- }
+ found = (std::find(ValidIPs.begin(), ValidIPs.end(), ip) != ValidIPs.end());
if (!found)
{
WriteOpers("Server connection from %s denied (no link blocks with that IP address)", ip);
@@ -3116,6 +3099,26 @@ class ServernameResolver : public Resolver
}
};
+class SecurityIPResolver : public Resolver
+{
+ private:
+ Link MyLink;
+ public:
+ SecurityIPResolver(const std::string &hostname, Link x) : Resolver(hostname, true), MyLink(x)
+ {
+ }
+
+ void OnLookupComplete(const std::string &result)
+ {
+ log(DEBUG,"Security IP cache: Adding IP address '%s' for Link '%s'",result.c_str(),MyLink.Name.c_str());
+ ValidIPs.push_back(result);
+ }
+
+ void OnError(ResolverError e)
+ {
+ log(DEBUG,"Could not resolve IP associated with Link '%s'!",MyLink.Name.c_str());
+ }
+};
void AddThisServer(TreeServer* server, std::deque<TreeServer*> &list)
{
@@ -3322,6 +3325,7 @@ void ReadConfiguration(bool rebind)
FlatLinks = Conf->ReadFlag("options","flatlinks",0);
HideULines = Conf->ReadFlag("options","hideulines",0);
LinkBlocks.clear();
+ ValidIPs.clear();
for (int j =0; j < Conf->Enumerate("link"); j++)
{
Link L;
@@ -3337,6 +3341,16 @@ void ReadConfiguration(bool rebind)
/* Bugfix by brain, do not allow people to enter bad configurations */
if ((L.IPAddr != "") && (L.RecvPass != "") && (L.SendPass != "") && (L.Name != "") && (L.Port))
{
+ ValidIPs.push_back(L.IPAddr);
+
+ /* Needs resolving */
+ insp_inaddr binip;
+ if (insp_aton(L.IPAddr.c_str(), &binip) < 1)
+ {
+ SecurityIPResolver* sr = new SecurityIPResolver(L.IPAddr, L);
+ Srv->AddResolver(sr);
+ }
+
LinkBlocks.push_back(L);
log(DEBUG,"m_spanningtree: Read server %s with host %s:%d",L.Name.c_str(),L.IPAddr.c_str(),L.Port);
}
diff --git a/src/socket.cpp b/src/socket.cpp
index ff460c473..e386e8188 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -43,51 +43,26 @@ bool BindSocket(int sockfd, insp_sockaddr client, insp_sockaddr server, int port
if (*addr == '*')
*addr = 0;
-
- if (*addr && (insp_aton(addr,&addy) < 1))
- {
- /* If they gave a hostname, bind to the IP it resolves to */
- if (CleanAndResolve(resolved_addr, addr, true, 1))
- {
- insp_aton(resolved_addr,&addy);
- log(DEFAULT,"Resolved binding '%s' -> '%s'",addr,resolved_addr);
-#ifdef IPV6
- /* Todo: Deal with resolution of IPV6 */
- server.sin6_addr = addy;
-#else
- server.sin_addr = addy;
-#endif
- resolved = true;
- }
- else
- {
- log(DEFAULT,"WARNING: Could not resolve '%s' to an IP for binding to on port %d",addr,port);
- return false;
- }
- }
#ifdef IPV6
server.sin6_family = AF_FAMILY;
#else
server.sin_family = AF_FAMILY;
#endif
- if (!resolved)
+ if (!*addr)
{
- if (!*addr)
- {
#ifdef IPV6
- memcpy(&addy, &server.sin6_addr, sizeof(in6_addr));
+ memcpy(&addy, &server.sin6_addr, sizeof(in6_addr));
#else
- server.sin_addr.s_addr = htonl(INADDR_ANY);
+ server.sin_addr.s_addr = htonl(INADDR_ANY);
#endif
- }
- else
- {
+ }
+ else
+ {
#ifdef IPV6
- memcpy(&addy, &server.sin6_addr, sizeof(in6_addr));
+ memcpy(&addy, &server.sin6_addr, sizeof(in6_addr));
#else
- server.sin_addr = addy;
+ server.sin_addr = addy;
#endif
- }
}
#ifdef IPV6
server.sin6_port = htons(port);