/* This code has not been tested, but in theory, should work */ /* It KINDA prevents a user/site from hammering/flooding the login ports */ /* with connections, either to hurt the CPU usage, or more importantly, */ /* use up all the connection slots so no more connections can be taken. */ /* It will allow up to MAX_CONNS_PER_MIN connections per minute per site */ /* before it auto-restricts that ip. We should really kill/quit all */ /* connections from said ip to the talker once auto-restrict is done, */ /* because said user might still have up to MAX_CONNS_PER_MIN connections */ /* still open after the auto-restrict (until they time-out). */ /* We also might need to consider the fact, that even though a site is */ /* auto-restricted, the user may still try and hammer the login port, */ /* and for each connection (up until the talker responds with the "your */ /* site has been restricted" message) take up a user slot for that amount */ /* of time. Whether this is effective for the flooder would depend on */ /* their quickness to generate a connection vs. our quickness to drop one */ /* One would think the flooder would win, given a non-stop stream of */ /* connections for a very extended period of time */ #define MAX_CONNLIST_ENTRIES 20 #define MAX_CONNS_PER_MIN 10 STRUCTURES: struct { char site[16]; time_t starttime; int connections; } connlist[MAX_CONNLIST_ENTRIES]; PROTOTYPES: int find_free_connslot(void); int in_connlist(int user); void expire_connlist_entries(int mode); START CODE (when talker boots): expire_connlist_entries(-1); CHECK CODE: before gethostbyaddr()/name resolution, but AFTER ip determination.. int pos=0,free=0; pos=in_connlist(new_user); if (!pos) { /* not in list */ free=find_free_connslot(); strcpy(connlist[free].site,ustr[user].site); connlist[free].connections=1; connlist[free].starttime=time(0); } else { /* pos is where they are */ if (connlist[pos].connections > MAX_CONNS_PER_MIN) { /* auto ban the site */ auto_restrict(new_user); expire_connlist_entries(pos); } else connlist[pos].connections++; } TIMED CODE: in do_events() (in NUTS) expire_connlist_entries(-2); DECLARATIONS: int in_connlist(int user) { int z=0; for (z=0;z= 60) goto DOCLEAR; else continue; } /* else if */ else { /* specific clear */ z=mode; goto DOCLEAR; } /* else */ DOCLEAR: connlist[z].site[0]=0; connlist[z].connections=0; connlist[z].starttime=0; if (mode >= 0) break; } /* for */ }