Add deadtime detection for SMB2. Correctly update lastused timestamp across all activ...
authorJeremy Allison <jra@samba.org>
Tue, 19 Oct 2010 18:11:56 +0000 (11:11 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 19 Oct 2010 22:13:17 +0000 (15:13 -0700)
source3/smbd/conn.c
source3/smbd/process.c

index e8f14fd9189cf91e6629eebf7b24cc5e6e7e3678..8de8ce2e11a6bccc81fa43aa5b42cd720f11c60b 100644 (file)
@@ -244,35 +244,93 @@ bool conn_close_all(struct smbd_server_connection *sconn)
        return ret;
 }
 
+/****************************************************************************
+ Update last used timestamps.
+****************************************************************************/
+
+static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t)
+{
+       if (sconn->using_smb2) {
+               /* SMB2 */
+               struct smbd_smb2_session *sess;
+               for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+                       struct smbd_smb2_tcon *ptcon;
+
+                       for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+                               connection_struct *conn = ptcon->compat_conn;
+                               /* Update if connection wasn't idle. */
+                               if (conn && conn->lastused != conn->lastused_count) {
+                                       conn->lastused = t;
+                                       conn->lastused_count = t;
+                               }
+                       }
+               }
+       } else {
+               /* SMB1 */
+               connection_struct *conn;
+               for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+                       /* Update if connection wasn't idle. */
+                       if (conn->lastused != conn->lastused_count) {
+                               conn->lastused = t;
+                               conn->lastused_count = t;
+                       }
+               }
+       }
+}
+
 /****************************************************************************
  Idle inactive connections.
 ****************************************************************************/
 
-bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
+bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
 {
        int deadtime = lp_deadtime()*60;
-       connection_struct *conn;
 
-       if (deadtime <= 0)
+       conn_lastused_update(sconn, t);
+
+       if (deadtime <= 0) {
                deadtime = DEFAULT_SMBD_TIMEOUT;
+       }
 
-       for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+       if (sconn->using_smb2) {
+               /* SMB2 */
+               struct smbd_smb2_session *sess;
+               for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
+                       struct smbd_smb2_tcon *ptcon;
 
-               time_t age = t - conn->lastused;
+                       for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
+                               time_t age;
+                               connection_struct *conn = ptcon->compat_conn;
 
-               /* Update if connection wasn't idle. */
-               if (conn->lastused != conn->lastused_count) {
-                       conn->lastused = t;
-                       conn->lastused_count = t;
-               }
+                               if (conn == NULL) {
+                                       continue;
+                               }
 
-               /* close dirptrs on connections that are idle */
-               if (age > DPTR_IDLE_TIMEOUT) {
-                       dptr_idlecnum(conn);
+                               age = t - conn->lastused;
+                               /* close dirptrs on connections that are idle */
+                               if (age > DPTR_IDLE_TIMEOUT) {
+                                       dptr_idlecnum(conn);
+                               }
+
+                               if (conn->num_files_open > 0 || age < deadtime) {
+                                       return false;
+                               }
+                       }
                }
+       } else {
+               /* SMB1 */
+               connection_struct *conn;
+               for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
+                       time_t age = t - conn->lastused;
 
-               if (conn->num_files_open > 0 || age < deadtime) {
-                       return False;
+                       /* close dirptrs on connections that are idle */
+                       if (age > DPTR_IDLE_TIMEOUT) {
+                               dptr_idlecnum(conn);
+                       }
+
+                       if (conn->num_files_open > 0 || age < deadtime) {
+                               return false;
+                       }
                }
        }
 
@@ -281,10 +339,10 @@ bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
         * idle with a handle open.
         */
        if (check_open_pipes()) {
-               return False;
+               return false;
        }
 
-       return True;
+       return true;
 }
 
 /****************************************************************************
index ff2b8fc67d503b8e6fbd2f4ff87690daf0b28ddc..f2aa23e3e09b334cb6f73578a053625b904f366a 100644 (file)
@@ -2467,21 +2467,9 @@ static bool deadtime_fn(const struct timeval *now, void *private_data)
        struct smbd_server_connection *sconn =
                (struct smbd_server_connection *)private_data;
 
-       if (sconn->using_smb2) {
-               /* TODO: implement real idle check */
-               if (sconn->smb2.sessions.list) {
-                       return true;
-               }
-               DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
-               messaging_send(sconn->msg_ctx,
-                              messaging_server_id(sconn->msg_ctx),
-                              MSG_SHUTDOWN, &data_blob_null);
-               return false;
-       }
-
        if ((conn_num_open(sconn) == 0)
            || (conn_idle_all(sconn, now->tv_sec))) {
-               DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
+               DEBUG( 2, ( "Closing idle connection\n" ) );
                messaging_send(sconn->msg_ctx,
                               messaging_server_id(sconn->msg_ctx),
                               MSG_SHUTDOWN, &data_blob_null);