Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#1671 closed defect (fixed)

Unfreed transmit buffer (pjsip_tx_data) upon stack shutdown/restart

Reported by: nanang Owned by: bennylp
Priority: normal Milestone: release-2.2
Component: pjsip Version: trunk
Keywords: Cc:
Backport to 1.x milestone: Backported: no

Description (last modified by nanang)

On stack shutdown/restart, some pending operations on a transmit buffer may be forced to break/stop the operation without notifying the application and cause the transmit buffer dangling unfreed. As the transmit buffer may hold OS resources (e.g: atomic counter, mutex, memory), this will introduce OS resource leak issue (especially on resource with 'OS handle' such as mutex, note that memory will automatically be freed by PJLIB memory pool framework on stack shutdown).

After investigation, here are possible async operations involving transmit buffer:

  • DNS resolve.
  • Transport send:
    • for TCP/TLS, it may actually a connect pending, this should be safe already, as on_data_sent() callback is invoked during transport destruction,
    • the async send operation itself.

Note that even usually there is timeout timer on every async operation, normally the timer poll is stopped during shutdown stage, so we cannot rely on it.

Alternative solution:

  • Introduce new behaviour: always invoke callback on DNS/transport destruction for any pending operation. This is considered to be risky as it potentially introduces more issues :)
  • Maintain a list of pending transmit buffers, so SIP endpoint can free any 'dangling' transmit buffers when the SIP endpoint is destroyed.

Steps to reproduce with pjsua app

  • Pending DNS resolve:
    • replace "status = pj_ioqueue_sendto(...)" with "status = PJ_EPENDING" in pjlib-util/src/pjlib-util/resolver.c
    • specify nameserver setting in pjsua config param, e.g: --nameserver 8.8.8.8
    • send OPTIONS message to a target URI with hostname, then quit pjsua.
  • Pending send:
    • replace any "status = pj_activesock_send(...)" with "status = PJ_EPENDING" in sip_transport_tcp.c
    • send OPTIONS message via TCP, then quit pjsua.

Change History (4)

comment:1 Changed 6 years ago by nanang

  • Description modified (diff)

comment:2 Changed 6 years ago by nanang

  • Description modified (diff)

comment:3 Changed 6 years ago by nanang

  • Resolution set to fixed
  • Status changed from new to closed

In 4530:

Fixed #1671:

  • Transport manager maintains transmit buffer instance list, so any dangling transmit buffer will be freed when transport manager is destroyed. This is configurable via PJSIP_HAS_TX_DATA_LIST, the default is zero/disabled.
  • Updated publish client subscription to not use the 'internal' pjsip_tx_data list structure.

comment:4 Changed 6 years ago by nanang

In 4533:

Re #1671: Destroy tdata_counter only after cleaning up dangling transmit buffer.

Note: See TracTickets for help on using tickets.