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