Hi, I am using rtpengine to convert SRTP to RTP for audio and video and I am also doing this for reINVITEs. At the moment I am using Chrome on the SRTP side and Linphone on the RTP side. So far, Linphone has been the most stable for sending and receiving VP8 video calls.
Linphone does not do ICE, but Chrome does. I need to force all traffic through rtpengine (to encrypt/decrypt) so I use the "ICE=force" flag in both directions.
I've put the SDP content of an on-hold scenario at the end of this email.
When Linphone puts the call on hold, it sets the connection to "c=0.0.0.0" and the direction to "a=sendonly" in the reINVITE. However, it does keep the same valid port numbers on the m= lines. RTPEngine processes this and sends SDP to Chrome that has "c=0.0.0.0", "a=ice-lite" and "a=inactive". The port numbers are set to 0 (disabled/rejected) Chrome does some other interesting stuff with that, so I am investigating.
RFC5245 (ICE) §9 is all about subsequent offer-answer exchanges. In this 'on-hold' scenario, I don't believe there is any need to restart the ICE processing.
From §9.1.1.1
These rules imply that setting the IP address in the c line to
0.0.0.0 will cause an ICE restart. Consequently, ICE implementations
MUST NOT utilize this mechanism for call hold, and instead MUST use
a=inactive and a=sendonly as described in [RFC3264http://tools.ietf.org/html/rfc3264]. In a lite implementation, I think that the "a=ice-ufrag" and "a=ice-pwd" attributes need to be included (with the same values) and also the currently selected (active) candidate §9.1.1.1 & §9.1.3.2.
RTPEngine appears to have disabled the two media streams, rather than putting them on hold. Is this a deliberate choice or the best choice given the multiple possibilities of client implementations? And can this behaviour be improved? If the call is taken off-hold later, I would prefer not to have to do the full ICE restart, including TURN, DTLS handshakes etc. etc. if it can be avoided.
Regards, Hugh
This is what Linphone sent to rtpengine to put the call on hold. v=0 o=447707319033 2969 189 IN IP4 10.X.X.X s=Talk c=IN IP4 0.0.0.0 t=0 0 m=audio 7078 RTP/AVP 124 111 110 0 8 101 a=rtpmap:124 opus/48000 a=fmtp:124 useinbandfec=1; usedtx=1 a=rtpmap:111 speex/16000 a=fmtp:111 vbr=on a=rtpmap:110 speex/8000 a=fmtp:110 vbr=on a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-15 a=sendonly m=video 9078 RTP/AVP 103 a=rtpmap:103 VP8/90000 a=sendonly
This is what rtpengine sent to Chrome v=0 o=447707319033 2969 189 IN IP4 10.X.X.X s=Talk c=IN IP4 0.0.0.0 t=0 0 a=ice-lite m=audio 0 RTP/SAVPF 124 111 110 0 8 101 a=rtpmap:124 opus/48000 a=fmtp:124 useinbandfec=1; usedtx=1 a=rtpmap:111 speex/16000 a=fmtp:111 vbr=on a=rtpmap:110 speex/8000 a=fmtp:110 vbr=on a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-15 a=inactive m=video 0 RTP/SAVPF 103 a=rtpmap:103 VP8/90000 a=inactive
This is what Chrome sent back - note the ICE syntax errors! v=0 o=- 5839956538493318716 3 IN IP4 127.0.0.1 s=- t=0 0 a=msid-semantic: WMS FS1XDFSCVuztEO87Lm7NEzuFX2EVnOYDP8VS m=audio 0 RTP/SAVPF 0 8 101 c=IN IP4 0.0.0.0 a=rtcp:1 IN IP4 0.0.0.0 a=ice-ufrag: a=ice-pwd: a=mid:audio a=inactive a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:101 telephone-event/8000 a=ssrc:1220950669 cname:txfWFsmZxl5fElCV a=ssrc:1220950669 msid:FS1XDFSCVuztEO87Lm7NEzuFX2EVnOYDP8VS 6bcb6a56-c38d-474a-9e1b-372dc4206754 a=ssrc:1220950669 mslabel:FS1XDFSCVuztEO87Lm7NEzuFX2EVnOYDP8VS a=ssrc:1220950669 label:6bcb6a56-c38d-474a-9e1b-372dc4206754 m=video 0 RTP/SAVPF 103 c=IN IP4 0.0.0.0 a=rtcp:1 IN IP4 0.0.0.0 a=ice-ufrag: a=ice-pwd: a=mid:video a=inactive a=rtpmap:103 VP8/90000 a=ssrc:2854598716 cname:txfWFsmZxl5fElCV a=ssrc:2854598716 msid:FS1XDFSCVuztEO87Lm7NEzuFX2EVnOYDP8VS 2f5be791-cf7a-48cf-ac4b-8c060f606f78 a=ssrc:2854598716 mslabel:FS1XDFSCVuztEO87Lm7NEzuFX2EVnOYDP8VS a=ssrc:2854598716 label:2f5be791-cf7a-48cf-ac4b-8c060f606f78
And this was sent back to Linphone. Linphone didn't like it and cleared the call down.
v=0 o=- 7461781248465050568 3 IN IP4 127.0.0.1 s=- t=0 0 a=msid-semantic: WMS iOUm0bgDPsb5B2riIq3JB1X3xkpkPhPgSRFc a=ice-lite m=audio 0 RTP/AVP 0 8 101 c=IN IP4 0.0.0.0 a=mid:audio a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:101 telephone-event/8000 a=ssrc:974659196 cname:YOhAbnOYADFFMGYH a=ssrc:974659196 msid:iOUm0bgDPsb5B2riIq3JB1X3xkpkPhPgSRFc ad66954d-2fad-4f30-9169-684b95f33abc a=ssrc:974659196 mslabel:iOUm0bgDPsb5B2riIq3JB1X3xkpkPhPgSRFc a=ssrc:974659196 label:ad66954d-2fad-4f30-9169-684b95f33abc a=inactive m=video 0 RTP/AVP 103 c=IN IP4 0.0.0.0 a=mid:video a=rtpmap:103 VP8/90000 a=ssrc:2605136941 cname:YOhAbnOYADFFMGYH a=ssrc:2605136941 msid:iOUm0bgDPsb5B2riIq3JB1X3xkpkPhPgSRFc c759c13f-b992-402c-bf57-00046d1a1008 a=ssrc:2605136941 mslabel:iOUm0bgDPsb5B2riIq3JB1X3xkpkPhPgSRFc a=ssrc:2605136941 label:c759c13f-b992-402c-bf57-00046d1a1008 a=inactive ________________________________ This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you for understanding.
On 07/17/14 12:48, Waite, Hugh wrote:
Hi,
I am using rtpengine to convert SRTP to RTP for audio and video and I am also doing this for reINVITEs.
At the moment I am using Chrome on the SRTP side and Linphone on the RTP side. So far, Linphone has been the most stable for sending and receiving VP8 video calls.
Linphone does not do ICE, but Chrome does. I need to force all traffic through rtpengine (to encrypt/decrypt) so I use the “ICE=force” flag in both directions.
I’ve put the SDP content of an on-hold scenario at the end of this email.
When Linphone puts the call on hold, it sets the connection to “c=0.0.0.0” and the direction to “a=sendonly” in the reINVITE. However, it does keep the same valid port numbers on the m= lines.
RTPEngine processes this and sends SDP to Chrome that has “c=0.0.0.0”, “a=ice-lite” and “a=inactive”. The port numbers are set to 0 (disabled/rejected)
Chrome does some other interesting stuff with that, so I am investigating.
RFC5245 (ICE) §9 is all about subsequent offer-answer exchanges. In this ‘on-hold’ scenario, I don’t believe there is any need to restart the ICE processing.
From §9.1.1.1
These rules imply that setting the IP address in the c line to
0.0.0.0 will cause an ICE restart. Consequently, ICE implementations
MUST NOT utilize this mechanism for call hold, and instead MUST use
a=inactive and a=sendonly as described in [RFC3264 http://tools.ietf.org/html/rfc3264].
In a lite implementation, I think that the “a=ice-ufrag” and “a=ice-pwd” attributes need to be included (with the same values) and also the currently selected (active) candidate §9.1.1.1 & §9.1.3.2.
RTPEngine appears to have disabled the two media streams, rather than putting them on hold. Is this a deliberate choice or the best choice given the multiple possibilities of client implementations? And can this behaviour be improved?
If the call is taken off-hold later, I would prefer not to have to do the full ICE restart, including TURN, DTLS handshakes etc. etc. if it can be avoided.
This is one of those cases where no matter what you do, it's always gonna be wrong for somebody. :)
There was a recent commit [1] which slightly changed the behaviour when putting a call on hold in this manner, I suspect your build is older than this. I'm not sure if it would fix your particular issue though.
Rtpengine could translate a null c= address into the respective attributes (and leave a valid c= address), but then you run into the problem of breaking compatibility with clients which don't support or misunderstand this type of signalling.
So yes, there's definitely room for improvement (there always is), it's just a matter of figuring out what the Right Thing[tm] to do is. :)
cheers
[1] https://github.com/sipwise/rtpengine/commit/a7784f5ca3437d1c7b58308022ef0e06...
Hi,
I updated to the latest from git but it didn't improve the situation with null IP addresses from the non-webRTC client. In fact, rtpengine sent some ICE candidate lines with null IP's. We decided we don't need to worry about clients that use the null IP mechanism for on-hold, so I sent some simulated traffic with sipp that has real IP addresses and uses a=sendonly/inactive. These results were better.
With the latest rtpengine version (as of 21/7/14), the initial invite towards Chrome uses a=setup:actpass for the DTLS handshake, as required. In the reINVITE, it uses a=setup:passive. Chrome rejects this because it isn't actpass. I can see the code that works out the setup direction string in sdp.c:1600 based on the active/passive flags. Should the value always be "actpass" if we are making an offer? (RFC5763 §5)
Regards, Hugh
-----Original Message----- From: sr-dev-bounces@lists.sip-router.org [mailto:sr-dev-bounces@lists.sip-router.org] On Behalf Of Richard Fuchs Sent: 17 July 2014 18:06 To: sr-dev@lists.sip-router.org Subject: Re: [sr-dev] RTPEngine in reINVITE/on-hold use case
On 07/17/14 12:48, Waite, Hugh wrote:
Hi,
I am using rtpengine to convert SRTP to RTP for audio and video and I am also doing this for reINVITEs.
RTPEngine appears to have disabled the two media streams, rather than putting them on hold. Is this a deliberate choice or the best choice given the multiple possibilities of client implementations? And can this behaviour be improved?
If the call is taken off-hold later, I would prefer not to have to do the full ICE restart, including TURN, DTLS handshakes etc. etc. if it can be avoided.
This is one of those cases where no matter what you do, it's always gonna be wrong for somebody. :)
There was a recent commit [1] which slightly changed the behaviour when putting a call on hold in this manner, I suspect your build is older than this. I'm not sure if it would fix your particular issue though.
Rtpengine could translate a null c= address into the respective attributes (and leave a valid c= address), but then you run into the problem of breaking compatibility with clients which don't support or misunderstand this type of signalling.
So yes, there's definitely room for improvement (there always is), it's just a matter of figuring out what the Right Thing[tm] to do is. :)
cheers
[1] https://github.com/sipwise/rtpengine/commit/a7784f5ca3437d1c7b58308022ef0e06...
_______________________________________________ sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev ________________________________ This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you for understanding.
On 21/07/14 07:00 AM, Waite, Hugh wrote:
Hi,
I updated to the latest from git but it didn't improve the situation with null IP addresses from the non-webRTC client. In fact, rtpengine sent some ICE candidate lines with null IP's. We decided we don't need to worry about clients that use the null IP mechanism for on-hold, so I sent some simulated traffic with sipp that has real IP addresses and uses a=sendonly/inactive. These results were better.
With the latest rtpengine version (as of 21/7/14), the initial invite towards Chrome uses a=setup:actpass for the DTLS handshake, as required. In the reINVITE, it uses a=setup:passive. Chrome rejects this because it isn't actpass. I can see the code that works out the setup direction string in sdp.c:1600 based on the active/passive flags. Should the value always be "actpass" if we are making an offer? (RFC5763 §5)
Yes it should be, call.c:1724 is supposed to take care of that. But I just noticed that this part can get skipped erroneously. Will fix, thx.
cheers