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