diff options
author | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2005-04-20 17:34:19 +0800 |
---|---|---|
committer | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2005-04-20 17:34:19 +0800 |
commit | eaa73de381ee283ff5e0da64ee49bfecddb21723 (patch) | |
tree | bff8d7eda27d9c2b138963f91cdb1b54c28ec923 | |
parent | 98d2b0e42f38b5fa8993ef1caf27aaebddfc5fb4 (diff) | |
download | pttbbs-eaa73de381ee283ff5e0da64ee49bfecddb21723.tar pttbbs-eaa73de381ee283ff5e0da64ee49bfecddb21723.tar.gz pttbbs-eaa73de381ee283ff5e0da64ee49bfecddb21723.tar.bz2 pttbbs-eaa73de381ee283ff5e0da64ee49bfecddb21723.tar.lz pttbbs-eaa73de381ee283ff5e0da64ee49bfecddb21723.tar.xz pttbbs-eaa73de381ee283ff5e0da64ee49bfecddb21723.tar.zst pttbbs-eaa73de381ee283ff5e0da64ee49bfecddb21723.zip |
add NOFLOODING on utmpserver
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@2701 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r-- | cacheserver/utmpserver.c | 150 | ||||
-rw-r--r-- | mbbsd/mbbsd.c | 3 | ||||
-rw-r--r-- | sample/pttbbs.conf | 7 |
3 files changed, 119 insertions, 41 deletions
diff --git a/cacheserver/utmpserver.c b/cacheserver/utmpserver.c index 2fb3f7ab..05a5ccfd 100644 --- a/cacheserver/utmpserver.c +++ b/cacheserver/utmpserver.c @@ -9,6 +9,23 @@ struct { int reject[MAX_REJECT]; } utmp[USHM_SIZE]; +#ifdef NOFLOODING +#define MAXWAIT 1024 +#define FLUSHTIME (3600*6) + +struct { + time_t lasttime; + int count; +} flooding[MAX_USERS]; + +int nWaits, lastflushtime; +struct { + int uid; + int fd; + int index; +} waitqueue[MAXWAIT]; +#endif /* NOFLOODING */ + inline int countarray(int *s, int max) { int i; @@ -68,11 +85,70 @@ void initdata(int index) sizeof(int), qsort_intcompar); } +inline void syncutmp(int cfd) +{ + int nSynced = 0, i; + for( i = 0 ; i < USHM_SIZE ; ++i, ++nSynced ) + if( toread(cfd, &utmp[i].uid, sizeof(utmp[i].uid)) > 0 && + toread(cfd, utmp[i].friend, sizeof(utmp[i].friend)) > 0 && + toread(cfd, utmp[i].reject, sizeof(utmp[i].reject)) > 0 ){ + if( utmp[i].uid ) + initdata(i); + } + else + for( ; i < USHM_SIZE ; ++i ) + utmp[i].uid = 0; + close(cfd); + fprintf(stderr, "%d users synced\n", nSynced); +} + +void processlogin(int cfd, int uid, int index) +{ + if( toread(cfd, utmp[index].friend, sizeof(utmp[index].friend)) > 0 && + toread(cfd, utmp[index].reject, sizeof(utmp[index].reject)) > 0 ){ + /* 因為 logout 的時候並不會通知 utmpserver , 可能會查到一些 + 已經 logout 的帳號。所以不能只取 MAX_FRIEND 而要多取一些 */ +#define MAX_FS (2 * MAX_FRIEND) + int iu, nFrs, stat, rstat; + ocfs_t fs[MAX_FS]; + + utmp[index].uid = uid; + initdata(index); + + for( nFrs = iu = 0 ; iu < USHM_SIZE && nFrs < MAX_FS ; ++iu ) + if( iu != index && utmp[iu].uid ){ + if( (stat = set_friend_bit(index, iu)) ){ + rstat = reverse_friend_stat(stat); + fs[nFrs].index = iu; + fs[nFrs].uid = utmp[iu].uid; + fs[nFrs].friendstat = (stat << 24) + iu; + fs[nFrs].rfriendstat = (rstat << 24) + index; + ++nFrs; + } + } + + towrite(cfd, &fs, sizeof(ocfs_t) * nFrs); + } + close(cfd); +} + +#ifdef NOFLOODING +void flushwaitqueue(void) +{ + int i; + for( i = 0 ; i < nWaits ; ++i ) + processlogin(waitqueue[i].fd, waitqueue[i].uid, waitqueue[i].index); + lastflushtime = time(NULL); + nWaits = 0; + memset(flooding, 0, sizeof(flooding)); +} +#endif + /* XXX 具有被 DoS 的可能, 請用 firewall 之類擋起來 */ int main(int argc, char **argv) { struct sockaddr_in clientaddr; - int ch, port = 5120, sfd, cfd, len, index, i, uid; + int ch, port = 5120, sfd, cfd, len, index, uid; char *iface_ip = NULL; while( (ch = getopt(argc, argv, "p:i:h")) != -1 ) @@ -92,7 +168,15 @@ int main(int argc, char **argv) if( (sfd = tobind(iface_ip, port)) < 0 ) return 1; +#ifdef NOFLOODING + lastflushtime = time(NULL); +#endif while( 1 ){ +#ifdef NOFLOODING + if( lastflushtime < (time(NULL) - 1800) ) + flushwaitqueue(); +#endif + len = sizeof(clientaddr); if( (cfd = accept(sfd, (struct sockaddr *)&clientaddr, &len)) < 0 ){ if( errno != EINTR ) @@ -101,49 +185,35 @@ int main(int argc, char **argv) } toread(cfd, &index, sizeof(index)); if( index == -1 ){ - int nSynced = 0; - for( i = 0 ; i < USHM_SIZE ; ++i, ++nSynced ) - if( toread(cfd, &utmp[i].uid, sizeof(utmp[i].uid)) > 0 && - toread(cfd, utmp[i].friend, sizeof(utmp[i].friend)) > 0 && - toread(cfd, utmp[i].reject, sizeof(utmp[i].reject)) > 0 ){ - if( utmp[i].uid ) - initdata(i); - } - else - for( ; i < USHM_SIZE ; ++i ) - utmp[i].uid = 0; - close(cfd); - fprintf(stderr, "%d users synced\n", nSynced); + syncutmp(cfd); continue; } - if( toread(cfd, &uid, sizeof(uid)) > 0 && - toread(cfd, utmp[index].friend, sizeof(utmp[index].friend)) > 0 && - toread(cfd, utmp[index].reject, sizeof(utmp[index].reject)) > 0 ){ - /* 因為 logout 的時候並不會通知 utmpserver , 可能會查到一些 - 已經 logout 的帳號。所以不能只取 MAX_FRIEND 而要多取一些 */ -#define MAX_FS (2 * MAX_FRIEND) - int iu, nFrs, stat, rstat; - ocfs_t fs[MAX_FS]; - - utmp[index].uid = uid; - initdata(index); - - for( nFrs = iu = 0 ; iu < USHM_SIZE && nFrs < MAX_FS ; ++iu ) - if( iu != index && utmp[iu].uid ){ - if( (stat = set_friend_bit(index, iu)) ){ - rstat = reverse_friend_stat(stat); - fs[nFrs].index = iu; - fs[nFrs].uid = utmp[iu].uid; - fs[nFrs].friendstat = (stat << 24) + iu; - fs[nFrs].rfriendstat = (rstat << 24) + index; - ++nFrs; - } - } - - towrite(cfd, &fs, sizeof(ocfs_t) * nFrs); + if( toread(cfd, &uid, sizeof(uid)) > 0 ){ + if( !(0 < uid || uid > MAX_USERS) ){ /* for safety */ + close(cfd); + continue; + } + +#ifdef NOFLOODING + if( (time(NULL) - flooding[uid].lasttime) < 20 ) + ++flooding[uid].count; + if( flooding[uid].count > 10 ){ + if( nWaits == MAXWAIT ) + flushwaitqueue(); + waitqueue[nWaits].uid = uid; + waitqueue[nWaits].index = index; + waitqueue[nWaits].fd = cfd; + ++nWaits; + + continue; + } + flooding[uid].lasttime = time(NULL); +#endif + + /* cfd will be closed in processlogin() */ + processlogin(cfd, uid, index); } - close(cfd); } return 0; } diff --git a/mbbsd/mbbsd.c b/mbbsd/mbbsd.c index cc8afba3..92377e37 100644 --- a/mbbsd/mbbsd.c +++ b/mbbsd/mbbsd.c @@ -819,7 +819,8 @@ setup_utmp(int mode) if (!(cuser.numlogins % 20) && cuser.userlevel & PERM_BM) check_BM(); /* Ptt 自動取下離職板主權力 */ #ifndef _BBS_UTIL_C_ - friend_load(0); + if( strcmp(cuser.userid, STR_GUEST) != 0 ) // guest 不處理好友 + friend_load(0); nice(3); #endif } diff --git a/sample/pttbbs.conf b/sample/pttbbs.conf index 3410610c..e3a3a68e 100644 --- a/sample/pttbbs.conf +++ b/sample/pttbbs.conf @@ -168,6 +168,13 @@ /* 如果 time_t 是 8 bytes的話 (如 X86_64) */ //#define TIMET64 +/* 使用 cacheserver, 在外部運算好友資料, 如果您確定這個在做什麼才開啟 */ +//#define OUTTACACHE +//#define OUTTACACHEHOST "192.168.0.1" +//#define OUTTACACHEPORT 5120 +/* 在 cacheserver 上面擋掉狂上下站的使用者 */ +//#define NOFLOODING + /* 前進站畫面 */ #define INSCREEN \ "前進站畫面 (請至 pttbbs.conf 修改您的前進站畫面)" |