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