hello. I didn't see any comments about this patch - does that mean it is ready to be merged?
On Thu, Aug 29, 2019 at 3:54 PM William Martin <unique.will.mar...@gmail.com> wrote: > From: Will Martin <will.mar...@verizondigitalmedia.com> > > Some rtmp streamers (i.e. AWS Elemental Encoder, Wirecast) send C0 and C1 > together and expect S0 and S1 returned together. When sent in different > packets, this results in a C2 handshake. This patch fixes that error. > Note that the patch is based off of a fix proposed by rubensanchez in > https://trac.ffmpeg.org/ticket/6453. > The only difference between that propsed fix and this patch is that > dummy_unit is declared as a uint32_t instead of unit8_8 (this addresses a > crash in debug builds). > This patch being submitted in a [v2] so that these commit messages could > be added for clarity. > --- > libavformat/rtmpproto.c | 103 +++++++++++++++++++++++----------------- > 1 file changed, 59 insertions(+), 44 deletions(-) > > diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c > index b741e421af..24070ba0f5 100644 > --- a/libavformat/rtmpproto.c > +++ b/libavformat/rtmpproto.c > @@ -1416,71 +1416,86 @@ static int rtmp_send_hs_packet(RTMPContext* rt, > uint32_t first_int, > */ > static int rtmp_server_handshake(URLContext *s, RTMPContext *rt) > { > - uint8_t buffer[RTMP_HANDSHAKE_PACKET_SIZE]; > - uint32_t hs_epoch; > + uint8_t hs_s0s1[RTMP_HANDSHAKE_PACKET_SIZE + 1]; > + uint8_t hs_c0c1[RTMP_HANDSHAKE_PACKET_SIZE + 1]; > + uint8_t hs_c2[RTMP_HANDSHAKE_PACKET_SIZE + 1]; > + uint8_t hs_s2[RTMP_HANDSHAKE_PACKET_SIZE]; > + uint32_t dummy_uint; > uint32_t hs_my_epoch; > - uint8_t hs_c1[RTMP_HANDSHAKE_PACKET_SIZE]; > - uint8_t hs_s1[RTMP_HANDSHAKE_PACKET_SIZE]; > - uint32_t zeroes; > uint32_t temp = 0; > int randomidx = 0; > int inoutsize = 0; > int ret; > > - inoutsize = ffurl_read_complete(rt->stream, buffer, 1); // > Receive C0 > - if (inoutsize <= 0) { > - av_log(s, AV_LOG_ERROR, "Unable to read handshake\n"); > - return AVERROR(EIO); > + /**************** > + * Receive C0+C1 > + ***************/ > + ret = rtmp_receive_hs_packet(rt, &dummy_uint, &dummy_uint, hs_c0c1, > + RTMP_HANDSHAKE_PACKET_SIZE + 1); > + if (ret) { > + av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error %d\n", ret); > + return ret; > } > // Check Version > - if (buffer[0] != 3) { > - av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch\n"); > + if (hs_c0c1[0] != 3) { > + av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch. Expected > 0x03 received %02x\n", hs_c0c1[0]); > return AVERROR(EIO); > } > - if (ffurl_write(rt->stream, buffer, 1) <= 0) { // > Send S0 > - av_log(s, AV_LOG_ERROR, > - "Unable to write answer - RTMP S0\n"); > + // Get client epoch and set our with the same value > + hs_my_epoch = AV_RB32(hs_c0c1 + 1); > + > + /************* > + * Send S0+S1 > + ************/ > + // Generate random data to send it on S0+S1 > + for (randomidx = 9; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE + 1); > + randomidx += 4) > + AV_WB32(hs_s0s1 + randomidx, av_get_random_seed()); > + // Set the RTMP protocol code on S0+S1 (First byte) > + hs_s0s1[0] = 0x03; > + // Copy the random data from C1 to S1 > + memcpy(hs_s0s1 + 1, hs_c0c1 + 1, RTMP_HANDSHAKE_PACKET_SIZE); > + AV_WB32(hs_s0s1 + 1, hs_my_epoch); > + AV_WB32(hs_s0s1 + 5, 0); > + inoutsize = ffurl_write(rt->stream, hs_s0s1, > + RTMP_HANDSHAKE_PACKET_SIZE + 1); > + if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE + 1) { > + av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error %d\n", ret); > return AVERROR(EIO); > } > - /* Receive C1 */ > - ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1, > - RTMP_HANDSHAKE_PACKET_SIZE); > - if (ret) { > - av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n"); > - return ret; > - } > - /* Send S1 */ > - /* By now same epoch will be sent */ > - hs_my_epoch = hs_epoch; > - /* Generate random */ > - for (randomidx = 8; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE); > - randomidx += 4) > - AV_WB32(hs_s1 + randomidx, av_get_random_seed()); > > - ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1, > - RTMP_HANDSHAKE_PACKET_SIZE); > - if (ret) { > - av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error\n"); > - return ret; > - } > - /* Send S2 */ > - ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1, > + /*********** > + * Send S2 > + **********/ > + // Get the S2 random data from C0+C1 > + memcpy(hs_s2, hs_c0c1, RTMP_HANDSHAKE_PACKET_SIZE); > + ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s2, > RTMP_HANDSHAKE_PACKET_SIZE); > if (ret) { > av_log(s, AV_LOG_ERROR, "RTMP Handshake S2 Error\n"); > return ret; > } > - /* Receive C2 */ > - ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer, > - RTMP_HANDSHAKE_PACKET_SIZE); > - if (ret) { > - av_log(s, AV_LOG_ERROR, "RTMP Handshake C2 Error\n"); > - return ret; > + > + /************* > + * Receive C2 > + ************/ > + > + ret = ffurl_read_complete(rt->stream, hs_c2, > + RTMP_HANDSHAKE_PACKET_SIZE + 1); > + if (ret <= 0) > + return AVERROR(EIO); > + if (ret != RTMP_HANDSHAKE_PACKET_SIZE + 1) { > + av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d" > + " not following standard\n", (int)inoutsize); > + return AVERROR(EINVAL); > } > + > + // Check timestamp and random data from C2 > + temp = AV_RB32(hs_c2 + 1); > if (temp != hs_my_epoch) > av_log(s, AV_LOG_WARNING, > - "Erroneous C2 Message epoch does not match up with C1 > epoch\n"); > - if (memcmp(buffer + 8, hs_s1 + 8, > + "Erroneous C2 Message epoch does not match up with C1 > epoch"); > + if (memcmp(hs_c2 + 9, hs_c0c1 + 9, > RTMP_HANDSHAKE_PACKET_SIZE - 8)) > av_log(s, AV_LOG_WARNING, > "Erroneous C2 Message random does not match up\n"); > -- > 2.20.1 (Apple Git-117) > > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".