jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00021 /* rate controls (for implementing connect-limiting or karma) */ 00022 00023 #include "util.h" 00024 00025 rate_t rate_new(int total, int seconds, int wait) 00026 { 00027 rate_t rt = (rate_t) calloc(1, sizeof(struct rate_st)); 00028 00029 rt->total = total; 00030 rt->seconds = seconds; 00031 rt->wait = wait; 00032 00033 return rt; 00034 } 00035 00036 void rate_free(rate_t rt) 00037 { 00038 free(rt); 00039 } 00040 00041 void rate_reset(rate_t rt) 00042 { 00043 rt->time = 0; 00044 rt->count = 0; 00045 rt->bad = 0; 00046 } 00047 00048 void rate_add(rate_t rt, int count) 00049 { 00050 time_t now; 00051 00052 now = time(NULL); 00053 00054 /* rate expired */ 00055 if(now - rt->time >= rt->seconds) 00056 rate_reset(rt); 00057 00058 rt->count += count; 00059 00060 /* first event, so set the time */ 00061 if(rt->time == 0) 00062 rt->time = now; 00063 00064 /* uhoh, they stuffed up */ 00065 if(rt->count >= rt->total) 00066 rt->bad = now; 00067 } 00068 00069 int rate_left(rate_t rt) 00070 { 00071 /* if we're bad, then there's none left */ 00072 if(rt->bad != 0) 00073 return 0; 00074 00075 return rt->total - rt->count; 00076 } 00077 00078 int rate_check(rate_t rt) 00079 { 00080 /* not tracking */ 00081 if(rt->time == 0) 00082 return 1; 00083 00084 /* under the limit */ 00085 if(rt->count < rt->total) 00086 return 1; 00087 00088 /* currently bad */ 00089 if(rt->bad != 0) 00090 { 00091 /* wait over, they're good again */ 00092 if(time(NULL) - rt->bad >= rt->wait) 00093 { 00094 rate_reset(rt); 00095 return 1; 00096 } 00097 00098 /* keep them waiting */ 00099 return 0; 00100 } 00101 00102 /* they're inside the time, and not bad yet */ 00103 return 1; 00104 }