diff options
author | paulo <paul@bayleaf.org.uk> | 2010-01-20 13:09:35 +0000 |
---|---|---|
committer | paulo <paul@bayleaf.org.uk> | 2010-01-20 13:09:35 +0000 |
commit | 13fad04d09978db15317d3d3fb71ab87ea52c110 (patch) | |
tree | dca03d21ec9517db4ee837873e6d54736ea20286 | |
parent | 5b8978176cbefe7c38f3ed72fd863e2e313d86d8 (diff) | |
download | quagga-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.c | 12 | ||||
-rw-r--r-- | bgpd/bgp_fsm.c | 5 | ||||
-rw-r--r-- | lib/qpnexus.c | 10 | ||||
-rw-r--r-- | lib/qtimers.c | 12 |
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 */ } ; |