[tor-bugs] #5263 [- Select a component]: Busy/infinite Libevent loops

Tor Bug Tracker & Wiki torproject-admin at torproject.org
Tue Feb 28 23:25:27 UTC 2012


#5263: Busy/infinite Libevent loops
----------------------------------+-----------------------------------------
 Reporter:  robgjansen            |          Owner:     
     Type:  defect                |         Status:  new
 Priority:  normal                |      Milestone:     
Component:  - Select a component  |        Version:     
 Keywords:                        |         Parent:     
   Points:                        |   Actualpoints:     
----------------------------------+-----------------------------------------
 There is a bug causing busy loops in Libevent and infinite loops in the
 Shadow simulator. A connection that is marked for close, wants to flush,
 is held open to flush, but is rate limited (the token bucket is empty)
 triggers the bug.

 A patch to the latest alpha (tor-0.2.3.12-alpha) is attached, and details
 are below.

 This currently happens on read and write callbacks when the active socket
 is marked for close. In this case, Tor doesn't actually try to complete
 the read or write (it returns from those methods when marked), but instead
 tries to clear the connection with conn_close_if_marked(). Tor will not
 close a marked connection that contains data: it must be flushed first.
 The bug occurs when this flush operation on the marked connection can not
 occur because the connection is rate-limited (its write token bucket is
 empty).

 The fix is to detect when rate limiting is preventing a marked connection
 from properly flushing. In this case, it should be flagged as
 read/write_blocked_on_bandwidth and the read/write events de-registered
 from Libevent. When the token bucket gets refilled, it will check the
 associated read/write_blocked_on_bandwidth flag, and add the read/write
 event back to Libevent, which will cause it to fire. This time, it will be
 properly flushed and closed.

 The reason that both read and write events are both de-registered when the
 marked connection can not flush is because both result in the same
 behavior. Both read/write events on marked connections will never again do
 any actual reads/writes, and are only useful to trigger the flush and
 close the connection. By setting the associated
 read/write_blocked_on_bandwidth flag, we ensure that the event will get
 added back to Libevent, properly flushed, and closed.

 Why is this important? Every Shadow event occurs at a discrete time
 instant. If Tor does not properly deregister Libevent events that fire but
 result in Tor essentially doing nothing, Libevent will repeatedly fire the
 event. In Shadow this means infinite loop, outside of Shadow this means
 wasted CPU cycles.

-- 
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/5263>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online


More information about the tor-bugs mailing list