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