< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index  

Re: [recon-devel] Flow::onReceiveSuccess(...) and Flow::onReceiveFailure(..)


Hi Scott,

 

I'll paste in some of our side-discussion for the benefit of the list:

 

[Scott] Do you have the testUA trace for this?  Obviously sending RTP is OK - are you saying the receive of RTP continues to fail (WSAECONNRESET) even after the ICMP messages stop arriving?

 

What is the use case of detecting an ICMP failure and then having it work again?  I'm pretty sure the target machine has to be running to get an ICMP error.  So all I can think of is that either the application crashes, then comes back again - but there is no use recovering here, since SIP session is lost too.  Or - the application for some reason hasn't started listening yet, and then starts listening some time later.  Or is there some other use case?

 

Assuming you actually have to close the socket and reopen it, couldn't you just close the entire media stream and re-create it?  Or are you thinking of something more efficient - ie. some kind of Flow::resetSocket API that you could call from onReceiveFailure if you get a WSAECONNRESET?

 

[Jeremy] I stepped in with the debugger, and actually the problem was just that the recon testUA was never trying to receive again after it got a failure.  So I added a call to turnReceive() at the end of TurnAsyncUdpSocket::onReceiveFailure(..) and that resolves the issue -- two way audio works for my test case.

 

This is going to cause me to revisit our existing media SDK to see if maybe this business of closing/reopening sockets was "a fix", but just a more complicated one than was really necessary -- if I find anything further that's relevant, I'll post back to the list.

 

As for the use case I had in mind -- badly implemented endpoints that don't start listening for incoming RTP/RTCP soon enough (e.g. waiting for a 200 or an ACK before they open up their ports, even though their SDP offer or answer has already been sent out).

 

Thanks,

Jeremy

 

 

From: slgodin@xxxxxxxxx [mailto:slgodin@xxxxxxxxx] On Behalf Of Scott Godin
Sent: June-16-09 10:26 AM
To: Jeremy Geras
Cc: recon-devel@xxxxxxxxxxxxxxx; Derek MacDonald
Subject: Re: Flow::onReceiveSuccess(...) and Flow::onReceiveFailure(..)

 

Hi Jeremy,

 

I have a feeling that the bulk of the MSDN description of WSAECONNRESET only really apply to TCP sockets.  I haven't seen the need for this in practice.  Have you actually tried this out - to see of closing the socket and re-opening is required?  

 

Scott

On Tue, Jun 16, 2009 at 12:44 PM, Jeremy Geras <jgeras@xxxxxxxxxxxxxxx> wrote:

Sorry, here's the other reference:

http://msdn.microsoft.com/en-us/library/ms740121(VS.85).aspx (again, where it talks about WSAECONNRESET)

 

Scott, I'll also send you a trace (off the mailing list) where I can reproduce one-way audio using the recon testUA.

 

Jeremy

 

 

 

From: Jeremy Geras
Sent: June-16-09 9:42 AM
To: 'Scott Godin'


Cc: recon-devel@xxxxxxxxxxxxxxx; Derek MacDonald

Subject: RE: Flow::onReceiveSuccess(...) and Flow::onReceiveFailure(..)

 

Here are a couple of references:

http://msdn.microsoft.com/en-us/library/ms740668(VS.85).aspx#winsock.wsaeconnreset_2

 

From: slgodin@xxxxxxxxx [mailto:slgodin@xxxxxxxxx] On Behalf Of Scott Godin
Sent: June-16-09 6:47 AM
To: Jeremy Geras
Cc: recon-devel@xxxxxxxxxxxxxxx; Derek MacDonald
Subject: Re: Flow::onReceiveSuccess(...) and Flow::onReceiveFailure(..)

 

...comments inline...

 

Scott

On Mon, Jun 15, 2009 at 7:43 PM, Jeremy Geras <jgeras@xxxxxxxxxxxxxxx> wrote:

Hi,

 

We're looking at building native support for reflow "Flows" into our media stack, and there are a couple of design considerations I'd like to bring up:

 

1) How to handle error conditions?  Currently Flow::onReceiveFailure(..) just logs an error -- is this sufficient?

 

For example, what to do if you get ICMP unreachable when you send UDP to the other side?  We've found that there are enough badly implemented endpoints around that that it's actually worth our while to keep trying to send RTP to the other end (i.e. optimistically assume that it will be ready at *some* point a few fractions of a second later).  On Windows, this requires us to close down/reopen our UDP socket (MSDN states that sockets are invalidated when you get ICMP errors).

[Scott]  I've just been recently testing a media relay application that uses Windows UDP sockets on windows XP.  When I get receive errors, due to ICMP packets being received, I can still use the socket to send and receive data (at least from other peers) .  As far as I've seen you don't need to close the socket and re-open it.  Can you post a pointer to the MSDN article?

For this particular situation, this is our preferred way to handle this problem -- I'm not sure if it's a solution that should be built in or not.  However, it's one case where currently we would need to modify Flow.cxx if we wanted to implement it.

 

2) How to receive incoming RTP?  Currently the design assumes that you call Flow::receive(..) from another thread.

 

Since the data is going to end up in a jitter buffer anyways, would it be prudent to provide a callback/handler class that provides the opportunity for us to do whatever we need to do in the context of the thread that is calling Flow::onReceiveSuccess(..) (i.e. the thread that calls io_service::run())?  It seems like this might be a worthwhile optimization (eliminates a queue and a thread).

 

[Scott] If we let the io_service::run thread automatically do receives, then you cannot do a receiveFrom type of API.  One objective of the Flow interface was to attempt to offer an API interface similar to the standard socket API.  However, I like the idea of adding an option for applications (like yours) where it makes sense.   

So for both 1) and 2), I think a new handler class, called by Flow in onReceiveSuccess(..) and onReceiveFailure(..), might be a reasonable solution.  Before I start experimenting too much with this approach, I thought I'd throw it out there for feedback -- any thoughts?

[Scott]  I think an optional handler class makes sense.  If it is installed, then the receive and receiveFrom API's are essentially disabled, and receive data comes back via the handlers.

 

Thanks,
Jeremy