-
-
Notifications
You must be signed in to change notification settings - Fork 149
Description
Description
For every request received, it seems library will terminate the server transaction after passing it to registered handler. In my case, this caused an issue during INVITE's mid-dialog handling when PRACK request is received in response to a provisional response. When attempting to send final response, in this case 487 through tx, somehow it repeatedly it for a few times and stop.
Below is pcap snapshot where "TAS_IP" is the app encountering this issue.

To confirm this, I've printed backtrace in tx.OnTerminate() of registered invite handler.
=== BACKTRACE ===
#0: func1()
at /mnt/tas/src/handlers.go:65
#1: func1()
at /go/pkg/mod/github.com/emiago/sipgo@v0.31.0/sip/transaction.go:210
#2: delete()
at /go/pkg/mod/github.com/emiago/sipgo@v0.31.0/sip/transaction_server_tx.go:259
#3: Terminate()
at /go/pkg/mod/github.com/emiago/sipgo@v0.31.0/sip/transaction_server_tx.go:152
#4: TerminateGracefully()
at /go/pkg/mod/github.com/emiago/sipgo@v0.31.0/sip/transaction_server_tx.go:173
#5: handleRequest()
at /go/pkg/mod/github.com/emiago/sipgo@v0.31.0/server.go:271
#6: serverTxRequest()
at /go/pkg/mod/github.com/emiago/sipgo@v0.31.0/sip/transaction_layer.go:155
#7: handleRequest()
at /go/pkg/mod/github.com/emiago/sipgo@v0.31.0/sip/transaction_layer.go:129
#8: handleRequestBackground()
at /go/pkg/mod/github.com/emiago/sipgo@v0.31.0/sip/transaction_layer.go:89
Attempting digging the source code, I do see it's applicable for all received request
// server.go
// handleRequest is handling transaction layer
func (srv *Server) handleRequest(req *sip.Request, tx *sip.ServerTx) {
for _, mid := range srv.requestMiddlewares {
mid(req)
}
handler := srv.getHandler(req.Method)
handler(req, tx)
if tx != nil {
// Must be called to prevent any transaction leaks
tx.TerminateGracefully()
}
}// transaction_server_tx.go
// TerminateGracefully allows retransmission to happen before shuting down transaction
func (tx *ServerTx) TerminateGracefully() {
if tx.reliable {
// reliable transports have no retransmission, so it is better just to terminate
tx.Terminate()
return
}
// Check did we receive final response
tx.fsmMu.Lock()
finalized := tx.fsmResp != nil && !tx.fsmResp.IsProvisional()
tx.fsmMu.Unlock()
if !finalized {
tx.Terminate()
return
}
tx.log.Debug("Server transaction waiting termination")
<-tx.Done()
}Question/Request
Please let me know if my approach is not as the library intended or this is an issue.
Note
For now, I'm able to achieve sending 487 with server.WriteResponse(res).
Thanks for the awesome library. It help me a lot on learning and understanding how SIP works.