void ServernameResolver::OnLookupComplete(const DNS::Query *r) { const DNS::ResourceRecord &ans_record = r->answers[0]; /* Initiate the connection, now that we have an IP to use. * Passing a hostname directly to BufferedSocket causes it to * just bail and set its FD to -1. */ TreeServer* CheckDupe = Utils->FindServer(MyLink->Name.c_str()); if (!CheckDupe) /* Check that nobody tried to connect it successfully while we were resolving */ { TreeSocket* newsocket = new TreeSocket(Utils, MyLink, myautoconnect, ans_record.rdata); if (newsocket->GetFd() > -1) { /* We're all OK */ } else { /* Something barfed, show the opers */ ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.", MyLink->Name.c_str(), newsocket->getError().c_str()); ServerInstance->GlobalCulls.AddItem(newsocket); } } }
void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y) { bool ipvalid = true; if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name))) { ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Not connecting to myself."); return; } DNS::QueryType start_type = DNS::QUERY_AAAA; if (strchr(x->IPAddr.c_str(),':')) { in6_addr n; if (inet_pton(AF_INET6, x->IPAddr.c_str(), &n) < 1) ipvalid = false; } else { in_addr n; if (inet_aton(x->IPAddr.c_str(),&n) < 1) ipvalid = false; } /* Do we already have an IP? If so, no need to resolve it. */ if (ipvalid) { /* Gave a hook, but it wasnt one we know */ TreeSocket* newsocket = new TreeSocket(x, y, x->IPAddr); if (newsocket->GetFd() > -1) { /* Handled automatically on success */ } else { ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.", x->Name.c_str(), newsocket->getError().c_str()); ServerInstance->GlobalCulls.AddItem(newsocket); } } else if (!DNS) { ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: Hostname given and m_dns.so is not loaded, unable to resolve.", x->Name.c_str()); } else { ServernameResolver* snr = new ServernameResolver(*DNS, x->IPAddr, x, start_type, y); try { DNS->Process(snr); } catch (DNS::Exception& e) { delete snr; ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.",x->Name.c_str(), e.GetReason()); ConnectServer(y, false); } } }
void ModuleSpanningTree::ConnectServer(Link* x) { bool ipvalid = true; QueryType start_type = DNS_QUERY_A; #ifdef IPV6 start_type = DNS_QUERY_AAAA; if (strchr(x->IPAddr.c_str(),':')) { in6_addr n; if (inet_pton(AF_INET6, x->IPAddr.c_str(), &n) < 1) ipvalid = false; } else #endif { in_addr n; if (inet_aton(x->IPAddr.c_str(),&n) < 1) ipvalid = false; } /* Do we already have an IP? If so, no need to resolve it. */ if (ipvalid) { /* Gave a hook, but it wasnt one we know */ if ((!x->Hook.empty()) && (Utils->hooks.find(x->Hook.c_str()) == Utils->hooks.end())) return; TreeSocket* newsocket = new TreeSocket(Utils, ServerInstance, x->IPAddr,x->Port,false,x->Timeout ? x->Timeout : 10,x->Name.c_str(), x->Bind, x->Hook.empty() ? NULL : Utils->hooks[x->Hook.c_str()]); if (newsocket->GetFd() > -1) { /* Handled automatically on success */ } else { ServerInstance->SNO->WriteToSnoMask('l',"CONNECT: Error connecting \002%s\002: %s.",x->Name.c_str(),strerror(errno)); delete newsocket; Utils->DoFailOver(x); } } else { try { bool cached; ServernameResolver* snr = new ServernameResolver((Module*)this, Utils, ServerInstance,x->IPAddr, *x, cached, start_type); ServerInstance->AddResolver(snr, cached); } catch (ModuleException& e) { ServerInstance->SNO->WriteToSnoMask('l',"CONNECT: Error connecting \002%s\002: %s.",x->Name.c_str(), e.GetReason()); Utils->DoFailOver(x); } } }
void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y) { bool ipvalid = true; if (InspIRCd::Match(ServerInstance->Config->ServerName, x->Name, ascii_case_insensitive_map)) { ServerInstance->SNO.WriteToSnoMask('l', "CONNECT: Not connecting to myself."); return; } #ifndef _WIN32 if (x->IPAddr.find('/') != std::string::npos) { struct stat sb; if (stat(x->IPAddr.c_str(), &sb) == -1 || !S_ISSOCK(sb.st_mode)) ipvalid = false; } #endif if (x->IPAddr.find(':') != std::string::npos) { in6_addr n; if (inet_pton(AF_INET6, x->IPAddr.c_str(), &n) < 1) ipvalid = false; } else { in_addr n; if (inet_pton(AF_INET, x->IPAddr.c_str(),&n) < 1) ipvalid = false; } /* Do we already have an IP? If so, no need to resolve it. */ if (ipvalid) { // Create a TreeServer object that will start connecting immediately in the background TreeSocket* newsocket = new TreeSocket(x, y, x->IPAddr); if (newsocket->GetFd() > -1) { /* Handled automatically on success */ } else { ServerInstance->SNO.WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.", x->Name.c_str(), newsocket->getError().c_str()); ServerInstance->GlobalCulls.AddItem(newsocket); } } else if (!DNS) { ServerInstance->SNO.WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: Hostname given and core_dns is not loaded, unable to resolve.", x->Name.c_str()); } else { // Guess start_type from bindip aftype DNS::QueryType start_type = DNS::QUERY_AAAA; irc::sockets::sockaddrs bind; if ((!x->Bind.empty()) && (irc::sockets::aptosa(x->Bind, 0, bind))) { if (bind.family() == AF_INET) start_type = DNS::QUERY_A; } ServernameResolver* snr = new ServernameResolver(*DNS, x->IPAddr, x, start_type, y); try { DNS->Process(snr); } catch (DNS::Exception& e) { delete snr; ServerInstance->SNO.WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.",x->Name.c_str(), e.GetReason().c_str()); ConnectServer(y, false); } } }