KallDrexx / rust-media-libs

Rust based libraries for misc media functionality
Apache License 2.0
229 stars 58 forks source link

UnknownPacket1Format error occors when trying to push to YouTube Live #4

Closed yuta0801 closed 3 years ago

yuta0801 commented 4 years ago

I trying to push rtmp stream to YouTube Live using mio_rtmp_server, but it sccors UnknownPacket1Format error. How can I deliver to YouTube Live?

$ dig +short a.rtmp.youtube.com # because it do not resolve domain
bartmp.l.google.com.
173.194.49.204
$ cargo run -h 173.194.49.204 -a live2 -t youtube-live-key -s mykey
Application options: AppOptions { log_io: false, pull: None, push: Some(PushOptions { host: "173.194.49.204", app: "live2", source_stream: "mykey", target_stream: "youtube-live-key" }) }
Listening for connections
New connection (id 0)
Spent 5 ms (0% of time) doing work over 11 seconds (avg 5009 microseconds per iteration)
Handshake successful!
Connection 0 requested connection to app 'live2'
Event raised by connection 0: UnhandleableAmf0Command { command_name: "_checkbw", transaction_id: 2.0, command_object: Null, additional_values: [] }
Event raised by connection 0: UnhandleableAmf0Command { command_name: "releaseStream", transaction_id: 3.0, command_object: Null, additional_values: [Utf8String("mykey")] 
}
Event raised by connection 0: UnhandleableAmf0Command { command_name: "FCPublish", transaction_id: 4.0, command_object: Null, additional_values: [Utf8String("mykey")] }   
Publish requested on app 'live2' and stream key 'mykey'
Publishing on the push source stream key!
Starting push to rtmp://173.194.49.204/live2/youtube-live-key
Push client started with connection id 1
Handshake error: HandshakeError { kind: UnknownPacket1Format }
Closing connection id 1
KallDrexx commented 4 years ago

Hi, thanks for the bug report. I'm pretty confident I tested it at some point against youtube but maybe not :(.

Based on the output it appears like Youtube is sending a non-zero 4 byte value as the 2nd portion of the packet 1, which most likely means their implementation of the fp9 digest handshake isn't what my code expects.

Unfortunately, I have been out of the live streaming space for well over a year and I'm not currently set up to test this at the current point in time (and a bit busy with real life stuff).. Not sure when I will be able to get to it unfortunately.

stan-kondrat commented 3 years ago

Hi, I did some investigation and found that if I remove that line, client handshaking to youtube will be completed.

@KallDrexx, why reader.read_u32 is used twice?


Moreover, about "non-zero 4 byte" here are some screenshots:

image image image

KallDrexx commented 3 years ago

Interesting find!

I just looked through the RTMP specification I used while developing this library, and section 5.2

What I can tell is that the version the next line is pointing to is not the protocol version, it's the "Adobe Version" that many servers are expecting the set of 4 bytes. The RTMP 1.0 specification says this 4 bytes should be zero, however it appears that behavior has changed since this spec was made and now clients and servers are expecting it to have the adobe flash version being used (iirc this was determined by me wire-sharking other rtmp clients and servers). You can see where I encode this here.

So the format of the P1 packet (which is S1 or C1 in the spec) is a time field, then zero field (what we put that adobe version in), then the "random" data field. Based on comments elsewhere in the code the line you highlighted is meant to ignore the time field (because everyone returns time of zero and it didn't seem useful).

I would expect the handshake would fail with removing that line, because otherwise the random data won't validate. If I remember correctly the random data they send in P1 I must send back in my P2 response and it must 100% match for the peer to approve the handshake. So if you comment out that line then I would expect that the random data to be offset and it would fail for any non-fp9 handshake, except I now see that the reader isn't used for pulling the random data out.


OH ok so I see (sorry for stream of consciousness :D) It appears commenting out that line ends up working by accident.

So the reason commenting the line works is because without that first line it's reading the version out of the "time" field, which is always zero in the real world. This version is traditionally used by other servers and clients to know if it should use the fp9 handshake or not (handshake that does a key exchange).

When a peer tries to connect if it sends a zero version in the zero field (NOT protocol version sent in packet 0, confusing I know) then it should be assumed that that peer does not do a key exchange and therefore the peer is expecting you to return the data back as-is with no modifications. If the peer sends an adobe version in the zero field of packet 1 then that peer is intending to do a key exchange type of handshake.

The way I wrote the code doesn't really use that field for determining if it should use a key exchange or not. Instead I try to derive the digest keys / hmac values from the "random data" payload. If we can compute digest keys that pass then we assume that's how it was meant to be and proceed with the fp9 handshake. Otherwise we default back to the original 1.0 spec handshake (return random data 'as-is'), but we only do that if the version we read is zero like in the original RTMP spec (otherwise we assume they meant an fp9 handshake but the keys couldn't be computed).

So commenting out that line of code you mentioned "works" because when we fail computing the fp9 handshake keys we have a "adobe version" of zero (because we read the time field) and therefore we assume it's an original RTMP 1.0 handshake.


That's a long way to say, it appears that the fp9 handshake code is not deriving Youtube's digest keys property and that seems to be the "root" issue.

The question is, when you comment out the line you pointed out, does it actually work and allow you to push video to Youtube? I would expect Youtube to reject our handshake because they tried a fp9 handshake and we instead responded with a 1.0 handshake. Maybe they are just backwards compatible and can handle either response?

stan-kondrat commented 3 years ago

Thank you for your answer.

After long searching, I decided to hardcode youtube response for now in my project 😔

But it is worth to come back to it and to look into some others open source rtmp libs.

image

KallDrexx commented 3 years ago

Yes for sure. Thanks to your finding I will try to carve out some time and see if I can get hints from some other open source RTMP libraries to see what I'm doing wrong.

kcking commented 3 years ago

I just ran into this as well, and adding the special case for youtube worked for me. Using request_connection("live2") instead of app made the stream succeed 💯

Since this code path is already a fallback, wdyt of adding this special case? I can make a quick PR

Also I ran wireshark on an OBS -> Youtube handshake and can confirm C1 == S2 and S1 == C2.

KallDrexx commented 3 years ago

I just ran into this as well, and adding the special case for youtube worked for me. Using request_connection("live2") instead of app made the stream succeed 💯

Sorry my brain is a bit fried (newborn) but I don't totally understand what you mean, or rather how the two parts of this sentence correlate. Do you mean you got it working by detecting live2 as the app name, and if that's found then you know it's youtube and do the special case?

Also I ran wireshark on an OBS -> Youtube handshake and can confirm C1 == S2 and S1 == C2.

Ok so that tells me that Youtube isn't doing the FP9 handshake, they are doing the original RTMP handshake. So the reason this is failing for Youtube is because while the original RTMP spec says the 2nd set of 4 bytes should all be zeros, Youtube is sending some other value for that.

If you have wireshark already set up for this would you mind telling me what the 2nd set of 4 bytes are that Youtube sends? I suspect the true fix for this is going to be one of two things:

The first option is to replace this code with something like:

        let received_digest = match get_digest_for_received_packet(&received_packet_1, &p1_key) {
            Ok(digest) => digest,
            Err(HandshakeError{kind: HandshakeErrorKind::UnknownPacket1Format}) => {
                // Since no digest was found chances are that
                // this handshake is not a fp9 handshake, but instead is the handshake from the
                // original RTMP specification.  If that's the case then this isn't an error,
                // we just need to send back an exact copy of their p1 and we are good.
                self.current_stage = Stage::WaitingForPacket2;
                return Ok(HandshakeProcessResult::InProgress {response_bytes: received_packet_1.to_vec()});
            },
            Err(x) => return Err(x),
        };

This essentially gets rid of the version check and makes the assumption that if we fail the digest/fp9 check but this isn't a valid RTMP handshake then that will get caught in the S2/C2 validations. In other words, we will send back the exact copy of the inbound data as a response, the other side was expecting an fp9 response instead and will kill the connection. However, in non-rtmp scenarios where we've accidentally had the right set of packets to get this far we might hang forever (until a timeout) because we won't ever have detected that this really wasn't an RTMP connection. I think the risk of this is low though.

The alternative is to make the if statement if version == 0 || version == XXXX where XXXX is the version number that Youtube is sending back. That's a bit safer but it feels a bit whackamole to me.

Since you are willing to do a PR (and thus theoretically setup for testing it), if you don't mind doing one of those options, testing it, and raising a PR I'll be glad to approve either way you go.

kcking commented 3 years ago

Sorry my brain is a bit fried (newborn) but I don't totally understand what you mean, or rather how the two parts of this sentence correlate. Do you mean you got it working by detecting live2 as the app name, and if that's found then you know it's youtube and do the special case?

I meant adding the special case for version == 0x04_00_00_01 made the handshake complete successfully, and using request_connection("live2") instead of request_connection("app") made the full stream progress successfully.

If you have wireshark already set up for this would you mind telling me what the 2nd set of 4 bytes are that Youtube sends?

For completeness here's the whole handshake:

C0+C1 ```text 0000 03 00 03 b6 a3 00 00 00 00 29 00 00 00 23 48 00 0010 00 be 18 00 00 84 67 00 00 e1 4a 00 00 6c 3d 00 0020 00 d6 2c 00 00 ae 72 00 00 52 69 00 00 90 5f 00 0030 00 49 16 00 00 f1 6d 00 00 f1 5a 00 00 bb 41 00 0040 00 e9 26 00 00 eb 01 00 00 b3 0b 00 00 a6 2e 00 0050 00 db 12 00 00 3c 15 00 00 87 7e 00 00 0c 39 00 0060 00 3e 0f 00 00 99 00 00 00 24 01 00 00 5e 30 00 0070 00 0d 44 00 00 1c 49 00 00 06 4d 00 00 b7 4d 00 0080 00 47 15 00 00 de 54 00 00 b3 39 00 00 12 2d 00 0090 00 4d 07 00 00 c8 4d 00 00 43 64 00 00 bb 66 00 00a0 00 8b 42 00 00 a6 26 00 00 1f 70 00 00 03 5d 00 00b0 00 5a 7a 00 00 7d 76 00 00 09 45 00 00 38 12 00 00c0 00 25 3b 00 00 1f 1e 00 00 5d 6e 00 00 d4 1a 00 00d0 00 cb 63 00 00 fc 6b 00 00 96 7f 00 00 f5 7f 00 00e0 00 45 4e 00 00 3b 32 00 00 13 22 00 00 0d 26 00 00f0 00 89 6b 00 00 0a 03 00 00 1c 30 00 00 db 0b 00 0100 00 ae 56 00 00 32 07 00 00 20 01 00 00 9a 75 00 0110 00 50 23 00 00 ee 22 00 00 40 4b 00 00 78 58 00 0120 00 36 6b 00 00 fd 5c 00 00 12 3e 00 00 49 1a 00 0130 00 32 5f 00 00 f6 3b 00 00 9e 3a 00 00 7d 79 00 0140 00 49 5f 00 00 dc 0d 00 00 ad 4c 00 00 4f 31 00 0150 00 14 5e 00 00 f2 4d 00 00 44 49 00 00 40 2e 00 0160 00 66 13 00 00 d0 1c 00 00 6b 36 00 00 c4 66 00 0170 00 30 42 00 00 b7 7e 00 00 32 60 00 00 3b 2c 00 0180 00 a1 15 00 00 22 54 00 00 f6 3e 00 00 22 08 00 0190 00 91 59 00 00 9d 40 00 00 e1 12 00 00 8b 79 00 01a0 00 1f 12 00 00 da 73 00 00 b0 58 00 00 ca 26 00 01b0 00 99 36 00 00 02 09 00 00 b9 7b 00 00 72 57 00 01c0 00 9d 13 00 00 49 70 00 00 2c 69 00 00 80 4a 00 01d0 00 7e 18 00 00 c5 16 00 00 99 68 00 00 d5 3c 00 01e0 00 e9 13 00 00 80 40 00 00 b2 5d 00 00 ea 33 00 01f0 00 c9 23 00 00 cc 48 00 00 53 57 00 00 bf 60 00 0200 00 67 5c 00 00 d6 3c 00 00 bf 0f 00 00 14 2f 00 0210 00 d6 6a 00 00 7e 04 00 00 2d 42 00 00 dc 54 00 0220 00 8e 36 00 00 66 0d 00 00 83 79 00 00 ef 75 00 0230 00 57 46 00 00 49 2c 00 00 61 3c 00 00 ff 2f 00 0240 00 69 6c 00 00 8f 28 00 00 61 3a 00 00 cd 22 00 0250 00 d1 7d 00 00 1e 26 00 00 9d 5e 00 00 9c 48 00 0260 00 16 19 00 00 72 61 00 00 72 6b 00 00 e6 32 00 0270 00 1d 40 00 00 f0 71 00 00 84 03 00 00 4f 7f 00 0280 00 4a 49 00 00 77 06 00 00 02 44 00 00 d7 18 00 0290 00 e8 6b 00 00 39 50 00 00 2c 54 00 00 53 19 00 02a0 00 cb 6b 00 00 c9 0f 00 00 12 0e 00 00 1e 5f 00 02b0 00 33 28 00 00 74 78 00 00 9e 24 00 00 0c 2b 00 02c0 00 f4 11 00 00 d5 5d 00 00 d4 6a 00 00 9f 5a 00 02d0 00 d4 4c 00 00 a4 5f 00 00 59 20 00 00 7e 12 00 02e0 00 35 00 00 00 cf 07 00 00 32 67 00 00 22 6d 00 02f0 00 f4 1a 00 00 cc 0e 00 00 cf 46 00 00 d3 01 00 0300 00 90 0e 00 00 2d 3a 00 00 48 60 00 00 d3 57 00 0310 00 8f 45 00 00 75 09 00 00 e6 37 00 00 d9 19 00 0320 00 1d 59 00 00 2a 25 00 00 e5 37 00 00 c0 1d 00 0330 00 f7 49 00 00 2b 44 00 00 78 50 00 00 81 14 00 0340 00 87 40 00 00 44 7b 00 00 0e 59 00 00 5f 76 00 0350 00 50 18 00 00 00 2b 00 00 d4 16 00 00 61 7f 00 0360 00 8d 3a 00 00 be 7f 00 00 7b 0c 00 00 05 50 00 0370 00 15 0c 00 00 07 38 00 00 3b 77 00 00 33 06 00 0380 00 82 72 00 00 1f 25 00 00 18 1d 00 00 70 62 00 0390 00 92 34 00 00 da 19 00 00 64 50 00 00 54 4d 00 03a0 00 ce 39 00 00 b1 3b 00 00 85 4c 00 00 3e 51 00 03b0 00 69 6d 00 00 15 6a 00 00 f8 4f 00 00 46 5c 00 03c0 00 6a 48 00 00 04 30 00 00 96 17 00 00 73 5e 00 03d0 00 0e 47 00 00 d9 73 00 00 16 1f 00 00 2f 18 00 03e0 00 67 4d 00 00 68 59 00 00 d4 4a 00 00 f7 2c 00 03f0 00 4a 3f 00 00 4a 0a 00 00 d0 5e 00 00 57 4e 00 0400 00 68 4f 00 00 76 58 00 00 fa 66 00 00 16 13 00 0410 00 bb 49 00 00 11 6f 00 00 ad 74 00 00 ae 4e 00 0420 00 24 5d 00 00 88 05 00 00 79 55 00 00 fe 7c 00 0430 00 52 28 00 00 db 48 00 00 25 27 00 00 43 16 00 0440 00 e5 0d 00 00 3c 6f 00 00 f4 6c 00 00 45 5f 00 0450 00 d3 13 00 00 d8 29 00 00 28 0a 00 00 ce 09 00 0460 00 0b 52 00 00 f5 68 00 00 c5 45 00 00 60 39 00 0470 00 59 34 00 00 3d 26 00 00 97 3b 00 00 27 40 00 0480 00 8a 13 00 00 59 29 00 00 76 5e 00 00 2d 28 00 0490 00 d0 69 00 00 c2 7a 00 00 c9 6f 00 00 cd 5c 00 04a0 00 68 26 00 00 d4 78 00 00 49 10 00 00 6a 08 00 04b0 00 79 64 00 00 25 43 00 00 08 4e 00 00 61 7a 00 04c0 00 40 09 00 00 14 70 00 00 b1 53 00 00 3b 29 00 04d0 00 6a 0d 00 00 a5 40 00 00 11 1d 00 00 28 25 00 04e0 00 c1 75 00 00 8c 46 00 00 d6 54 00 00 a9 0e 00 04f0 00 0b 3f 00 00 87 30 00 00 97 3f 00 00 8c 65 00 0500 00 2f 41 00 00 f1 30 00 00 15 58 00 00 1d 44 00 0510 00 9a 4d 00 00 95 32 00 00 c1 00 00 00 9b 5a 00 0520 00 e1 0c 00 00 c0 4f 00 00 7e 6e 00 00 e9 3e 00 0530 00 a8 5f 00 00 9a 3f 00 00 a7 30 00 00 86 64 00 0540 00 c2 46 00 00 b5 2d 00 00 54 7a 00 00 bf 50 00 0550 00 9a 16 00 00 e7 2f 00 00 d9 10 00 00 23 5f 00 0560 00 d1 79 00 00 55 4e 00 00 90 03 00 00 38 2a 00 0570 00 28 07 00 00 d1 51 00 00 d9 10 00 00 6c 6c 00 0580 00 a1 6e 00 00 66 4c 00 00 5e 5c 00 00 4e 6d 00 0590 00 e1 01 00 00 30 10 00 00 9c 5a 00 00 fe 4e 00 05a0 00 d9 1b 00 00 71 08 00 00 9f 15 00 00 e2 4f 00 05b0 00 a5 2b 00 00 e2 28 00 00 0c 2f 00 00 9b 54 00 05c0 00 b4 66 00 00 47 67 00 00 65 43 00 00 38 4e 00 05d0 00 2a 66 00 00 46 73 00 00 89 12 00 00 a9 50 00 05e0 00 82 33 00 00 79 20 00 00 7a 11 00 00 76 6d 00 05f0 00 78 08 00 00 c2 36 00 00 63 49 00 00 b1 26 00 0600 00 ```
S0+S1+S2 (S2 starts at byte 0601) ``` 0000 03 00 00 00 00 04 00 00 01 fb 59 2e 84 a0 3e 88 0010 f2 30 e5 1e f5 fc cc a7 fe b0 c3 9e 28 55 5e 07 0020 36 55 74 21 f9 27 9e 42 20 68 22 a7 54 59 22 c3 0030 ba b5 17 78 62 81 04 c9 ae 63 57 14 c3 f5 a8 97 0040 23 53 b2 72 12 3f 50 40 18 68 53 29 11 f8 72 ed 0050 63 71 b5 32 66 4c 73 f2 90 e6 e6 2f 8e d6 99 ee 0060 b0 8f 8e 77 eb 10 4b 57 23 29 5d 2d 5a b9 87 4d 0070 d2 d5 d1 42 8c fa b9 1e 7a 90 1c 58 c9 f6 64 e3 0080 9a 9d 46 ac ed 5a b4 57 09 1d 3e 9f f1 d7 22 99 0090 ca e7 8f bd 0a 03 fc 92 1d 3b f5 6b 9a 0d a6 5b 00a0 0c ec 1e 9f 64 14 2e c6 ec cf 89 07 0f 66 89 6b 00b0 8e 99 1f eb 1f e2 be af 26 8e ed 64 59 22 7f 27 00c0 30 b0 fe 37 6a 17 13 2a a0 13 ff 64 ae 80 0a a2 00d0 c3 99 88 44 33 31 3f 9c 4a b9 75 1f 5f 25 ba 40 00e0 51 0e b1 9f 4e f7 6f 1e af 8b f5 c6 20 c1 37 a9 00f0 f1 7f b0 f4 88 36 e4 7a 32 91 bf 21 8f d2 27 04 0100 4c 14 b4 42 c4 e8 a5 ee 9b 0c 5f b7 a9 44 95 8a 0110 e9 f8 63 97 d0 8f 91 82 10 10 5f 3c 3c 64 f9 e9 0120 3e 8f d7 d4 7e ca 91 96 c6 94 5e e1 df f3 e1 ae 0130 92 05 d8 60 f8 79 8c 1d 45 98 64 13 44 1e f1 16 0140 e8 94 20 69 7e 53 ba fa df 21 59 06 fa 39 c0 03 0150 26 7b 9e fe 7a 93 dc 17 01 66 0b d2 4f d9 8d e7 0160 43 81 f8 5b ce 0a bb 18 43 a6 00 f5 2e a0 0b c2 0170 f0 5d c1 61 49 20 74 f8 fb 7d 04 d1 77 e9 1d 92 0180 b3 58 ef 7e b9 d9 f0 43 99 63 08 3a 66 89 c2 75 0190 b3 cf 07 f8 4a c6 40 be 98 0d 0d f0 30 18 8d ef 01a0 02 5d 0b c1 3f 3a aa 60 ad e4 22 f6 ec d4 b4 62 01b0 46 ab 4b 6f 8a 0c ab 0b 99 f5 2d 1b 4a 62 9b 83 01c0 75 2e 53 6b 6f ce 2c d1 27 3e 71 ee b0 25 09 83 01d0 02 49 0a 10 0b 58 af dc 2a 7a 8b 05 22 db ee 7e 01e0 d5 9f 86 45 46 35 40 83 9b 7b 72 ff 26 95 e8 04 01f0 5f 9f 9b 70 52 87 23 0b 41 5c 88 24 fe 1a bb 11 0200 05 f0 f6 bc 6f ba 66 8d 32 64 8e 24 e7 7c 53 a4 0210 19 e4 9a 6d d2 b1 e2 cf 38 e7 0d e3 16 73 70 a5 0220 5c 78 5d f3 c4 b0 d7 21 6c d5 2a c9 82 be ff c5 0230 55 98 66 07 69 42 b3 b4 c4 e6 9a 67 68 64 65 e5 0240 09 9d e9 07 78 de 85 41 bb eb 15 46 8a b2 aa 26 0250 e7 23 9f 72 71 7e 4c 61 07 35 81 f1 57 ba f9 9e 0260 ff ab 22 4c f3 93 f2 07 ff ab 6b 56 92 52 c6 fe 0270 a0 0a f8 96 39 aa 6f 17 64 80 76 85 f0 42 59 c4 0280 c6 c4 78 ad 2a b0 aa 5c d7 2d 6a 4f 80 78 56 e9 0290 a1 72 93 9f 95 e7 77 72 b7 f8 fe 9d 4f 28 ff 00 02a0 d7 d6 19 74 e8 0f 77 c9 86 d3 9b 4f 91 30 c6 fd 02b0 44 83 19 2c 3b 2a 89 01 50 d0 e4 ca 80 03 db b5 02c0 14 e7 ca 7e d1 fc 50 ad 54 e4 ce 27 2f ae c1 19 02d0 4e 37 59 6f ec 78 aa 81 25 2b d8 52 91 3a 64 eb 02e0 b6 dd fd 4a e6 50 f6 fb db bf f8 4b 4f b0 b7 fb 02f0 7a 84 c2 a7 40 0f 70 d6 21 44 fa a7 29 76 7f 93 0300 af fc 59 c5 7f 21 a3 b7 0b e6 02 e8 1a 20 0b 71 0310 39 21 07 dd 4e 5e 6d 25 27 ea 9a 0a de c5 ff 12 0320 56 49 94 ec 98 7f e7 6e 77 51 08 1c ed 82 62 88 0330 1c 17 c0 54 3b a9 2c 36 a2 c4 0a ac 32 80 f6 1d 0340 c9 31 d1 dc 88 2e 4f 57 7c 21 f0 a4 90 97 41 96 0350 78 68 05 5e 8a aa fb 4c 9d bd 99 81 0a a4 e6 ce 0360 12 ef 22 2f 87 e2 d5 93 16 31 ff 67 63 1f d1 c1 0370 13 a2 45 10 f6 9a 6d ee 3d 38 7b 8b a8 bd 39 60 0380 5d b0 40 7a b9 11 0f a8 56 11 7f 69 1b 52 49 68 0390 be fa b1 95 fe 90 20 91 64 7a db df b7 6d fb 38 03a0 30 39 10 65 55 dc a0 a4 30 e6 79 8d d0 e1 4f 48 03b0 9d 10 52 ac a9 65 b6 89 d7 81 9b 92 a0 a3 7e cc 03c0 8a 78 e5 6c 86 88 f7 6b 14 16 a9 36 65 03 ff f1 03d0 5a 08 af 7f 55 fb f5 e2 2f be 6c b4 10 3d 6b 4b 03e0 63 7f 14 c7 7d 07 7a 7b 44 77 e0 91 8e ea 84 0f 03f0 3d c6 27 12 6e 15 07 06 66 25 00 80 a6 08 78 20 0400 ed eb e5 2f c3 85 8d 9d 57 ae 37 b6 f9 e8 f8 0d 0410 01 be 87 31 87 94 b0 05 dd e8 6b 0d bc b3 a6 2d 0420 1c 2f df 29 d8 0d 6f b1 bc d0 06 af 91 fe 73 88 0430 c3 64 92 fc 52 a2 0e 2e 5f eb 9d e8 cb 80 94 09 0440 a1 30 47 11 17 73 9f 4a 05 40 3a 4e d6 80 e7 00 0450 da a0 df 45 be 46 f6 f7 02 38 c5 f0 3c 74 48 ee 0460 a9 df 5e 55 0d 40 a8 a6 95 77 6e bf 66 94 18 36 0470 4d c9 2c f6 bb 75 87 d1 e4 05 6b a4 ce 73 29 69 0480 ce 79 8c 09 22 53 af 8a b1 41 bb 55 27 ca 29 1e 0490 ca 26 28 01 f1 d3 e5 39 98 24 f6 8c d9 11 7c 7a 04a0 18 bc bf ba 25 41 8f 63 ed 76 e3 61 47 77 6d 41 04b0 1f 99 31 e4 4f 3b dc 8f 90 1b 7a 43 bb 0e 9b c1 04c0 7b ca 9f 67 70 87 6c a1 02 6e 74 a4 18 e2 5e 3f 04d0 a4 4e d6 94 a7 41 7d ca 91 2b 22 b1 9b 42 d0 d1 04e0 0c 58 09 ad 9d 03 0b d8 67 b5 f9 0a 7f 34 27 da 04f0 aa 40 8b 37 06 0d c5 bc d4 79 c0 2d db 3d 0f 93 0500 f4 d5 91 3a dd 37 50 dc 8f 18 41 17 0b e0 6d d5 0510 bc ec 18 8a 3f ac d0 06 da 4b 85 7a 07 58 de 11 0520 cd 72 a1 5d 44 dc fd 5b ce 8e 90 fa 01 b6 0c 20 0530 6a d8 82 6b 1c a7 3c a6 f2 9b af e8 21 0d 8a d3 0540 04 e0 5b 82 0f aa 38 d0 19 58 4f 45 dc 85 f2 88 0550 d8 ab 7c 0e 01 b9 8e 1c 7c ac 49 4f 2f 6f 6a 14 0560 ec 6c 5b 99 f5 7a a4 e5 96 e6 4b c7 ab 17 9f 19 0570 81 3d cc 0b 29 c6 3d 4a 79 98 71 c6 0e c4 33 04 0580 19 a7 66 f5 94 7c 72 a4 b9 4d 50 34 b8 2d 21 9f 0590 bf 29 1f 9d 36 e7 c0 b2 86 31 d0 cf 09 63 75 26 05a0 6c 3b 3b 95 a7 a2 1f 84 17 f2 03 1f 73 4f 9b da 05b0 a8 72 56 52 83 de 9f 30 23 a8 ef 29 58 81 b3 3b 05c0 74 8c 83 1d bc 96 ce c6 8f c1 9b 31 35 c4 02 10 05d0 cc 15 e9 d8 25 78 e6 80 b6 fd a2 c6 b6 e4 79 0a 05e0 9d 56 cb 6f a6 c2 73 fe 07 ee 81 af 8c eb 8e 2c 05f0 7e 5d ad 3d a3 e3 bd de 2e 67 af 01 af 18 31 d9 0600 8c 00 03 b6 a3 00 00 00 00 29 00 00 00 23 48 00 0610 00 be 18 00 00 84 67 00 00 e1 4a 00 00 6c 3d 00 0620 00 d6 2c 00 00 ae 72 00 00 52 69 00 00 90 5f 00 0630 00 49 16 00 00 f1 6d 00 00 f1 5a 00 00 bb 41 00 0640 00 e9 26 00 00 eb 01 00 00 b3 0b 00 00 a6 2e 00 0650 00 db 12 00 00 3c 15 00 00 87 7e 00 00 0c 39 00 0660 00 3e 0f 00 00 99 00 00 00 24 01 00 00 5e 30 00 0670 00 0d 44 00 00 1c 49 00 00 06 4d 00 00 b7 4d 00 0680 00 47 15 00 00 de 54 00 00 b3 39 00 00 12 2d 00 0690 00 4d 07 00 00 c8 4d 00 00 43 64 00 00 bb 66 00 06a0 00 8b 42 00 00 a6 26 00 00 1f 70 00 00 03 5d 00 06b0 00 5a 7a 00 00 7d 76 00 00 09 45 00 00 38 12 00 06c0 00 25 3b 00 00 1f 1e 00 00 5d 6e 00 00 d4 1a 00 06d0 00 cb 63 00 00 fc 6b 00 00 96 7f 00 00 f5 7f 00 06e0 00 45 4e 00 00 3b 32 00 00 13 22 00 00 0d 26 00 06f0 00 89 6b 00 00 0a 03 00 00 1c 30 00 00 db 0b 00 0700 00 ae 56 00 00 32 07 00 00 20 01 00 00 9a 75 00 0710 00 50 23 00 00 ee 22 00 00 40 4b 00 00 78 58 00 0720 00 36 6b 00 00 fd 5c 00 00 12 3e 00 00 49 1a 00 0730 00 32 5f 00 00 f6 3b 00 00 9e 3a 00 00 7d 79 00 0740 00 49 5f 00 00 dc 0d 00 00 ad 4c 00 00 4f 31 00 0750 00 14 5e 00 00 f2 4d 00 00 44 49 00 00 40 2e 00 0760 00 66 13 00 00 d0 1c 00 00 6b 36 00 00 c4 66 00 0770 00 30 42 00 00 b7 7e 00 00 32 60 00 00 3b 2c 00 0780 00 a1 15 00 00 22 54 00 00 f6 3e 00 00 22 08 00 0790 00 91 59 00 00 9d 40 00 00 e1 12 00 00 8b 79 00 07a0 00 1f 12 00 00 da 73 00 00 b0 58 00 00 ca 26 00 07b0 00 99 36 00 00 02 09 00 00 b9 7b 00 00 72 57 00 07c0 00 9d 13 00 00 49 70 00 00 2c 69 00 00 80 4a 00 07d0 00 7e 18 00 00 c5 16 00 00 99 68 00 00 d5 3c 00 07e0 00 e9 13 00 00 80 40 00 00 b2 5d 00 00 ea 33 00 07f0 00 c9 23 00 00 cc 48 00 00 53 57 00 00 bf 60 00 0800 00 67 5c 00 00 d6 3c 00 00 bf 0f 00 00 14 2f 00 0810 00 d6 6a 00 00 7e 04 00 00 2d 42 00 00 dc 54 00 0820 00 8e 36 00 00 66 0d 00 00 83 79 00 00 ef 75 00 0830 00 57 46 00 00 49 2c 00 00 61 3c 00 00 ff 2f 00 0840 00 69 6c 00 00 8f 28 00 00 61 3a 00 00 cd 22 00 0850 00 d1 7d 00 00 1e 26 00 00 9d 5e 00 00 9c 48 00 0860 00 16 19 00 00 72 61 00 00 72 6b 00 00 e6 32 00 0870 00 1d 40 00 00 f0 71 00 00 84 03 00 00 4f 7f 00 0880 00 4a 49 00 00 77 06 00 00 02 44 00 00 d7 18 00 0890 00 e8 6b 00 00 39 50 00 00 2c 54 00 00 53 19 00 08a0 00 cb 6b 00 00 c9 0f 00 00 12 0e 00 00 1e 5f 00 08b0 00 33 28 00 00 74 78 00 00 9e 24 00 00 0c 2b 00 08c0 00 f4 11 00 00 d5 5d 00 00 d4 6a 00 00 9f 5a 00 08d0 00 d4 4c 00 00 a4 5f 00 00 59 20 00 00 7e 12 00 08e0 00 35 00 00 00 cf 07 00 00 32 67 00 00 22 6d 00 08f0 00 f4 1a 00 00 cc 0e 00 00 cf 46 00 00 d3 01 00 0900 00 90 0e 00 00 2d 3a 00 00 48 60 00 00 d3 57 00 0910 00 8f 45 00 00 75 09 00 00 e6 37 00 00 d9 19 00 0920 00 1d 59 00 00 2a 25 00 00 e5 37 00 00 c0 1d 00 0930 00 f7 49 00 00 2b 44 00 00 78 50 00 00 81 14 00 0940 00 87 40 00 00 44 7b 00 00 0e 59 00 00 5f 76 00 0950 00 50 18 00 00 00 2b 00 00 d4 16 00 00 61 7f 00 0960 00 8d 3a 00 00 be 7f 00 00 7b 0c 00 00 05 50 00 0970 00 15 0c 00 00 07 38 00 00 3b 77 00 00 33 06 00 0980 00 82 72 00 00 1f 25 00 00 18 1d 00 00 70 62 00 0990 00 92 34 00 00 da 19 00 00 64 50 00 00 54 4d 00 09a0 00 ce 39 00 00 b1 3b 00 00 85 4c 00 00 3e 51 00 09b0 00 69 6d 00 00 15 6a 00 00 f8 4f 00 00 46 5c 00 09c0 00 6a 48 00 00 04 30 00 00 96 17 00 00 73 5e 00 09d0 00 0e 47 00 00 d9 73 00 00 16 1f 00 00 2f 18 00 09e0 00 67 4d 00 00 68 59 00 00 d4 4a 00 00 f7 2c 00 09f0 00 4a 3f 00 00 4a 0a 00 00 d0 5e 00 00 57 4e 00 0a00 00 68 4f 00 00 76 58 00 00 fa 66 00 00 16 13 00 0a10 00 bb 49 00 00 11 6f 00 00 ad 74 00 00 ae 4e 00 0a20 00 24 5d 00 00 88 05 00 00 79 55 00 00 fe 7c 00 0a30 00 52 28 00 00 db 48 00 00 25 27 00 00 43 16 00 0a40 00 e5 0d 00 00 3c 6f 00 00 f4 6c 00 00 45 5f 00 0a50 00 d3 13 00 00 d8 29 00 00 28 0a 00 00 ce 09 00 0a60 00 0b 52 00 00 f5 68 00 00 c5 45 00 00 60 39 00 0a70 00 59 34 00 00 3d 26 00 00 97 3b 00 00 27 40 00 0a80 00 8a 13 00 00 59 29 00 00 76 5e 00 00 2d 28 00 0a90 00 d0 69 00 00 c2 7a 00 00 c9 6f 00 00 cd 5c 00 0aa0 00 68 26 00 00 d4 78 00 00 49 10 00 00 6a 08 00 0ab0 00 79 64 00 00 25 43 00 00 08 4e 00 00 61 7a 00 0ac0 00 40 09 00 00 14 70 00 00 b1 53 00 00 3b 29 00 0ad0 00 6a 0d 00 00 a5 40 00 00 11 1d 00 00 28 25 00 0ae0 00 c1 75 00 00 8c 46 00 00 d6 54 00 00 a9 0e 00 0af0 00 0b 3f 00 00 87 30 00 00 97 3f 00 00 8c 65 00 0b00 00 2f 41 00 00 f1 30 00 00 15 58 00 00 1d 44 00 0b10 00 9a 4d 00 00 95 32 00 00 c1 00 00 00 9b 5a 00 0b20 00 e1 0c 00 00 c0 4f 00 00 7e 6e 00 00 e9 3e 00 0b30 00 a8 5f 00 00 9a 3f 00 00 a7 30 00 00 86 64 00 0b40 00 c2 46 00 00 b5 2d 00 00 54 7a 00 00 bf 50 00 0b50 00 9a 16 00 00 e7 2f 00 00 d9 10 00 00 23 5f 00 0b60 00 d1 79 00 00 55 4e 00 00 90 03 00 00 38 2a 00 0b70 00 28 07 00 00 d1 51 00 00 d9 10 00 00 6c 6c 00 0b80 00 a1 6e 00 00 66 4c 00 00 5e 5c 00 00 4e 6d 00 0b90 00 e1 01 00 00 30 10 00 00 9c 5a 00 00 fe 4e 00 0ba0 00 d9 1b 00 00 71 08 00 00 9f 15 00 00 e2 4f 00 0bb0 00 a5 2b 00 00 e2 28 00 00 0c 2f 00 00 9b 54 00 0bc0 00 b4 66 00 00 47 67 00 00 65 43 00 00 38 4e 00 0bd0 00 2a 66 00 00 46 73 00 00 89 12 00 00 a9 50 00 0be0 00 82 33 00 00 79 20 00 00 7a 11 00 00 76 6d 00 0bf0 00 78 08 00 00 c2 36 00 00 63 49 00 00 b1 26 00 0c00 00 ```
C2 ``` 0000 00 00 00 00 04 00 00 01 fb 59 2e 84 a0 3e 88 f2 0010 30 e5 1e f5 fc cc a7 fe b0 c3 9e 28 55 5e 07 36 0020 55 74 21 f9 27 9e 42 20 68 22 a7 54 59 22 c3 ba 0030 b5 17 78 62 81 04 c9 ae 63 57 14 c3 f5 a8 97 23 0040 53 b2 72 12 3f 50 40 18 68 53 29 11 f8 72 ed 63 0050 71 b5 32 66 4c 73 f2 90 e6 e6 2f 8e d6 99 ee b0 0060 8f 8e 77 eb 10 4b 57 23 29 5d 2d 5a b9 87 4d d2 0070 d5 d1 42 8c fa b9 1e 7a 90 1c 58 c9 f6 64 e3 9a 0080 9d 46 ac ed 5a b4 57 09 1d 3e 9f f1 d7 22 99 ca 0090 e7 8f bd 0a 03 fc 92 1d 3b f5 6b 9a 0d a6 5b 0c 00a0 ec 1e 9f 64 14 2e c6 ec cf 89 07 0f 66 89 6b 8e 00b0 99 1f eb 1f e2 be af 26 8e ed 64 59 22 7f 27 30 00c0 b0 fe 37 6a 17 13 2a a0 13 ff 64 ae 80 0a a2 c3 00d0 99 88 44 33 31 3f 9c 4a b9 75 1f 5f 25 ba 40 51 00e0 0e b1 9f 4e f7 6f 1e af 8b f5 c6 20 c1 37 a9 f1 00f0 7f b0 f4 88 36 e4 7a 32 91 bf 21 8f d2 27 04 4c 0100 14 b4 42 c4 e8 a5 ee 9b 0c 5f b7 a9 44 95 8a e9 0110 f8 63 97 d0 8f 91 82 10 10 5f 3c 3c 64 f9 e9 3e 0120 8f d7 d4 7e ca 91 96 c6 94 5e e1 df f3 e1 ae 92 0130 05 d8 60 f8 79 8c 1d 45 98 64 13 44 1e f1 16 e8 0140 94 20 69 7e 53 ba fa df 21 59 06 fa 39 c0 03 26 0150 7b 9e fe 7a 93 dc 17 01 66 0b d2 4f d9 8d e7 43 0160 81 f8 5b ce 0a bb 18 43 a6 00 f5 2e a0 0b c2 f0 0170 5d c1 61 49 20 74 f8 fb 7d 04 d1 77 e9 1d 92 b3 0180 58 ef 7e b9 d9 f0 43 99 63 08 3a 66 89 c2 75 b3 0190 cf 07 f8 4a c6 40 be 98 0d 0d f0 30 18 8d ef 02 01a0 5d 0b c1 3f 3a aa 60 ad e4 22 f6 ec d4 b4 62 46 01b0 ab 4b 6f 8a 0c ab 0b 99 f5 2d 1b 4a 62 9b 83 75 01c0 2e 53 6b 6f ce 2c d1 27 3e 71 ee b0 25 09 83 02 01d0 49 0a 10 0b 58 af dc 2a 7a 8b 05 22 db ee 7e d5 01e0 9f 86 45 46 35 40 83 9b 7b 72 ff 26 95 e8 04 5f 01f0 9f 9b 70 52 87 23 0b 41 5c 88 24 fe 1a bb 11 05 0200 f0 f6 bc 6f ba 66 8d 32 64 8e 24 e7 7c 53 a4 19 0210 e4 9a 6d d2 b1 e2 cf 38 e7 0d e3 16 73 70 a5 5c 0220 78 5d f3 c4 b0 d7 21 6c d5 2a c9 82 be ff c5 55 0230 98 66 07 69 42 b3 b4 c4 e6 9a 67 68 64 65 e5 09 0240 9d e9 07 78 de 85 41 bb eb 15 46 8a b2 aa 26 e7 0250 23 9f 72 71 7e 4c 61 07 35 81 f1 57 ba f9 9e ff 0260 ab 22 4c f3 93 f2 07 ff ab 6b 56 92 52 c6 fe a0 0270 0a f8 96 39 aa 6f 17 64 80 76 85 f0 42 59 c4 c6 0280 c4 78 ad 2a b0 aa 5c d7 2d 6a 4f 80 78 56 e9 a1 0290 72 93 9f 95 e7 77 72 b7 f8 fe 9d 4f 28 ff 00 d7 02a0 d6 19 74 e8 0f 77 c9 86 d3 9b 4f 91 30 c6 fd 44 02b0 83 19 2c 3b 2a 89 01 50 d0 e4 ca 80 03 db b5 14 02c0 e7 ca 7e d1 fc 50 ad 54 e4 ce 27 2f ae c1 19 4e 02d0 37 59 6f ec 78 aa 81 25 2b d8 52 91 3a 64 eb b6 02e0 dd fd 4a e6 50 f6 fb db bf f8 4b 4f b0 b7 fb 7a 02f0 84 c2 a7 40 0f 70 d6 21 44 fa a7 29 76 7f 93 af 0300 fc 59 c5 7f 21 a3 b7 0b e6 02 e8 1a 20 0b 71 39 0310 21 07 dd 4e 5e 6d 25 27 ea 9a 0a de c5 ff 12 56 0320 49 94 ec 98 7f e7 6e 77 51 08 1c ed 82 62 88 1c 0330 17 c0 54 3b a9 2c 36 a2 c4 0a ac 32 80 f6 1d c9 0340 31 d1 dc 88 2e 4f 57 7c 21 f0 a4 90 97 41 96 78 0350 68 05 5e 8a aa fb 4c 9d bd 99 81 0a a4 e6 ce 12 0360 ef 22 2f 87 e2 d5 93 16 31 ff 67 63 1f d1 c1 13 0370 a2 45 10 f6 9a 6d ee 3d 38 7b 8b a8 bd 39 60 5d 0380 b0 40 7a b9 11 0f a8 56 11 7f 69 1b 52 49 68 be 0390 fa b1 95 fe 90 20 91 64 7a db df b7 6d fb 38 30 03a0 39 10 65 55 dc a0 a4 30 e6 79 8d d0 e1 4f 48 9d 03b0 10 52 ac a9 65 b6 89 d7 81 9b 92 a0 a3 7e cc 8a 03c0 78 e5 6c 86 88 f7 6b 14 16 a9 36 65 03 ff f1 5a 03d0 08 af 7f 55 fb f5 e2 2f be 6c b4 10 3d 6b 4b 63 03e0 7f 14 c7 7d 07 7a 7b 44 77 e0 91 8e ea 84 0f 3d 03f0 c6 27 12 6e 15 07 06 66 25 00 80 a6 08 78 20 ed 0400 eb e5 2f c3 85 8d 9d 57 ae 37 b6 f9 e8 f8 0d 01 0410 be 87 31 87 94 b0 05 dd e8 6b 0d bc b3 a6 2d 1c 0420 2f df 29 d8 0d 6f b1 bc d0 06 af 91 fe 73 88 c3 0430 64 92 fc 52 a2 0e 2e 5f eb 9d e8 cb 80 94 09 a1 0440 30 47 11 17 73 9f 4a 05 40 3a 4e d6 80 e7 00 da 0450 a0 df 45 be 46 f6 f7 02 38 c5 f0 3c 74 48 ee a9 0460 df 5e 55 0d 40 a8 a6 95 77 6e bf 66 94 18 36 4d 0470 c9 2c f6 bb 75 87 d1 e4 05 6b a4 ce 73 29 69 ce 0480 79 8c 09 22 53 af 8a b1 41 bb 55 27 ca 29 1e ca 0490 26 28 01 f1 d3 e5 39 98 24 f6 8c d9 11 7c 7a 18 04a0 bc bf ba 25 41 8f 63 ed 76 e3 61 47 77 6d 41 1f 04b0 99 31 e4 4f 3b dc 8f 90 1b 7a 43 bb 0e 9b c1 7b 04c0 ca 9f 67 70 87 6c a1 02 6e 74 a4 18 e2 5e 3f a4 04d0 4e d6 94 a7 41 7d ca 91 2b 22 b1 9b 42 d0 d1 0c 04e0 58 09 ad 9d 03 0b d8 67 b5 f9 0a 7f 34 27 da aa 04f0 40 8b 37 06 0d c5 bc d4 79 c0 2d db 3d 0f 93 f4 0500 d5 91 3a dd 37 50 dc 8f 18 41 17 0b e0 6d d5 bc 0510 ec 18 8a 3f ac d0 06 da 4b 85 7a 07 58 de 11 cd 0520 72 a1 5d 44 dc fd 5b ce 8e 90 fa 01 b6 0c 20 6a 0530 d8 82 6b 1c a7 3c a6 f2 9b af e8 21 0d 8a d3 04 0540 e0 5b 82 0f aa 38 d0 19 58 4f 45 dc 85 f2 88 d8 0550 ab 7c 0e 01 b9 8e 1c 7c ac 49 4f 2f 6f 6a 14 ec 0560 6c 5b 99 f5 7a a4 e5 96 e6 4b c7 ab 17 9f 19 81 0570 3d cc 0b 29 c6 3d 4a 79 98 71 c6 0e c4 33 04 19 0580 a7 66 f5 94 7c 72 a4 b9 4d 50 34 b8 2d 21 9f bf 0590 29 1f 9d 36 e7 c0 b2 86 31 d0 cf 09 63 75 26 6c 05a0 3b 3b 95 a7 a2 1f 84 17 f2 03 1f 73 4f 9b da a8 05b0 72 56 52 83 de 9f 30 23 a8 ef 29 58 81 b3 3b 74 05c0 8c 83 1d bc 96 ce c6 8f c1 9b 31 35 c4 02 10 cc 05d0 15 e9 d8 25 78 e6 80 b6 fd a2 c6 b6 e4 79 0a 9d 05e0 56 cb 6f a6 c2 73 fe 07 ee 81 af 8c eb 8e 2c 7e 05f0 5d ad 3d a3 e3 bd de 2e 67 af 01 af 18 31 d9 8c ```

The "version" bytes sent by YouTube are indeed 0x04_00_00_01.

I suspect the true fix for this is going to be one of two things:

The first option is to replace this code with something like:

        let received_digest = match get_digest_for_received_packet(&received_packet_1, &p1_key) {
            Ok(digest) => digest,
            Err(HandshakeError{kind: HandshakeErrorKind::UnknownPacket1Format}) => {
                // Since no digest was found chances are that
                // this handshake is not a fp9 handshake, but instead is the handshake from the
                // original RTMP specification.  If that's the case then this isn't an error,
                // we just need to send back an exact copy of their p1 and we are good.
                self.current_stage = Stage::WaitingForPacket2;
                return Ok(HandshakeProcessResult::InProgress {response_bytes: received_packet_1.to_vec()});
            },
            Err(x) => return Err(x),
        };

This essentially gets rid of the version check and makes the assumption that if we fail the digest/fp9 check but this isn't a valid RTMP handshake then that will get caught in the S2/C2 validations. In other words, we will send back the exact copy of the inbound data as a response, the other side was expecting an fp9 response instead and will kill the connection. However, in non-rtmp scenarios where we've accidentally had the right set of packets to get this far we might hang forever (until a timeout) because we won't ever have detected that this really wasn't an RTMP connection. I think the risk of this is low though.

The alternative is to make the if statement if version == 0 || version == XXXX where XXXX is the version number that Youtube is sending back. That's a bit safer but it feels a bit whackamole to me.

Since you are willing to do a PR (and thus theoretically setup for testing it), if you don't mind doing one of those options, testing it, and raising a PR I'll be glad to approve either way you go.

I agree with your analysis here, the special case is a bit whack-a-mole and the potential downside of a timeout seems small. I'll try removing the version check and make sure twitch/youtube still work!