bool InitTypes(ServerConfig* conf, const char* tag)
{
- if (!conf->opertypes.size())
- return true;
-
- conf->GetInstance()->Log(DEBUG,"Currently %d items to clear",conf->opertypes.size());
- for (opertype_t::iterator n = conf->opertypes.begin(); n != conf->opertypes.end(); n++)
+ if (conf->opertypes.size())
{
- conf->GetInstance()->Log(DEBUG,"Clear item");
- if (n->second)
- delete[] n->second;
+ conf->GetInstance()->Log(DEBUG,"Currently %d items to clear",conf->opertypes.size());
+ for (opertype_t::iterator n = conf->opertypes.begin(); n != conf->opertypes.end(); n++)
+ {
+ conf->GetInstance()->Log(DEBUG,"Clear item");
+ if (n->second)
+ delete[] n->second;
+ }
}
conf->opertypes.clear();
bool InitClasses(ServerConfig* conf, const char* tag)
{
- if (!conf->operclass.size())
- return true;
-
- for (operclass_t::iterator n = conf->operclass.begin(); n != conf->operclass.end(); n++)
+ if (conf->operclass.size())
{
- if (n->second)
- delete[] n->second;
+ for (operclass_t::iterator n = conf->operclass.begin(); n != conf->operclass.end(); n++)
+ {
+ if (n->second)
+ delete[] n->second;
+ }
}
conf->operclass.clear();
try
{
ServerInstance->Log(DEBUG,"Passing instance: %08x",this->ServerInstance);
- res_reverse = new UserResolver(this->ServerInstance, this, this->GetIPString(), false);
+ res_reverse = new UserResolver(this->ServerInstance, this, this->GetIPString(), DNS_QUERY_REVERSE);
this->ServerInstance->AddResolver(res_reverse);
}
catch (ModuleException& e)
}
}
-UserResolver::UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, bool forward) :
- Resolver(Instance, to_resolve, forward ? DNS_QUERY_FORWARD : DNS_QUERY_REVERSE), bound_user(user)
+UserResolver::UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, QueryType qt) :
+ Resolver(Instance, to_resolve, qt), bound_user(user)
{
- this->fwd = forward;
+ this->fwd = (qt == DNS_QUERY_A || qt == DNS_QUERY_AAAA);
this->bound_fd = user->GetFd();
}
/* Check we didnt time out */
if (this->bound_user->registered != REG_ALL)
{
- bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, true);
+ const char *ip = this->bound_user->GetIPString();
+ bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, (strstr(ip,"0::ffff:") == ip ? DNS_QUERY_A : DNS_QUERY_AAAA));
this->ServerInstance->AddResolver(bound_user->res_forward);
}
}
else if ((this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user))
{
/* Both lookups completed */
- if (this->bound_user->GetIPString() == result)
+ std::string result2 = "0::ffff:";
+ result2.append(result);
+ if (this->bound_user->GetIPString() == result || this->bound_user->GetIPString() == result2)
{
std::string hostname = this->bound_user->stored_host;
if (hostname.length() < 65)
*password = *nick = *ident = *host = *dhost = *fullname = *awaymsg = *oper = 0;
server = (char*)Instance->FindServerNamePtr(Instance->Config->ServerName);
reset_due = ServerInstance->Time();
+ age = ServerInstance->Time(true);
lines_in = lastping = signon = idle_lastmsg = nping = registered = 0;
ChannelCount = timeout = flood = bytes_in = bytes_out = cmds_in = cmds_out = 0;
haspassed = dns_done = false;
}
}
-/* XXX - minor point, other *Host functions return a char *, this one creates it. Might be nice to be consistant? */
-void userrec::MakeHost(char* nhost)
+char* userrec::MakeHost()
{
+ static char nhost[MAXBUF];
/* This is much faster than snprintf */
char* t = nhost;
for(char* n = ident; *n; n++)
for(char* n = host; *n; n++)
*t++ = *n;
*t = 0;
+ return nhost;
+}
+
+char* userrec::MakeHostIP()
+{
+ static char ihost[MAXBUF];
+ /* This is much faster than snprintf */
+ char* t = ihost;
+ for(char* n = ident; *n; n++)
+ *t++ = *n;
+ *t++ = '@';
+ for(const char* n = this->GetIPString(); *n; n++)
+ *t++ = *n;
+ *t = 0;
+ return ihost;
}
void userrec::CloseSocket()
{
try
{
- if (this->fd == FD_MAGIC_NUMBER)
+ if ((this->fd == FD_MAGIC_NUMBER) || (*this->GetWriteError()))
{
sendq = "";
}
if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER))
{
+ int old_sendq_length = sendq.length();
const char* tb = this->sendq.c_str();
int n_sent = write(this->fd,tb,this->sendq.length());
if (n_sent == -1)
{
- if (errno != EAGAIN)
+ if (errno == EAGAIN)
+ {
+ ServerInstance->Log(DEBUG,"EAGAIN, want write");
+ this->ServerInstance->SE->WantWrite(this);
+ }
+ else
this->SetWriteError(strerror(errno));
}
else
{
+ /*ServerInstance->Log(DEBUG,"Wrote: %d of %d: %s", n_sent, old_sendq_length, sendq.substr(0, n_sent).c_str());*/
// advance the queue
tb += n_sent;
this->sendq = tb;
// update the user's stats counters
this->bytes_out += n_sent;
this->cmds_out++;
+ if (n_sent != old_sendq_length)
+ {
+ ServerInstance->Log(DEBUG,"Not all written, want write");
+ this->ServerInstance->SE->WantWrite(this);
+ }
}
}
}
/* IP addresses starting with a : on irc are a Bad Thing (tm) */
if (*buf == ':')
{
- strlcpy(&temp[1], buf, sizeof(temp));
+ strlcpy(&temp[1], buf, sizeof(temp) - 1);
*temp = '0';
return temp;
}
/* IP addresses starting with a : on irc are a Bad Thing (tm) */
if (*buf == ':')
{
- strlcpy(&temp[1], buf, sizeof(temp));
+ strlcpy(&temp[1], buf, sizeof(temp) - 1);
*temp = '0';
strlcpy(buf, temp, sizeof(temp));
}
this->AddWriteBuf(text);
}
ServerInstance->stats->statsSent += text.length();
+ this->ServerInstance->SE->WantWrite(this);
}
/** Write()
try
{
- prefix << ":" << ServerInstance->Config->ServerName << " 319 " << this->nick << " " << dest->nick << " :";
+ prefix << this->nick << " " << dest->nick << " :";
line = prefix.str();
+ int namelen = strlen(ServerInstance->Config->ServerName) + 6;
for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1)
{
length = (pos == std::string::npos) ? cl.length() : pos;
- if (line.length() + length - start > 510)
+ if (line.length() + namelen + length - start > 510)
{
this->Write(line);
line = prefix.str();
if (line.length())
{
- this->Write(line);
+ ServerInstance->SendWhoisLine(this, dest, 319, "%s", line.c_str());
}
}
this->WriteServ("NOTICE %s :End of %s rules.",this->nick,ServerInstance->Config->ServerName);
}
-void userrec::HandleEvent(EventType et)
+void userrec::HandleEvent(EventType et, int errornum)
{
/* WARNING: May delete this user! */
try
{
- ServerInstance->ProcessUser(this);
+ switch (et)
+ {
+ case EVENT_READ:
+ ServerInstance->ProcessUser(this);
+ break;
+ case EVENT_WRITE:
+ this->FlushWriteBuf();
+ break;
+ case EVENT_ERROR:
+ this->SetWriteError(errornum ? strerror(errornum) : "EOF from client");
+ break;
+ }
}
catch (...)
{