diff options
author | George Joseph <gjoseph@digium.com> | 2016-05-18 06:54:14 -0600 |
---|---|---|
committer | Mark Michelson <mmichelson@digium.com> | 2016-05-18 14:05:47 -0500 |
commit | 935e0496c4b10604c100005cb3ebff594380486b (patch) | |
tree | 14b8feba177cf81d73fe1c95e6b40201d0a1ffed | |
parent | 3f6ef63099d58d0aa74895156e8038eb44180ea8 (diff) |
udptl: Don't eat sequence numbers until OK is received
Scenario:
Local fax -> Asterisk w/ firewall -> Provider -> Remote fax
* Local fax starts rtp call to remote fax
* Remote fax starts t38 call back to local fax.
* Local fax sends t38 no-signal to Asterisk before sending an OK.
* udptl processes the frame and increments the expected sequence number.
* chan_sip drops the frame because the call isn't up so nothing goes out
the external interface to open the port for incoming packets.
* Local fax sends OK and Asterisk sends OK to the remote fax.
* Remote fax sends t38 packets which are dropped by the firewall.
* Local fax re-sends t38 no-signal with the same sequence number.
* udptl drops the frame because it thinks it's a dup.
* Still no outgoing packets to open the firewall.
* t38 negotiation fails.
The patch drops frames t38 received before udptl sequence processing
when the call hasn't been answered yet. The second no-signal frame
is then seen as new and is relayed out the external interface which
opens the port and allows negotiation to continue.
ASTERISK-26034 #close
Change-Id: I11744b39748bd2ecbbe8ea84cdb4f3c5943c5af9
-rw-r--r-- | main/udptl.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/main/udptl.c b/main/udptl.c index e8410cc8b..a568cd1ec 100644 --- a/main/udptl.c +++ b/main/udptl.c @@ -769,6 +769,18 @@ struct ast_frame *ast_udptl_read(struct ast_udptl *udptl) return &ast_null_frame; } + /* + * If early media isn't turned on for the channel driver, it's going to + * drop this frame. By that time though, udptl has already incremented + * the expected sequence number so if the CPE re-sends, the second frame + * will be dropped as a dup even though the first frame never went through. + * So we drop the frame here if the channel isn't up. 'tag' is set by the + * channel drivers on T38_ENABLED or T38_PEER_REINVITE. + */ + if (udptl->tag == NULL) { + return &ast_null_frame; + } + if (udptl->nat) { /* Send to whoever sent to us */ if (ast_sockaddr_cmp(&udptl->them, &addr)) { |