Changeset 14648


Ignore:
Timestamp:
Dec 31, 2015, 2:17:37 PM (5 years ago)
Author:
mikedld
Message:

#5891: Fix crash on session shutdown (evdns_getaddrinfo_cancel)

Location:
trunk/libtransmission
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/announcer-udp.c

    r14644 r14648  
    452452tau_tracker_free (struct tau_tracker * t)
    453453{
     454    assert (t->dns_request == NULL);
     455
    454456    if (t->addr)
    455457        evutil_freeaddrinfo (t->addr);
    456     if (t->dns_request != NULL)
    457         evdns_getaddrinfo_cancel (t->dns_request);
    458458    tr_ptrArrayDestruct (&t->announces, (PtrArrayForeachFunc)tau_announce_request_free);
    459459    tr_ptrArrayDestruct (&t->scrapes, (PtrArrayForeachFunc)tau_scrape_request_free);
     
    501501    {
    502502        char * errmsg = tr_strdup_printf (_("DNS Lookup failed: %s"),
    503                                           evdns_err_to_string (errcode));
     503                                          evutil_gai_strerror (errcode));
    504504        dbgmsg (tracker->key, "%s", errmsg);
    505505        tau_tracker_fail_all (tracker, false, false, errmsg);
     
    655655{
    656656    return tr_ptrArrayEmpty (&tracker->announces)
    657         && tr_ptrArrayEmpty (&tracker->scrapes);
     657        && tr_ptrArrayEmpty (&tracker->scrapes)
     658        && tracker->dns_request == NULL;
    658659}
    659660
     
    662663{
    663664    const time_t now = tr_time ();
     665    const bool closing = tracker->close_at != 0;
    664666
    665667    /* if the address info is too old, expire it */
    666     if (tracker->addr && (tracker->addr_expiration_time <= now)) {
     668    if (tracker->addr != NULL && (closing || tracker->addr_expiration_time <= now)) {
    667669        dbgmsg (tracker->host, "Expiring old DNS result");
    668670        evutil_freeaddrinfo (tracker->addr);
     
    675677
    676678    /* if we don't have an address yet, try & get one now. */
    677     if (!tracker->addr && (tracker->dns_request == NULL))
     679    if (!closing && tracker->addr == NULL && tracker->dns_request == NULL)
    678680    {
    679681        struct evutil_addrinfo hints;
     
    854856        {
    855857            struct tau_tracker * tracker = tr_ptrArrayNth (&tau->trackers, i);
     858            if (tracker->dns_request != NULL)
     859                evdns_getaddrinfo_cancel (tracker->dns_request);
    856860            tracker->close_at = now + 3;
    857861            tau_tracker_upkeep (tracker);
  • trunk/libtransmission/session.c

    r14644 r14648  
    17821782
    17831783static void
    1784 sessionCloseImpl (void * vsession)
     1784sessionCloseImplStart (tr_session * session)
    17851785{
    17861786  int i, n;
    17871787  tr_torrent ** torrents;
    1788   tr_session * session = vsession;
    1789 
    1790   assert (tr_isSession (session));
    17911788
    17921789  session->isClosing = true;
     
    18301827  tr_cacheFree (session->cache);
    18311828  session->cache = NULL;
    1832 
    1833   /* gotta keep udp running long enough to send out all
    1834      the &event=stopped UDP tracker messages */
    1835   while (!tr_tracker_udp_is_idle (session))
    1836     {
    1837       tr_tracker_udp_upkeep (session);
    1838       tr_wait_msec (100);
    1839     }
    1840 
     1829}
     1830
     1831static void
     1832sessionCloseImplFinish (tr_session * session)
     1833{
    18411834  /* we had to wait until UDP trackers were closed before closing these: */
    18421835  evdns_base_free (session->evdns_base, 0);
     
    18531846
    18541847  session->isClosed = true;
     1848}
     1849
     1850static void
     1851sessionCloseImplWaitForIdleUdp (evutil_socket_t   foo UNUSED,
     1852                                short             bar UNUSED,
     1853                                void            * vsession)
     1854{
     1855  tr_session * session = vsession;
     1856
     1857  assert (tr_isSession (session));
     1858
     1859  /* gotta keep udp running long enough to send out all
     1860     the &event=stopped UDP tracker messages */
     1861  if (!tr_tracker_udp_is_idle (session))
     1862    {
     1863      tr_tracker_udp_upkeep (session);
     1864      tr_timerAdd (session->saveTimer, 0, 100000);
     1865      return;
     1866    }
     1867
     1868  sessionCloseImplFinish (session);
     1869}
     1870
     1871static void
     1872sessionCloseImpl (void * vsession)
     1873{
     1874  tr_session * session = vsession;
     1875
     1876  assert (tr_isSession (session));
     1877
     1878  sessionCloseImplStart (session);
     1879
     1880  /* saveTimer is not used at this point, reusing for UDP shutdown wait */
     1881  assert (session->saveTimer == NULL);
     1882  session->saveTimer = evtimer_new (session->event_base, sessionCloseImplWaitForIdleUdp, session);
     1883  tr_timerAdd (session->saveTimer, 0, 0);
    18551884}
    18561885
  • trunk/libtransmission/trevent.c

    r14644 r14648  
    204204            dbgmsg ("pipe eof reached... removing event listener");
    205205            event_free (eh->pipeEvent);
     206            tr_netCloseSocket (eh->fds[0]);
     207            event_base_loopexit (eh->base, NULL);
    206208            break;
    207209        }
Note: See TracChangeset for help on using the changeset viewer.