summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cacheserver/utmpserver2.c110
-rw-r--r--mbbsd/mbbsd.c43
-rw-r--r--mbbsd/talk.c106
3 files changed, 154 insertions, 105 deletions
diff --git a/cacheserver/utmpserver2.c b/cacheserver/utmpserver2.c
index c38855f9..3ad6c4c3 100644
--- a/cacheserver/utmpserver2.c
+++ b/cacheserver/utmpserver2.c
@@ -18,32 +18,47 @@ time_t begin_time;
int count_flooding, count_login;
#ifdef NOFLOODING
-#define MAXWAIT 1024
-#define FLUSHTIME (3600*6)
+/* 0 ok, 1 delay action, 2 reject */
+int action_frequently(int uid)
+{
+ int i;
+ time_t now = time(NULL);
+ time_t minute = now/60;
+ time_t hour = minute/60;
-struct {
- time_t lasttime;
- int count;
-} flooding[MAX_USERS];
+ static time_t flood_base_minute;
+ static time_t flood_base_hour;
+ static struct {
+ unsigned short minute_count;
+ unsigned short hour_count;
+ } flooding[MAX_USERS];
-int nWaits, lastflushtime;
-struct {
- int uid;
- int fd;
- int index;
-} waitqueue[MAXWAIT];
+ if(minute!=flood_base_minute) {
+ for(i=0; i<MAX_USERS; i++)
+ flooding[i].minute_count=0;
+ flood_base_minute=minute;
+ }
+ if(hour!=flood_base_hour) {
+ for(i=0; i<MAX_USERS; i++)
+ flooding[i].hour_count=0;
+ flood_base_hour=hour;
+ }
-void processlogin(int cfd, int uid, int index);
-void flushwaitqueue(void)
-{
- int i;
- for( i = 0 ; i < nWaits ; ++i ) {
- processlogin(waitqueue[i].fd, waitqueue[i].uid, waitqueue[i].index);
- close(waitqueue[i].fd);
+ if(flooding[uid].minute_count>30 ||
+ flooding[uid].hour_count>60) {
+ count_flooding++;
+ return 2;
+ }
+ if(flooding[uid].minute_count>5 ||
+ flooding[uid].hour_count>20) {
+ count_flooding++;
+ return 1;
}
- lastflushtime = time(NULL);
- nWaits = 0;
- memset(flooding, 0, sizeof(flooding));
+
+ flooding[uid].minute_count++;
+ flooding[uid].hour_count++;
+
+ return 0;
}
#endif /* NOFLOODING */
@@ -106,6 +121,7 @@ void processlogin(int cfd, int uid, int index)
/* 因為 logout 的時候並不會通知 utmpserver , 可能會查到一些
已經 logout 的帳號。所以不能只取 MAX_FRIEND 而要多取一些 */
#define MAX_FS (2 * MAX_FRIEND)
+ int res;
int nfs;
ocfs_t fs[MAX_FS];
@@ -131,6 +147,12 @@ void processlogin(int cfd, int uid, int index)
utmplogin(uid, index, like, hate);
nfs=genfriendlist(uid, index, fs, MAX_FS);
#ifndef FAKEDATA
+ res=0;
+#ifdef NOFLOODING
+ res=action_frequently(uid);
+#endif
+ towrite(cfd, &res, sizeof(res));
+ towrite(cfd, &nfs, sizeof(nfs));
towrite(cfd, fs, sizeof(ocfs_t) * nfs);
#endif
}
@@ -162,6 +184,7 @@ int main(int argc, char *argv[])
int cmd;
int uid,index;
int fail;
+ int firstsync=0;
#ifdef UTMPLOG
logfp = fopen("utmp.log","a");
@@ -192,15 +215,7 @@ int main(int argc, char *argv[])
if( (sfd = tobind(iface_ip, port)) < 0 )
return 1;
#endif
-#ifdef NOFLOODING
- lastflushtime = time(NULL);
-#endif
while(1) {
-#ifdef NOFLOODING
- if( lastflushtime < (time(NULL) - 1800) )
- flushwaitqueue();
-#endif
-
#ifdef FAKEDATA
if(fread(&cmd, sizeof(cmd), 1, fp)==0) break;
#else
@@ -218,6 +233,12 @@ int main(int argc, char *argv[])
#ifndef FAKEDATA
close(cfd);
#endif
+ firstsync=1;
+ continue;
+ }
+ if(!firstsync) {
+ // don't accept client before first sync, to prevent incorrect friend data
+ close(cfd);
continue;
}
@@ -226,9 +247,17 @@ int main(int argc, char *argv[])
fread(&uid, sizeof(uid), 1, fp);
fread(&index, sizeof(index), 1, fp);
#else
- index=cmd; // bad protocol
- if(toread(cfd, &uid, sizeof(uid)) <= 0)
+ if(cmd==-2) {
+ if(toread(cfd, &index, sizeof(index)) <= 0)
+ fail=1;
+ if(toread(cfd, &uid, sizeof(uid)) <= 0)
+ fail=1;
+ } else if(cmd>=0) {
+ // old client
fail=1;
+ } else {
+ printf("unknown cmd=%d\n",cmd);
+ }
#endif
if(index>=USHM_SIZE) {
fprintf(stderr, "bad index=%d\n",index);
@@ -242,23 +271,6 @@ int main(int argc, char *argv[])
continue;
}
-#ifdef NOFLOODING
- if( (time(NULL) - flooding[uid].lasttime) < 20 )
- ++flooding[uid].count;
- if( flooding[uid].count > 10 ){
- count_flooding++;
- if( nWaits == MAXWAIT )
- flushwaitqueue();
- waitqueue[nWaits].uid = uid;
- waitqueue[nWaits].index = index;
- waitqueue[nWaits].fd = cfd;
- ++nWaits;
-
- continue;
- }
- flooding[uid].lasttime = time(NULL);
-#endif
-
count_login++;
processlogin(cfd, uid, index);
if(count_login>=4000 || time(NULL)-begin_time>30*60)
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("nJWc, קKtέtL, еyA\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("ФWcnJHKytιL׭t");
+ }
+ 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("\nbsPPBuWϥΪ̤ΦnͦWAtέtqjɷ|ݮɸ[...\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);
-
- /* nѤU, nM|d 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