bluenviron / mediamtx

Ready-to-use SRT / WebRTC / RTSP / RTMP / LL-HLS media server and media proxy that allows to read, publish, proxy, record and playback video and audio streams.
MIT License
11.4k stars 1.45k forks source link

"Transport header does not contain interleaved IDs" with specific TCP client #1650

Closed neilyoung closed 1 year ago

neilyoung commented 1 year ago

Which version are you using?

v0.21.1

Which operating system are you using?

Describe the issue

Customer (Australia) uses "Genetec Video System to receive the RTSP". They are unable to receive video via TCP using this system. UDP is reported to work. VLC and FFPLAY is reported to work too. With the Genetec system sometimes the DESCRIBE request is answered with "BAD REQUEST", sometimes "OK". Even in OK case there is no video (flowing).

The only indication that something is wrong: I see a lot of traces of this kind in the RTSP server log:

2023/04/05 07:21:23 INF [RTSP] [session 028d421f] created by 202.xxx.xxx.xxx:34140
2023/04/05 07:21:23 INF [RTSP] [conn 202.xxx.xxx.xxx:34140] closed (transport header does not contain interleaved IDs)
2023/04/05 07:21:23 INF [RTSP] [session 028d421f] destroyed (not in use)

Describe how to replicate the issue

Replication difficult, I also don't have that "video system". I just have the Wireshark traces taken by them.

Did you attach the server logs?

No

Did you attach a network dump?

I have that, but I would not like to publish it here. Can provide it using a private dropbox link, if I would have a way to securely communicate that.

Sorry for the "no-information". Hoping we could get in touch with this.

neilyoung commented 1 year ago

I will be getting access to such a system later today. Would you consider dealing with this issue then?

aler9 commented 1 year ago

Hello, send server logs with logLevel: debug and network dump to aler9.dev@gmail.com

neilyoung commented 1 year ago

Thanks. Will do when I get some fresh ones.

neilyoung commented 1 year ago

Sent it

neilyoung commented 1 year ago

So this error message "Transport header does not contain interleaved IDs" does have its origin in gosrtplib (https://github.com/bluenviron/gortsplib).

https://github.com/bluenviron/gortsplib/blob/main/client.go#L1410

gosrtplib obviously unconditionally expects the Transport header of a TCP setup to look like so or similar

SETUP rtsp://foo.com/bar.file RTSP/1.0
           CSeq: 2
           Transport: RTP/AVP/TCP;interleaved=0-1

This is not the case from the Genetec. According to the RFC https://www.rfc-editor.org/rfc/rfc2326.html#section-12.39 the parameter is mandatory for TCP, not UDP. It separates the various streams (0 for Audio and 1 for Video in the above case).

aler9 commented 1 year ago

Hello,

Regarding UDP, handshake between the NVR and the server is working as expected, but communication can't be established because UDP only works when server and client are on the same LAN.

Regarding TCP, please test this nightly release and let me know if it fixes the issue. If it doesn't, provide server logs with the logLevel: debug option.

[link removed]

neilyoung commented 1 year ago

Regarding UDP, handshake between the NVR and the server is working as expected, but communication can't be established because UDP only works when server and client are on the same LAN.

Are you sure with this UDP only works when server and client are on the same LAN.? Could you kindly elaborate? I'm asking because up to now I was under the impression, that this SETUP is really setting up an UDP communication for the RTP (a bit anonymized):

SETUP rtsp://******:8554/6227329315/vx/mediaUUID=b719d37a-a808-436a-b916-5d5eb41a0552 RTSP/1.0
Transport: RTP/AVP/UDP;unicast;client_port=34836-34837
CSeq: 4
User-Agent: Lavf59.27.100
Authorization: Basic ******

RTSP/1.0 200 OK
CSeq: 4
Server: gortsplib
Session: a519ce47-9044-42f2-8404-e314613cf392;timeout=60
Transport: RTP/AVP;unicast;client_port=34836-34837;server_port=8000-8001;ssrc=D42CC60C

And in fact - it works, even though the server is somewhere at AWS and my client is here.

The FFPLAY command line is

ffplay  rtsp://xxx:xxx@*******:8554/6227329315/vx

In addition, I'm perfectly able to establish a TCP RTP session with this SETUP sequence:

SETUP rtsp://******:8554/6227329315/vx/mediaUUID=b719d37a-a808-436a-b916-5d5eb41a0552 RTSP/1.0
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
CSeq: 4
User-Agent: Lavf59.27.100
Authorization: Basic ******

RTSP/1.0 200 OK
CSeq: 4
Server: gortsplib
Session: c16d3bf5-5e12-4b61-9ab1-0bc6538765de
Transport: RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=D42CC60C

The matching FFPLAY command line is this:

ffplay  rtsp://xxx:xxx@*******:8554/6227329315/vx -rtsp_transport tcp

Thanks for the code provided. I will let you know. I saw that you made a PR to the gortsplib, so I'm sure it will work. But isn't this interleaved info element for a TCP session mandatory? I checked the RFC and couldn't find a hint that this would be optional.

PS: I also asked ChatGPT on this (is interleaved mandatory?), the answer was long, but yes :) OK, ChatGPT could perhaps easily be convinced to claim the contrary, but I don't want to make you weakening a lib, just because the client fails to match the standard

neilyoung commented 1 year ago

I noticed that you have renamed your product meanwhile. I made kind of a quick hack by keeping the old server name and log file name, but just adjusting the service entry by replacing rtsp-simple-server by mediamtx. That seems to work.

aler9 commented 1 year ago

UDP only works when server and client are on the same LAN.?

UDP also works when the server has a public IP, like an AWS elastic IP. The issue is not the handshake, that happens by using a TCP session, but the streaming, which happens through UDP packets. If there's a NAT/firewall in between, there's a high probability that these UDP packets get their source port changed or get blocked.

Anyway, the topic of this issue is the ability to support TCP readers that don't provide interleaved IDs in requests. For any other question, you can open additional issues or discussions.

Regarding standards and specifications, there are a lot of RTSP devices that don't follow rules and can't be changed since they are embedded hardware. Supporting or not supporting them depends on evaluating whether the change required for them to work impacts other devices or has security implications.

Just test the nightly release and report whether the fix is enough to solve the issue.

neilyoung commented 1 year ago

Anyway, the topic of this issue is the ability to support TCP readers that don't provide interleaved IDs in requests. For any other question, you can open additional issues or discussions.

Sure. I was just stumbling over that UDP only in the same LAN claim. But I'm also sure, that AWS has NAT applied. Even though it works. I think the port address translation possibly applied by NAT does only could have an impact, if you want to stream UDP towards the RTSP server through NAT. Here in this case it is the other way around and if the client demands a specific port and the server follows: What can go wrong?

In another UDP case the client did setup

image

And this was the result from AWS to me:

image

I don't see the problem here with NAT. But agreed, this is another party.

neilyoung commented 1 year ago

I can confirm the workaround works for audio and video. Thanks for having done that. Any time frame for a new release?

aler9 commented 1 year ago

added in MediaMTX v0.22.1

neilyoung commented 1 year ago

Perfect. Thank you very much.

neilyoung commented 1 year ago

BTW: FYI. The Genetec UDP issue is a missing UDP hole punching, which is done by VLC and Co. Will most likely not work in all cases, but in many. But here 2 times 4 bytes are sufficient to make the way free for the RTP from the server downstream.

We could show that by using "nc" as a side process to fire up these packets.

aler9 commented 1 year ago

@neilyoung the server performs UDP hole punching too, in the same exact way

neilyoung commented 1 year ago

I will forward this info to Genetec. Hoping they consider to adopt.

neilyoung commented 1 year ago

@neilyoung the server performs UDP hole punching too, in the same exact way

Out of curiosity: Could you provide me a code link, where exactly the server is doing this? It could help me in my discussion with Genetec

aler9 commented 1 year ago

A small clarification: when i said that "the server performs UDP hole punching" i meant that MediaMTX performs UDP hole punching when reading a stream from a RTSP camera or from a RTSP client. It's the reader that must implement UDP hole punching.

In your case it's the Genetec NVR that must implement UDP hole punching.

here's the code:

https://github.com/bluenviron/gortsplib/blob/5258f5b6e69254edb0dcb4958b0bf24ce8af5dd3/client.go#L1497-L1509

neilyoung commented 1 year ago

Yes. Thanks. I’m aware of the roles. Thanks for the link. I already digested my results and will forward it to Genetec in the hope that they’ll fix it. I also already tested several other clients, namely FFPLAY, GStreamer and VLC and they are all doing this UDP hole punching in one way or another. And also the mandatory interlaced info element for TCP/TLS is sent by them. So the ball is in the field of Genetc. I hope they’ll see that too.

At least you have saved our solution by enabling TCP with them for our clients. This was a boss move. 😀. Thanks again. I love your project.

github-actions[bot] commented 10 months ago

This issue is being locked automatically because it has been closed for more than 6 months. Please open a new issue in case you encounter a similar problem.