extern InspIRCd* ServerInstance;
extern ServerConfig* Config;
extern time_t TIME;
+extern Server* MyServer;
InspSocket* socket_ref[MAX_DESCRIPTORS];
+
InspSocket::InspSocket()
{
this->state = I_DISCONNECTED;
}
}
-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)
}
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();
this->fd = -1;
this->state = I_ERROR;
this->OnError(I_ERR_BIND);
this->ClosePending = true;
- log(DEBUG,"BindSocket() error %s",strerror(errno));
return;
}
else
}
else
{
- strlcpy(this->host,ahost.c_str(),MAXBUF);
+ strlcpy(this->host,ipaddr.c_str(),MAXBUF);
this->port = aport;
- if (!inet_aton(host,&addy))
+ if (insp_aton(host,&addy) < 1)
{
- log(DEBUG,"Attempting to resolve %s",this->host);
- /* Its not an ip, spawn the resolver */
- this->dns.SetNS(std::string(Config->DNSServer));
- this->dns.ForwardLookupWithFD(host,fd);
- timeout_end = time(NULL) + maxtime;
- timeout = false;
- this->state = I_RESOLVING;
- socket_ref[this->fd] = this;
+ log(DEBUG,"You cannot pass hostnames to InspSocket, resolve them first with Resolver!");
+ this->Close();
+ this->fd = -1;
+ this->state = I_ERROR;
+ this->OnError(I_ERR_RESOLVE);
+ this->ClosePending = true;
+ return;
}
else
{
setsockopt(nfd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
}
-bool InspSocket::DoResolve()
-{
- log(DEBUG,"In DoResolve(), trying to resolve IP");
- if (this->dns.HasResult())
- {
- log(DEBUG,"Socket has result");
- std::string res_ip = dns.GetResultIP();
- if (res_ip != "")
- {
- log(DEBUG,"Socket result set to %s",res_ip.c_str());
- strlcpy(this->IP,res_ip.c_str(),MAXBUF);
- socket_ref[this->fd] = NULL;
- }
- else
- {
- log(DEBUG,"Socket DNS failure");
- this->Close();
- this->state = I_ERROR;
- this->OnError(I_ERR_RESOLVE);
- this->fd = -1;
- this->ClosePending = true;
- return false;
- }
- return this->DoConnect();
- }
- log(DEBUG,"No result for socket yet!");
- return true;
-}
-
/* Most irc servers require you to specify the ip you want to bind to.
* If you dont specify an IP, they rather dumbly bind to the first IP
* of the box (e.g. INADDR_ANY). In InspIRCd, we scan thought the IP
if ((IP != "*") && (IP != "127.0.0.1") && (IP != ""))
{
insp_sockaddr s;
- char resolved_addr[MAXBUF];
-
- if (!inet_aton(IP.c_str(),&n))
- {
- /* 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))
- {
- log(DEBUG,"Resolved host %s to %s",IP.c_str(),resolved_addr);
- IP = resolved_addr;
- }
- }
- if (inet_aton(IP.c_str(),&n))
+ if (insp_aton(IP.c_str(),&n) > 0)
{
log(DEBUG,"Found an IP to bind to: %s",IP.c_str());
+#ifdef IPV6
+ s.sin6_addr = n;
+ s.sin6_family = AF_FAMILY;
+#else
s.sin_addr = n;
- s.sin_family = AF_INET;
+ s.sin_family = AF_FAMILY;
+#endif
if (bind(this->fd,(struct sockaddr*)&s,sizeof(s)) < 0)
{
log(DEBUG,"Cant bind()");
bool InspSocket::DoConnect()
{
log(DEBUG,"In DoConnect()");
- if ((this->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+ if ((this->fd = socket(AF_FAMILY, SOCK_STREAM, 0)) == -1)
{
log(DEBUG,"Cant socket()");
this->state = I_ERROR;
return false;
}
- if (!this->BindAddr())
- return false;
+ if ((strstr(this->IP,"::ffff:") != (char*)&this->IP) && (strstr(this->IP,"::FFFF:") != (char*)&this->IP))
+ {
+ if (!this->BindAddr())
+ return false;
+ }
log(DEBUG,"Part 2 DoConnect() %s",this->IP);
- inet_aton(this->IP,&addy);
- addr.sin_family = AF_INET;
+ insp_aton(this->IP,&addy);
+#ifdef IPV6
+ addr.sin6_family = AF_FAMILY;
+ memcpy(&addr.sin6_addr, &addy, sizeof(insp_inaddr));
+ addr.sin6_port = htons(this->port);
+#else
+ addr.sin_family = AF_FAMILY;
addr.sin_addr = addy;
addr.sin_port = htons(this->port);
+#endif
int flags;
flags = fcntl(this->fd, F_GETFL, 0);
return true;
}
- if (((this->state == I_RESOLVING) || (this->state == I_CONNECTING)) && (current > timeout_end))
+ if ((this->state == I_CONNECTING) && (current > timeout_end))
{
log(DEBUG,"Timed out, current=%lu timeout_end=%lu");
// for non-listening sockets, the timeout can occur
switch (this->state)
{
- case I_RESOLVING:
- log(DEBUG,"State = I_RESOLVING, calling DoResolve()");
- return this->DoResolve();
- break;
case I_CONNECTING:
log(DEBUG,"State = I_CONNECTING");
this->SetState(I_CONNECTED);
length = sizeof (client);
incoming = accept (this->fd, (sockaddr*)&client,&length);
this->SetQueues(incoming);
- this->OnIncomingConnection(incoming,inet_ntoa(client.sin_addr));
+#ifdef IPV6
+ this->OnIncomingConnection(incoming,(char*)insp_ntoa(client.sin6_addr));
+#else
+ this->OnIncomingConnection(incoming,(char*)insp_ntoa(client.sin_addr));
+#endif
return true;
break;
case I_CONNECTED: