-/* add a client connection to the sockets list */
-void AddClient(int socket, char* host, int port, bool iscached, char* ip)
-{
- string tempnick;
- char tn2[MAXBUF];
- user_hash::iterator iter;
-
- tempnick = ConvToStr(socket) + "-unknown";
- sprintf(tn2,"%lu-unknown",(unsigned long)socket);
-
- iter = clientlist.find(tempnick);
-
- // fix by brain.
- // as these nicknames are 'RFC impossible', we can be sure nobody is going to be
- // using one as a registered connection. As theyre per fd, we can also safely assume
- // that we wont have collisions. Therefore, if the nick exists in the list, its only
- // used by a dead socket, erase the iterator so that the new client may reclaim it.
- // this was probably the cause of 'server ignores me when i hammer it with reconnects'
- // issue in earlier alphas/betas
- if (iter != clientlist.end())
- {
- userrec* goner = iter->second;
- delete goner;
- clientlist.erase(iter);
- }
-
- /*
- * It is OK to access the value here this way since we know
- * it exists, we just created it above.
- *
- * At NO other time should you access a value in a map or a
- * hash_map this way.
- */
- clientlist[tempnick] = new userrec();
-
- log(DEBUG,"AddClient: %lu %s %d %s",(unsigned long)socket,host,port,ip);
-
- clientlist[tempnick]->fd = socket;
- strlcpy(clientlist[tempnick]->nick, tn2,NICKMAX);
- strlcpy(clientlist[tempnick]->host, host,160);
- strlcpy(clientlist[tempnick]->dhost, host,160);
- clientlist[tempnick]->server = (char*)FindServerNamePtr(Config->ServerName);
- strlcpy(clientlist[tempnick]->ident, "unknown",IDENTMAX);
- clientlist[tempnick]->registered = 0;
- clientlist[tempnick]->signon = TIME + Config->dns_timeout;
- clientlist[tempnick]->lastping = 1;
- clientlist[tempnick]->port = port;
- strlcpy(clientlist[tempnick]->ip,ip,16);
-
- // set the registration timeout for this user
- unsigned long class_regtimeout = 90;
- int class_flood = 0;
- long class_threshold = 5;
- long class_sqmax = 262144; // 256kb
- long class_rqmax = 4096; // 4k
-
- for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
- {
- if (match(clientlist[tempnick]->host,i->host.c_str()) && (i->type == CC_ALLOW))
- {
- class_regtimeout = (unsigned long)i->registration_timeout;
- class_flood = i->flood;
- clientlist[tempnick]->pingmax = i->pingtime;
- class_threshold = i->threshold;
- class_sqmax = i->sendqmax;
- class_rqmax = i->recvqmax;
- break;
- }
- }
-
- clientlist[tempnick]->nping = TIME+clientlist[tempnick]->pingmax + Config->dns_timeout;
- clientlist[tempnick]->timeout = TIME+class_regtimeout;
- clientlist[tempnick]->flood = class_flood;
- clientlist[tempnick]->threshold = class_threshold;
- clientlist[tempnick]->sendqmax = class_sqmax;
- clientlist[tempnick]->recvqmax = class_rqmax;
-
- ucrec a;
- a.channel = NULL;
- a.uc_modes = 0;
- for (int i = 0; i < MAXCHANS; i++)
- clientlist[tempnick]->chans.push_back(a);
-
- if (local_users.size() > Config->SoftLimit)
- {
- kill_link(clientlist[tempnick],"No more connections allowed");
- return;
- }
-
- if (local_users.size() >= MAXCLIENTS)
- {
- kill_link(clientlist[tempnick],"No more connections allowed");
- return;
- }
-
- // this is done as a safety check to keep the file descriptors within range of fd_ref_table.
- // its a pretty big but for the moment valid assumption:
- // file descriptors are handed out starting at 0, and are recycled as theyre freed.
- // therefore if there is ever an fd over 65535, 65536 clients must be connected to the
- // irc server at once (or the irc server otherwise initiating this many connections, files etc)
- // which for the time being is a physical impossibility (even the largest networks dont have more
- // than about 10,000 users on ONE server!)
- if ((unsigned)socket > MAX_DESCRIPTORS)
- {
- kill_link(clientlist[tempnick],"Server is full");
- return;
- }
- char* e = matches_exception(ip);
- if (!e)
- {
- char* r = matches_zline(ip);
- if (r)
- {
- char reason[MAXBUF];
- snprintf(reason,MAXBUF,"Z-Lined: %s",r);
- kill_link(clientlist[tempnick],reason);
- return;
- }
- }
- fd_ref_table[socket] = clientlist[tempnick];
+ log(DEBUG,"AddClient: %d %d %s",socket,port,ipaddr);
+
+ clientlist[tempnick] = new userrec();
+ clientlist[tempnick]->fd = socket;
+ strlcpy(clientlist[tempnick]->nick,tempnick.c_str(),NICKMAX-1);
+
+ /* Smarter than your average bear^H^H^H^Hset of strlcpys. */
+ for (char* temp = (char*)ipaddr; *temp && j < 64; temp++, j++)
+ clientlist[tempnick]->dhost[j] = clientlist[tempnick]->host[j] = *temp;
+ clientlist[tempnick]->dhost[j] = clientlist[tempnick]->host[j] = 0;
+
+ clientlist[tempnick]->server = (char*)FindServerNamePtr(Config->ServerName);
+ /* We don't need range checking here, we KNOW 'unknown\0' will fit into the ident field. */
+ strcpy(clientlist[tempnick]->ident, "unknown");
+
+ clientlist[tempnick]->registered = 0;
+ clientlist[tempnick]->signon = TIME + Config->dns_timeout;
+ clientlist[tempnick]->lastping = 1;
+ clientlist[tempnick]->ip4 = ip4;
+ clientlist[tempnick]->port = port;
+
+ // set the registration timeout for this user
+ unsigned long class_regtimeout = 90;
+ int class_flood = 0;
+ long class_threshold = 5;
+ long class_sqmax = 262144; // 256kb
+ long class_rqmax = 4096; // 4k
+
+ for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
+ {
+ if ((i->type == CC_ALLOW) && (match(ipaddr,i->host.c_str())))
+ {
+ class_regtimeout = (unsigned long)i->registration_timeout;
+ class_flood = i->flood;
+ clientlist[tempnick]->pingmax = i->pingtime;
+ class_threshold = i->threshold;
+ class_sqmax = i->sendqmax;
+ class_rqmax = i->recvqmax;
+ break;
+ }
+ }
+
+ clientlist[tempnick]->nping = TIME+clientlist[tempnick]->pingmax + Config->dns_timeout;
+ clientlist[tempnick]->timeout = TIME+class_regtimeout;
+ clientlist[tempnick]->flood = class_flood;
+ clientlist[tempnick]->threshold = class_threshold;
+ clientlist[tempnick]->sendqmax = class_sqmax;
+ clientlist[tempnick]->recvqmax = class_rqmax;
+
+ fd_ref_table[socket] = clientlist[tempnick];