diff mbox

[FFmpeg-devel] avformat/rtmpproto: Fix RTMP control message handling error in listen mode.

Message ID 20161012063344.15023-1-oyama@module.jp
State Accepted
Commit 47f74df29cb1ad2cef468f6acc7c572241937b04
Headers show

Commit Message

Hiroyuki OYAMA Oct. 12, 2016, 6:33 a.m. UTC
Fix problem to fail by a RTMP Control Message except "Set Chunk Size (1)" after an RTMP handshake. When 'nginx-rtmp-module' relays an RTMP, it sends not only control message 'Set Chunk Size (1)' but also 'Window Acknowledgement Size (5)'.
---
 libavformat/rtmpproto.c | 47 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 9 deletions(-)

Comments

Hiroyuki OYAMA Oct. 21, 2016, 8:47 a.m. UTC | #1
ping

> 2016/10/12 15:33、Hiroyuki OYAMA <oyama@module.jp> :
> 
> Fix problem to fail by a RTMP Control Message except "Set Chunk Size (1)" after an RTMP handshake. When 'nginx-rtmp-module' relays an RTMP, it sends not only control message 'Set Chunk Size (1)' but also 'Window Acknowledgement Size (5)'.
> ---
> libavformat/rtmpproto.c | 47 ++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 38 insertions(+), 9 deletions(-)
> 
> diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
> index 95d1c1d..b118b4e 100644
> --- a/libavformat/rtmpproto.c
> +++ b/libavformat/rtmpproto.c
> @@ -156,6 +156,8 @@ static const uint8_t rtmp_server_key[] = {
> };
> 
> static int handle_chunk_size(URLContext *s, RTMPPacket *pkt);
> +static int handle_server_bw(URLContext *s, RTMPPacket *pkt);
> +static int handle_client_bw(URLContext *s, RTMPPacket *pkt);
> 
> static int add_tracked_method(RTMPContext *rt, const char *name, int id)
> {
> @@ -399,6 +401,9 @@ static int gen_connect(URLContext *s, RTMPContext *rt)
>     return rtmp_send_packet(rt, &pkt, 1);
> }
> 
> +
> +#define RTMP_CTRL_ABORT_MESSAGE  (2)
> +
> static int read_connect(URLContext *s, RTMPContext *rt)
> {
>     RTMPPacket pkt = { 0 };
> @@ -411,18 +416,42 @@ static int read_connect(URLContext *s, RTMPContext *rt)
>     uint8_t tmpstr[256];
>     GetByteContext gbc;
> 
> -    if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
> -                                   &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
> -        return ret;
> -
> -    if (pkt.type == RTMP_PT_CHUNK_SIZE) {
> -        if ((ret = handle_chunk_size(s, &pkt)) < 0)
> -            return ret;
> -
> -        ff_rtmp_packet_destroy(&pkt);
> +    // handle RTMP Protocol Control Messages
> +    for (;;) {
>         if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
>                                        &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
>             return ret;
> +#ifdef DEBUG
> +        ff_rtmp_packet_dump(s, &pkt);
> +#endif
> +        if (pkt.type == RTMP_PT_CHUNK_SIZE) {
> +            if ((ret = handle_chunk_size(s, &pkt)) < 0) {
> +                ff_rtmp_packet_destroy(&pkt);
> +                return ret;
> +            }
> +        } else if (pkt.type == RTMP_CTRL_ABORT_MESSAGE) {
> +            av_log(s, AV_LOG_ERROR, "received abort message\n");
> +            ff_rtmp_packet_destroy(&pkt);
> +            return AVERROR_UNKNOWN;
> +        } else if (pkt.type == RTMP_PT_BYTES_READ) {
> +            av_log(s, AV_LOG_TRACE, "received acknowledgement\n");
> +        } else if (pkt.type == RTMP_PT_SERVER_BW) {
> +            if ((ret = handle_server_bw(s, &pkt)) < 0) {
> +                ff_rtmp_packet_destroy(&pkt);
> +                return ret;
> +            }
> +        } else if (pkt.type == RTMP_PT_CLIENT_BW) {
> +            if ((ret = handle_client_bw(s, &pkt)) < 0) {
> +                ff_rtmp_packet_destroy(&pkt);
> +                return ret;
> +            }
> +        } else if (pkt.type == RTMP_PT_INVOKE) {
> +            // received RTMP Command Message
> +            break;
> +        } else {
> +            av_log(s, AV_LOG_ERROR, "Unknown control message type (%d)\n", pkt.type);
> +        }
> +        ff_rtmp_packet_destroy(&pkt);
>     }
> 
>     cp = pkt.data;
> -- 
> 2.8.4 (Apple Git-73)
>
Steven Liu Oct. 21, 2016, 1:05 p.m. UTC | #2
LGTM

小山浩之 <oyama@module.jp>于2016年10月21日 周五上午4:47写道:

> ping
>
> > 2016/10/12 15:33、Hiroyuki OYAMA <oyama@module.jp> :
> >
> > Fix problem to fail by a RTMP Control Message except "Set Chunk Size
> (1)" after an RTMP handshake. When 'nginx-rtmp-module' relays an RTMP, it
> sends not only control message 'Set Chunk Size (1)' but also 'Window
> Acknowledgement Size (5)'.
> > ---
> > libavformat/rtmpproto.c | 47
> ++++++++++++++++++++++++++++++++++++++---------
> > 1 file changed, 38 insertions(+), 9 deletions(-)
> >
> > diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
> > index 95d1c1d..b118b4e 100644
> > --- a/libavformat/rtmpproto.c
> > +++ b/libavformat/rtmpproto.c
> > @@ -156,6 +156,8 @@ static const uint8_t rtmp_server_key[] = {
> > };
> >
> > static int handle_chunk_size(URLContext *s, RTMPPacket *pkt);
> > +static int handle_server_bw(URLContext *s, RTMPPacket *pkt);
> > +static int handle_client_bw(URLContext *s, RTMPPacket *pkt);
> >
> > static int add_tracked_method(RTMPContext *rt, const char *name, int id)
> > {
> > @@ -399,6 +401,9 @@ static int gen_connect(URLContext *s, RTMPContext
> *rt)
> >     return rtmp_send_packet(rt, &pkt, 1);
> > }
> >
> > +
> > +#define RTMP_CTRL_ABORT_MESSAGE  (2)
> > +
> > static int read_connect(URLContext *s, RTMPContext *rt)
> > {
> >     RTMPPacket pkt = { 0 };
> > @@ -411,18 +416,42 @@ static int read_connect(URLContext *s, RTMPContext
> *rt)
> >     uint8_t tmpstr[256];
> >     GetByteContext gbc;
> >
> > -    if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
> > -                                   &rt->prev_pkt[0],
> &rt->nb_prev_pkt[0])) < 0)
> > -        return ret;
> > -
> > -    if (pkt.type == RTMP_PT_CHUNK_SIZE) {
> > -        if ((ret = handle_chunk_size(s, &pkt)) < 0)
> > -            return ret;
> > -
> > -        ff_rtmp_packet_destroy(&pkt);
> > +    // handle RTMP Protocol Control Messages
> > +    for (;;) {
> >         if ((ret = ff_rtmp_packet_read(rt->stream, &pkt,
> rt->in_chunk_size,
> >                                        &rt->prev_pkt[0],
> &rt->nb_prev_pkt[0])) < 0)
> >             return ret;
> > +#ifdef DEBUG
> > +        ff_rtmp_packet_dump(s, &pkt);
> > +#endif
> > +        if (pkt.type == RTMP_PT_CHUNK_SIZE) {
> > +            if ((ret = handle_chunk_size(s, &pkt)) < 0) {
> > +                ff_rtmp_packet_destroy(&pkt);
> > +                return ret;
> > +            }
> > +        } else if (pkt.type == RTMP_CTRL_ABORT_MESSAGE) {
> > +            av_log(s, AV_LOG_ERROR, "received abort message\n");
> > +            ff_rtmp_packet_destroy(&pkt);
> > +            return AVERROR_UNKNOWN;
> > +        } else if (pkt.type == RTMP_PT_BYTES_READ) {
> > +            av_log(s, AV_LOG_TRACE, "received acknowledgement\n");
> > +        } else if (pkt.type == RTMP_PT_SERVER_BW) {
> > +            if ((ret = handle_server_bw(s, &pkt)) < 0) {
> > +                ff_rtmp_packet_destroy(&pkt);
> > +                return ret;
> > +            }
> > +        } else if (pkt.type == RTMP_PT_CLIENT_BW) {
> > +            if ((ret = handle_client_bw(s, &pkt)) < 0) {
> > +                ff_rtmp_packet_destroy(&pkt);
> > +                return ret;
> > +            }
> > +        } else if (pkt.type == RTMP_PT_INVOKE) {
> > +            // received RTMP Command Message
> > +            break;
> > +        } else {
> > +            av_log(s, AV_LOG_ERROR, "Unknown control message type
> (%d)\n", pkt.type);
> > +        }
> > +        ff_rtmp_packet_destroy(&pkt);
> >     }
> >
> >     cp = pkt.data;
> > --
> > 2.8.4 (Apple Git-73)
> >
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Michael Niedermayer Oct. 21, 2016, 2:52 p.m. UTC | #3
On Fri, Oct 21, 2016 at 01:05:13PM +0000, Steven Liu wrote:
> LGTM

applied

thx

[...]
diff mbox

Patch

diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 95d1c1d..b118b4e 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -156,6 +156,8 @@  static const uint8_t rtmp_server_key[] = {
 };
 
 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt);
+static int handle_server_bw(URLContext *s, RTMPPacket *pkt);
+static int handle_client_bw(URLContext *s, RTMPPacket *pkt);
 
 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
 {
@@ -399,6 +401,9 @@  static int gen_connect(URLContext *s, RTMPContext *rt)
     return rtmp_send_packet(rt, &pkt, 1);
 }
 
+
+#define RTMP_CTRL_ABORT_MESSAGE  (2)
+
 static int read_connect(URLContext *s, RTMPContext *rt)
 {
     RTMPPacket pkt = { 0 };
@@ -411,18 +416,42 @@  static int read_connect(URLContext *s, RTMPContext *rt)
     uint8_t tmpstr[256];
     GetByteContext gbc;
 
-    if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
-                                   &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
-        return ret;
-
-    if (pkt.type == RTMP_PT_CHUNK_SIZE) {
-        if ((ret = handle_chunk_size(s, &pkt)) < 0)
-            return ret;
-
-        ff_rtmp_packet_destroy(&pkt);
+    // handle RTMP Protocol Control Messages
+    for (;;) {
         if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
                                        &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
             return ret;
+#ifdef DEBUG
+        ff_rtmp_packet_dump(s, &pkt);
+#endif
+        if (pkt.type == RTMP_PT_CHUNK_SIZE) {
+            if ((ret = handle_chunk_size(s, &pkt)) < 0) {
+                ff_rtmp_packet_destroy(&pkt);
+                return ret;
+            }
+        } else if (pkt.type == RTMP_CTRL_ABORT_MESSAGE) {
+            av_log(s, AV_LOG_ERROR, "received abort message\n");
+            ff_rtmp_packet_destroy(&pkt);
+            return AVERROR_UNKNOWN;
+        } else if (pkt.type == RTMP_PT_BYTES_READ) {
+            av_log(s, AV_LOG_TRACE, "received acknowledgement\n");
+        } else if (pkt.type == RTMP_PT_SERVER_BW) {
+            if ((ret = handle_server_bw(s, &pkt)) < 0) {
+                ff_rtmp_packet_destroy(&pkt);
+                return ret;
+            }
+        } else if (pkt.type == RTMP_PT_CLIENT_BW) {
+            if ((ret = handle_client_bw(s, &pkt)) < 0) {
+                ff_rtmp_packet_destroy(&pkt);
+                return ret;
+            }
+        } else if (pkt.type == RTMP_PT_INVOKE) {
+            // received RTMP Command Message
+            break;
+        } else {
+            av_log(s, AV_LOG_ERROR, "Unknown control message type (%d)\n", pkt.type);
+        }
+        ff_rtmp_packet_destroy(&pkt);
     }
 
     cp = pkt.data;