diff options
author | kcwu <kcwu@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2006-03-30 01:14:01 +0800 |
---|---|---|
committer | kcwu <kcwu@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2006-03-30 01:14:01 +0800 |
commit | fd8c79217d534ad45ac189b9f78ad49157dd24b1 (patch) | |
tree | 3bdcbefeee197843efe650e4df775b6b83a2ef9e /mbbsd | |
parent | 99cefa7694fc89c2830341b2f4d41c0e9ee571a1 (diff) | |
download | pttbbs-fd8c79217d534ad45ac189b9f78ad49157dd24b1.tar pttbbs-fd8c79217d534ad45ac189b9f78ad49157dd24b1.tar.gz pttbbs-fd8c79217d534ad45ac189b9f78ad49157dd24b1.tar.bz2 pttbbs-fd8c79217d534ad45ac189b9f78ad49157dd24b1.tar.lz pttbbs-fd8c79217d534ad45ac189b9f78ad49157dd24b1.tar.xz pttbbs-fd8c79217d534ad45ac189b9f78ad49157dd24b1.tar.zst pttbbs-fd8c79217d534ad45ac189b9f78ad49157dd24b1.zip |
prevent multi-login and slow login flooding.
WARRNING, utmpserver protocol is incompatiable with old mbbsd.
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3312 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd')
-rw-r--r-- | mbbsd/mbbsd.c | 43 | ||||
-rw-r--r-- | mbbsd/talk.c | 106 |
2 files changed, 93 insertions, 56 deletions
diff --git a/mbbsd/mbbsd.c b/mbbsd/mbbsd.c index 19709aa8..5ce3af8a 100644 --- a/mbbsd/mbbsd.c +++ b/mbbsd/mbbsd.c @@ -522,21 +522,18 @@ write_request(int sig) } static userinfo_t* -getotherlogin(void) +getotherlogin(int num) { userinfo_t *ui; - if (!(ui = (userinfo_t *) search_ulist(usernum))) - return NULL; /* user isn't logged in */ + do { + if (!(ui = (userinfo_t *) search_ulistn(usernum, num))) + return NULL; /* user isn't logged in */ -#ifdef DEBUGSLEEP - /* skip sleeping process */ - while (ui->pid && - (ui->uid == usernum && ui->mode == DEBUGSLEEPING)) - ui++; + /* skip sleeping process, this is slow if lots */ + if(ui->mode == DEBUGSLEEPING) + num++; + } while (ui->mode == DEBUGSLEEPING); - if(ui->uid != usernum) - return NULL; -#endif return ui; } @@ -550,7 +547,7 @@ multi_user_check(void) return; /* don't check sysops */ if (cuser.userlevel) { - ui = getotherlogin(); + ui = getotherlogin(1); if(ui == NULL) return; if (!ui->pid /* || (kill(pid, 0) == -1) */ ) @@ -562,16 +559,22 @@ multi_user_check(void) if (genbuf[0] != 'n') { // race condition here, sleep may help..? usleep(random()%1000000+100000); // 0.1~1.1s - // scan again, old ui may be invalid - ui = getotherlogin(); - if(ui == NULL) - return; - if (ui->pid > 0) - kill(ui->pid, SIGHUP); - log_usies("KICK ", cuser.nickname); + do { + // scan again, old ui may be invalid + ui = getotherlogin(1); + if(ui==NULL) + return; + if (ui->pid > 0) { + kill(ui->pid, SIGHUP); + log_usies("KICK ", cuser.nickname); + } else { + fprintf(stderr, "id=%s ui->pid=0\n", cuser.userid); + } + sleep(1); + } while(getotherlogin(3) != NULL); } else { /* deny login if still have 3 */ - if (search_ulistn(usernum, 3) != NULL) + if (getotherlogin(3) != NULL) abort_bbs(0); /* Goodbye(); */ } } else { diff --git a/mbbsd/talk.c b/mbbsd/talk.c index 9d627ab2..e177822d 100644 --- a/mbbsd/talk.c +++ b/mbbsd/talk.c @@ -237,6 +237,70 @@ void verbose_progress(int em, int *i, int *dir, int max) *dir *= -1; } +#ifdef OUTTACACHE +int sync_outta_server(int sfd) +{ + int i; + int offset = (int)(currutmp - &SHM->uinfo[0]); + + int cmd, res; + int nfs; + ocfs_t fs[MAX_FRIEND*2]; + + int iBar = 0, barMax = t_columns/2, dir = 1; + + verbose_progress(0, &iBar, &dir, barMax); + cmd = -2; + if(towrite(sfd, &cmd, sizeof(cmd))<0 || + towrite(sfd, &offset, sizeof(offset))<0 || + towrite(sfd, &currutmp->uid, sizeof(currutmp->uid)) < 0 || + towrite(sfd, currutmp->myfriend, sizeof(currutmp->myfriend))<0 || + towrite(sfd, currutmp->reject, sizeof(currutmp->reject))<0) + return -1; + + verbose_progress(0, &iBar, &dir, barMax); + if(toread(sfd, &res, sizeof(res))<0) + return -1; + + if(res<0) + return -1; + if(res==2) { + outs("登入太頻繁, 為避免系統負荷過重, 請稍後再試\n"); + refresh(); + sleep(10); + abort_bbs(0); + } + + verbose_progress(0, &iBar, &dir, barMax); + if(toread(sfd, &nfs, sizeof(nfs))<0) + return -1; + if(nfs<0 || nfs>=MAX_FRIEND) { + fprintf(stderr, "invalid nfs=%d\n",nfs); + return -1; + } + + if(toread(sfd, fs, sizeof(fs[0])*nfs)<0) + return -1; + + verbose_progress(0, &iBar, &dir, barMax); + for(i=0; i<nfs; i++) { + if( SHM->uinfo[fs[i].index].uid != fs[i].uid ) + continue; // double check, server may not know user have logout + currutmp->friend_online[currutmp->friendtotal++] + = fs[i].friendstat; + /* XXX: race here */ + if( SHM->uinfo[fs[i].index].friendtotal < MAX_FRIEND ) + SHM->uinfo[fs[i].index].friend_online[ SHM->uinfo[fs[i].index].friendtotal++ ] = fs[i].rfriendstat; + } + verbose_progress(1, &iBar, &dir, barMax); + + if(res==1) { + vmsg("請勿頻繁登入以免造成系統過度負荷"); + } + return 0; +} +#endif + void login_friend_online(void) { userinfo_t *uentp; @@ -244,48 +308,18 @@ void login_friend_online(void) int offset = (int)(currutmp - &SHM->uinfo[0]); #ifdef OUTTACACHE - int sfd; - - int iBar = 0, barMax = t_columns/2, dir = 1; - + int sfd; /* OUTTACACHE is TOO slow, let's prompt user here. */ move(b_lines-2, 0); clrtobot(); outs("\n正在更新與同步線上使用者及好友名單,系統負荷量大時會需時較久...\n"); refresh(); - verbose_progress(0, &iBar, &dir, barMax); - if( (sfd = toconnect(OUTTACACHEHOST, OUTTACACHEPORT)) > 0 ){ - - verbose_progress(0, &iBar, &dir, barMax); - if( towrite(sfd, &offset, sizeof(offset)) > 0 && - towrite(sfd, &currutmp->uid, sizeof(currutmp->uid)) > 0 && - towrite(sfd, currutmp->myfriend, sizeof(currutmp->myfriend)) > 0 && - towrite(sfd, currutmp->reject, sizeof(currutmp->reject)) > 0 ){ - - ocfs_t fs; - while( currutmp->friendtotal < MAX_FRIEND && - toread(sfd, &fs, sizeof(fs)) > 0 ) - { - verbose_progress(0, &iBar, &dir, barMax); - if( SHM->uinfo[fs.index].uid == fs.uid ) - { - currutmp->friend_online[currutmp->friendtotal++] - = fs.friendstat; - /* XXX: race here */ - if( SHM->uinfo[fs.index].friendtotal < MAX_FRIEND ) - SHM->uinfo[fs.index].friend_online[ SHM->uinfo[fs.index].friendtotal++ ] = fs.rfriendstat; - } - } - verbose_progress(1, &iBar, &dir, barMax); - - /* 要把剩下的收完, 要不然會卡死 utmpserver */ - if( currutmp->friendtotal == MAX_FRIEND ) - while( toread(sfd, &fs, sizeof(fs)) > 0 ) - verbose_progress(1, &iBar, &dir, barMax); - close(sfd); - return; - } + sfd = toconnect(OUTTACACHEHOST, OUTTACACHEPORT); + if(sfd>=0) { + int res=sync_outta_server(sfd); close(sfd); + if(res==0) + return; } #endif |