OSDN Git Service

Ver1.5.18 Modified treatment of overlapped sessions. Fixed bugs.
authorwatanaby <>
Mon, 30 Jul 2012 02:01:18 +0000 (02:01 +0000)
committerwatanaby <>
Mon, 30 Jul 2012 02:01:18 +0000 (02:01 +0000)
opengate/conf/ipfwctrl.pl.sample
opengate/doc/Changes.html
opengate/opengatesrv/comm-cgi.c
opengate/opengatesrv/comm-ip6fw.c
opengate/opengatesrv/comm-ipfw.c
opengate/opengatesrv/comm-userdb.c
opengate/opengatesrv/ctrl-firewall.c
opengate/opengatesrv/main.c
opengate/opengatesrv/opengatesrv.h
opengate/opengatesrv/test-comm-userdb.c
opengate/opengatesrv/watch-client.c

index 460a15f..709e1a8 100644 (file)
@@ -15,100 +15,8 @@ system "$ipfwpath","-q","add","$rulenumber",
 system "$ipfwpath","-q","add","$rulenumber",
     "count","tag","$ipfwtagnumber","ip","from","any","to","$clientaddr";
 
-## remove process attached to the same user on different ip address.
-## if you allow multi-login, comment out next line.
-removeSameUserProc
-    ($ipfwpath,$rulenumber,$clientaddr,$userid,$macaddr,$userproperty,$ipfwtagnumber);
-
 exit 0;
 
-
-######## Search same user processes and remove.############
-sub removeSameUserProc
-{
-    # get response from 'ps ax'.
-    open(pspipe, "ps -axww|");
-
-    # scan ps output
-    while(<pspipe>){
-       # get lines for opengatesrv process and divide it with ','
-       if(/\s*(\d*) .* opengatesrv.cgi: (.*),(.*),(.*) /){
-           $ps_number=$1; $ps_arg1=$2; $ps_arg2=$3; $ps_arg3=$4;
-           
-           # get the user id before '('
-           if($ps_arg1=~/(.*)\(/){
-               $ps_user=$1;
-           }else{
-               $ps_user=$ps_arg1;
-           }
-           
-           # get the IPv4 address located between '[' and '('
-           if($ps_arg2=~/\[(.*)\(/){
-               $ps_ipv4=$1;
-           }else{
-               $ps_ipv4="";
-           }
-           # get the IPv4 rule number located between '(' and ')'
-           if($ps_arg2=~/\((\d*)\)\]/){
-               $ps_rule4=$1;
-           }else{
-               $ps_rule4="";
-           }
-           
-           # get the IPv6 address located between '[' and '('
-           if($ps_arg3=~/\[(.*)\(/){
-               $ps_ipv6=$1;
-           }else{
-               $ps_ipv6="";
-           }
-           # get the IPv6 rule number located between '(' and ')'
-           if($ps_arg3=~/\((\d*)\)\]/){
-               $ps_rule6=$1;
-           }else{
-               $ps_rule6="";
-           }
-           
-           # get the IPv6 address located between '[' and '('
-           if($ps_arg3=~/\[(.*)\(/){
-               $ps_ipv6=$1;
-           }else{
-               $ps_ipv6="";
-           }
-           
-           # kill process attached to same user on different address.
-           $need_to_kill = 0;
-
-           # is same user?
-           if($userid eq $ps_user){
-
-               # is ipv6 addr ?
-               if($clientaddr=~/:/){
-
-                   # is not same ipv6 addr ?
-                   if( ($ps_ipv6 ne "") && ($ps_ipv6 ne $clientaddr) ){
-                       system "$ipfwpath","-q","del","$ps_rule6";
-                       $need_to_kill = 1;
-                   }
-
-               }else{
-
-                   # is not same ipv4 addr ?
-                   if( ($ps_ipv4 ne "") && ($ps_ipv4 ne $clientaddr) ){
-                       system "$ipfwpath","-q","del","$ps_rule4";
-                       $need_to_kill = 1;
-                   }
-               }
-               
-               # is found process need to kill ?
-               if( $need_to_kill == 1 ){
-                   system "kill", "$ps_number";
-               }
-           }
-       }
-    }
-    close(pspipe);
-}
-
 __END__
 
 ########### Above line is the end of interpreting#############
@@ -163,11 +71,6 @@ system "$ipfwpath","-q","add","$rulenumber",
 system "$ipfwpath","-q","add","$rulenumber",
     "count","tag","$ipfwtagnumber","ip","from","any","to","$clientaddr";
 
-## remove process attached to the same user on different ip address.
-## if you allow multi-login, comment out next line.
-removeSameUserProc
-    ($ipfwpath,$rulenumber,$clientaddr,$userid,$macaddr,$userproperty,$ipfwtagnumber);
-
 exit 0;
 ======================================================
 
index d743f39..c4039f6 100644 (file)
@@ -704,6 +704,10 @@ Opengate History</H3>
        Ver.1.5.17 at 2012.2.13
        </DT><DD>
        Removed 2 error messages.
+       </DD><DT>
+       Ver.1.5.18 at 2012.2.28
+       </DT><DD>
+       Modified treatment of overlapped sessions. Fixed bugs.
        </DD>
        </DL>
 <P>
index 45cd6af..90c5bb0 100644 (file)
@@ -238,7 +238,7 @@ int getUserIdFromEnv(char *userid){
 /********************************************/
 /* get data related to cookie from client  */
 /********************************************/
-int getCookieData(char *userid, char *clientAddr4, int *duration, int *durationEntered, char *language)
+int getCookieData(char *userid, char *clientAddr4, int *duration, int *durationEntered, char *language, char* closeTime)
 {
   char cookie[SIDMAXLN]=""; /* md5 session key from cookie */
   char useridInCookie[USERMAXLN]=""; /* userid from cookie */
@@ -250,7 +250,7 @@ int getCookieData(char *userid, char *clientAddr4, int *duration, int *durationE
 
   /* get related info from DB */ 
   if(!GetSessionInfoFromDb(cookie, userid, clientAddr4, macAddrInDb, 
-                          duration, durationEntered, language)) return FALSE;
+                          duration, durationEntered, language, closeTime)) return FALSE;
     
   /* if userid is changed, cookie auth is failed */
   if(strcmp(useridInCookie, userid)!=0) return FALSE;
@@ -721,11 +721,12 @@ int GetAuthCookie(char *cookie, char *userid){
   return ret;
 }
 
-int GetCookieData(char *userid, char *clientAddr4, int *duration, int *durationEntered, char *language){
+int GetCookieData(char *userid, char *clientAddr4, int *duration, int *durationEntered, char *language, char* closeTime){
   int ret;
 
   if(debug>1) err_msg("DEBUG:=>getCookieData( )");
-  ret=getCookieData(userid,clientAddr4,duration,durationEntered,language);
-  if(debug>1) err_msg("DEBUG:%d<=getCookieData(%s,passwd,%s,%d,%d,%s)",ret,userid,clientAddr4,*duration,*durationEntered,language);
+  ret=getCookieData(userid,clientAddr4,duration,durationEntered,
+                   language,closeTime);
+  if(debug>1) err_msg("DEBUG:%d<=getCookieData(%s,passwd,%s,%d,%d,%s,%s)",ret,userid,clientAddr4,*duration,*durationEntered,language,closeTime);
   return ret;
 }
index 1c548dd..6f66302 100644 (file)
@@ -42,7 +42,7 @@ int openClientGate6(char *clientAddr6, char *userid, char *macAddr6, char *userP
 
   Sigfunc *defaultSigFunc;
 
-  /* exclusive exec of ipfw to avoid overlapped rule number */
+  /* exclusive exec of ipfw to avoid duplicated rule number */
 
   /**** prepare ****/
   /* open lockfile */
@@ -85,12 +85,8 @@ int openClientGate6(char *clientAddr6, char *userid, char *macAddr6, char *userP
       err_msg("ERR at %s#%d: exec ipfw script error",__FILE__,__LINE__);
       ret=1; /* abmormal */
     }
-
-    /* lock is not necessary in following exec */
-    Unlock(fd);
-    Close(fd);    /* because reserved number is used */
-
-  }else{
+  }
+  else{
     /********** direct control of firewall **********************/
     /********** add outgoing ipfw rule for the client *************/
     if(Systeml(1, GetConfValue("IpfwPath"),"-q","add",ruleNumber6,
@@ -100,10 +96,6 @@ int openClientGate6(char *clientAddr6, char *userid, char *macAddr6, char *userP
              err_msg("ERR at %s#%d: exec ipfw add error",__FILE__,__LINE__);
              ret=1;
     }
-    
-    /* lock is not necessary in following exec */
-    Unlock(fd);
-    Close(fd);    /* because reserved number is used */
 
     /********** add incoming ipfw rule for the client *************/
     if(Systeml(1, GetConfValue("IpfwPath"),"-q","add",ruleNumber6,
@@ -114,6 +106,11 @@ int openClientGate6(char *clientAddr6, char *userid, char *macAddr6, char *userP
              ret=1; /* abnormal */
     }
   }
+
+  /* uplock */
+  Unlock(fd);
+  Close(fd);
+
   return ret;
 }
 
@@ -177,7 +174,7 @@ int getRuleNumber6(char *clientAddr6)
   int ip6fwinterval;
   int portStatus;
   int fileStatus;
-  enum status {NORMAL, ABNORMAL, FOUND, NOTFOUND, DUPLICATED};
+  enum status {NORMAL, ABNORMAL, FOUND, NOTFOUND, DUP};
 
   if((fpipe=Popenl(1, "r", GetConfValue("IpfwPath"),"list",(char *)0)) == NULL){ 
       err_msg("ERR at %s#%d: exec ipfw list error",__FILE__,__LINE__);
@@ -237,7 +234,7 @@ int getRuleNumber6(char *clientAddr6)
         && !isalnum(*(p+strlen(clientAddr6)))){
        /* the clientAddr is found in the rule num */
        newNum=num;
-       portStatus=DUPLICATED;
+       portStatus=DUP;
        break;
       }
       /* the num is used for other client */
@@ -265,7 +262,8 @@ int getRuleNumber6(char *clientAddr6)
     err_msg("ERR at %s#%d: cannot get unused ipfw number",__FILE__,__LINE__);
     return -1;
   }
-  if(portStatus==DUPLICATED){
+  if(portStatus==DUP){
+    snprintf(ruleNumber6, WORDMAXLN, "%d", newNum); /* to string */
     return -newNum;
   }
 
index e614943..4a1558f 100644 (file)
@@ -43,7 +43,7 @@ int openClientGate4(char *clientAddr4, char *userid, char *macAddr4, char *userP
 
   Sigfunc *defaultSigFunc;
 
-  /* exclusive exec of ipfw to avoid overlapped rule number */
+  /* exclusive exec of ipfw to avoid duplicated rule number */
   /**** prepare ****/
   /* open lockfile */
   fd=open(GetConfValue("LockFile"), O_RDWR|O_CREAT, 
@@ -87,12 +87,8 @@ int openClientGate4(char *clientAddr4, char *userid, char *macAddr4, char *userP
       err_msg("ERR at %s#%d: exec script error",__FILE__,__LINE__);
       ret=1;  /* abnormal */
     }
-    
-    /* lock is not necessary in following exec */
-    Unlock(fd);
-    Close(fd);    /* because reserved number is used */
-
-  }else{
+  }
+  else{
     /********** direct control of firewall **********************/
     /********** add outgoing ipfw rule for the client *************/
     if(Systeml(1, GetConfValue("IpfwPath"),"-q","add",ruleNumber4,
@@ -103,10 +99,6 @@ int openClientGate4(char *clientAddr4, char *userid, char *macAddr4, char *userP
       ret=1;  /* abnormal */
     }
 
-    /* lock is not necessary in following exec */
-    Unlock(fd);
-    Close(fd);    /* because reserved number is used */
-    
     if(Systeml(1, GetConfValue("IpfwPath"),"-q","add",ruleNumber4,
               "count","tag",GetConfValue("IpfwTagNumber"),
               "ip","from","any","to",clientAddr4,
@@ -115,6 +107,11 @@ int openClientGate4(char *clientAddr4, char *userid, char *macAddr4, char *userP
       ret=1; /* abnormal */
     }
   }
+
+  /* unlock */
+  Unlock(fd);
+  Close(fd); 
+
   return ret;
 }
 
@@ -179,7 +176,7 @@ int getRuleNumber4(char *clientAddr4)
   int ipfwinterval;
   int portStatus;
   int fileStatus;
-  enum status {NORMAL, ABNORMAL, FOUND, NOTFOUND, DUPLICATED};
+  enum status {NORMAL, ABNORMAL, FOUND, NOTFOUND, DUP};
 
   /* exec ipfw list and open pipe */
   if((fpipe=Popenl(1, "r", GetConfValue("IpfwPath"),"list",(char *)0)) == NULL){ 
@@ -238,10 +235,8 @@ int getRuleNumber4(char *clientAddr4)
       if(((p=(char*)strstr(buf+1,clientAddr4))!=NULL)
        && isspace(*(p-1))
        && !isalnum(*(p+strlen(clientAddr4)))){
-       err_msg("ERR at %s#%d: overlapped request from %s",
-               __FILE__,__LINE__, clientAddr4);
        newNum=num;
-       portStatus=DUPLICATED;
+       portStatus=DUP;
        break;
       }
       /* the num is used for other client */
@@ -269,7 +264,8 @@ int getRuleNumber4(char *clientAddr4)
     err_msg("ERR at %s#%d: cannot get unused ipfw number",__FILE__,__LINE__);
     return -1;
   }
-  if(portStatus==DUPLICATED){
+  if(portStatus==DUP){
+    snprintf(ruleNumber4, WORDMAXLN, "%d", newNum); /* to string */
     return -newNum;
   }
 
index c44d370..96f53ee 100644 (file)
@@ -21,12 +21,20 @@ int putSessionBeginToDb(char* cookie, char* userid,
   sqlite3 *db;
   char *pErrMsg;
   /* SQL CREATE COMMAND */
-  char *createCmd="CREATE TABLE session (cookie TEXT PRIMARY KEY,\
+  char *createTblCmd="CREATE TABLE IF NOT EXISTS \
+ session (cookie TEXT PRIMARY KEY,\
  userid TEXT, pid INTEGER, openTime TEXT, closeTime TEXT,\
  clientAddr4 TEXT, clientAddr6 TEXT, macAddr TEXT,\
  ruleNumber4 INTEGER, ruleNumber6 INTEGER,duration INTEGER,\
  durationEntered INTEGER, cookieAuth INTEGER, language TEXT, watchMode TEXT)";
 
+  char *createIdx1Cmd="CREATE INDEX IF NOT EXISTS \
+ clientAddr4Index ON session (clientAddr4)";
+
+  char *createIdx2Cmd="CREATE INDEX IF NOT EXISTS \
+ closeTimeIndex ON session (closeTime)";
+
+
   /* SQL INSERT COMMAND, where %x is replaced in snprintf */
   char *insertFormat="INSERT INTO session\
  (cookie, userid, pid, openTime, closeTime,\
@@ -45,6 +53,24 @@ int putSessionBeginToDb(char* cookie, char* userid,
     return FALSE;
   }
   
+  /* create table if not exists */
+  if(sqlite3_exec(db, createTblCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+    resultFlag=FALSE;
+    err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+  }
+
+  /* create index for clientAddr4 if not exists */
+  if(sqlite3_exec(db, createIdx1Cmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+    resultFlag=FALSE;
+    err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+  }
+
+  /* create index for closeTime if not exists */
+  if(sqlite3_exec(db, createIdx2Cmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+    resultFlag=FALSE;
+    err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+  }
+
   /* Prepare insert command */
   insertCmd=sqlite3_mprintf(insertFormat,cookie,userid, 
                            getpid(),time(NULL),clientAddr4,clientAddr6, 
@@ -53,24 +79,10 @@ int putSessionBeginToDb(char* cookie, char* userid,
 
   /* Execute insert to sqlite */
   if((rc=sqlite3_exec(db, insertCmd, NULL, NULL, &pErrMsg))!=SQLITE_OK){
-       
-    /* If the error is 'no such table' It might be initial state */
-    if(rc==SQLITE_ERROR && strstr(pErrMsg, "no such table:")!=NULL){
-
-      /* retry from create */
-      if(sqlite3_exec(db, createCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
-       resultFlag=FALSE;
-       err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
-      }
-      if(sqlite3_exec(db, insertCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
-       resultFlag=FALSE;
-       err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
-      }
-    }
 
     /* If the error is 'table session has no column named xxx' */
     /* It might be adding column in varsion up */
-    else if(rc==SQLITE_ERROR && strstr(pErrMsg, "has no column named")!=NULL){
+    if(rc==SQLITE_ERROR && strstr(pErrMsg, "has no column named")!=NULL){
       err_msg("ERR at %s#%d: DB format is changed in version up, remove '%s' and retry",__FILE__,__LINE__,GetConfValue("SqliteDb"));
       resultFlag=FALSE;
     }
@@ -130,19 +142,60 @@ int putSessionEndToDb(char* cookie, char* watchMode){
   return resultFlag;
 }
 
+/**************************************************************/
+/* write close time to db to fix no-close error               */ 
+/**************************************************************/
+int fixProcessEndInDb(int pid, char* watchMode){
+
+  sqlite3 *db;
+  char *pErrMsg;
+
+  /* SQL UPDATE COMMAND, where %x is replaced in mprintf */
+  char *updateFormat="UPDATE session SET closeTime=\
+ datetime(%d,'unixepoch','localtime'), watchMode='%s' WHERE pid=%d";
+  char *updateCmd;
+  int resultFlag=TRUE;
+
+  /* open sqlite */
+  if(sqlite3_open(GetConfValue("SqliteDb"),&db)!=SQLITE_OK){
+    err_msg("ERR at %s#%d: sqlite3_open",__FILE__,__LINE__);
+    sqlite3_close(db);
+    return FALSE;
+  }
+  
+  /* prepare command */
+  updateCmd=sqlite3_mprintf(updateFormat, time(NULL), watchMode, pid);
+
+  /* execute replace to sqlite */
+  if(sqlite3_exec(db, updateCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+    resultFlag=FALSE;
+    err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+  }
+
+  /*memory free for sqlite3 string */
+  sqlite3_free(updateCmd);
+  
+  /* sqlite close */
+  sqlite3_close(db);
+
+  return resultFlag;
+}
+
 /*************************************************/
-/* read userid and others from session database  */ 
+/* read userid and others from session database  */
+/* search key is coocke                          */ 
 /*************************************************/
 int getSessionInfoFromDb(char* cookie, char* userid, 
                          char* clientAddr4, char *macAddr, 
-                        int *duration, int *durationEntered, char *language){
+                        int *duration, int *durationEntered, char *language,
+                        char* closeTime){
 
   sqlite3 *db;
   sqlite3_stmt *stmt;
  
   /* SQL UPDATE COMMAND, where %x is replaced in snprintf */
   char *selectFormat="SELECT userid, clientAddr4, macAddr,\
- duration, durationEntered,language FROM session WHERE cookie='%s'";
+ duration, durationEntered,language,closeTime FROM session WHERE cookie='%s'";
   char *selectCmd;
   int resultFlag=TRUE;
 
@@ -177,6 +230,7 @@ int getSessionInfoFromDb(char* cookie, char* userid,
     *duration=(int)sqlite3_column_int(stmt, 3);
     *durationEntered=(int)sqlite3_column_int(stmt, 4);
     strncpy(language, (char*)sqlite3_column_text(stmt, 5), WORDMAXLN);
+    strncpy(closeTime, (char*)sqlite3_column_text(stmt, 6), WORDMAXLN);
     resultFlag=TRUE;
   }else{
     resultFlag=FALSE;
@@ -276,6 +330,164 @@ int getUserProperty(char userid[USERMAXLN], char userProperty[BUFFMAXLN])
   return ACCEPT;           /* The User is Accepted     */
 }
 
+
+/******************************************
+find the duplicated entry in db for an ipv4 address
+if redundant rule exists, positive value is returned
+******************************************/
+int findDuplicateInDbAndClose(char* clientAddr4, int* redundantRule4, 
+                           int* redundantRule6, int* redundantPid ){
+
+  sqlite3 *db;
+  sqlite3_stmt *stmt;
+  char *pErrMsg;
+  /* SQL COMMAND, where %x is replaced in mprintf */
+  char *selectMeFormat="SELECT ruleNumber4, ruleNumber6 \
+ FROM session WHERE clientAddr4='%s' and closeTime='-' and pid=%d";
+  char *selectOtherFormat="SELECT ruleNumber4, ruleNumber6, pid \
+ FROM session WHERE clientAddr4='%s' and closeTime='-' and pid!=%d";
+  char *selectCmd;
+
+  /* SQL UPDATE COMMAND to write close time */
+  char *updateFormat="UPDATE session SET closeTime=\
+ datetime(%d,'unixepoch','localtime'), watchMode='%s' \
+ WHERE clientAddr4='%s' and closeTime='-' and pid=%d";
+
+  /* SQL TRANSACTION COMMAND */
+  char *beginTransaction="BEGIN TRANSACTION";
+  char *commitTransaction="COMMIT TRANSACTION";
+
+  char *updateCmd;
+  int resultFlag=TRUE;
+  int ruleNumberMe4=0;
+  int ruleNumberMe6=0;
+  int ruleNumberOther4=0;
+  int ruleNumberOther6=0;
+
+  /* initial values */
+  *redundantRule4=0;
+  *redundantRule6=0;
+  *redundantPid=0;
+
+  /********************prepare db**********************/
+  /* open sqlite */
+  if(sqlite3_open(GetConfValue("SqliteDb"),&db)!=SQLITE_OK){
+    err_msg("ERR at %s#%d: sqlite3_open",__FILE__,__LINE__);
+    sqlite3_close(db);
+    return FALSE;
+  }
+
+  /* begin transaction */
+  sqlite3_exec(db, beginTransaction, NULL, NULL, &pErrMsg);
+
+  /***************** search other session in db******************/
+
+  /* prepare command string to search other session */
+  selectCmd=sqlite3_mprintf(selectOtherFormat, clientAddr4, getpid());
+  
+  /* compile to internal statement */
+  if(sqlite3_prepare(db, selectCmd, BUFFMAXLN, &stmt, NULL)!=SQLITE_OK){
+    resultFlag=FALSE;
+    err_msg("ERR at %s#%d: sqlite3_prepare:%s",__FILE__,__LINE__,
+           sqlite3_errmsg(db));
+
+    /* finalize */
+    sqlite3_free(selectCmd);
+    sqlite3_finalize(stmt);
+    sqlite3_close(db);
+    return FALSE;
+  }
+
+  /* get first match item */
+  if(sqlite3_step(stmt)==SQLITE_ROW){
+    ruleNumberOther4=(int)sqlite3_column_int(stmt, 0);
+    ruleNumberOther6=(int)sqlite3_column_int(stmt, 1);
+    *redundantPid=(int)sqlite3_column_int(stmt, 2);
+    resultFlag=TRUE;
+  }else{
+    resultFlag=FALSE;
+  }
+  
+  /* finalize */
+  sqlite3_free(selectCmd);
+  sqlite3_finalize(stmt);
+  if(resultFlag==FALSE){
+    sqlite3_close(db);
+    return FALSE;
+  }
+
+  /***********if found other, search my session in db ***********/
+
+  /* prepare command string to search my session */
+  selectCmd=sqlite3_mprintf(selectMeFormat, clientAddr4, getpid());
+  
+  /* compile to internal statement */
+  if(sqlite3_prepare(db, selectCmd, BUFFMAXLN, &stmt, NULL)!=SQLITE_OK){
+    resultFlag=FALSE;
+    err_msg("ERR at %s#%d: sqlite3_prepare:%s",__FILE__,__LINE__,
+           sqlite3_errmsg(db));
+
+    /* finalize */
+    sqlite3_free(selectCmd);
+    sqlite3_finalize(stmt);
+    sqlite3_close(db);
+    return FALSE;
+  }
+
+  /* get first match item */
+  if(sqlite3_step(stmt)==SQLITE_ROW){
+    ruleNumberMe4=(int)sqlite3_column_int(stmt, 0);
+    ruleNumberMe6=(int)sqlite3_column_int(stmt, 1);
+    resultFlag=TRUE;
+  }else{
+    resultFlag=FALSE;
+  }
+
+  /* finalize */
+  sqlite3_free(selectCmd);
+  sqlite3_finalize(stmt);
+  if(resultFlag==FALSE){
+    sqlite3_close(db);
+    return FALSE;
+  }
+
+  /*****************write close of my session**********/
+
+  /* prepare command to write close time */
+  updateCmd=sqlite3_mprintf(updateFormat, time(NULL), "NONE",
+                           clientAddr4, getpid());
+
+  /* execute replace to sqlite */
+  if(sqlite3_exec(db, updateCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+    resultFlag=FALSE;
+    err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+  }
+
+  /*memory free for sqlite3 string */
+  sqlite3_free(updateCmd);
+
+  /***************finalize db***********************/
+
+  /* end transaction and sqlite close */
+  sqlite3_exec(db, commitTransaction, NULL, NULL, &pErrMsg);
+  sqlite3_close(db);
+
+  /******************check overlapped rule*************/
+
+  /* if rule number is not match, my rule is redundant */
+  if(resultFlag==TRUE){
+    if(ruleNumberMe4==ruleNumberOther4) *redundantRule4=0;
+    else *redundantRule4=ruleNumberMe4;
+    if(ruleNumberMe6==ruleNumberOther6) *redundantRule6=0;
+    else *redundantRule6=ruleNumberMe6;
+  }
+
+  return resultFlag;
+}
+
+
+/***************************************************************/
 /***************************************************************/
 /* debug write routine */
 int PutSessionBeginToDb(char* cookie, char* userid, 
@@ -308,17 +520,29 @@ int PutSessionEndToDb(char* cookie, char* watchMode){
   return ret;
 }
 
+
+int FixProcessEndInDb(int pid, char* watchMode){
+  int ret;
+
+  if(debug>1) err_msg("DEBUG:=>fixProcessEndInDb(%s,%s)", pid, watchMode);
+  ret=fixProcessEndInDb(pid,watchMode);
+  if(debug>1) err_msg("DEBUG:(%d)<=fixProcessEndInDb()",ret);
+
+  return ret;
+}
+
+
 int GetSessionInfoFromDb(char* cookie, char* userid, char* clientAddr4, 
                         char *macAddr, int *duration, int *durationEntered,
-                        char *language){
+                        char *language, char* closeTime){
   int ret;
 
   if(debug>1) err_msg("DEBUG:=>getInfoFromDb(%s)",cookie);
   ret=getSessionInfoFromDb(cookie,userid,clientAddr4, macAddr,
-                          duration,durationEntered,language);
+                          duration,durationEntered,language,closeTime);
   if(debug>1) err_msg("DEBUG:(%d)<=getInfoFromDb(%s,%s,%s,%s,%d,%d,%s)",
                      ret,cookie,userid,clientAddr4, macAddr, 
-                     *duration,*durationEntered,language);
+                     *duration,*durationEntered,language,closeTime);
   return ret;
 }
 
@@ -341,3 +565,13 @@ int CheckNatInsertion(char* macAddr4, char* macAddr6, char* userid){
   if(debug>1) err_msg("DEBUG:(%d)<=checkNatInsertion( )",ret);
   return ret;
 }
+
+int FindDuplicateInDbAndClose(char* clientAddr4, int* redundantRule4, 
+                           int* redundantRule6, int* redundantPid ){
+  int ret;
+  if(debug>1) err_msg("DEBUG:=>findDuplicateInDbAndClose(%s,)",clientAddr4);
+  ret=findDuplicateInDbAndClose(clientAddr4,redundantRule4,redundantRule6, redundantPid);
+  if(debug>1) err_msg("DEBUG:(%d)<=findDuplicateInDbAndClose(,%d,%d,%d)",ret, 
+                     *redundantRule4,*redundantRule6, *redundantPid);
+  return ret;
+}
index 96b1acc..976d3aa 100644 (file)
@@ -30,10 +30,6 @@ extern char ruleNumber6[WORDMAXLN];  /* ip6fw rule number in string form */
 struct clientAddr *pClientAddr = NULL;
 int ipStatus;
 
-void RemoveOverlapRule(int overlapRule4, int overlapRule6);
-void KillOverlapProcess(int overlapRule4, int overlapRule6, 
-                       char *clientAddr4, char *clientAddr6);
-
 /**************************************/
 /* Open client gate for IPv4 and IPv6 */
 /**************************************/
@@ -41,7 +37,7 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
 {
   int ret;
   struct clientAddr *pLastClientAddr=NULL;
-  int overlapRule4=0, overlapRule6=0;
+  int duplicateRule4=0, duplicateRule6=0;
 
   switch(ipStatus){
 
@@ -49,13 +45,17 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
   case IPV46DUAL:
     
     /*** at first, open IPv4 gate *****/
-    if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))==0){
+    ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty);
+    if(ret==0 || ret<-2){ /* normally open or duplicated open */
 
       /* open success */
       err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
 
       /* create new address list. head and tail pointer point the same item. */
       pLastClientAddr=pClientAddr=CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
+
+      /* save dupliacted rule */
+      if(ret<-2) duplicateRule4=-ret;
     }
 
     /* open fail */
@@ -64,18 +64,19 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
       return FALSE;
     }
 
-    /* other case (ret<-2) means overlapped rule */
-    else overlapRule4=-ret;
-
 
     /*** next, open IPv6 gate *****/
-    if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))==0){
+    ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty);
+    if(ret==0 || ret<-2){ /* normally open or duplicated open */
 
       /* open success */
       err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
 
       /* add the address info to list */
       pLastClientAddr->next = CreateAddrListItem(clientAddr6,ruleNumber6,IPV6);
+
+      /* save dupliacted rule */
+      if(ret<-2) duplicateRule6=-ret;
     }
     /* open fail */
     else{
@@ -90,9 +91,6 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
        PutClientMsg("Error: Please contact to the administrator");
        return FALSE;
       }
-      
-      /* other case (ret<-2) means overlapped rule */
-      else overlapRule6=-ret;
     }
       break;  /* case IPV46DUAL end */
 
@@ -101,7 +99,8 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
   case IPV4ONLY:
 
     /* open IPv4 gate */
-    if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))==0){
+    ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty);
+    if(ret==0 || ret<-2){ /* normally open or duplicated open */
 
       /* open success */
       err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
@@ -109,6 +108,9 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
       /* create new address list. head and tail pointer point the same item. */
       pLastClientAddr=pClientAddr
        =CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
+
+      /* save dupliacted rule */
+      if(ret<-2) duplicateRule4=-ret;
     }
 
     /* open fail */
@@ -116,17 +118,14 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
       PutClientMsg("Error: Please contact to the administrator");
       return FALSE;
     }
-
-    /* other case (ret<-2) means overlapped rule */
-    else overlapRule4=-ret;
-
     break; /* case IPV4ONLY end */
     
 
     /***** if client have IPv6 only, do below ******/
   case IPV6ONLY:
     /* open IPv6 gate */
-    if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))==0){
+    ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty);
+    if(ret==0 || ret<-2){ /* normally open or duplicated open */
 
       /* open success */
       err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
@@ -134,6 +133,9 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
       /* create new address list. head and tail pointer point the same item. */
        pLastClientAddr=pClientAddr
         =CreateAddrListItem(clientAddr6,ruleNumber6,IPV6);
+
+      /* save dupliacted rule */
+      if(ret<-2) duplicateRule6=-ret;
      }
 
     /* open fail */
@@ -141,10 +143,6 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
       PutClientMsg("Error: Please contact to the administrator");
       return FALSE;
     }
-    
-    /* other case (ret<-2) means overlapped rule */
-    else overlapRule6=-ret;
-
     break; /* case IPv6ONLY end */
 
   default:
@@ -153,107 +151,45 @@ int openClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *m
   } /* switch end */
   
 
-  /* if overlapped rules exist, remove them */
-  if(overlapRule4>0 || overlapRule6>0){
+  /* if duplicated rules exist, ignore */
+  if(duplicateRule4>0 || duplicateRule6>0){
 
-    /* to cope to modification of IPv4 addr in Dual stack(send as http param)*/ 
+    /* to cope to modification of IPv4 addr in Dual stack(send as http param) */ 
     if(ipStatus==IPV46DUAL && IsSameMacAddr(macAddr4, macAddr6)==FALSE){
       err_msg("ERR at %s#%d: arp and ndp return different mac addr",
              __FILE__,__LINE__);
       PutClientMsg("Error. Please End Web and Retry. ");
-    
-    }else{
-
-      /* ipfw rule is deleted and the process is killed */
-      RemoveOverlapRule(overlapRule4,overlapRule6);
-      KillOverlapProcess(overlapRule4,overlapRule6,clientAddr4,clientAddr6);
+      return FALSE;
 
-      err_msg("INFO: user %s forces to close overlapped client", userid);
-      PutClientMsg("Network is closed. Please End Web and Retry. ");
+    }else{
+       return TRUE;
     }
-    return FALSE;
   }
 
   return TRUE;
 }
 
 /*************************************************/
-/* remove overlapped firewall rule for same addr */
+/* remove duplicated firewall rule for same addr */
 /*************************************************/
-void removeOverlapRule(int overlapRule4, int overlapRule6)
+void removeDuplicateRule(int duplicateRule4, int duplicateRule6)
 {
   char ruleNumStr[WORDMAXLN];
 
   /* if ipfw rule exist, delete it */
-  if(overlapRule4>0){
-    snprintf(ruleNumStr,WORDMAXLN,"%d",overlapRule4);
+  if(duplicateRule4>0){
+    snprintf(ruleNumStr,WORDMAXLN,"%d",duplicateRule4);
     DelIpfwRule(ruleNumStr);
   }
 
   /* if ip6fw rule exist, delete it */
-  if(overlapRule6>0){
-    snprintf(ruleNumStr,WORDMAXLN,"%d",overlapRule6);
+  if(duplicateRule6>0){
+    snprintf(ruleNumStr,WORDMAXLN,"%d",duplicateRule6);
     DelIp6fwRule(ruleNumStr);
   }
 
 }
 
-/*************************************************/
-/* kill overlapped process                       */
-/*************************************************/
-void killOverlapProcess(int overlapRule4, int overlapRule6, char *clientAddr4, char *clientAddr6){
-
-  FILE *fpipe;
-  char buff[BUFFMAXLN];
-  char cgiNamePattern[WORDMAXLN];
-  char addr4Pattern[ADDRMAXLN]="*dummy*";
-  char addr6Pattern[ADDRMAXLN]="*dummy*";
-  int procNumber=0;
-  char procNumStr[WORDMAXLN];
-
-  /* make cgi name pattern in ps title */
-  snprintf(cgiNamePattern,WORDMAXLN," %s: ", GetConfValue("MainCgi"));
-  
-  /* make cgi param pattern in ps title */
-  if(overlapRule4>0){
-    snprintf(addr4Pattern,ADDRMAXLN,"[%s(%d)]", clientAddr4, overlapRule4);
-  }
-  if(overlapRule6>0){
-    snprintf(addr6Pattern,ADDRMAXLN,"[%s(%d)]", clientAddr6, overlapRule6);
-  }
-  /* search process corresponding to the overlap rule */
-  /* opengate.cgi process shows the following title line for ps command */
-  /* "123 ... opengatesrv.cgi: ..,[123.4.5.6(10000)],[2001:1:1:1::1(10000)]..." */
-
-  /* exec "ps -axww" */
-  if((fpipe=Popenl(1, "r", GetConfValue("PsPath"), "-axww", (char *)0)) == NULL){ 
-    err_msg("ERR at %s#%d: exec ps ax error",__FILE__,__LINE__);
-  }
-    
-  /* read "ps -axww" output as follows */
-  while(fgets(buff, BUFFMAXLN, fpipe)!=NULL){
-
-    /* if opengatesrv cgi corresponding to overlap rule */
-    if(strstr(buff, cgiNamePattern)!=NULL &&
-       ( strstr(buff, addr4Pattern)!=NULL ||
-        strstr(buff, addr6Pattern)!=NULL ) ){
-
-      /* get the process number */
-      sscanf(buff, "%d", &procNumber);
-
-      /* kill the process */
-      snprintf(procNumStr, WORDMAXLN, "%d", procNumber);
-      if(Systeml(1, "kill", procNumStr, (char *)0) != 0){
-       err_msg("ERR at %s#%d: exec kill error",__FILE__,__LINE__);
-      }
-    }
-  }
-          
-  /* close pipe */
-  Pclose(fpipe);
-}  
-
 /**************************/
 /* make address list      */
 /**************************/
@@ -350,22 +286,13 @@ int CheckIpVersions(char *clientAddr4, char *clientAddr6)
   return ret;
 }
 
-void RemoveOverlapRule(int overlapRule4, int overlapRule6){
-
-  if(debug>1) err_msg("DEBUG:=>removeOverlapRule(%d,%d)",overlapRule4,overlapRule6);
-  removeOverlapRule(overlapRule4,overlapRule6);
-  if(debug>1) err_msg("DEBUG:<=removeOverlapRule( )");
-}
+void RemoveDuplicateRule(int duplicateRule4, int duplicateRule6){
 
-void KillOverlapProcess(int overlapRule4, int overlapRule6, 
-                      char *clientAddr4, char *clientAddr6){
-  if(debug>1) err_msg("DEBUG:=>killOverlapProcess(%d,%d,%s,%s)", 
-                   overlapRule4,overlapRule6,clientAddr4,clientAddr6);
-  killOverlapProcess(overlapRule4,overlapRule6,clientAddr4,clientAddr6);
-  if(debug>1) err_msg("DEBUG:<=killOverlapProcess( )");
+  if(debug>1) err_msg("DEBUG:=>removeDuplicateRule(%d,%d)",duplicateRule4,duplicateRule6);
+  removeDuplicateRule(duplicateRule4,duplicateRule6);
+  if(debug>1) err_msg("DEBUG:<=removeDuplicateRule( )");
 }
 
-
 int GetPacketCount(struct clientAddr *pClientAddr)
 {
   int ret;
index b13bb22..fe4e077 100644 (file)
@@ -42,7 +42,7 @@ char userProperty[BUFFMAXLN];
 time_t timeIn, timeOut;
 int ipStatus;              /* flag for IPV4ONLY,IPV6ONLY or IPV46DUAL */
 int connectionMode;   /* client connect mode */
-char *mode[3]={"NONE","HTTP","TIME"};
+char *mode[4]={"NONE","HTTP","TIME", "NONE"};
 
 /* variable to measuring processing time (in msec) */
 struct timeval timeBeginCgi, timeBeginWait, timeConnect, timeDisconnect;
@@ -72,6 +72,7 @@ int  main(int argc, char **argv)
   int authNum=1; /* present authserver number to check user */
   int cookieAuth=FALSE; /* Auth with HTTP-Cookie is passed */
   int isUidInEnv=FALSE; /* userid is included in environment (shibb/basic) */
+  char closeTime[WORDMAXLN]; /* session closing time ('-'=not close) */
 
   /* drop root privilege */
   seteuid(getuid());
@@ -112,7 +113,13 @@ int  main(int argc, char **argv)
   /* if cookie auth is enabled. */
   if( (*GetConfValue("EnableCookieAuth")!='0') ){
     cookieAuth=GetCookieData(userid, clientAddr4,
-                          &duration,&durationEntered,language);
+                          &duration,&durationEntered,language,closeTime);
+  }
+
+  /* if already opened, exit */
+  if(cookieAuth && closeTime[0]=='-'){
+    PutClientMsg("Already opened. Please close this page and retry.");
+    return 0;
   }
 
   /* split user@server to user and server */
@@ -274,7 +281,7 @@ void putCloseMsg(time_t timeOut, time_t timeIn)
   hour=time/60/60;
   min=(time-hour*60*60)/60;
   sec=(time-hour*60*60-min*60);
-  //err_msg("STOP: user %s at %s ( %02d:%02d:%02d )", userid, macAddr4, hour,min,sec);
+  // err_msg("STOP: user %s at %s ( %02d:%02d:%02d )", userid, macAddr4, hour,min,sec);
   return;
 }
 
@@ -284,30 +291,37 @@ void putCloseMsg(time_t timeOut, time_t timeIn)
 /*****************************/
 void closeExit(int signo)
 {
-  /* save the connect mode */
-  logConnectMode();
-
   /* write closing information to database */
   PutSessionEndToDb(cookie, mode[connectionMode]);
 
   /* signal is disabled */
   Signal(SIGTERM, SIG_DFL);
 
-  /* close firewalls */
-  while(pClientAddr!=NULL){
+  /* ignore redundant process */
+  if(connectionMode!=DUPLICATED){
+
+    /* save the connect mode */
+    logConnectMode();
 
-    if(pClientAddr->ipType==IPV4){
-      CloseClientGate4(pClientAddr,userid,macAddr4);
-    }else{
-      CloseClientGate6(pClientAddr,userid,macAddr6);
-      DeleteNdpEntry(pClientAddr->ipAddr);
+    /* close firewalls */
+    while(pClientAddr!=NULL){
+
+      if(pClientAddr->ipType==IPV4){
+
+       CloseClientGate4(pClientAddr,userid,macAddr4);
+      }else{
+
+       CloseClientGate6(pClientAddr,userid,macAddr6);
+       DeleteNdpEntry(pClientAddr->ipAddr);
+      }
+      pClientAddr = pClientAddr->next;
     }
-    pClientAddr = pClientAddr->next;
+
+    /* put out time */
+    timeOut=time(NULL);
+    PutCloseMsg(timeOut,timeIn);
   }
 
-  /* put out time */
-  timeOut=time(NULL);
-  PutCloseMsg(timeOut,timeIn);
   if(debug>1) err_msg("DEBUG:terminated");
 
   exit(1);
@@ -345,10 +359,12 @@ void logConnectMode()
 {
   long time1sec,time2sec,time3sec;
   long time1usec,time2usec,time3usec;
+  int conMode=0;
 
   /* set value on failure */
-  if(connectionMode<0 || connectionMode>2) connectionMode=NOCONNECT;
-  if(connectionMode==NOCONNECT){
+  conMode=connectionMode;
+  if(connectionMode<0 || connectionMode>2) conMode=NOCONNECT;
+  if(conMode==NOCONNECT){
     gettimeofday(&timeBeginWait, NULL) ;
     gettimeofday(&timeConnect, NULL) ;
   }
@@ -375,7 +391,7 @@ void logConnectMode()
   }
 
   if(debug>0) err_msg("INFO: user=%s watchmode=%s procsec=%ld.%06ld,%ld.%06ld,%ld.%06ld ipversion=%d useragent=%s",
-                     userid, mode[connectionMode], 
+                     userid, mode[conMode], 
                      time1sec,time1usec,
                      time2sec,time2usec,
                      time3sec,time3usec,
index d59c5ae..51f4d4d 100644 (file)
@@ -88,6 +88,7 @@ typedef       void    Sigfunc(int);   /* for signal handlers */
 #define NOCONNECT 0    /* the client is not connected yet. */
 #define HTTPCONNECT 1  /* the client is connected by HTTP Keep-Alive */
 #define ENDCONNECT 2   /* the client is now terminating */
+#define DUPLICATED 3   /* the client is duplicated */
 
 #define IPV4ONLY 4
 #define IPV46DUAL 46
@@ -130,6 +131,7 @@ int CountRuleNumber6(char *ruleNumber);
 int OpenClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *macAddr6, char *userid, char *userProperty, int ipStatus);
 void DelIpfwRule(char *ruleNumber);
 void DelIp6fwRule(char *ruleNumber);
+void RemoveDuplicateRule(int duplicateRule4, int duplicateRule6);
 
 /* ndp and arp control */
 void DeleteNdpEntry(char *clientAddr6);
@@ -142,7 +144,7 @@ struct clientAddr *CreateAddrListItem(char* ipAddr, char *ruleNumber, int ipType
 /* cgi interface */
 void GetClientAddr(char *clientAddr);
 int GetPostData(char *userid, char *password, char *clientAddr4, int *durationPtr, int *durationEntered,char *language, char *redirectedUrl);
-int GetCookieData(char *userid, char *clientAddr4, int *durationPtr, int *durationEntered,char *language);
+int GetCookieData(char *userid, char *clientAddr4, int *durationPtr, int *durationEntered,char *language, char* closeTime);
 int GetAuthCookie(char *cookie, char *userid);
 void SplitId(char* userid, char* useridshort, char* extraId);
 int CheckReferer(void);
@@ -161,10 +163,14 @@ int PutSessionBeginToDb(char* cookie, char* userid,
                        int duration, int durationEntered, int cookieAuth, 
                        char *language);
 int PutSessionEndToDb(char* cookie, char* watchMode);
+int FixProcessEndInDb(int pid, char* watchMode);
 int GetSessionInfoFromDb(char* cookie, char* userid, char* clientAddr4,
-                         char *macAddr, int *duration, int *durationEntered, char *language);
+                         char *macAddr, int *duration, int *durationEntered,
+                        char *language, char* closeTime);
 int GetUserProperty(char *userid, char *userProperty);
 int CheckNatInsertion(char* macAddr4, char* macAddr6, char* userid);
+int FindDuplicateInDbAndClose(char* clientAddr4, int* redundantRule4, 
+                           int* redundantRule6, int* redundantPid );
 
 /* TCP communication with client */
 int GetListenPort(void);
index 2e7b1a6..75edba3 100644 (file)
@@ -35,12 +35,12 @@ int  main(int argc, char **argv)
   char clientAddr4[ADDRMAXLN];
   char macAddr[ADDRMAXLN];
   char language[WORDMAXLN];
+  char closeTime[WORDMAXLN];
   int duration;
   int durationEntered;  
   char *pErrMsg;
   sqlite3 *db;
   sqlite3_stmt *stmt;
 
   printf("This is a test program for accessing sqlite db\n");
 
@@ -131,7 +131,7 @@ int  main(int argc, char **argv)
   /* get data from db */
   GetSessionInfoFromDb("testcookie", userid, 
                       clientAddr4, macAddr, 
-                      &duration, &durationEntered, language);
+                      &duration, &durationEntered, language, closeTime);
 
   /* dump getting data */
   printf("%s, %s, %s, %d, %d, %s\n",  userid, clientAddr4, macAddr, 
index 44e72b5..b32355f 100644 (file)
@@ -42,6 +42,9 @@ void OnCheckBasicAlarm(int signo);
 void OnCheckHttpAlarm(int signo);
 void OnReadWaitAlarm(int signo);
 void OnAjaxWaitAlarm(int signo);
+void CheckBasic(void);
+void CheckHttp(void);
+
 
 extern char ruleNumber4[WORDMAXLN];  /* ipfw rule number in string form  */
 extern char ruleNumber6[WORDMAXLN];  /* ip6fw rule number in string form */
@@ -72,6 +75,9 @@ int readHelloTime=0;  /* the time of reading hello */
 int sendHelloTime=0;  /* the time of sending hello */
 int noReplyCount=0; /* count up the no reply to hello message */
 
+int checkBasicAlarmRinged=FALSE;
+int checkHttpAlarmRinged=FALSE;
+
 
 /***************************************/
 /* get temp listen port of this server */
@@ -180,16 +186,22 @@ int waitClientConnect(char *userid, char *userProperty, char *sessionId, char *c
     /* start alarms */
     EnableAlarm();
 
-    /* connection wait. retry at abnormal  */
-    if((connfd = SelectAccept()) < 0 ){
+    /* connection wait */
+    connfd = SelectAccept();
+
+    /* stop alarms*/
+    DisableAlarm();
+
+    /* if abnormal accept check interupt */
+    if(connfd<0){
+      
+      /* periodic check */
+      if(checkBasicAlarmRinged) CheckBasic();
+
       Close(connfd);
       continue;
     }
 
-    /* at normal connection */
-    /* stop alarm interupt between checking */
-    DisableAlarm();
-    
     /* is it from the correct client addr(the check is skipped for IPv6) */
     if(ipType==IPV4 && ipStatus!=IPV6ONLY){
       GetPeerAddr(connfd, connectAddr);
@@ -355,14 +367,25 @@ void onAjaxWaitAlarm(int signo)
   connectMode=NOCONNECT;
 }
 
- /***************************************/
+/***************************************/
 /* called at periodic alive basic check */
 /***************************************/
 void onCheckBasicAlarm(int signo)
 {
+  checkBasicAlarmRinged=TRUE;
+}
+
+/***************************************/
+/* called at periodic alive basic check */
+/***************************************/
+void checkBasic(void)
+{
   static int packetCountPrev=0;  /* packet count at previous check */
   int packetCountNow=0;   /* packet count at now */
-  static   int noPacketPeriod=0; /* no packet period count in check loop */
+  static int noPacketPeriod=0; /* no packet period count in check loop */
+  static int firstCheck=TRUE;
+  int duplicateRule4,duplicateRule6;
+  int otherPid;
 
   /* search new IPv6 addresses */
   ScanNdpEntry(alarmArg.pClientAddr, alarmArg.userid,
@@ -392,7 +415,23 @@ void onCheckBasicAlarm(int signo)
     connectMode=ENDCONNECT;
     return;
   }
+
+  /* duplicated session check */
+  if(firstCheck){
+    firstCheck=FALSE;
+    if( FindDuplicateInDbAndClose(alarmArg.clientAddr4, 
+                               &duplicateRule4, &duplicateRule6, &otherPid) ){
+      if(kill(otherPid, 0)==0){ /* the process exists */
+       RemoveDuplicateRule(duplicateRule4, duplicateRule6);
+       connectMode=DUPLICATED;
+      }else{ /* the process does not exist */
+       FixProcessEndInDb(otherPid, "NONE");
+      }
+    }
+  }
+
   /* set the alarm for next periodic keep alive check */
+  checkBasicAlarmRinged=FALSE;
   AddAlarm("CheckBasicAlarm", alarmArg.checkInterval, FALSE, OnCheckBasicAlarm);  /* EnableAlarm is called automatically in alarm function */
 }
 
@@ -579,7 +618,11 @@ void waitHttpClose(struct clientAddr *pClientAddr, char *userid, char *userPrope
     else{
       /*abnormal read */
       /* some alarm is ringed or connecion is closed */
-      /*  connectionMode might be modified in onAlarm */
+
+      /* periodic check */
+      if(checkHttpAlarmRinged) CheckHttp();
+
+      /* if no connection, retry connect */
       if(connectMode==NOCONNECT){
 
        /* wait short time to accept reconnection */
@@ -697,6 +740,14 @@ int isRightKey(char *arg, char *sessionId)
 /***************************************/
 void onCheckHttpAlarm(int signo)
 {
+  checkHttpAlarmRinged=TRUE;
+}
+
+/***************************************/
+/* called at periodic http alive check */
+/***************************************/
+void checkHttp(void)
+{
   /* at this timing, hello request might be received */
   /* if in hello wait mode, it is abnormal */
   if(helloWait==TRUE){
@@ -726,6 +777,7 @@ void onCheckHttpAlarm(int signo)
   }
 
   /* set the alarm for next periodic check */
+  checkHttpAlarmRinged=FALSE;
   AddAlarm("CheckHttpAlarm", alarmArg.checkInterval, FALSE, OnCheckHttpAlarm);
   /* EnableAlarm is called automatically in alarm function */
 
@@ -926,6 +978,8 @@ void sendHttpNotFound(void)
   Writefmt(connfd,"\r\n");
 }
 
+
+
 /***************************************************/
 /***************************************************/
 void GetPeerAddr(int sockfd, char *peerAddr)
@@ -1016,6 +1070,13 @@ void OnCheckBasicAlarm(int signo){
   if(debug>1) err_msg("DEBUG:<=onCheckBasicAlarm()");
 }
 
+void CheckBasic(void){
+
+  if(debug>1) err_msg("DEBUG:=>checkBasic()");
+  checkBasic();
+  if(debug>1) err_msg("DEBUG:<=checkBasic()");
+}
+
 void OnCheckHttpAlarm(int signo){
 
   if(debug>1) err_msg("DEBUG:=>onCheckHttpAlarm()");
@@ -1023,6 +1084,13 @@ void OnCheckHttpAlarm(int signo){
   if(debug>1) err_msg("DEBUG:<=onCheckHttpAlarm()");
 }
 
+void CheckHttp(void){
+
+  if(debug>1) err_msg("DEBUG:=>checkHttp()");
+  checkHttp();
+  if(debug>1) err_msg("DEBUG:<=checkHttp()");
+}
+
 void OnReadWaitAlarm(int signo){
 
   if(debug>1) err_msg("DEBUG:=>onReadWaitAlarm()");
@@ -1086,3 +1154,4 @@ void SendHttpNotFound(void){
   sendHttpNotFound();
   if(debug>1) err_msg("DEBUG:<=sendHttpNotFound()");
 }
+