rtmpproto: Check the buffer sizes when copying app/playpath strings
[ffmpeg.git] / libavformat / rtmpproto.c
1 /*
2  * RTMP network protocol
3  * Copyright (c) 2009 Konstantin Shishkov
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file
24  * RTMP protocol
25  */
26
27 #include "libavcodec/bytestream.h"
28 #include "libavutil/avstring.h"
29 #include "libavutil/base64.h"
30 #include "libavutil/intfloat.h"
31 #include "libavutil/lfg.h"
32 #include "libavutil/md5.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/random_seed.h"
35 #include "libavutil/sha.h"
36 #include "avformat.h"
37 #include "internal.h"
38
39 #include "network.h"
40
41 #include "flv.h"
42 #include "rtmp.h"
43 #include "rtmpcrypt.h"
44 #include "rtmppkt.h"
45 #include "url.h"
46
47 #if CONFIG_ZLIB
48 #include <zlib.h>
49 #endif
50
51 #define APP_MAX_LENGTH 128
52 #define PLAYPATH_MAX_LENGTH 256
53 #define TCURL_MAX_LENGTH 512
54 #define FLASHVER_MAX_LENGTH 64
55 #define RTMP_PKTDATA_DEFAULT_SIZE 4096
56 #define RTMP_HEADER 11
57
58 /** RTMP protocol handler state */
59 typedef enum {
60     STATE_START,      ///< client has not done anything yet
61     STATE_HANDSHAKED, ///< client has performed handshake
62     STATE_FCPUBLISH,  ///< client FCPublishing stream (for output)
63     STATE_PLAYING,    ///< client has started receiving multimedia data from server
64     STATE_SEEKING,    ///< client has started the seek operation. Back on STATE_PLAYING when the time comes
65     STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
66     STATE_RECEIVING,  ///< received a publish command (for input)
67     STATE_SENDING,    ///< received a play command (for output)
68     STATE_STOPPED,    ///< the broadcast has been stopped
69 } ClientState;
70
71 typedef struct TrackedMethod {
72     char *name;
73     int id;
74 } TrackedMethod;
75
76 /** protocol handler context */
77 typedef struct RTMPContext {
78     const AVClass *class;
79     URLContext*   stream;                     ///< TCP stream used in interactions with RTMP server
80     RTMPPacket    *prev_pkt[2];               ///< packet history used when reading and sending packets ([0] for reading, [1] for writing)
81     int           nb_prev_pkt[2];             ///< number of elements in prev_pkt
82     int           in_chunk_size;              ///< size of the chunks incoming RTMP packets are divided into
83     int           out_chunk_size;             ///< size of the chunks outgoing RTMP packets are divided into
84     int           is_input;                   ///< input/output flag
85     char          *playpath;                  ///< stream identifier to play (with possible "mp4:" prefix)
86     int           live;                       ///< 0: recorded, -1: live, -2: both
87     char          *app;                       ///< name of application
88     char          *conn;                      ///< append arbitrary AMF data to the Connect message
89     ClientState   state;                      ///< current state
90     int           stream_id;                  ///< ID assigned by the server for the stream
91     uint8_t*      flv_data;                   ///< buffer with data for demuxer
92     int           flv_size;                   ///< current buffer size
93     int           flv_off;                    ///< number of bytes read from current buffer
94     int           flv_nb_packets;             ///< number of flv packets published
95     RTMPPacket    out_pkt;                    ///< rtmp packet, created from flv a/v or metadata (for output)
96     uint32_t      client_report_size;         ///< number of bytes after which client should report to server
97     uint32_t      bytes_read;                 ///< number of bytes read from server
98     uint32_t      last_bytes_read;            ///< number of bytes read last reported to server
99     int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call
100     uint8_t       flv_header[RTMP_HEADER];    ///< partial incoming flv packet header
101     int           flv_header_bytes;           ///< number of initialized bytes in flv_header
102     int           nb_invokes;                 ///< keeps track of invoke messages
103     char*         tcurl;                      ///< url of the target stream
104     char*         flashver;                   ///< version of the flash plugin
105     char*         swfhash;                    ///< SHA256 hash of the decompressed SWF file (32 bytes)
106     int           swfhash_len;                ///< length of the SHA256 hash
107     int           swfsize;                    ///< size of the decompressed SWF file
108     char*         swfurl;                     ///< url of the swf player
109     char*         swfverify;                  ///< URL to player swf file, compute hash/size automatically
110     char          swfverification[42];        ///< hash of the SWF verification
111     char*         pageurl;                    ///< url of the web page
112     char*         subscribe;                  ///< name of live stream to subscribe
113     int           server_bw;                  ///< server bandwidth
114     int           client_buffer_time;         ///< client buffer time in ms
115     int           flush_interval;             ///< number of packets flushed in the same request (RTMPT only)
116     int           encrypted;                  ///< use an encrypted connection (RTMPE only)
117     TrackedMethod*tracked_methods;            ///< tracked methods buffer
118     int           nb_tracked_methods;         ///< number of tracked methods
119     int           tracked_methods_size;       ///< size of the tracked methods buffer
120     int           listen;                     ///< listen mode flag
121     int           listen_timeout;             ///< listen timeout to wait for new connections
122     int           nb_streamid;                ///< The next stream id to return on createStream calls
123     char          username[50];
124     char          password[50];
125     char          auth_params[500];
126     int           do_reconnect;
127     int           auth_tried;
128 } RTMPContext;
129
130 #define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing
131 /** Client key used for digest signing */
132 static const uint8_t rtmp_player_key[] = {
133     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
134     'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
135
136     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
137     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
138     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
139 };
140
141 #define SERVER_KEY_OPEN_PART_LEN 36   ///< length of partial key used for first server digest signing
142 /** Key used for RTMP server digest signing */
143 static const uint8_t rtmp_server_key[] = {
144     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
145     'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
146     'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
147
148     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
149     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
150     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
151 };
152
153 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt);
154
155 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
156 {
157     int err;
158
159     if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
160         rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
161         if ((err = av_reallocp(&rt->tracked_methods, rt->tracked_methods_size *
162                                sizeof(*rt->tracked_methods))) < 0) {
163             rt->nb_tracked_methods = 0;
164             rt->tracked_methods_size = 0;
165             return err;
166         }
167     }
168
169     rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
170     if (!rt->tracked_methods[rt->nb_tracked_methods].name)
171         return AVERROR(ENOMEM);
172     rt->tracked_methods[rt->nb_tracked_methods].id = id;
173     rt->nb_tracked_methods++;
174
175     return 0;
176 }
177
178 static void del_tracked_method(RTMPContext *rt, int index)
179 {
180     memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
181             sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
182     rt->nb_tracked_methods--;
183 }
184
185 static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset,
186                                char **tracked_method)
187 {
188     RTMPContext *rt = s->priv_data;
189     GetByteContext gbc;
190     double pkt_id;
191     int ret;
192     int i;
193
194     bytestream2_init(&gbc, pkt->data + offset, pkt->size - offset);
195     if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
196         return ret;
197
198     for (i = 0; i < rt->nb_tracked_methods; i++) {
199         if (rt->tracked_methods[i].id != pkt_id)
200             continue;
201
202         *tracked_method = rt->tracked_methods[i].name;
203         del_tracked_method(rt, i);
204         break;
205     }
206
207     return 0;
208 }
209
210 static void free_tracked_methods(RTMPContext *rt)
211 {
212     int i;
213
214     for (i = 0; i < rt->nb_tracked_methods; i ++)
215         av_free(rt->tracked_methods[i].name);
216     av_free(rt->tracked_methods);
217     rt->tracked_methods      = NULL;
218     rt->tracked_methods_size = 0;
219     rt->nb_tracked_methods   = 0;
220 }
221
222 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
223 {
224     int ret;
225
226     if (pkt->type == RTMP_PT_INVOKE && track) {
227         GetByteContext gbc;
228         char name[128];
229         double pkt_id;
230         int len;
231
232         bytestream2_init(&gbc, pkt->data, pkt->size);
233         if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
234             goto fail;
235
236         if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
237             goto fail;
238
239         if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
240             goto fail;
241     }
242
243     ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
244                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
245 fail:
246     ff_rtmp_packet_destroy(pkt);
247     return ret;
248 }
249
250 static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
251 {
252     char *field, *value;
253     char type;
254
255     /* The type must be B for Boolean, N for number, S for string, O for
256      * object, or Z for null. For Booleans the data must be either 0 or 1 for
257      * FALSE or TRUE, respectively. Likewise for Objects the data must be
258      * 0 or 1 to end or begin an object, respectively. Data items in subobjects
259      * may be named, by prefixing the type with 'N' and specifying the name
260      * before the value (ie. NB:myFlag:1). This option may be used multiple times
261      * to construct arbitrary AMF sequences. */
262     if (param[0] && param[1] == ':') {
263         type = param[0];
264         value = param + 2;
265     } else if (param[0] == 'N' && param[1] && param[2] == ':') {
266         type = param[1];
267         field = param + 3;
268         value = strchr(field, ':');
269         if (!value)
270             goto fail;
271         *value = '\0';
272         value++;
273
274         if (!field || !value)
275             goto fail;
276
277         ff_amf_write_field_name(p, field);
278     } else {
279         goto fail;
280     }
281
282     switch (type) {
283     case 'B':
284         ff_amf_write_bool(p, value[0] != '0');
285         break;
286     case 'S':
287         ff_amf_write_string(p, value);
288         break;
289     case 'N':
290         ff_amf_write_number(p, strtod(value, NULL));
291         break;
292     case 'Z':
293         ff_amf_write_null(p);
294         break;
295     case 'O':
296         if (value[0] != '0')
297             ff_amf_write_object_start(p);
298         else
299             ff_amf_write_object_end(p);
300         break;
301     default:
302         goto fail;
303         break;
304     }
305
306     return 0;
307
308 fail:
309     av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
310     return AVERROR(EINVAL);
311 }
312
313 /**
314  * Generate 'connect' call and send it to the server.
315  */
316 static int gen_connect(URLContext *s, RTMPContext *rt)
317 {
318     RTMPPacket pkt;
319     uint8_t *p;
320     int ret;
321
322     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
323                                      0, 4096)) < 0)
324         return ret;
325
326     p = pkt.data;
327
328     ff_amf_write_string(&p, "connect");
329     ff_amf_write_number(&p, ++rt->nb_invokes);
330     ff_amf_write_object_start(&p);
331     ff_amf_write_field_name(&p, "app");
332     ff_amf_write_string2(&p, rt->app, rt->auth_params);
333
334     if (!rt->is_input) {
335         ff_amf_write_field_name(&p, "type");
336         ff_amf_write_string(&p, "nonprivate");
337     }
338     ff_amf_write_field_name(&p, "flashVer");
339     ff_amf_write_string(&p, rt->flashver);
340
341     if (rt->swfurl) {
342         ff_amf_write_field_name(&p, "swfUrl");
343         ff_amf_write_string(&p, rt->swfurl);
344     }
345
346     ff_amf_write_field_name(&p, "tcUrl");
347     ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
348     if (rt->is_input) {
349         ff_amf_write_field_name(&p, "fpad");
350         ff_amf_write_bool(&p, 0);
351         ff_amf_write_field_name(&p, "capabilities");
352         ff_amf_write_number(&p, 15.0);
353
354         /* Tell the server we support all the audio codecs except
355          * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
356          * which are unused in the RTMP protocol implementation. */
357         ff_amf_write_field_name(&p, "audioCodecs");
358         ff_amf_write_number(&p, 4071.0);
359         ff_amf_write_field_name(&p, "videoCodecs");
360         ff_amf_write_number(&p, 252.0);
361         ff_amf_write_field_name(&p, "videoFunction");
362         ff_amf_write_number(&p, 1.0);
363
364         if (rt->pageurl) {
365             ff_amf_write_field_name(&p, "pageUrl");
366             ff_amf_write_string(&p, rt->pageurl);
367         }
368     }
369     ff_amf_write_object_end(&p);
370
371     if (rt->conn) {
372         char *param = rt->conn;
373
374         // Write arbitrary AMF data to the Connect message.
375         while (param != NULL) {
376             char *sep;
377             param += strspn(param, " ");
378             if (!*param)
379                 break;
380             sep = strchr(param, ' ');
381             if (sep)
382                 *sep = '\0';
383             if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
384                 // Invalid AMF parameter.
385                 ff_rtmp_packet_destroy(&pkt);
386                 return ret;
387             }
388
389             if (sep)
390                 param = sep + 1;
391             else
392                 break;
393         }
394     }
395
396     pkt.size = p - pkt.data;
397
398     return rtmp_send_packet(rt, &pkt, 1);
399 }
400
401 static int read_connect(URLContext *s, RTMPContext *rt)
402 {
403     RTMPPacket pkt = { 0 };
404     uint8_t *p;
405     const uint8_t *cp;
406     int ret;
407     char command[64];
408     int stringlen;
409     double seqnum;
410     uint8_t tmpstr[256];
411     GetByteContext gbc;
412
413     if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
414                                    &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
415         return ret;
416
417     if (pkt.type == RTMP_PT_CHUNK_SIZE) {
418         if ((ret = handle_chunk_size(s, &pkt)) < 0)
419             return ret;
420         ff_rtmp_packet_destroy(&pkt);
421         if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
422                                        &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
423             return ret;
424     }
425
426     cp = pkt.data;
427     bytestream2_init(&gbc, cp, pkt.size);
428     if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
429         av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
430         ff_rtmp_packet_destroy(&pkt);
431         return AVERROR_INVALIDDATA;
432     }
433     if (strcmp(command, "connect")) {
434         av_log(s, AV_LOG_ERROR, "Expecting connect, got %s\n", command);
435         ff_rtmp_packet_destroy(&pkt);
436         return AVERROR_INVALIDDATA;
437     }
438     ret = ff_amf_read_number(&gbc, &seqnum);
439     if (ret)
440         av_log(s, AV_LOG_WARNING, "SeqNum not found\n");
441     /* Here one could parse an AMF Object with data as flashVers and others. */
442     ret = ff_amf_get_field_value(gbc.buffer,
443                                  gbc.buffer + bytestream2_get_bytes_left(&gbc),
444                                  "app", tmpstr, sizeof(tmpstr));
445     if (ret)
446         av_log(s, AV_LOG_WARNING, "App field not found in connect\n");
447     if (!ret && strcmp(tmpstr, rt->app))
448         av_log(s, AV_LOG_WARNING, "App field don't match up: %s <-> %s\n",
449                tmpstr, rt->app);
450     ff_rtmp_packet_destroy(&pkt);
451
452     // Send Window Acknowledgement Size (as defined in speficication)
453     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
454                                      RTMP_PT_SERVER_BW, 0, 4)) < 0)
455         return ret;
456     p = pkt.data;
457     bytestream_put_be32(&p, rt->server_bw);
458     pkt.size = p - pkt.data;
459     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
460                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
461     ff_rtmp_packet_destroy(&pkt);
462     if (ret < 0)
463         return ret;
464     // Send Peer Bandwidth
465     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
466                                      RTMP_PT_CLIENT_BW, 0, 5)) < 0)
467         return ret;
468     p = pkt.data;
469     bytestream_put_be32(&p, rt->server_bw);
470     bytestream_put_byte(&p, 2); // dynamic
471     pkt.size = p - pkt.data;
472     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
473                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
474     ff_rtmp_packet_destroy(&pkt);
475     if (ret < 0)
476         return ret;
477
478     // Ping request
479     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
480                                      RTMP_PT_PING, 0, 6)) < 0)
481         return ret;
482
483     p = pkt.data;
484     bytestream_put_be16(&p, 0); // 0 -> Stream Begin
485     bytestream_put_be32(&p, 0);
486     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
487                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
488     ff_rtmp_packet_destroy(&pkt);
489     if (ret < 0)
490         return ret;
491
492     // Chunk size
493     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
494                                      RTMP_PT_CHUNK_SIZE, 0, 4)) < 0)
495         return ret;
496
497     p = pkt.data;
498     bytestream_put_be32(&p, rt->out_chunk_size);
499     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
500                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
501     ff_rtmp_packet_destroy(&pkt);
502     if (ret < 0)
503         return ret;
504
505     // Send result_ NetConnection.Connect.Success to connect
506     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
507                                      RTMP_PT_INVOKE, 0,
508                                      RTMP_PKTDATA_DEFAULT_SIZE)) < 0)
509         return ret;
510
511     p = pkt.data;
512     ff_amf_write_string(&p, "_result");
513     ff_amf_write_number(&p, seqnum);
514
515     ff_amf_write_object_start(&p);
516     ff_amf_write_field_name(&p, "fmsVer");
517     ff_amf_write_string(&p, "FMS/3,0,1,123");
518     ff_amf_write_field_name(&p, "capabilities");
519     ff_amf_write_number(&p, 31);
520     ff_amf_write_object_end(&p);
521
522     ff_amf_write_object_start(&p);
523     ff_amf_write_field_name(&p, "level");
524     ff_amf_write_string(&p, "status");
525     ff_amf_write_field_name(&p, "code");
526     ff_amf_write_string(&p, "NetConnection.Connect.Success");
527     ff_amf_write_field_name(&p, "description");
528     ff_amf_write_string(&p, "Connection succeeded.");
529     ff_amf_write_field_name(&p, "objectEncoding");
530     ff_amf_write_number(&p, 0);
531     ff_amf_write_object_end(&p);
532
533     pkt.size = p - pkt.data;
534     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
535                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
536     ff_rtmp_packet_destroy(&pkt);
537     if (ret < 0)
538         return ret;
539
540     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
541                                      RTMP_PT_INVOKE, 0, 30)) < 0)
542         return ret;
543     p = pkt.data;
544     ff_amf_write_string(&p, "onBWDone");
545     ff_amf_write_number(&p, 0);
546     ff_amf_write_null(&p);
547     ff_amf_write_number(&p, 8192);
548     pkt.size = p - pkt.data;
549     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
550                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
551     ff_rtmp_packet_destroy(&pkt);
552
553     return ret;
554 }
555
556 /**
557  * Generate 'releaseStream' call and send it to the server. It should make
558  * the server release some channel for media streams.
559  */
560 static int gen_release_stream(URLContext *s, RTMPContext *rt)
561 {
562     RTMPPacket pkt;
563     uint8_t *p;
564     int ret;
565
566     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
567                                      0, 29 + strlen(rt->playpath))) < 0)
568         return ret;
569
570     av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
571     p = pkt.data;
572     ff_amf_write_string(&p, "releaseStream");
573     ff_amf_write_number(&p, ++rt->nb_invokes);
574     ff_amf_write_null(&p);
575     ff_amf_write_string(&p, rt->playpath);
576
577     return rtmp_send_packet(rt, &pkt, 1);
578 }
579
580 /**
581  * Generate 'FCPublish' call and send it to the server. It should make
582  * the server preapare for receiving media streams.
583  */
584 static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
585 {
586     RTMPPacket pkt;
587     uint8_t *p;
588     int ret;
589
590     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
591                                      0, 25 + strlen(rt->playpath))) < 0)
592         return ret;
593
594     av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
595     p = pkt.data;
596     ff_amf_write_string(&p, "FCPublish");
597     ff_amf_write_number(&p, ++rt->nb_invokes);
598     ff_amf_write_null(&p);
599     ff_amf_write_string(&p, rt->playpath);
600
601     return rtmp_send_packet(rt, &pkt, 1);
602 }
603
604 /**
605  * Generate 'FCUnpublish' call and send it to the server. It should make
606  * the server destroy stream.
607  */
608 static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
609 {
610     RTMPPacket pkt;
611     uint8_t *p;
612     int ret;
613
614     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
615                                      0, 27 + strlen(rt->playpath))) < 0)
616         return ret;
617
618     av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
619     p = pkt.data;
620     ff_amf_write_string(&p, "FCUnpublish");
621     ff_amf_write_number(&p, ++rt->nb_invokes);
622     ff_amf_write_null(&p);
623     ff_amf_write_string(&p, rt->playpath);
624
625     return rtmp_send_packet(rt, &pkt, 0);
626 }
627
628 /**
629  * Generate 'createStream' call and send it to the server. It should make
630  * the server allocate some channel for media streams.
631  */
632 static int gen_create_stream(URLContext *s, RTMPContext *rt)
633 {
634     RTMPPacket pkt;
635     uint8_t *p;
636     int ret;
637
638     av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
639
640     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
641                                      0, 25)) < 0)
642         return ret;
643
644     p = pkt.data;
645     ff_amf_write_string(&p, "createStream");
646     ff_amf_write_number(&p, ++rt->nb_invokes);
647     ff_amf_write_null(&p);
648
649     return rtmp_send_packet(rt, &pkt, 1);
650 }
651
652
653 /**
654  * Generate 'deleteStream' call and send it to the server. It should make
655  * the server remove some channel for media streams.
656  */
657 static int gen_delete_stream(URLContext *s, RTMPContext *rt)
658 {
659     RTMPPacket pkt;
660     uint8_t *p;
661     int ret;
662
663     av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
664
665     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
666                                      0, 34)) < 0)
667         return ret;
668
669     p = pkt.data;
670     ff_amf_write_string(&p, "deleteStream");
671     ff_amf_write_number(&p, ++rt->nb_invokes);
672     ff_amf_write_null(&p);
673     ff_amf_write_number(&p, rt->stream_id);
674
675     return rtmp_send_packet(rt, &pkt, 0);
676 }
677
678 /**
679  * Generate client buffer time and send it to the server.
680  */
681 static int gen_buffer_time(URLContext *s, RTMPContext *rt)
682 {
683     RTMPPacket pkt;
684     uint8_t *p;
685     int ret;
686
687     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
688                                      1, 10)) < 0)
689         return ret;
690
691     p = pkt.data;
692     bytestream_put_be16(&p, 3);
693     bytestream_put_be32(&p, rt->stream_id);
694     bytestream_put_be32(&p, rt->client_buffer_time);
695
696     return rtmp_send_packet(rt, &pkt, 0);
697 }
698
699 /**
700  * Generate 'play' call and send it to the server, then ping the server
701  * to start actual playing.
702  */
703 static int gen_play(URLContext *s, RTMPContext *rt)
704 {
705     RTMPPacket pkt;
706     uint8_t *p;
707     int ret;
708
709     av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
710
711     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
712                                      0, 29 + strlen(rt->playpath))) < 0)
713         return ret;
714
715     pkt.extra = rt->stream_id;
716
717     p = pkt.data;
718     ff_amf_write_string(&p, "play");
719     ff_amf_write_number(&p, ++rt->nb_invokes);
720     ff_amf_write_null(&p);
721     ff_amf_write_string(&p, rt->playpath);
722     ff_amf_write_number(&p, rt->live * 1000);
723
724     return rtmp_send_packet(rt, &pkt, 1);
725 }
726
727 static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)
728 {
729     RTMPPacket pkt;
730     uint8_t *p;
731     int ret;
732
733     av_log(s, AV_LOG_DEBUG, "Sending seek command for timestamp %"PRId64"\n",
734            timestamp);
735
736     if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 26)) < 0)
737         return ret;
738
739     pkt.extra = rt->stream_id;
740
741     p = pkt.data;
742     ff_amf_write_string(&p, "seek");
743     ff_amf_write_number(&p, 0); //no tracking back responses
744     ff_amf_write_null(&p); //as usual, the first null param
745     ff_amf_write_number(&p, timestamp); //where we want to jump
746
747     return rtmp_send_packet(rt, &pkt, 1);
748 }
749
750 /**
751  * Generate 'publish' call and send it to the server.
752  */
753 static int gen_publish(URLContext *s, RTMPContext *rt)
754 {
755     RTMPPacket pkt;
756     uint8_t *p;
757     int ret;
758
759     av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
760
761     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
762                                      0, 30 + strlen(rt->playpath))) < 0)
763         return ret;
764
765     pkt.extra = rt->stream_id;
766
767     p = pkt.data;
768     ff_amf_write_string(&p, "publish");
769     ff_amf_write_number(&p, ++rt->nb_invokes);
770     ff_amf_write_null(&p);
771     ff_amf_write_string(&p, rt->playpath);
772     ff_amf_write_string(&p, "live");
773
774     return rtmp_send_packet(rt, &pkt, 1);
775 }
776
777 /**
778  * Generate ping reply and send it to the server.
779  */
780 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
781 {
782     RTMPPacket pkt;
783     uint8_t *p;
784     int ret;
785
786     if (ppkt->size < 6) {
787         av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
788                ppkt->size);
789         return AVERROR_INVALIDDATA;
790     }
791
792     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
793                                      ppkt->timestamp + 1, 6)) < 0)
794         return ret;
795
796     p = pkt.data;
797     bytestream_put_be16(&p, 7);
798     bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
799
800     return rtmp_send_packet(rt, &pkt, 0);
801 }
802
803 /**
804  * Generate SWF verification message and send it to the server.
805  */
806 static int gen_swf_verification(URLContext *s, RTMPContext *rt)
807 {
808     RTMPPacket pkt;
809     uint8_t *p;
810     int ret;
811
812     av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n");
813     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
814                                      0, 44)) < 0)
815         return ret;
816
817     p = pkt.data;
818     bytestream_put_be16(&p, 27);
819     memcpy(p, rt->swfverification, 42);
820
821     return rtmp_send_packet(rt, &pkt, 0);
822 }
823
824 /**
825  * Generate server bandwidth message and send it to the server.
826  */
827 static int gen_server_bw(URLContext *s, RTMPContext *rt)
828 {
829     RTMPPacket pkt;
830     uint8_t *p;
831     int ret;
832
833     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW,
834                                      0, 4)) < 0)
835         return ret;
836
837     p = pkt.data;
838     bytestream_put_be32(&p, rt->server_bw);
839
840     return rtmp_send_packet(rt, &pkt, 0);
841 }
842
843 /**
844  * Generate check bandwidth message and send it to the server.
845  */
846 static int gen_check_bw(URLContext *s, RTMPContext *rt)
847 {
848     RTMPPacket pkt;
849     uint8_t *p;
850     int ret;
851
852     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
853                                      0, 21)) < 0)
854         return ret;
855
856     p = pkt.data;
857     ff_amf_write_string(&p, "_checkbw");
858     ff_amf_write_number(&p, ++rt->nb_invokes);
859     ff_amf_write_null(&p);
860
861     return rtmp_send_packet(rt, &pkt, 1);
862 }
863
864 /**
865  * Generate report on bytes read so far and send it to the server.
866  */
867 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
868 {
869     RTMPPacket pkt;
870     uint8_t *p;
871     int ret;
872
873     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ,
874                                      ts, 4)) < 0)
875         return ret;
876
877     p = pkt.data;
878     bytestream_put_be32(&p, rt->bytes_read);
879
880     return rtmp_send_packet(rt, &pkt, 0);
881 }
882
883 static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
884                                   const char *subscribe)
885 {
886     RTMPPacket pkt;
887     uint8_t *p;
888     int ret;
889
890     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
891                                      0, 27 + strlen(subscribe))) < 0)
892         return ret;
893
894     p = pkt.data;
895     ff_amf_write_string(&p, "FCSubscribe");
896     ff_amf_write_number(&p, ++rt->nb_invokes);
897     ff_amf_write_null(&p);
898     ff_amf_write_string(&p, subscribe);
899
900     return rtmp_send_packet(rt, &pkt, 1);
901 }
902
903 int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
904                         const uint8_t *key, int keylen, uint8_t *dst)
905 {
906     struct AVSHA *sha;
907     uint8_t hmac_buf[64+32] = {0};
908     int i;
909
910     sha = av_sha_alloc();
911     if (!sha)
912         return AVERROR(ENOMEM);
913
914     if (keylen < 64) {
915         memcpy(hmac_buf, key, keylen);
916     } else {
917         av_sha_init(sha, 256);
918         av_sha_update(sha,key, keylen);
919         av_sha_final(sha, hmac_buf);
920     }
921     for (i = 0; i < 64; i++)
922         hmac_buf[i] ^= HMAC_IPAD_VAL;
923
924     av_sha_init(sha, 256);
925     av_sha_update(sha, hmac_buf, 64);
926     if (gap <= 0) {
927         av_sha_update(sha, src, len);
928     } else { //skip 32 bytes used for storing digest
929         av_sha_update(sha, src, gap);
930         av_sha_update(sha, src + gap + 32, len - gap - 32);
931     }
932     av_sha_final(sha, hmac_buf + 64);
933
934     for (i = 0; i < 64; i++)
935         hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
936     av_sha_init(sha, 256);
937     av_sha_update(sha, hmac_buf, 64+32);
938     av_sha_final(sha, dst);
939
940     av_free(sha);
941
942     return 0;
943 }
944
945 int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val,
946                             int add_val)
947 {
948     int i, digest_pos = 0;
949
950     for (i = 0; i < 4; i++)
951         digest_pos += buf[i + off];
952     digest_pos = digest_pos % mod_val + add_val;
953
954     return digest_pos;
955 }
956
957 /**
958  * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
959  * will be stored) into that packet.
960  *
961  * @param buf handshake data (1536 bytes)
962  * @param encrypted use an encrypted connection (RTMPE)
963  * @return offset to the digest inside input data
964  */
965 static int rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)
966 {
967     int ret, digest_pos;
968
969     if (encrypted)
970         digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
971     else
972         digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
973
974     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
975                               rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
976                               buf + digest_pos);
977     if (ret < 0)
978         return ret;
979
980     return digest_pos;
981 }
982
983 /**
984  * Verify that the received server response has the expected digest value.
985  *
986  * @param buf handshake data received from the server (1536 bytes)
987  * @param off position to search digest offset from
988  * @return 0 if digest is valid, digest position otherwise
989  */
990 static int rtmp_validate_digest(uint8_t *buf, int off)
991 {
992     uint8_t digest[32];
993     int ret, digest_pos;
994
995     digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
996
997     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
998                               rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
999                               digest);
1000     if (ret < 0)
1001         return ret;
1002
1003     if (!memcmp(digest, buf + digest_pos, 32))
1004         return digest_pos;
1005     return 0;
1006 }
1007
1008 static int rtmp_calc_swf_verification(URLContext *s, RTMPContext *rt,
1009                                       uint8_t *buf)
1010 {
1011     uint8_t *p;
1012     int ret;
1013
1014     if (rt->swfhash_len != 32) {
1015         av_log(s, AV_LOG_ERROR,
1016                "Hash of the decompressed SWF file is not 32 bytes long.\n");
1017         return AVERROR(EINVAL);
1018     }
1019
1020     p = &rt->swfverification[0];
1021     bytestream_put_byte(&p, 1);
1022     bytestream_put_byte(&p, 1);
1023     bytestream_put_be32(&p, rt->swfsize);
1024     bytestream_put_be32(&p, rt->swfsize);
1025
1026     if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
1027         return ret;
1028
1029     return 0;
1030 }
1031
1032 #if CONFIG_ZLIB
1033 static int rtmp_uncompress_swfplayer(uint8_t *in_data, int64_t in_size,
1034                                      uint8_t **out_data, int64_t *out_size)
1035 {
1036     z_stream zs = { 0 };
1037     void *ptr;
1038     int size;
1039     int ret = 0;
1040
1041     zs.avail_in = in_size;
1042     zs.next_in  = in_data;
1043     ret = inflateInit(&zs);
1044     if (ret != Z_OK)
1045         return AVERROR_UNKNOWN;
1046
1047     do {
1048         uint8_t tmp_buf[16384];
1049
1050         zs.avail_out = sizeof(tmp_buf);
1051         zs.next_out  = tmp_buf;
1052
1053         ret = inflate(&zs, Z_NO_FLUSH);
1054         if (ret != Z_OK && ret != Z_STREAM_END) {
1055             ret = AVERROR_UNKNOWN;
1056             goto fail;
1057         }
1058
1059         size = sizeof(tmp_buf) - zs.avail_out;
1060         if (!(ptr = av_realloc(*out_data, *out_size + size))) {
1061             ret = AVERROR(ENOMEM);
1062             goto fail;
1063         }
1064         *out_data = ptr;
1065
1066         memcpy(*out_data + *out_size, tmp_buf, size);
1067         *out_size += size;
1068     } while (zs.avail_out == 0);
1069
1070 fail:
1071     inflateEnd(&zs);
1072     return ret;
1073 }
1074 #endif
1075
1076 static int rtmp_calc_swfhash(URLContext *s)
1077 {
1078     RTMPContext *rt = s->priv_data;
1079     uint8_t *in_data = NULL, *out_data = NULL, *swfdata;
1080     int64_t in_size, out_size;
1081     URLContext *stream;
1082     char swfhash[32];
1083     int swfsize;
1084     int ret = 0;
1085
1086     /* Get the SWF player file. */
1087     if ((ret = ffurl_open(&stream, rt->swfverify, AVIO_FLAG_READ,
1088                           &s->interrupt_callback, NULL)) < 0) {
1089         av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify);
1090         goto fail;
1091     }
1092
1093     if ((in_size = ffurl_seek(stream, 0, AVSEEK_SIZE)) < 0) {
1094         ret = AVERROR(EIO);
1095         goto fail;
1096     }
1097
1098     if (!(in_data = av_malloc(in_size))) {
1099         ret = AVERROR(ENOMEM);
1100         goto fail;
1101     }
1102
1103     if ((ret = ffurl_read_complete(stream, in_data, in_size)) < 0)
1104         goto fail;
1105
1106     if (in_size < 3) {
1107         ret = AVERROR_INVALIDDATA;
1108         goto fail;
1109     }
1110
1111     if (!memcmp(in_data, "CWS", 3)) {
1112         /* Decompress the SWF player file using Zlib. */
1113         if (!(out_data = av_malloc(8))) {
1114             ret = AVERROR(ENOMEM);
1115             goto fail;
1116         }
1117         *in_data = 'F'; // magic stuff
1118         memcpy(out_data, in_data, 8);
1119         out_size = 8;
1120
1121 #if CONFIG_ZLIB
1122         if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8,
1123                                              &out_data, &out_size)) < 0)
1124             goto fail;
1125 #else
1126         av_log(s, AV_LOG_ERROR,
1127                "Zlib is required for decompressing the SWF player file.\n");
1128         ret = AVERROR(EINVAL);
1129         goto fail;
1130 #endif
1131         swfsize = out_size;
1132         swfdata = out_data;
1133     } else {
1134         swfsize = in_size;
1135         swfdata = in_data;
1136     }
1137
1138     /* Compute the SHA256 hash of the SWF player file. */
1139     if ((ret = ff_rtmp_calc_digest(swfdata, swfsize, 0,
1140                                    "Genuine Adobe Flash Player 001", 30,
1141                                    swfhash)) < 0)
1142         goto fail;
1143
1144     /* Set SWFVerification parameters. */
1145     av_opt_set_bin(rt, "rtmp_swfhash", swfhash, 32, 0);
1146     rt->swfsize = swfsize;
1147
1148 fail:
1149     av_freep(&in_data);
1150     av_freep(&out_data);
1151     ffurl_close(stream);
1152     return ret;
1153 }
1154
1155 /**
1156  * Perform handshake with the server by means of exchanging pseudorandom data
1157  * signed with HMAC-SHA2 digest.
1158  *
1159  * @return 0 if handshake succeeds, negative value otherwise
1160  */
1161 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
1162 {
1163     AVLFG rnd;
1164     uint8_t tosend    [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
1165         3,                // unencrypted data
1166         0, 0, 0, 0,       // client uptime
1167         RTMP_CLIENT_VER1,
1168         RTMP_CLIENT_VER2,
1169         RTMP_CLIENT_VER3,
1170         RTMP_CLIENT_VER4,
1171     };
1172     uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
1173     uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
1174     int i;
1175     int server_pos, client_pos;
1176     uint8_t digest[32], signature[32];
1177     int ret, type = 0;
1178
1179     av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
1180
1181     av_lfg_init(&rnd, 0xDEADC0DE);
1182     // generate handshake packet - 1536 bytes of pseudorandom data
1183     for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
1184         tosend[i] = av_lfg_get(&rnd) >> 24;
1185
1186     if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1187         /* When the client wants to use RTMPE, we have to change the command
1188          * byte to 0x06 which means to use encrypted data and we have to set
1189          * the flash version to at least 9.0.115.0. */
1190         tosend[0] = 6;
1191         tosend[5] = 128;
1192         tosend[6] = 0;
1193         tosend[7] = 3;
1194         tosend[8] = 2;
1195
1196         /* Initialize the Diffie-Hellmann context and generate the public key
1197          * to send to the server. */
1198         if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
1199             return ret;
1200     }
1201
1202     client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
1203     if (client_pos < 0)
1204         return client_pos;
1205
1206     if ((ret = ffurl_write(rt->stream, tosend,
1207                            RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1208         av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
1209         return ret;
1210     }
1211
1212     if ((ret = ffurl_read_complete(rt->stream, serverdata,
1213                                    RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1214         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1215         return ret;
1216     }
1217
1218     if ((ret = ffurl_read_complete(rt->stream, clientdata,
1219                                    RTMP_HANDSHAKE_PACKET_SIZE)) < 0) {
1220         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1221         return ret;
1222     }
1223
1224     av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
1225     av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
1226            serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
1227
1228     if (rt->is_input && serverdata[5] >= 3) {
1229         server_pos = rtmp_validate_digest(serverdata + 1, 772);
1230         if (server_pos < 0)
1231             return server_pos;
1232
1233         if (!server_pos) {
1234             type = 1;
1235             server_pos = rtmp_validate_digest(serverdata + 1, 8);
1236             if (server_pos < 0)
1237                 return server_pos;
1238
1239             if (!server_pos) {
1240                 av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
1241                 return AVERROR(EIO);
1242             }
1243         }
1244
1245         /* Generate SWFVerification token (SHA256 HMAC hash of decompressed SWF,
1246          * key are the last 32 bytes of the server handshake. */
1247         if (rt->swfsize) {
1248             if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
1249                                                   RTMP_HANDSHAKE_PACKET_SIZE - 32)) < 0)
1250                 return ret;
1251         }
1252
1253         ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
1254                                   rtmp_server_key, sizeof(rtmp_server_key),
1255                                   digest);
1256         if (ret < 0)
1257             return ret;
1258
1259         ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
1260                                   0, digest, 32, signature);
1261         if (ret < 0)
1262             return ret;
1263
1264         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1265             /* Compute the shared secret key sent by the server and initialize
1266              * the RC4 encryption. */
1267             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1268                                                    tosend + 1, type)) < 0)
1269                 return ret;
1270
1271             /* Encrypt the signature received by the server. */
1272             ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
1273         }
1274
1275         if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
1276             av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
1277             return AVERROR(EIO);
1278         }
1279
1280         for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
1281             tosend[i] = av_lfg_get(&rnd) >> 24;
1282         ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
1283                                   rtmp_player_key, sizeof(rtmp_player_key),
1284                                   digest);
1285         if (ret < 0)
1286             return ret;
1287
1288         ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
1289                                   digest, 32,
1290                                   tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
1291         if (ret < 0)
1292             return ret;
1293
1294         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1295             /* Encrypt the signature to be send to the server. */
1296             ff_rtmpe_encrypt_sig(rt->stream, tosend +
1297                                  RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
1298                                  serverdata[0]);
1299         }
1300
1301         // write reply back to the server
1302         if ((ret = ffurl_write(rt->stream, tosend,
1303                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1304             return ret;
1305
1306         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1307             /* Set RC4 keys for encryption and update the keystreams. */
1308             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1309                 return ret;
1310         }
1311     } else {
1312         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1313             /* Compute the shared secret key sent by the server and initialize
1314              * the RC4 encryption. */
1315             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1316                             tosend + 1, 1)) < 0)
1317                 return ret;
1318
1319             if (serverdata[0] == 9) {
1320                 /* Encrypt the signature received by the server. */
1321                 ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
1322                                      serverdata[0]);
1323             }
1324         }
1325
1326         if ((ret = ffurl_write(rt->stream, serverdata + 1,
1327                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1328             return ret;
1329
1330         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1331             /* Set RC4 keys for encryption and update the keystreams. */
1332             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1333                 return ret;
1334         }
1335     }
1336
1337     return 0;
1338 }
1339
1340 static int rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int,
1341                                   uint32_t *second_int, char *arraydata,
1342                                   int size)
1343 {
1344     int inoutsize;
1345
1346     inoutsize = ffurl_read_complete(rt->stream, arraydata,
1347                                     RTMP_HANDSHAKE_PACKET_SIZE);
1348     if (inoutsize <= 0)
1349         return AVERROR(EIO);
1350     if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1351         av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d"
1352                " not following standard\n", (int)inoutsize);
1353         return AVERROR(EINVAL);
1354     }
1355
1356     *first_int  = AV_RB32(arraydata);
1357     *second_int = AV_RB32(arraydata + 4);
1358     return 0;
1359 }
1360
1361 static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
1362                                uint32_t second_int, char *arraydata, int size)
1363 {
1364     int inoutsize;
1365
1366     AV_WB32(arraydata, first_int);
1367     AV_WB32(arraydata + 4, second_int);
1368     inoutsize = ffurl_write(rt->stream, arraydata,
1369                             RTMP_HANDSHAKE_PACKET_SIZE);
1370     if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1371         av_log(rt, AV_LOG_ERROR, "Unable to write answer\n");
1372         return AVERROR(EIO);
1373     }
1374
1375     return 0;
1376 }
1377
1378 /**
1379  * rtmp handshake server side
1380  */
1381 static int rtmp_server_handshake(URLContext *s, RTMPContext *rt)
1382 {
1383     uint8_t buffer[RTMP_HANDSHAKE_PACKET_SIZE];
1384     uint32_t hs_epoch;
1385     uint32_t hs_my_epoch;
1386     uint8_t hs_c1[RTMP_HANDSHAKE_PACKET_SIZE];
1387     uint8_t hs_s1[RTMP_HANDSHAKE_PACKET_SIZE];
1388     uint32_t zeroes;
1389     uint32_t temp       = 0;
1390     int randomidx       = 0;
1391     int inoutsize       = 0;
1392     int ret;
1393
1394     inoutsize = ffurl_read_complete(rt->stream, buffer, 1);       // Receive C0
1395     if (inoutsize <= 0) {
1396         av_log(s, AV_LOG_ERROR, "Unable to read handshake\n");
1397         return AVERROR(EIO);
1398     }
1399     // Check Version
1400     if (buffer[0] != 3) {
1401         av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch\n");
1402         return AVERROR(EIO);
1403     }
1404     if (ffurl_write(rt->stream, buffer, 1) <= 0) {                 // Send S0
1405         av_log(s, AV_LOG_ERROR,
1406                "Unable to write answer - RTMP S0\n");
1407         return AVERROR(EIO);
1408     }
1409     /* Receive C1 */
1410     ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1,
1411                                  RTMP_HANDSHAKE_PACKET_SIZE);
1412     if (ret) {
1413         av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n");
1414         return ret;
1415     }
1416     /* Send S1 */
1417     /* By now same epoch will be sent */
1418     hs_my_epoch = hs_epoch;
1419     /* Generate random */
1420     for (randomidx = 8; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE);
1421          randomidx += 4)
1422         AV_WB32(hs_s1 + randomidx, av_get_random_seed());
1423
1424     ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1,
1425                               RTMP_HANDSHAKE_PACKET_SIZE);
1426     if (ret) {
1427         av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error\n");
1428         return ret;
1429     }
1430     /* Send S2 */
1431     ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1,
1432                               RTMP_HANDSHAKE_PACKET_SIZE);
1433     if (ret) {
1434         av_log(s, AV_LOG_ERROR, "RTMP Handshake S2 Error\n");
1435         return ret;
1436     }
1437     /* Receive C2 */
1438     ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer,
1439                                  RTMP_HANDSHAKE_PACKET_SIZE);
1440     if (ret) {
1441         av_log(s, AV_LOG_ERROR, "RTMP Handshake C2 Error\n");
1442         return ret;
1443     }
1444     if (temp != hs_my_epoch)
1445         av_log(s, AV_LOG_WARNING,
1446                "Erroneous C2 Message epoch does not match up with C1 epoch\n");
1447     if (memcmp(buffer + 8, hs_s1 + 8,
1448                RTMP_HANDSHAKE_PACKET_SIZE - 8))
1449         av_log(s, AV_LOG_WARNING,
1450                "Erroneous C2 Message random does not match up\n");
1451
1452     return 0;
1453 }
1454
1455 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
1456 {
1457     RTMPContext *rt = s->priv_data;
1458     int ret;
1459
1460     if (pkt->size < 4) {
1461         av_log(s, AV_LOG_ERROR,
1462                "Too short chunk size change packet (%d)\n",
1463                pkt->size);
1464         return AVERROR_INVALIDDATA;
1465     }
1466
1467     if (!rt->is_input) {
1468         /* Send the same chunk size change packet back to the server,
1469          * setting the outgoing chunk size to the same as the incoming one. */
1470         if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
1471                                         &rt->prev_pkt[1], &rt->nb_prev_pkt[1])) < 0)
1472             return ret;
1473         rt->out_chunk_size = AV_RB32(pkt->data);
1474     }
1475
1476     rt->in_chunk_size = AV_RB32(pkt->data);
1477     if (rt->in_chunk_size <= 0) {
1478         av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n",
1479                rt->in_chunk_size);
1480         return AVERROR_INVALIDDATA;
1481     }
1482     av_log(s, AV_LOG_DEBUG, "New incoming chunk size = %d\n",
1483            rt->in_chunk_size);
1484
1485     return 0;
1486 }
1487
1488 static int handle_ping(URLContext *s, RTMPPacket *pkt)
1489 {
1490     RTMPContext *rt = s->priv_data;
1491     int t, ret;
1492
1493     if (pkt->size < 2) {
1494         av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
1495                pkt->size);
1496         return AVERROR_INVALIDDATA;
1497     }
1498
1499     t = AV_RB16(pkt->data);
1500     if (t == 6) {
1501         if ((ret = gen_pong(s, rt, pkt)) < 0)
1502             return ret;
1503     } else if (t == 26) {
1504         if (rt->swfsize) {
1505             if ((ret = gen_swf_verification(s, rt)) < 0)
1506                 return ret;
1507         } else {
1508             av_log(s, AV_LOG_WARNING, "Ignoring SWFVerification request.\n");
1509         }
1510     }
1511
1512     return 0;
1513 }
1514
1515 static int handle_client_bw(URLContext *s, RTMPPacket *pkt)
1516 {
1517     RTMPContext *rt = s->priv_data;
1518
1519     if (pkt->size < 4) {
1520         av_log(s, AV_LOG_ERROR,
1521                "Client bandwidth report packet is less than 4 bytes long (%d)\n",
1522                pkt->size);
1523         return AVERROR_INVALIDDATA;
1524     }
1525
1526     rt->client_report_size = AV_RB32(pkt->data);
1527     if (rt->client_report_size <= 0) {
1528         av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n",
1529                 rt->client_report_size);
1530         return AVERROR_INVALIDDATA;
1531
1532     }
1533     av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size);
1534     rt->client_report_size >>= 1;
1535
1536     return 0;
1537 }
1538
1539 static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
1540 {
1541     RTMPContext *rt = s->priv_data;
1542
1543     if (pkt->size < 4) {
1544         av_log(s, AV_LOG_ERROR,
1545                "Too short server bandwidth report packet (%d)\n",
1546                pkt->size);
1547         return AVERROR_INVALIDDATA;
1548     }
1549
1550     rt->server_bw = AV_RB32(pkt->data);
1551     if (rt->server_bw <= 0) {
1552         av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
1553                rt->server_bw);
1554         return AVERROR_INVALIDDATA;
1555     }
1556     av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
1557
1558     return 0;
1559 }
1560
1561 static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
1562                          const char *opaque, const char *challenge)
1563 {
1564     uint8_t hash[16];
1565     char hashstr[AV_BASE64_SIZE(sizeof(hash))], challenge2[10];
1566     struct AVMD5 *md5 = av_md5_alloc();
1567     if (!md5)
1568         return AVERROR(ENOMEM);
1569
1570     snprintf(challenge2, sizeof(challenge2), "%08x", av_get_random_seed());
1571
1572     av_md5_init(md5);
1573     av_md5_update(md5, user, strlen(user));
1574     av_md5_update(md5, salt, strlen(salt));
1575     av_md5_update(md5, rt->password, strlen(rt->password));
1576     av_md5_final(md5, hash);
1577     av_base64_encode(hashstr, sizeof(hashstr), hash,
1578                      sizeof(hash));
1579     av_md5_init(md5);
1580     av_md5_update(md5, hashstr, strlen(hashstr));
1581     if (opaque)
1582         av_md5_update(md5, opaque, strlen(opaque));
1583     else if (challenge)
1584         av_md5_update(md5, challenge, strlen(challenge));
1585     av_md5_update(md5, challenge2, strlen(challenge2));
1586     av_md5_final(md5, hash);
1587     av_base64_encode(hashstr, sizeof(hashstr), hash,
1588                      sizeof(hash));
1589     snprintf(rt->auth_params, sizeof(rt->auth_params),
1590              "?authmod=%s&user=%s&challenge=%s&response=%s",
1591              "adobe", user, challenge2, hashstr);
1592     if (opaque)
1593         av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
1594                     "&opaque=%s", opaque);
1595
1596     av_free(md5);
1597     return 0;
1598 }
1599
1600 static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
1601 {
1602     uint8_t hash[16];
1603     char hashstr1[33], hashstr2[33];
1604     const char *realm = "live";
1605     const char *method = "publish";
1606     const char *qop = "auth";
1607     const char *nc = "00000001";
1608     char cnonce[10];
1609     struct AVMD5 *md5 = av_md5_alloc();
1610     if (!md5)
1611         return AVERROR(ENOMEM);
1612
1613     snprintf(cnonce, sizeof(cnonce), "%08x", av_get_random_seed());
1614
1615     av_md5_init(md5);
1616     av_md5_update(md5, user, strlen(user));
1617     av_md5_update(md5, ":", 1);
1618     av_md5_update(md5, realm, strlen(realm));
1619     av_md5_update(md5, ":", 1);
1620     av_md5_update(md5, rt->password, strlen(rt->password));
1621     av_md5_final(md5, hash);
1622     ff_data_to_hex(hashstr1, hash, 16, 1);
1623     hashstr1[32] = '\0';
1624
1625     av_md5_init(md5);
1626     av_md5_update(md5, method, strlen(method));
1627     av_md5_update(md5, ":/", 2);
1628     av_md5_update(md5, rt->app, strlen(rt->app));
1629     if (!strchr(rt->app, '/'))
1630         av_md5_update(md5, "/_definst_", strlen("/_definst_"));
1631     av_md5_final(md5, hash);
1632     ff_data_to_hex(hashstr2, hash, 16, 1);
1633     hashstr2[32] = '\0';
1634
1635     av_md5_init(md5);
1636     av_md5_update(md5, hashstr1, strlen(hashstr1));
1637     av_md5_update(md5, ":", 1);
1638     if (nonce)
1639         av_md5_update(md5, nonce, strlen(nonce));
1640     av_md5_update(md5, ":", 1);
1641     av_md5_update(md5, nc, strlen(nc));
1642     av_md5_update(md5, ":", 1);
1643     av_md5_update(md5, cnonce, strlen(cnonce));
1644     av_md5_update(md5, ":", 1);
1645     av_md5_update(md5, qop, strlen(qop));
1646     av_md5_update(md5, ":", 1);
1647     av_md5_update(md5, hashstr2, strlen(hashstr2));
1648     av_md5_final(md5, hash);
1649     ff_data_to_hex(hashstr1, hash, 16, 1);
1650
1651     snprintf(rt->auth_params, sizeof(rt->auth_params),
1652              "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
1653              "llnw", user, nonce, cnonce, nc, hashstr1);
1654
1655     av_free(md5);
1656     return 0;
1657 }
1658
1659 static int handle_connect_error(URLContext *s, const char *desc)
1660 {
1661     RTMPContext *rt = s->priv_data;
1662     char buf[300], *ptr, authmod[15];
1663     int i = 0, ret = 0;
1664     const char *user = "", *salt = "", *opaque = NULL,
1665                *challenge = NULL, *cptr = NULL, *nonce = NULL;
1666
1667     if (!(cptr = strstr(desc, "authmod=adobe")) &&
1668         !(cptr = strstr(desc, "authmod=llnw"))) {
1669         av_log(s, AV_LOG_ERROR,
1670                "Unknown connect error (unsupported authentication method?)\n");
1671         return AVERROR_UNKNOWN;
1672     }
1673     cptr += strlen("authmod=");
1674     while (*cptr && *cptr != ' ' && i < sizeof(authmod) - 1)
1675         authmod[i++] = *cptr++;
1676     authmod[i] = '\0';
1677
1678     if (!rt->username[0] || !rt->password[0]) {
1679         av_log(s, AV_LOG_ERROR, "No credentials set\n");
1680         return AVERROR_UNKNOWN;
1681     }
1682
1683     if (strstr(desc, "?reason=authfailed")) {
1684         av_log(s, AV_LOG_ERROR, "Incorrect username/password\n");
1685         return AVERROR_UNKNOWN;
1686     } else if (strstr(desc, "?reason=nosuchuser")) {
1687         av_log(s, AV_LOG_ERROR, "Incorrect username\n");
1688         return AVERROR_UNKNOWN;
1689     }
1690
1691     if (rt->auth_tried) {
1692         av_log(s, AV_LOG_ERROR, "Authentication failed\n");
1693         return AVERROR_UNKNOWN;
1694     }
1695
1696     rt->auth_params[0] = '\0';
1697
1698     if (strstr(desc, "code=403 need auth")) {
1699         snprintf(rt->auth_params, sizeof(rt->auth_params),
1700                  "?authmod=%s&user=%s", authmod, rt->username);
1701         return 0;
1702     }
1703
1704     if (!(cptr = strstr(desc, "?reason=needauth"))) {
1705         av_log(s, AV_LOG_ERROR, "No auth parameters found\n");
1706         return AVERROR_UNKNOWN;
1707     }
1708
1709     av_strlcpy(buf, cptr + 1, sizeof(buf));
1710     ptr = buf;
1711
1712     while (ptr) {
1713         char *next  = strchr(ptr, '&');
1714         char *value = strchr(ptr, '=');
1715         if (next)
1716             *next++ = '\0';
1717         if (value)
1718             *value++ = '\0';
1719         if (!strcmp(ptr, "user")) {
1720             user = value;
1721         } else if (!strcmp(ptr, "salt")) {
1722             salt = value;
1723         } else if (!strcmp(ptr, "opaque")) {
1724             opaque = value;
1725         } else if (!strcmp(ptr, "challenge")) {
1726             challenge = value;
1727         } else if (!strcmp(ptr, "nonce")) {
1728             nonce = value;
1729         }
1730         ptr = next;
1731     }
1732
1733     if (!strcmp(authmod, "adobe")) {
1734         if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
1735             return ret;
1736     } else {
1737         if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
1738             return ret;
1739     }
1740
1741     rt->auth_tried = 1;
1742     return 0;
1743 }
1744
1745 static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
1746 {
1747     RTMPContext *rt = s->priv_data;
1748     const uint8_t *data_end = pkt->data + pkt->size;
1749     char *tracked_method = NULL;
1750     int level = AV_LOG_ERROR;
1751     uint8_t tmpstr[256];
1752     int ret;
1753
1754     if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
1755         return ret;
1756
1757     if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1758                                 "description", tmpstr, sizeof(tmpstr))) {
1759         if (tracked_method && (!strcmp(tracked_method, "_checkbw")      ||
1760                                !strcmp(tracked_method, "releaseStream") ||
1761                                !strcmp(tracked_method, "FCSubscribe")   ||
1762                                !strcmp(tracked_method, "FCPublish"))) {
1763             /* Gracefully ignore Adobe-specific historical artifact errors. */
1764             level = AV_LOG_WARNING;
1765             ret = 0;
1766         } else if (tracked_method && !strcmp(tracked_method, "connect")) {
1767             ret = handle_connect_error(s, tmpstr);
1768             if (!ret) {
1769                 rt->do_reconnect = 1;
1770                 level = AV_LOG_VERBOSE;
1771             }
1772         } else
1773             ret = AVERROR_UNKNOWN;
1774         av_log(s, level, "Server error: %s\n", tmpstr);
1775     }
1776
1777     av_free(tracked_method);
1778     return ret;
1779 }
1780
1781 static int write_begin(URLContext *s)
1782 {
1783     RTMPContext *rt = s->priv_data;
1784     PutByteContext pbc;
1785     RTMPPacket spkt = { 0 };
1786     int ret;
1787
1788     // Send Stream Begin 1
1789     if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
1790                                      RTMP_PT_PING, 0, 6)) < 0) {
1791         av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1792         return ret;
1793     }
1794
1795     bytestream2_init_writer(&pbc, spkt.data, spkt.size);
1796     bytestream2_put_be16(&pbc, 0);          // 0 -> Stream Begin
1797     bytestream2_put_be32(&pbc, rt->nb_streamid);
1798
1799     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1800                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1801
1802     ff_rtmp_packet_destroy(&spkt);
1803
1804     return ret;
1805 }
1806
1807 static int write_status(URLContext *s, RTMPPacket *pkt,
1808                         const char *status, const char *filename)
1809 {
1810     RTMPContext *rt = s->priv_data;
1811     RTMPPacket spkt = { 0 };
1812     char statusmsg[128];
1813     uint8_t *pp;
1814     int ret;
1815
1816     if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1817                                      RTMP_PT_INVOKE, 0,
1818                                      RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1819         av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1820         return ret;
1821     }
1822
1823     pp = spkt.data;
1824     spkt.extra = pkt->extra;
1825     ff_amf_write_string(&pp, "onStatus");
1826     ff_amf_write_number(&pp, 0);
1827     ff_amf_write_null(&pp);
1828
1829     ff_amf_write_object_start(&pp);
1830     ff_amf_write_field_name(&pp, "level");
1831     ff_amf_write_string(&pp, "status");
1832     ff_amf_write_field_name(&pp, "code");
1833     ff_amf_write_string(&pp, status);
1834     ff_amf_write_field_name(&pp, "description");
1835     snprintf(statusmsg, sizeof(statusmsg),
1836              "%s is now published", filename);
1837     ff_amf_write_string(&pp, statusmsg);
1838     ff_amf_write_field_name(&pp, "details");
1839     ff_amf_write_string(&pp, filename);
1840     ff_amf_write_field_name(&pp, "clientid");
1841     snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
1842     ff_amf_write_string(&pp, statusmsg);
1843     ff_amf_write_object_end(&pp);
1844
1845     spkt.size = pp - spkt.data;
1846     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1847                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1848     ff_rtmp_packet_destroy(&spkt);
1849
1850     return ret;
1851 }
1852
1853 static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
1854 {
1855     RTMPContext *rt = s->priv_data;
1856     double seqnum;
1857     char filename[64];
1858     char command[64];
1859     int stringlen;
1860     char *pchar;
1861     const uint8_t *p = pkt->data;
1862     uint8_t *pp      = NULL;
1863     RTMPPacket spkt  = { 0 };
1864     GetByteContext gbc;
1865     int ret;
1866
1867     bytestream2_init(&gbc, p, pkt->size);
1868     if (ff_amf_read_string(&gbc, command, sizeof(command),
1869                            &stringlen)) {
1870         av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
1871         return AVERROR_INVALIDDATA;
1872     }
1873
1874     ret = ff_amf_read_number(&gbc, &seqnum);
1875     if (ret)
1876         return ret;
1877     ret = ff_amf_read_null(&gbc);
1878     if (ret)
1879         return ret;
1880     if (!strcmp(command, "FCPublish") ||
1881         !strcmp(command, "publish")) {
1882         ret = ff_amf_read_string(&gbc, filename,
1883                                  sizeof(filename), &stringlen);
1884         // check with url
1885         if (s->filename) {
1886             pchar = strrchr(s->filename, '/');
1887             if (!pchar) {
1888                 av_log(s, AV_LOG_WARNING,
1889                        "Unable to find / in url %s, bad format\n",
1890                        s->filename);
1891                 pchar = s->filename;
1892             }
1893             pchar++;
1894             if (strcmp(pchar, filename))
1895                 av_log(s, AV_LOG_WARNING, "Unexpected stream %s, expecting"
1896                        " %s\n", filename, pchar);
1897         }
1898         rt->state = STATE_RECEIVING;
1899     }
1900
1901     if (!strcmp(command, "FCPublish")) {
1902         if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1903                                          RTMP_PT_INVOKE, 0,
1904                                          RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1905             av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1906             return ret;
1907         }
1908         pp = spkt.data;
1909         ff_amf_write_string(&pp, "onFCPublish");
1910     } else if (!strcmp(command, "publish")) {
1911         ret = write_begin(s);
1912         if (ret < 0)
1913             return ret;
1914
1915         // Send onStatus(NetStream.Publish.Start)
1916         return write_status(s, pkt, "NetStream.Publish.Start",
1917                            filename);
1918     } else if (!strcmp(command, "play")) {
1919         ret = write_begin(s);
1920         if (ret < 0)
1921             return ret;
1922         rt->state = STATE_SENDING;
1923         return write_status(s, pkt, "NetStream.Play.Start",
1924                             filename);
1925     } else {
1926         if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1927                                          RTMP_PT_INVOKE, 0,
1928                                          RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1929             av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1930             return ret;
1931         }
1932         pp = spkt.data;
1933         ff_amf_write_string(&pp, "_result");
1934         ff_amf_write_number(&pp, seqnum);
1935         ff_amf_write_null(&pp);
1936         if (!strcmp(command, "createStream")) {
1937             rt->nb_streamid++;
1938             if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
1939                 rt->nb_streamid++; /* Values 0 and 2 are reserved */
1940             ff_amf_write_number(&pp, rt->nb_streamid);
1941             /* By now we don't control which streams are removed in
1942              * deleteStream. There is no stream creation control
1943              * if a client creates more than 2^32 - 2 streams. */
1944         }
1945     }
1946     spkt.size = pp - spkt.data;
1947     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1948                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1949     ff_rtmp_packet_destroy(&spkt);
1950     return ret;
1951 }
1952
1953 static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
1954 {
1955     RTMPContext *rt = s->priv_data;
1956     char *tracked_method = NULL;
1957     int ret = 0;
1958
1959     if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
1960         return ret;
1961
1962     if (!tracked_method) {
1963         /* Ignore this reply when the current method is not tracked. */
1964         return ret;
1965     }
1966
1967     if (!strcmp(tracked_method, "connect")) {
1968         if (!rt->is_input) {
1969             if ((ret = gen_release_stream(s, rt)) < 0)
1970                 goto fail;
1971
1972             if ((ret = gen_fcpublish_stream(s, rt)) < 0)
1973                 goto fail;
1974         } else {
1975             if ((ret = gen_server_bw(s, rt)) < 0)
1976                 goto fail;
1977         }
1978
1979         if ((ret = gen_create_stream(s, rt)) < 0)
1980             goto fail;
1981
1982         if (rt->is_input) {
1983             /* Send the FCSubscribe command when the name of live
1984              * stream is defined by the user or if it's a live stream. */
1985             if (rt->subscribe) {
1986                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
1987                     goto fail;
1988             } else if (rt->live == -1) {
1989                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
1990                     goto fail;
1991             }
1992         }
1993     } else if (!strcmp(tracked_method, "createStream")) {
1994         //extract a number from the result
1995         if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
1996             av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
1997         } else {
1998             rt->stream_id = av_int2double(AV_RB64(pkt->data + 21));
1999         }
2000
2001         if (!rt->is_input) {
2002             if ((ret = gen_publish(s, rt)) < 0)
2003                 goto fail;
2004         } else {
2005             if ((ret = gen_play(s, rt)) < 0)
2006                 goto fail;
2007             if ((ret = gen_buffer_time(s, rt)) < 0)
2008                 goto fail;
2009         }
2010     }
2011
2012 fail:
2013     av_free(tracked_method);
2014     return ret;
2015 }
2016
2017 static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
2018 {
2019     RTMPContext *rt = s->priv_data;
2020     const uint8_t *data_end = pkt->data + pkt->size;
2021     const uint8_t *ptr = pkt->data + RTMP_HEADER;
2022     uint8_t tmpstr[256];
2023     int i, t;
2024
2025     for (i = 0; i < 2; i++) {
2026         t = ff_amf_tag_size(ptr, data_end);
2027         if (t < 0)
2028             return 1;
2029         ptr += t;
2030     }
2031
2032     t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
2033     if (!t && !strcmp(tmpstr, "error")) {
2034         t = ff_amf_get_field_value(ptr, data_end,
2035                                    "description", tmpstr, sizeof(tmpstr));
2036         if (t || !tmpstr[0])
2037             t = ff_amf_get_field_value(ptr, data_end, "code",
2038                                        tmpstr, sizeof(tmpstr));
2039         if (!t)
2040             av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
2041         return -1;
2042     }
2043
2044     t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
2045     if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
2046     if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
2047     if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
2048     if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
2049     if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
2050
2051     return 0;
2052 }
2053
2054 static int handle_invoke(URLContext *s, RTMPPacket *pkt)
2055 {
2056     RTMPContext *rt = s->priv_data;
2057     int ret = 0;
2058
2059     //TODO: check for the messages sent for wrong state?
2060     if (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
2061         if ((ret = handle_invoke_error(s, pkt)) < 0)
2062             return ret;
2063     } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
2064         if ((ret = handle_invoke_result(s, pkt)) < 0)
2065             return ret;
2066     } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
2067         if ((ret = handle_invoke_status(s, pkt)) < 0)
2068             return ret;
2069     } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) {
2070         if ((ret = gen_check_bw(s, rt)) < 0)
2071             return ret;
2072     } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
2073                ff_amf_match_string(pkt->data, pkt->size, "FCPublish")     ||
2074                ff_amf_match_string(pkt->data, pkt->size, "publish")       ||
2075                ff_amf_match_string(pkt->data, pkt->size, "play")          ||
2076                ff_amf_match_string(pkt->data, pkt->size, "_checkbw")      ||
2077                ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
2078         if ((ret = send_invoke_response(s, pkt)) < 0)
2079             return ret;
2080     }
2081
2082     return ret;
2083 }
2084
2085 static int update_offset(RTMPContext *rt, int size)
2086 {
2087     int old_flv_size;
2088
2089     // generate packet header and put data into buffer for FLV demuxer
2090     if (rt->flv_off < rt->flv_size) {
2091         // There is old unread data in the buffer, thus append at the end
2092         old_flv_size  = rt->flv_size;
2093         rt->flv_size += size;
2094     } else {
2095         // All data has been read, write the new data at the start of the buffer
2096         old_flv_size = 0;
2097         rt->flv_size = size;
2098         rt->flv_off  = 0;
2099     }
2100
2101     return old_flv_size;
2102 }
2103
2104 static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
2105 {
2106     int old_flv_size, ret;
2107     PutByteContext pbc;
2108     const uint8_t *data = pkt->data + skip;
2109     const int size      = pkt->size - skip;
2110     uint32_t ts         = pkt->timestamp;
2111
2112     old_flv_size = update_offset(rt, size + 15);
2113
2114     if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2115         rt->flv_size = rt->flv_off = 0;
2116         return ret;
2117     }
2118     bytestream2_init_writer(&pbc, rt->flv_data, rt->flv_size);
2119     bytestream2_skip_p(&pbc, old_flv_size);
2120     bytestream2_put_byte(&pbc, pkt->type);
2121     bytestream2_put_be24(&pbc, size);
2122     bytestream2_put_be24(&pbc, ts);
2123     bytestream2_put_byte(&pbc, ts >> 24);
2124     bytestream2_put_be24(&pbc, 0);
2125     bytestream2_put_buffer(&pbc, data, size);
2126     bytestream2_put_be32(&pbc, 0);
2127
2128     return 0;
2129 }
2130
2131 static int handle_notify(URLContext *s, RTMPPacket *pkt)
2132 {
2133     RTMPContext *rt  = s->priv_data;
2134     uint8_t commandbuffer[64];
2135     char statusmsg[128];
2136     int stringlen, ret, skip = 0;
2137     GetByteContext gbc;
2138
2139     bytestream2_init(&gbc, pkt->data, pkt->size);
2140     if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
2141                            &stringlen))
2142         return AVERROR_INVALIDDATA;
2143
2144     // Skip the @setDataFrame string and validate it is a notification
2145     if (!strcmp(commandbuffer, "@setDataFrame")) {
2146         skip = gbc.buffer - pkt->data;
2147         ret = ff_amf_read_string(&gbc, statusmsg,
2148                                  sizeof(statusmsg), &stringlen);
2149         if (ret < 0)
2150             return AVERROR_INVALIDDATA;
2151     }
2152
2153     return append_flv_data(rt, pkt, skip);
2154 }
2155
2156 /**
2157  * Parse received packet and possibly perform some action depending on
2158  * the packet contents.
2159  * @return 0 for no errors, negative values for serious errors which prevent
2160  *         further communications, positive values for uncritical errors
2161  */
2162 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
2163 {
2164     int ret;
2165
2166 #ifdef DEBUG
2167     ff_rtmp_packet_dump(s, pkt);
2168 #endif
2169
2170     switch (pkt->type) {
2171     case RTMP_PT_BYTES_READ:
2172         av_dlog(s, "received bytes read report\n");
2173         break;
2174     case RTMP_PT_CHUNK_SIZE:
2175         if ((ret = handle_chunk_size(s, pkt)) < 0)
2176             return ret;
2177         break;
2178     case RTMP_PT_PING:
2179         if ((ret = handle_ping(s, pkt)) < 0)
2180             return ret;
2181         break;
2182     case RTMP_PT_CLIENT_BW:
2183         if ((ret = handle_client_bw(s, pkt)) < 0)
2184             return ret;
2185         break;
2186     case RTMP_PT_SERVER_BW:
2187         if ((ret = handle_server_bw(s, pkt)) < 0)
2188             return ret;
2189         break;
2190     case RTMP_PT_INVOKE:
2191         if ((ret = handle_invoke(s, pkt)) < 0)
2192             return ret;
2193         break;
2194     case RTMP_PT_VIDEO:
2195     case RTMP_PT_AUDIO:
2196     case RTMP_PT_METADATA:
2197     case RTMP_PT_NOTIFY:
2198         /* Audio, Video and Metadata packets are parsed in get_packet() */
2199         break;
2200     default:
2201         av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
2202         break;
2203     }
2204     return 0;
2205 }
2206
2207 static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
2208 {
2209     int ret, old_flv_size, type;
2210     const uint8_t *next;
2211     uint8_t *p;
2212     uint32_t size;
2213     uint32_t ts, cts, pts = 0;
2214
2215     old_flv_size = update_offset(rt, pkt->size);
2216
2217     if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2218         rt->flv_size = rt->flv_off = 0;
2219         return ret;
2220     }
2221
2222     next = pkt->data;
2223     p    = rt->flv_data + old_flv_size;
2224
2225     /* copy data while rewriting timestamps */
2226     ts = pkt->timestamp;
2227
2228     while (next - pkt->data < pkt->size - RTMP_HEADER) {
2229         type = bytestream_get_byte(&next);
2230         size = bytestream_get_be24(&next);
2231         cts  = bytestream_get_be24(&next);
2232         cts |= bytestream_get_byte(&next) << 24;
2233         if (!pts)
2234             pts = cts;
2235         ts += cts - pts;
2236         pts = cts;
2237         if (size + 3 + 4 > pkt->data + pkt->size - next)
2238             break;
2239         bytestream_put_byte(&p, type);
2240         bytestream_put_be24(&p, size);
2241         bytestream_put_be24(&p, ts);
2242         bytestream_put_byte(&p, ts >> 24);
2243         memcpy(p, next, size + 3 + 4);
2244         next += size + 3 + 4;
2245         p    += size + 3 + 4;
2246     }
2247     if (p != rt->flv_data + rt->flv_size) {
2248         av_log(NULL, AV_LOG_WARNING, "Incomplete flv packets in "
2249                                      "RTMP_PT_METADATA packet\n");
2250         rt->flv_size = p - rt->flv_data;
2251     }
2252
2253     return 0;
2254 }
2255
2256 /**
2257  * Interact with the server by receiving and sending RTMP packets until
2258  * there is some significant data (media data or expected status notification).
2259  *
2260  * @param s          reading context
2261  * @param for_header non-zero value tells function to work until it
2262  * gets notification from the server that playing has been started,
2263  * otherwise function will work until some media data is received (or
2264  * an error happens)
2265  * @return 0 for successful operation, negative value in case of error
2266  */
2267 static int get_packet(URLContext *s, int for_header)
2268 {
2269     RTMPContext *rt = s->priv_data;
2270     int ret;
2271
2272     if (rt->state == STATE_STOPPED)
2273         return AVERROR_EOF;
2274
2275     for (;;) {
2276         RTMPPacket rpkt = { 0 };
2277         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2278                                        rt->in_chunk_size, &rt->prev_pkt[0],
2279                                        &rt->nb_prev_pkt[0])) <= 0) {
2280             if (ret == 0) {
2281                 return AVERROR(EAGAIN);
2282             } else {
2283                 return AVERROR(EIO);
2284             }
2285         }
2286         rt->bytes_read += ret;
2287         if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
2288             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
2289             if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
2290                 return ret;
2291             rt->last_bytes_read = rt->bytes_read;
2292         }
2293
2294         ret = rtmp_parse_result(s, rt, &rpkt);
2295
2296         // At this point we must check if we are in the seek state and continue
2297         // with the next packet. handle_invoke will get us out of this state
2298         // when the right message is encountered
2299         if (rt->state == STATE_SEEKING) {
2300             ff_rtmp_packet_destroy(&rpkt);
2301             // We continue, let the natural flow of things happen:
2302             // AVERROR(EAGAIN) or handle_invoke gets us out of here
2303             continue;
2304         }
2305
2306         if (ret < 0) {//serious error in current packet
2307             ff_rtmp_packet_destroy(&rpkt);
2308             return ret;
2309         }
2310         if (rt->do_reconnect && for_header) {
2311             ff_rtmp_packet_destroy(&rpkt);
2312             return 0;
2313         }
2314         if (rt->state == STATE_STOPPED) {
2315             ff_rtmp_packet_destroy(&rpkt);
2316             return AVERROR_EOF;
2317         }
2318         if (for_header && (rt->state == STATE_PLAYING    ||
2319                            rt->state == STATE_PUBLISHING ||
2320                            rt->state == STATE_SENDING    ||
2321                            rt->state == STATE_RECEIVING)) {
2322             ff_rtmp_packet_destroy(&rpkt);
2323             return 0;
2324         }
2325         if (!rpkt.size || !rt->is_input) {
2326             ff_rtmp_packet_destroy(&rpkt);
2327             continue;
2328         }
2329         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO) {
2330             ret = append_flv_data(rt, &rpkt, 0);
2331             ff_rtmp_packet_destroy(&rpkt);
2332             return ret;
2333         } else if (rpkt.type == RTMP_PT_NOTIFY) {
2334             ret = handle_notify(s, &rpkt);
2335             ff_rtmp_packet_destroy(&rpkt);
2336             return ret;
2337         } else if (rpkt.type == RTMP_PT_METADATA) {
2338             ret = handle_metadata(rt, &rpkt);
2339             ff_rtmp_packet_destroy(&rpkt);
2340             return 0;
2341         }
2342         ff_rtmp_packet_destroy(&rpkt);
2343     }
2344 }
2345
2346 static int rtmp_close(URLContext *h)
2347 {
2348     RTMPContext *rt = h->priv_data;
2349     int ret = 0, i, j;
2350
2351     if (!rt->is_input) {
2352         rt->flv_data = NULL;
2353         if (rt->out_pkt.size)
2354             ff_rtmp_packet_destroy(&rt->out_pkt);
2355         if (rt->state > STATE_FCPUBLISH)
2356             ret = gen_fcunpublish_stream(h, rt);
2357     }
2358     if (rt->state > STATE_HANDSHAKED)
2359         ret = gen_delete_stream(h, rt);
2360     for (i = 0; i < 2; i++) {
2361         for (j = 0; j < rt->nb_prev_pkt[i]; j++)
2362             ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
2363         av_freep(&rt->prev_pkt[i]);
2364     }
2365
2366     free_tracked_methods(rt);
2367     av_freep(&rt->flv_data);
2368     ffurl_close(rt->stream);
2369     return ret;
2370 }
2371
2372 /**
2373  * Open RTMP connection and verify that the stream can be played.
2374  *
2375  * URL syntax: rtmp://server[:port][/app][/playpath]
2376  *             where 'app' is first one or two directories in the path
2377  *             (e.g. /ondemand/, /flash/live/, etc.)
2378  *             and 'playpath' is a file name (the rest of the path,
2379  *             may be prefixed with "mp4:")
2380  */
2381 static int rtmp_open(URLContext *s, const char *uri, int flags)
2382 {
2383     RTMPContext *rt = s->priv_data;
2384     char proto[8], hostname[256], path[1024], auth[100], *fname;
2385     char *old_app, *qmark, fname_buffer[1024];
2386     uint8_t buf[2048];
2387     int port;
2388     AVDictionary *opts = NULL;
2389     int ret;
2390
2391     if (rt->listen_timeout > 0)
2392         rt->listen = 1;
2393
2394     rt->is_input = !(flags & AVIO_FLAG_WRITE);
2395
2396     av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2397                  hostname, sizeof(hostname), &port,
2398                  path, sizeof(path), s->filename);
2399
2400     if (strchr(path, ' ')) {
2401         av_log(s, AV_LOG_WARNING,
2402                "Detected librtmp style URL parameters, these aren't supported "
2403                "by the libavformat internal RTMP handler currently enabled. "
2404                "See the documentation for the correct way to pass parameters.\n");
2405     }
2406
2407     if (auth[0]) {
2408         char *ptr = strchr(auth, ':');
2409         if (ptr) {
2410             *ptr = '\0';
2411             av_strlcpy(rt->username, auth, sizeof(rt->username));
2412             av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2413         }
2414     }
2415
2416     if (rt->listen && strcmp(proto, "rtmp")) {
2417         av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2418                proto);
2419         return AVERROR(EINVAL);
2420     }
2421     if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2422         if (!strcmp(proto, "rtmpts"))
2423             av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
2424
2425         /* open the http tunneling connection */
2426         ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2427     } else if (!strcmp(proto, "rtmps")) {
2428         /* open the tls connection */
2429         if (port < 0)
2430             port = RTMPS_DEFAULT_PORT;
2431         ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2432     } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2433         if (!strcmp(proto, "rtmpte"))
2434             av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
2435
2436         /* open the encrypted connection */
2437         ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2438         rt->encrypted = 1;
2439     } else {
2440         /* open the tcp connection */
2441         if (port < 0)
2442             port = RTMP_DEFAULT_PORT;
2443         if (rt->listen)
2444             ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2445                         "?listen&listen_timeout=%d",
2446                         rt->listen_timeout * 1000);
2447         else
2448             ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
2449     }
2450
2451 reconnect:
2452     if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2453                           &s->interrupt_callback, &opts)) < 0) {
2454         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2455         goto fail;
2456     }
2457
2458     if (rt->swfverify) {
2459         if ((ret = rtmp_calc_swfhash(s)) < 0)
2460             goto fail;
2461     }
2462
2463     rt->state = STATE_START;
2464     if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2465         goto fail;
2466     if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2467         goto fail;
2468
2469     rt->out_chunk_size = 128;
2470     rt->in_chunk_size  = 128; // Probably overwritten later
2471     rt->state = STATE_HANDSHAKED;
2472
2473     // Keep the application name when it has been defined by the user.
2474     old_app = rt->app;
2475
2476     rt->app = av_malloc(APP_MAX_LENGTH);
2477     if (!rt->app) {
2478         ret = AVERROR(ENOMEM);
2479         goto fail;
2480     }
2481
2482     //extract "app" part from path
2483     qmark = strchr(path, '?');
2484     if (qmark && strstr(qmark, "slist=")) {
2485         char* amp;
2486         // After slist we have the playpath, before the params, the app
2487         av_strlcpy(rt->app, path + 1, FFMIN(qmark - path, APP_MAX_LENGTH));
2488         fname = strstr(path, "slist=") + 6;
2489         // Strip any further query parameters from fname
2490         amp = strchr(fname, '&');
2491         if (amp) {
2492             av_strlcpy(fname_buffer, fname, FFMIN(amp - fname + 1,
2493                                                   sizeof(fname_buffer)));
2494             fname = fname_buffer;
2495         }
2496     } else if (!strncmp(path, "/ondemand/", 10)) {
2497         fname = path + 10;
2498         memcpy(rt->app, "ondemand", 9);
2499     } else {
2500         char *next = *path ? path + 1 : path;
2501         char *p = strchr(next, '/');
2502         if (!p) {
2503             fname = next;
2504             rt->app[0] = '\0';
2505         } else {
2506             // make sure we do not mismatch a playpath for an application instance
2507             char *c = strchr(p + 1, ':');
2508             fname = strchr(p + 1, '/');
2509             if (!fname || (c && c < fname)) {
2510                 fname = p + 1;
2511                 av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH));
2512             } else {
2513                 fname++;
2514                 av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH));
2515             }
2516         }
2517     }
2518
2519     if (old_app) {
2520         // The name of application has been defined by the user, override it.
2521         av_free(rt->app);
2522         rt->app = old_app;
2523     }
2524
2525     if (!rt->playpath) {
2526         int len = strlen(fname);
2527
2528         rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
2529         if (!rt->playpath) {
2530             ret = AVERROR(ENOMEM);
2531             goto fail;
2532         }
2533
2534         if (!strchr(fname, ':') && len >= 4 &&
2535             (!strcmp(fname + len - 4, ".f4v") ||
2536              !strcmp(fname + len - 4, ".mp4"))) {
2537             memcpy(rt->playpath, "mp4:", 5);
2538         } else {
2539             if (len >= 4 && !strcmp(fname + len - 4, ".flv"))
2540                 fname[len - 4] = '\0';
2541             rt->playpath[0] = 0;
2542         }
2543         av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH);
2544     }
2545
2546     if (!rt->tcurl) {
2547         rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
2548         if (!rt->tcurl) {
2549             ret = AVERROR(ENOMEM);
2550             goto fail;
2551         }
2552         ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2553                     port, "/%s", rt->app);
2554     }
2555
2556     if (!rt->flashver) {
2557         rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
2558         if (!rt->flashver) {
2559             ret = AVERROR(ENOMEM);
2560             goto fail;
2561         }
2562         if (rt->is_input) {
2563             snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2564                     RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
2565                     RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
2566         } else {
2567             snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
2568                     "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2569         }
2570     }
2571
2572     rt->client_report_size = 1048576;
2573     rt->bytes_read = 0;
2574     rt->last_bytes_read = 0;
2575     rt->server_bw = 2500000;
2576
2577     av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2578            proto, path, rt->app, rt->playpath);
2579     if (!rt->listen) {
2580         if ((ret = gen_connect(s, rt)) < 0)
2581             goto fail;
2582     } else {
2583         if ((ret = read_connect(s, s->priv_data)) < 0)
2584             goto fail;
2585     }
2586
2587     do {
2588         ret = get_packet(s, 1);
2589     } while (ret == AVERROR(EAGAIN));
2590     if (ret < 0)
2591         goto fail;
2592
2593     if (rt->do_reconnect) {
2594         int i;
2595         ffurl_close(rt->stream);
2596         rt->stream       = NULL;
2597         rt->do_reconnect = 0;
2598         rt->nb_invokes   = 0;
2599         for (i = 0; i < 2; i++)
2600             memset(rt->prev_pkt[i], 0,
2601                    sizeof(**rt->prev_pkt) * rt->nb_prev_pkt[i]);
2602         free_tracked_methods(rt);
2603         goto reconnect;
2604     }
2605
2606     if (rt->is_input) {
2607         int err;
2608         // generate FLV header for demuxer
2609         rt->flv_size = 13;
2610         if ((err = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
2611             return err;
2612         rt->flv_off  = 0;
2613         memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
2614     } else {
2615         rt->flv_size = 0;
2616         rt->flv_data = NULL;
2617         rt->flv_off  = 0;
2618         rt->skip_bytes = 13;
2619     }
2620
2621     s->max_packet_size = rt->stream->max_packet_size;
2622     s->is_streamed     = 1;
2623     return 0;
2624
2625 fail:
2626     av_dict_free(&opts);
2627     rtmp_close(s);
2628     return ret;
2629 }
2630
2631 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2632 {
2633     RTMPContext *rt = s->priv_data;
2634     int orig_size = size;
2635     int ret;
2636
2637     while (size > 0) {
2638         int data_left = rt->flv_size - rt->flv_off;
2639
2640         if (data_left >= size) {
2641             memcpy(buf, rt->flv_data + rt->flv_off, size);
2642             rt->flv_off += size;
2643             return orig_size;
2644         }
2645         if (data_left > 0) {
2646             memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2647             buf  += data_left;
2648             size -= data_left;
2649             rt->flv_off = rt->flv_size;
2650             return data_left;
2651         }
2652         if ((ret = get_packet(s, 0)) < 0)
2653            return ret;
2654     }
2655     return orig_size;
2656 }
2657
2658 static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp,
2659                          int flags)
2660 {
2661     RTMPContext *rt = s->priv_data;
2662     int ret;
2663     av_log(s, AV_LOG_DEBUG,
2664            "Seek on stream index %d at timestamp %"PRId64" with flags %08x\n",
2665            stream_index, timestamp, flags);
2666     if ((ret = gen_seek(s, rt, timestamp)) < 0) {
2667         av_log(s, AV_LOG_ERROR,
2668                "Unable to send seek command on stream index %d at timestamp "
2669                "%"PRId64" with flags %08x\n",
2670                stream_index, timestamp, flags);
2671         return ret;
2672     }
2673     rt->flv_off = rt->flv_size;
2674     rt->state = STATE_SEEKING;
2675     return timestamp;
2676 }
2677
2678 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2679 {
2680     RTMPContext *rt = s->priv_data;
2681     int size_temp = size;
2682     int pktsize, pkttype;
2683     uint32_t ts;
2684     const uint8_t *buf_temp = buf;
2685     uint8_t c;
2686     int ret;
2687
2688     do {
2689         if (rt->skip_bytes) {
2690             int skip = FFMIN(rt->skip_bytes, size_temp);
2691             buf_temp       += skip;
2692             size_temp      -= skip;
2693             rt->skip_bytes -= skip;
2694             continue;
2695         }
2696
2697         if (rt->flv_header_bytes < RTMP_HEADER) {
2698             const uint8_t *header = rt->flv_header;
2699             int copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
2700             int channel = RTMP_AUDIO_CHANNEL;
2701             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2702             rt->flv_header_bytes += copy;
2703             size_temp            -= copy;
2704             if (rt->flv_header_bytes < RTMP_HEADER)
2705                 break;
2706
2707             pkttype = bytestream_get_byte(&header);
2708             pktsize = bytestream_get_be24(&header);
2709             ts = bytestream_get_be24(&header);
2710             ts |= bytestream_get_byte(&header) << 24;
2711             bytestream_get_be24(&header);
2712             rt->flv_size = pktsize;
2713
2714             if (pkttype == RTMP_PT_VIDEO)
2715                 channel = RTMP_VIDEO_CHANNEL;
2716
2717             //force 12bytes header
2718             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
2719                 pkttype == RTMP_PT_NOTIFY) {
2720                 if (pkttype == RTMP_PT_NOTIFY)
2721                     pktsize += 16;
2722                 if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1],
2723                                                      &rt->nb_prev_pkt[1],
2724                                                      channel)) < 0)
2725                     return ret;
2726                 rt->prev_pkt[1][channel].channel_id = 0;
2727             }
2728
2729             //this can be a big packet, it's better to send it right here
2730             if ((ret = ff_rtmp_packet_create(&rt->out_pkt, channel,
2731                                              pkttype, ts, pktsize)) < 0)
2732                 return ret;
2733
2734             rt->out_pkt.extra = rt->stream_id;
2735             rt->flv_data = rt->out_pkt.data;
2736
2737             if (pkttype == RTMP_PT_NOTIFY)
2738                 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
2739         }
2740
2741         if (rt->flv_size - rt->flv_off > size_temp) {
2742             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
2743             rt->flv_off += size_temp;
2744             size_temp = 0;
2745         } else {
2746             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
2747             size_temp   -= rt->flv_size - rt->flv_off;
2748             rt->flv_off += rt->flv_size - rt->flv_off;
2749         }
2750
2751         if (rt->flv_off == rt->flv_size) {
2752             rt->skip_bytes = 4;
2753
2754             if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
2755                 return ret;
2756             rt->flv_size = 0;
2757             rt->flv_off = 0;
2758             rt->flv_header_bytes = 0;
2759             rt->flv_nb_packets++;
2760         }
2761     } while (buf_temp - buf < size);
2762
2763     if (rt->flv_nb_packets < rt->flush_interval)
2764         return size;
2765     rt->flv_nb_packets = 0;
2766
2767     /* set stream into nonblocking mode */
2768     rt->stream->flags |= AVIO_FLAG_NONBLOCK;
2769
2770     /* try to read one byte from the stream */
2771     ret = ffurl_read(rt->stream, &c, 1);
2772
2773     /* switch the stream back into blocking mode */
2774     rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
2775
2776     if (ret == AVERROR(EAGAIN)) {
2777         /* no incoming data to handle */
2778         return size;
2779     } else if (ret < 0) {
2780         return ret;
2781     } else if (ret == 1) {
2782         RTMPPacket rpkt = { 0 };
2783
2784         if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
2785                                                 rt->in_chunk_size,
2786                                                 &rt->prev_pkt[0],
2787                                                 &rt->nb_prev_pkt[0], c)) <= 0)
2788              return ret;
2789
2790         if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
2791             return ret;
2792
2793         ff_rtmp_packet_destroy(&rpkt);
2794     }
2795
2796     return size;
2797 }
2798
2799 #define OFFSET(x) offsetof(RTMPContext, x)
2800 #define DEC AV_OPT_FLAG_DECODING_PARAM
2801 #define ENC AV_OPT_FLAG_ENCODING_PARAM
2802
2803 static const AVOption rtmp_options[] = {
2804     {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2805     {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {.i64 = 3000}, 0, INT_MAX, DEC|ENC},
2806     {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2807     {"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2808     {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {.i64 = 10}, 0, INT_MAX, ENC},
2809     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {.i64 = -2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
2810     {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
2811     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
2812     {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
2813     {"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2814     {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2815     {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2816     {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
2817     {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
2818     {"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2819     {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2820     {"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2821     {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2822     {"listen",      "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2823     {"timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies -rtmp_listen 1",  OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2824     { NULL },
2825 };
2826
2827 #define RTMP_PROTOCOL(flavor)                    \
2828 static const AVClass flavor##_class = {          \
2829     .class_name = #flavor,                       \
2830     .item_name  = av_default_item_name,          \
2831     .option     = rtmp_options,                  \
2832     .version    = LIBAVUTIL_VERSION_INT,         \
2833 };                                               \
2834                                                  \
2835 URLProtocol ff_##flavor##_protocol = {           \
2836     .name           = #flavor,                   \
2837     .url_open       = rtmp_open,                 \
2838     .url_read       = rtmp_read,                 \
2839     .url_read_seek  = rtmp_seek,                 \
2840     .url_write      = rtmp_write,                \
2841     .url_close      = rtmp_close,                \
2842     .priv_data_size = sizeof(RTMPContext),       \
2843     .flags          = URL_PROTOCOL_FLAG_NETWORK, \
2844     .priv_data_class= &flavor##_class,           \
2845 };
2846
2847
2848 RTMP_PROTOCOL(rtmp)
2849 RTMP_PROTOCOL(rtmpe)
2850 RTMP_PROTOCOL(rtmps)
2851 RTMP_PROTOCOL(rtmpt)
2852 RTMP_PROTOCOL(rtmpte)
2853 RTMP_PROTOCOL(rtmpts)