- if (0 == entry->target) {
- entry->target = (struct IPTargetEntry *)MyMalloc(sizeof(struct IPTargetEntry));
- assert(0 != entry->target);
- entry->target->count = STARTTARGETS;
- }
- memcpy(entry->target->targets, cptr->targets, MAXTARGETS);
-
- /*
- * This calculation can be pretty unfair towards large multi-user hosts,
- * but there is "nothing" we can do without also allowing spam bots to
- * send more messages or by drastically increasing the ammount of memory
- * used in the IPregistry.
- *
- * The problem is that when a client disconnects, leaving no free targets,
- * then the next client from that IP number has to pay for it (getting no
- * free targets). But ALSO the next client, and the next client, and the
- * next client etc - until another client disconnects that DOES leave free
- * targets. The reason for this is that if there are 10 SPAM bots, and
- * they all disconnect at once, then they ALL should get no free targets
- * when reconnecting. We'd need to store an entry per client (instead of
- * per IP number) to avoid this.
- */
- if (cptr->nexttarget < CurrentTime)
- free_targets = (CurrentTime - cptr->nexttarget) / TARGET_DELAY + 1;
- else
- free_targets = 0;
-
- /* Add bonus, this is pretty fuzzy, but it will help in some cases. */
- if ((CurrentTime - cptr->firsttime) > 600)
- free_targets += (CurrentTime - cptr->firsttime - 600) / TARGET_DELAY;
-
- /* Finally, store smallest value for Judgement Day */
- if (free_targets < entry->target->count)
- entry->target->count = free_targets;
+ /* Add bonus, if you've been connected for more than 10 minutes you
+ * get a free target every TARGET_DELAY seconds.
+ * this is pretty fuzzy, but it will help in some cases.
+ */
+ if ((CurrentTime - cptr->firsttime) > 600)
+ free_targets += (CurrentTime - cptr->firsttime - 600) / TARGET_DELAY;
+
+ /* Finally, store smallest value for Judgement Day */
+ if (free_targets < entry->target->count)
+ entry->target->count = free_targets;
+
+}
+
+/*----------------------------------------------------------------------------
+ * ip_registry_remote_disconnect
+ *
+ * Event:
+ * A remote client disconnected.
+ *
+ * Action:
+ * Update the IPcheck registry.
+ * Remove all expired IPregistry structures from the hash bucket
+ * that belongs to this clients IP number.
+ *--------------------------------------------------------------------------*/
+void ip_registry_remote_disconnect(struct Client *cptr)
+{
+ struct IPRegistryEntry *entry;
+
+ assert(0 != cptr);
+
+ entry = ip_registry_find(cptr->ip.s_addr);
+
+ assert(entry);
+
+ assert(entry->connected > 0);
+ Debug((DEBUG_DEBUG,"IPcheck: Remote Disconnect"));
+
+ if (entry->connected > 0) {
+ entry->connected--;
+ }
+
+ /*
+ * If this was the last one, set `last_connect' to disconnect time
+ * (used for expiration) Note that we reset attempts here as well if our
+ * threshhold hasn't been crossed.
+ */
+ if (0 == entry->connected) {
+ ip_registry_update_free_targets(entry);
+ entry->last_connect=NOW;