[asterisk-bugs] [JIRA] (ASTERISK-24873) Cancelling transmission of IAX2 packet loop wrap around

Y Ateya (JIRA) noreply at issues.asterisk.org
Mon Mar 23 15:49:37 CDT 2015


    [ https://issues.asterisk.org/jira/browse/ASTERISK-24873?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=225569#comment-225569 ] 

Y Ateya edited comment on ASTERISK-24873 at 3/23/15 3:48 PM:
-------------------------------------------------------------

@ibercom After investigating more, it seems that the problem is not -only- with the canceling for loop.

The problem is accepting control frames with {{fr->iseqno}} less than {code}iaxs[fr->callno]->rseqno{code}. It happens more with VNAK; but this is [correlation not causation|https://xkcd.com/552/].

{code}
* Rx <ACK> with 008 ISeqno: 007
--------------------------------
[2015-03-12 13:26:03.071] VERBOSE[6960] chan_iax2.c: Rx-Frame Retry[ No] -- OSeqno: 008 ISeqno: 007 Type: IAX     Subclass: ACK    
[2015-03-12 13:26:03.071] VERBOSE[6960] chan_iax2.c:    Timestamp: 19717ms  SCall: 07431  DCall: 25289 45.56.114.174:4566

* Rx <LAGRP> with OSeqno: 008 ISeqno: 006
------------------------------------------
[2015-03-12 13:26:03.099] VERBOSE[6960] chan_iax2.c: Rx-Frame Retry[ No] -- OSeqno: 008 ISeqno: 006 Type: IAX     Subclass: LAGRP  
[2015-03-12 13:26:03.099] VERBOSE[6960] chan_iax2.c:    Timestamp: 20007ms  SCall: 07431  DCall: 25289 45.56.114.174:4566
{code}
The cause of this problem is some packet arrives out-of-order; so {code}iaxs[fr->callno]->rseqno{code} (highest recieved {{fr->iseqno}}) is higher than {{fr->iseqno}}). The following steps occurs:

- Peer receives frame with {{fr->iseqno= N, fr->oseqno=Y}}, it cancels all waiting-for-ack packets before N (N-1, N-2, ... )
- Peer receives out-of-sequence frame with {{fr->iseqno = N-1, fr->oseqno=Y}} (same oseqno), frame is accepted and trying to cancel all waiting-for-ack packets before N; 
**but wait** N-1 was acknowledged before!

Either we :
 - Send VNAK for out-of-order {{fr->iseqno}} as we do for {{fr->oseqno}} (this might violate RFC).
 - Prevent starting two control messages at same time (ex. don't send PING if you are waiting for LAGRP); but solution seems too complex.
 - Add special handling for this case to prevent this case specifically.


was (Author: yateya):
@ibercom After investigating more, it seems that the problem is not with the canceling for loop.

The problem is accepting control frames with {{fr->iseqno}} less than {code}iaxs[fr->callno]->rseqno{code}. It happens more with VNAK; but this is [correlation not causation|https://xkcd.com/552/].

{code}
* Rx <ACK> with 008 ISeqno: 007
--------------------------------
[2015-03-12 13:26:03.071] VERBOSE[6960] chan_iax2.c: Rx-Frame Retry[ No] -- OSeqno: 008 ISeqno: 007 Type: IAX     Subclass: ACK    
[2015-03-12 13:26:03.071] VERBOSE[6960] chan_iax2.c:    Timestamp: 19717ms  SCall: 07431  DCall: 25289 45.56.114.174:4566

* Rx <LAGRP> with OSeqno: 008 ISeqno: 006
------------------------------------------
[2015-03-12 13:26:03.099] VERBOSE[6960] chan_iax2.c: Rx-Frame Retry[ No] -- OSeqno: 008 ISeqno: 006 Type: IAX     Subclass: LAGRP  
[2015-03-12 13:26:03.099] VERBOSE[6960] chan_iax2.c:    Timestamp: 20007ms  SCall: 07431  DCall: 25289 45.56.114.174:4566
{code}
The cause of this problem is some packet arrives out-of-order; so {code}iaxs[fr->callno]->rseqno{code} (highest recieved {{fr->iseqno}}) is higher than {{fr->iseqno}}). The following steps occurs:

- Peer receives frame with {{fr->iseqno= N, fr->oseqno=Y}}, it cancels all waiting-for-ack packets before N (N-1, N-2, ... )
- Peer receives out-of-sequence frame with {{fr->iseqno = N-1, fr->oseqno=Y}} (same oseqno), frame is accepted and trying to cancel all waiting-for-ack packets before N; 
**but wait** N-1 was acknowledged before!

Either we :
 - Send VNAK for out-of-order {{fr->iseqno}} as we do for {{fr->oseqno}} (this might violate RFC).
 - Prevent starting two control messages at same time (ex. don't send PING if you are waiting for LAGRP); but solution seems too complex.
 - Add special handling for this case to prevent this case specifically.

> Cancelling transmission of IAX2 packet loop wrap around
> -------------------------------------------------------
>
>                 Key: ASTERISK-24873
>                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-24873
>             Project: Asterisk
>          Issue Type: Bug
>      Security Level: None
>          Components: Channels/chan_iax2
>    Affects Versions: 13.2.0
>            Reporter: Y Ateya
>            Severity: Minor
>         Attachments: client_logs_cancelling_packet_issue.txt.bz2, use_case.txt
>
>
> In IAX, when a packet is received with sequence number, all not-yet-ACKed packets with lower sequence number shall be considered ACKed.
> Sometimes after VNAK is recieved, the first packet sequence number makes the for loop run for useless 255 times.
> check attachment: use_case.txt for extracted sequence of packets.
> check attachment: client_logs_cancelling_packet_issue.txt.bz2 for a full log with many occurrences of this issue.
> {code:title=The affected for loop|borderStyle=solid}
> 			/* First we have to qualify that the ACKed value is within our window */
> 			if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
> 				x = fr->iseqno;
> 			else
> 				x = iaxs[fr->callno]->oseqno;
> 			if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
> 				/* The acknowledgement is within our window.  Time to acknowledge everything
> 				   that it says to */
> 				for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
> 					/* Ack the packet with the given timestamp */
> 					if (iaxdebug)
> 						ast_debug(1, "Cancelling transmission of packet %d\n", x);
> {code}
> "Cancelling transmission of packet X" shall be printed only for packets with lower sequence number than received packet.
> Simple solution of using `<` for checking end of loop is not enough as it don't handle sequence number wrap around.
> Note that there is not functional effect of this issue. It just blocks its thread in useless 255 loop.



--
This message was sent by Atlassian JIRA
(v6.2#6252)



More information about the asterisk-bugs mailing list