fixed a use-after-free bug in dpd_timeout()
[strongswan.git] / src / pluto / state.c
index 5957654..d1587a1 100644 (file)
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: state.c,v 1.12 2006/04/03 15:49:36 as Exp $
+ * RCSID $Id$
  */
 
 #include <stdio.h>
@@ -464,12 +464,7 @@ delete_states_by_connection(struct connection *c, bool relations)
        passert(sr->routing != RT_ROUTED_TUNNEL);
        sr = sr->next;
     }
-
-    if (ck == CK_INSTANCE)
-    {
-       c->kind = ck;
-       delete_connection(c, relations);
-    }
+    c->kind = ck;
 }
 
 /* Walk through the state table, and delete each state whose phase 1 (IKE)
@@ -506,6 +501,8 @@ delete_states_by_peer(ip_address *peer)
                         , peerstr
                         , c->name);
                    delete_states_by_connection(c, TRUE);
+                   if (c->kind == CK_INSTANCE)
+                       delete_connection(c, TRUE);
                    break;      /* can only delete it once */
                }
            }
@@ -716,7 +713,7 @@ state_eroute_usage(ip_subnet *ours, ip_subnet *his
        });
 }
 
-void fmt_state(struct state *st, time_t n
+void fmt_state(bool all, struct state *st, time_t n
 , char *state_buf, size_t state_buf_len
 , char *state_buf2, size_t state_buf2_len)
 {
@@ -735,20 +732,22 @@ void fmt_state(struct state *st, time_t n
     /* XXX spd-enum */
     const char *eo = c->spd.eroute_owner == st->st_serialno
        ? "; eroute owner" : "";
-
+    const char *dpd = (all && st->st_dpd && c->dpd_action != DPD_ACTION_NONE)
+                     ? "; DPD active" : "";
+    
     passert(st->st_event != 0);
 
     fmt_conn_instance(c, inst);
 
     snprintf(state_buf, state_buf_len
-       , "#%lu: \"%s\"%s %s (%s); %s in %lds%s%s%s"
+       , "#%lu: \"%s\"%s %s (%s); %s in %lds%s%s%s%s"
        , st->st_serialno
        , c->name, inst
        , enum_name(&state_names, st->st_state)
        , state_story[st->st_state - STATE_MAIN_R0]
        , enum_name(&timer_event_names, st->st_event->ev_type)
        , delta
-       , np1, np2, eo);
+       , np1, np2, eo, dpd);
 
     /* print out SPIs if SAs are established */
     if (state_buf2_len != 0)
@@ -846,7 +845,7 @@ state_compare(const void *a, const void *b)
 }
 
 void
-show_states_status(const char *name)
+show_states_status(bool all, const char *name)
 {
     time_t n = now();
     int i;
@@ -892,7 +891,8 @@ show_states_status(const char *name)
 
        st = array[i];
 
-       fmt_state(st, n, state_buf, sizeof(state_buf)
+       fmt_state(all, st, n
+                 , state_buf, sizeof(state_buf)
                  , state_buf2, sizeof(state_buf2));
        whack_log(RC_COMMENT, state_buf);
        if (state_buf2[0] != '\0')
@@ -902,6 +902,8 @@ show_states_status(const char *name)
        if (IS_PHASE1(st->st_state))
            show_pending_phase2(st->st_connection->host_pair, st);
     }
+    if (count > 0)
+       whack_log(RC_COMMENT, BLANK_FORMAT);    /* spacer */
 
     /* free the array */
     pfree(array);