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