GNOME Bugzilla – Bug 559545
rtspsrc could not receive data from RTSP server because of the firewall in the Internet
Last modified: 2009-01-23 08:42:49 UTC
Please describe the problem: Rtspsrc sends `PLAY' method after `OPTIONS, DESCRIBE, SETUP', then the RTSP server begins to send data to the client. But the data cannot be received by rtspsrc because the firewall in the Internet blocks these data by default. Especially, when your client machine is in a NAT network environment, the firewall will block all the data comes from outside by default except your client machine initiates this connection. This will make rtspsrc plays a RTSP clip failed. Steps to reproduce: 1. Construct a NAT environment which blocks all data from outside network by default. 2. Use rtspsrc to play a rtsp movie. E.g: a movie from m.youtube.com. 3. Rtspsrc cannot receive any data and playout fails. Actual results: The playout fails and rtspsrc reports that it receives no data. Expected results: Rtspsrc should do something to make data passes through the firewalls. Does this happen every time? Yes Other information:
Created attachment 122071 [details] patch for gstrtspsrc.c & gstrtspsrc.h to make data passes through the firewalls I made a small trick to make firewalls forwards data from RTSP server while not blocks them. The trick is: Just send some UDP packets to the RTSP server before we send `PLAY' method to RTSP server. Because we know the RTP & RTCP ports in client and server, so we sends UDP packets to the server first to make the firewall believes that the connection was initiated by the client so the data coming next is safe. The result is the firewall will forward data while not block them.
Created attachment 122174 [details] This is the new version patch which fixed bugs in the patch provided above. Use this patch, please.
I'm inclined to add support for this into udpsrc, like make it accept a destination address with a property and make it send those dummy packets before going into receiving mode.
I tried this and it does not work. How did you test this? sending a packet from the client to the server still makes the server send to the RTP port behind the NAT. Somehow the server should be instructed to send the RTP packets to the port of the dummy packets.
OK, First I tried to play the movie on m.youtube.com and used `tcpdump' to monitor the incoming packets -- there were no packets come in so the udpsrc cannot receive any data. Then, I patched gstrtspsrc.c to make it send dummy udp packets to youtube server -- the source port is the RTP & RTCP ports we allocated during SETUP stage and the destination port is the RTP & RTCP ports which youtube server allocated. After that, I used `tcpdump' to monitor the incoming packets and found I received packets from youtube. That's it. I also used `tcpdump' to monitor the realplayer's behavior and found that realplayer will also send dummy udp packets to youtube server to make packets pass through the firewalls. So I think perhaps you can try `tcpdump' to monitor the behavior of your program -- does it indeed send out dummy udp packets? And the source/destination ports are correct? P.S: If you are not familiar with tcpdump, you can try `wireshark' which has a GUI interface and very easy to operate to monitor your network stuffs. You also mentioned you wanna add these logics to udpsrc. I think this is a great idea. I am looking forward to see this feature in next gst-plugins-good release.
Created attachment 122545 [details] The latest patch. Use this patch, pls.
OK, I'm going to assume it fixes some cases of NATed connections. I changed it so that it fits in more with the rest of the connection setup. Also added a property to configure the NAT traversal method in case we want to use ICE or STUN later. Based on patch by: Eric Zhang <chao.zhang at access-company dot com> * gst/rtsp/gstrtspsrc.c: (gst_rtsp_nat_method_get_type), (gst_rtspsrc_class_init), (gst_rtspsrc_set_property), (gst_rtspsrc_get_property), (gst_rtspsrc_create_stream), (gst_rtspsrc_stream_free), (gst_rtspsrc_stream_configure_udp_sinks), (gst_rtspsrc_stream_configure_transport), (gst_rtspsrc_send_dummy_packets), (gst_rtspsrc_create_transports_string), (gst_rtspsrc_handle_message), (gst_rtspsrc_change_state): * gst/rtsp/gstrtspsrc.h: Add property to configure NAT traversal method. Ignore EOS from the internal sinks. Implement sending dummy packets as a (simple) method to open up some firewalls. Send PLAY request to the server after we started the udp sources. Fixes #559545.
I still can't play any rtsp streams from behind the firewall. Tried with a bunch of random rtsp urls (some from gst-plugins-good/gst/rtsp/URLS). $ gst-launch rtspsrc nat-method=dummy location=rtsp://media2.gseis.ucla.edu/2005/webb/ed230b_20050112.mov ! decodebin name=d ! queue ! xvimagesink d. ! queue ! pulsesink Setting pipeline to PAUSED ... ERROR: Pipeline doesn't want to pause. ERROR: from element /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0: Could not open resource for reading and writing. Additional debug info: gstrtspsrc.c(4316): gst_rtspsrc_open (): /GstPipeline:pipeline0/GstRTSPSrc:rtspsrc0: Could not connect to server. (Timeout while waiting for server response) Setting pipeline to NULL ... FREEING pipeline ...
Comment #8, that is correct, this method has little chance of succeeding for most sane firewalls.
Created attachment 122625 [details] RTP Packets received Hi, Stefan. Seems I can play your rtsp video but I haven't the depay & decoder needed in this video: ============================================================= eric@eric-desktop:~/Access/8.RTSP_RTP/Codes$ ./rtspplayer "rtsp://media2.gseis.ucla.edu/2005/webb/ed230b_20050112.mov" ** Message: Got RTSP url input: rtsp://media2.gseis.ucla.edu/2005/webb/ed230b_20050112.mov ** Message: Set window id. Let xvimagesink draws on drawing area. ** Message: Begin playing the clip. ** Message: source_new_pad: Find 0 structure(s) in the cap of this pad, the content is: application/x-rtp, media=(string)audio, payload=(int)97, clock-rate=(int)44100, encoding-name=(string)X-PUREVOICE, encoding-params=(string)1, clock-base=(guint)1771415028, seqnum-base=(guint)18579, npt-start=(guint64)0, npt-stop=(guint64)10847254882812, play-speed=(double)1, play-scale=(double)1; ** Message: Link audio pad result: 0 ** Message: source_new_pad: Find 0 structure(s) in the cap of this pad, the content is: application/x-rtp, media=(string)video, payload=(int)96, clock-rate=(int)90000, encoding-name=(string)X-SV3V-ES, clock-base=(guint)784232230, seqnum-base=(guint)12332, npt-start=(guint64)0, npt-stop=(guint64)10847254882812, play-speed=(double)1, play-scale=(double)1; ** Message: Link video pad result: 0 ============================================================= rtspplayer is a program written by me. I also tried gst-launch: ============================================================= eric@eric-desktop:~/Access/8.RTSP_RTP/Codes$ gst-launch rtspsrc location="rtsp://media2.gseis.ucla.edu/2005/webb/ed230b_20050112.mov" name=d d. ! "application/x-rtp,media=video" ! decodebin ! ffmpegcolorspace ! xvimagesink d. ! "application/x-rtp,media=audio" ! decodebin ! audioconvert ! alsasink Setting pipeline to PAUSED ... Pipeline is live and does not need PREROLL ... Setting pipeline to PLAYING ... New clock: GstSystemClock ERROR: from element /pipeline0/decodebin1: A PUREVOICE audio RTP depayloader plugin is required to play this stream, but not installed. Additional debug info: gstdecodebin.c(845): close_pad_link (): /pipeline0/decodebin1: No decoder to handle media type 'application/x-rtp' Execution ended after 6069340 ns. Setting pipeline to PAUSED ... Setting pipeline to READY ... Setting pipeline to NULL ... FREEING pipeline ... ============================================================= I also attached a screenshot which showed the RTP packets I received from media2.gseis.ucla.edu