summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpaulo <paul@bayleaf.org.uk>2010-01-20 13:09:35 +0000
committerpaulo <paul@bayleaf.org.uk>2010-01-20 13:09:35 +0000
commit13fad04d09978db15317d3d3fb71ab87ea52c110 (patch)
treedca03d21ec9517db4ee837873e6d54736ea20286
parent5b8978176cbefe7c38f3ed72fd863e2e313d86d8 (diff)
downloadquagga-13fad04d09978db15317d3d3fb71ab87ea52c110.tar.bz2
quagga-13fad04d09978db15317d3d3fb71ab87ea52c110.tar.xz
Fix bug in bgp_connection not clearing pointers after free. Planted
asserts to try to track timer crash.
-rw-r--r--bgpd/bgp_connection.c12
-rw-r--r--bgpd/bgp_fsm.c5
-rw-r--r--lib/qpnexus.c10
-rw-r--r--lib/qtimers.c12
4 files changed, 32 insertions, 7 deletions
diff --git a/bgpd/bgp_connection.c b/bgpd/bgp_connection.c
index 690b2903..dcfd57e7 100644
--- a/bgpd/bgp_connection.c
+++ b/bgpd/bgp_connection.c
@@ -572,8 +572,16 @@ bgp_connection_close(bgp_connection connection)
bgp_connection_disable_accept(connection) ;
/* forget any addresses */
- sockunion_clear(connection->su_local) ;
- sockunion_clear(connection->su_remote) ;
+ if (connection->su_local != NULL)
+ {
+ sockunion_clear(connection->su_local) ;
+ connection->su_local = NULL;
+ }
+ if (connection->su_remote != NULL)
+ {
+ sockunion_clear(connection->su_remote) ;
+ connection->su_remote = NULL;
+ }
/* Unset all the timers */
qtimer_unset(&connection->hold_timer) ;
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index bd1eb600..97c60b1c 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1556,6 +1556,9 @@ bgp_fsm_event(bgp_connection connection, bgp_fsm_event_t event)
do
{
+ assert(bgp_nexus->pile == connection->hold_timer.pile);
+ assert(bgp_nexus->pile == connection->keepalive_timer.pile);
+
assert(connection->fsm_active == 1) ;
fsm = &bgp_fsm[connection->state][event] ;
@@ -1596,6 +1599,8 @@ bgp_fsm_event(bgp_connection connection, bgp_fsm_event_t event)
event = connection->post ;
connection->post = bgp_fsm_null_event ;
+ assert(bgp_nexus->pile == connection->hold_timer.pile);
+ assert(bgp_nexus->pile == connection->keepalive_timer.pile);
} while (--connection->fsm_active != 0) ;
/* If required, post session event. */
diff --git a/lib/qpnexus.c b/lib/qpnexus.c
index efa81c66..a350a274 100644
--- a/lib/qpnexus.c
+++ b/lib/qpnexus.c
@@ -153,14 +153,15 @@ qpn_start(void* arg)
while (!qpn->terminate)
{
+ now = qt_get_monotonic();
+
/* Signals are highest priority.
* only execute on the main thread */
if (qpn->main_thread)
quagga_sigevent_process ();
/* max time to wait in pselect */
- now = qt_get_monotonic();
- max_wait = now + QTIME(MAX_PSELECT_TIMOUT);
+ max_wait = QTIME(MAX_PSELECT_TIMOUT);
/* event hooks, if any */
for (i = 0; i < NUM_EVENT_HOOK; ++i)
@@ -185,8 +186,8 @@ qpn_start(void* arg)
}
/* block for some input, output, signal or timeout */
- actions = qps_pselect(qpn->selection,
- qtimer_pile_top_time(qpn->pile, max_wait));
+ actions = qps_pselect(qpn->selection,
+ qtimer_pile_top_time(qpn->pile, now + max_wait));
/* process I/O actions */
while (actions)
@@ -195,7 +196,6 @@ qpn_start(void* arg)
mqueue_done_waiting(qpn->queue, qpn->mts);
/* process timers */
- now = qt_get_monotonic();
while (qtimer_pile_dispatch_next(qpn->pile, now))
{
}
diff --git a/lib/qtimers.c b/lib/qtimers.c
index 6b3db500..43335d55 100644
--- a/lib/qtimers.c
+++ b/lib/qtimers.c
@@ -87,6 +87,9 @@ qtimer_cmp(qtimer* a, qtimer* b) /* the heap discipline */
return 0 ;
} ;
+/* Kill this */
+qtimer_pile our_pile;
+
/*==============================================================================
* qtimer_pile handling
*/
@@ -113,6 +116,9 @@ qtimer_pile_init_new(qtimer_pile qtp)
heap_init_new_backlinked(&qtp->timers, 0, (heap_cmp*)qtimer_cmp,
offsetof(qtimer_t, backlink)) ;
+
+ /* TODO: kill this */
+ our_pile = qtp;
return qtp ;
} ;
@@ -151,9 +157,11 @@ qtimer_pile_dispatch_next(qtimer_pile qtp, qtime_mono_t upto)
qtr = heap_top_item(&qtp->timers) ;
if ((qtr != NULL) && (qtr->time <= upto))
{
+ passert(qtp == qtr->pile);
qtr->state = qtr_state_unset_pending ;
qtr->action(qtr, qtr->timer_info, upto) ;
+ assert(qtp == qtr->pile);
if (qtr->state == qtr_state_unset_pending)
qtimer_unset(qtr) ;
@@ -312,6 +320,7 @@ qtimer_set(qtimer qtr, qtime_mono_t when, qtimer_action* action)
qtp = qtr->pile ;
dassert(qtp != NULL) ;
+ assert(qtp == our_pile);
qtr->time = when ;
@@ -319,6 +328,7 @@ qtimer_set(qtimer qtr, qtime_mono_t when, qtimer_action* action)
heap_update_item(&qtp->timers, qtr) ; /* update in heap */
else
heap_push_item(&qtp->timers, qtr) ; /* add to heap */
+ assert(qtp == qtr->pile);
qtr->state = qtr_state_active ; /* overrides any unset pending */
@@ -339,8 +349,10 @@ qtimer_unset(qtimer qtr)
{
qtimer_pile qtp = qtr->pile ;
dassert(qtp != NULL) ;
+ assert(qtp == our_pile);
heap_delete_item(&qtp->timers, qtr) ;
+ assert(qtp == qtr->pile);
qtr->state = qtr_state_inactive ; /* overrides any unset pending */
} ;