mirror of https://bitbucket.org/ausocean/av.git
rtmp: remove librtmp
This commit is contained in:
parent
515e63802a
commit
ae53aa146e
10
Makefile
10
Makefile
|
@ -1,12 +1,2 @@
|
|||
all:
|
||||
cd cmd/revid-cli; go build
|
||||
|
||||
deps:
|
||||
@cd rtmp; $(MAKE) all
|
||||
@echo "\n\nNow run sudo make install-deps\n"
|
||||
|
||||
install-deps:
|
||||
@cd rtmp; $(MAKE) install
|
||||
|
||||
clean:
|
||||
@cd rtmp; $(MAKE) clean
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
all:
|
||||
@cd rtmp_c/librtmp; $(MAKE) all
|
||||
|
||||
install:
|
||||
@cd rtmp_c/librtmp; $(MAKE) install
|
||||
|
||||
clean:
|
||||
@cd rtmp_c; $(MAKE) clean
|
|
@ -1,94 +0,0 @@
|
|||
VERSION=v2.4
|
||||
|
||||
prefix=/usr/local
|
||||
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
LD=$(CROSS_COMPILE)ld
|
||||
|
||||
SYS=posix
|
||||
#SYS=mingw
|
||||
|
||||
CRYPTO=OPENSSL
|
||||
#CRYPTO=POLARSSL
|
||||
#CRYPTO=GNUTLS
|
||||
LIBZ=-lz
|
||||
LIB_GNUTLS=-lgnutls -lhogweed -lnettle -lgmp $(LIBZ)
|
||||
LIB_OPENSSL=-lssl -lcrypto $(LIBZ)
|
||||
LIB_POLARSSL=-lpolarssl $(LIBZ)
|
||||
CRYPTO_LIB=$(LIB_$(CRYPTO))
|
||||
DEF_=-DNO_CRYPTO
|
||||
CRYPTO_DEF=$(DEF_$(CRYPTO))
|
||||
|
||||
DEF=-DRTMPDUMP_VERSION=\"$(VERSION)\" $(CRYPTO_DEF) $(XDEF)
|
||||
OPT=-O2
|
||||
CFLAGS=-Wall $(XCFLAGS) $(INC) $(DEF) $(OPT)
|
||||
LDFLAGS=-Wall $(XLDFLAGS)
|
||||
|
||||
bindir=$(prefix)/bin
|
||||
sbindir=$(prefix)/sbin
|
||||
mandir=$(prefix)/man
|
||||
|
||||
BINDIR=$(DESTDIR)$(bindir)
|
||||
SBINDIR=$(DESTDIR)$(sbindir)
|
||||
MANDIR=$(DESTDIR)$(mandir)
|
||||
|
||||
LIBS_posix=
|
||||
LIBS_darwin=
|
||||
LIBS_mingw=-lws2_32 -lwinmm -lgdi32
|
||||
LIB_RTMP=-Llibrtmp -lrtmp
|
||||
LIBS=$(LIB_RTMP) $(CRYPTO_LIB) $(LIBS_$(SYS)) $(XLIBS)
|
||||
|
||||
THREADLIB_posix=-lpthread
|
||||
THREADLIB_darwin=-lpthread
|
||||
THREADLIB_mingw=
|
||||
THREADLIB=$(THREADLIB_$(SYS))
|
||||
SLIBS=$(THREADLIB) $(LIBS)
|
||||
|
||||
LIBRTMP=librtmp/librtmp.a
|
||||
INCRTMP=librtmp/rtmp_sys.h librtmp/rtmp.h librtmp/log.h librtmp/amf.h
|
||||
|
||||
EXT_posix=
|
||||
EXT_darwin=
|
||||
EXT_mingw=.exe
|
||||
EXT=$(EXT_$(SYS))
|
||||
|
||||
PROGS=rtmpdump rtmpgw rtmpsrv rtmpsuck
|
||||
|
||||
all: $(LIBRTMP) $(PROGS)
|
||||
|
||||
$(PROGS): $(LIBRTMP)
|
||||
|
||||
install: $(PROGS)
|
||||
-mkdir -p $(BINDIR) $(SBINDIR) $(MANDIR)/man1 $(MANDIR)/man8
|
||||
cp rtmpdump$(EXT) $(BINDIR)
|
||||
cp rtmpgw$(EXT) rtmpsrv$(EXT) rtmpsuck$(EXT) $(SBINDIR)
|
||||
cp rtmpdump.1 $(MANDIR)/man1
|
||||
cp rtmpgw.8 $(MANDIR)/man8
|
||||
@cd librtmp; $(MAKE) install
|
||||
|
||||
clean:
|
||||
rm -f *.o rtmpdump$(EXT) rtmpgw$(EXT) rtmpsrv$(EXT) rtmpsuck$(EXT)
|
||||
@cd librtmp; $(MAKE) clean
|
||||
|
||||
FORCE:
|
||||
|
||||
$(LIBRTMP): FORCE
|
||||
@cd librtmp; $(MAKE) all
|
||||
|
||||
rtmpdump: rtmpdump.o
|
||||
$(CC) $(LDFLAGS) -o $@$(EXT) $@.o $(LIBS)
|
||||
|
||||
rtmpsrv: rtmpsrv.o thread.o
|
||||
$(CC) $(LDFLAGS) -o $@$(EXT) $@.o thread.o $(SLIBS)
|
||||
|
||||
rtmpsuck: rtmpsuck.o thread.o
|
||||
$(CC) $(LDFLAGS) -o $@$(EXT) $@.o thread.o $(SLIBS)
|
||||
|
||||
rtmpgw: rtmpgw.o thread.o
|
||||
$(CC) $(LDFLAGS) -o $@$(EXT) $@.o thread.o $(SLIBS)
|
||||
|
||||
rtmpgw.o: rtmpgw.c $(INCRTMP) Makefile
|
||||
rtmpdump.o: rtmpdump.c $(INCRTMP) Makefile
|
||||
rtmpsrv.o: rtmpsrv.c $(INCRTMP) Makefile
|
||||
rtmpsuck.o: rtmpsuck.c $(INCRTMP) Makefile
|
||||
thread.o: thread.c thread.h
|
|
@ -1,220 +0,0 @@
|
|||
RTMP Dump v2.4
|
||||
(C) 2009 Andrej Stepanchuk
|
||||
(C) 2009-2011 Howard Chu
|
||||
(C) 2010 2a665470ced7adb7156fcef47f8199a6371c117b8a79e399a2771e0b36384090
|
||||
(C) 2011 33ae1ce77301f4b4494faaa5f609f3c48b9dcf82
|
||||
License: GPLv2
|
||||
librtmp license: LGPLv2.1
|
||||
http://rtmpdump.mplayerhq.hu/
|
||||
|
||||
To compile type "make" with SYS=<platform name>, e.g.
|
||||
|
||||
$ make SYS=posix
|
||||
|
||||
for Linux, Unix, etc. or
|
||||
|
||||
$ make SYS=darwin
|
||||
|
||||
for MacOSX or
|
||||
|
||||
$ make SYS=mingw
|
||||
|
||||
for Windows.
|
||||
|
||||
You can cross-compile for other platforms using the CROSS_COMPILE variable:
|
||||
|
||||
$ make CROSS_COMPILE=arm-none-linux- INC=-I/my/cross/includes
|
||||
|
||||
Please read the Makefile to see what other make variables are used.
|
||||
|
||||
This code also requires you to have OpenSSL and zlib installed. You may
|
||||
optionally use GnuTLS or polarssl instead of OpenSSL if desired. You may
|
||||
also build with just rtmpe support, and no rtmps/https support, by
|
||||
specifying -DNO_SSL in the XDEF macro, e.g.
|
||||
|
||||
$ make XDEF=-DNO_SSL
|
||||
|
||||
or
|
||||
|
||||
$ make CRYPTO=POLARSSL XDEF=-DNO_SSL
|
||||
|
||||
You may also turn off all crypto support if desired
|
||||
|
||||
$ make CRYPTO=
|
||||
|
||||
A shared library is now built by default, in addition to the static
|
||||
library. You can also turn it off if desired
|
||||
|
||||
$ make SHARED=
|
||||
|
||||
The rtmpdump programs still link to the static library, regardless.
|
||||
|
||||
Note that if using OpenSSL, you must have version 0.9.8 or newer.
|
||||
For Polar SSL you must have version 1.0.0 or newer.
|
||||
|
||||
Credit goes to team boxee for the XBMC RTMP code originally used in RTMPDumper.
|
||||
The current code is based on the XBMC code but rewritten in C by Howard Chu.
|
||||
|
||||
|
||||
SWF Verification
|
||||
----------------
|
||||
|
||||
Note: these instructions for manually generating the SWFVerification
|
||||
info are provided only for historical documentation. The software can now
|
||||
generate this info automatically, so it is no longer necessary to
|
||||
run the commands described here. Just use the -W (--swfVfy) option
|
||||
to perform automatic SWFVerification.
|
||||
|
||||
Download the swf player you want to use for SWFVerification, unzip it using
|
||||
|
||||
$ flasm -x file.swf
|
||||
|
||||
It will show the decompressed filesize, use it for --swfsize
|
||||
|
||||
Now generate the hash
|
||||
|
||||
$ openssl sha -sha256 -hmac "Genuine Adobe Flash Player 001" file.swf
|
||||
|
||||
and use the --swfhash "01234..." option to pass it.
|
||||
|
||||
e.g. $ ./rtmpdump --swfhash "123456..." --swfsize 987...
|
||||
|
||||
|
||||
Connect Parameters
|
||||
------------------
|
||||
|
||||
Some servers expect additional custom parameters to be attached to the
|
||||
RTMP connect request. The "--auth" option handles a specific case, where
|
||||
a boolean TRUE followed by the given string are added to the request.
|
||||
Other servers may require completely different parameters, so the new
|
||||
"--conn" option has been added. This option can be set multiple times
|
||||
on the command line, adding one parameter each time.
|
||||
|
||||
The argument to the option must take the form <type> : <value> where
|
||||
type can be B for boolean, S for string, N for number, and O for object.
|
||||
For booleans the value must be 0 or 1. Also, for objects the value must
|
||||
be 1 to start a new object, or 0 to end the current object.
|
||||
|
||||
Examples:
|
||||
--conn B:0 --conn S:hello --conn N:3.14159
|
||||
|
||||
Named parameters can be specified by prefixing 'N' to the type. Then the
|
||||
name should come next, and finally the value:
|
||||
--conn NB:myflag:1 --conn NS:category:something --conn NN:pi:3.14159
|
||||
|
||||
Objects may be added sequentially:
|
||||
-C O:1 -C NB:flag:1 -C NS:status:success -C O:0 -C O:1 -C NN:time:12.30 -C O:0
|
||||
or nested:
|
||||
-C O:1 -C NS:code:hello -C NO:extra:1 -C NS:data:stuff -C O:0 -C O:0
|
||||
|
||||
|
||||
Building OpenSSL 0.9.8k
|
||||
-----------------------
|
||||
arm:
|
||||
./Configure -DL_ENDIAN --prefix=`pwd`/armlibs linux-generic32
|
||||
|
||||
Then replace gcc, cc, ar, ranlib in Makefile and crypto/Makefile by arm-linux-* variants and use make && make install_sw
|
||||
|
||||
win32:
|
||||
Try ./Configure mingw --prefix=`pwd`/win32libs -DL_ENDIAN -DOPENSSL_NO_HW
|
||||
Replace gcc, cc, ... by mingw32-* variants in Makefile and crypto/Makefile
|
||||
make && make install_sw
|
||||
|
||||
OpenSSL cross-compiling can be a difficult beast.
|
||||
|
||||
Precompiled OpenSSL binaries for Windows are available on
|
||||
http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
|
||||
If you're just running a pre-built Windows rtmpdump binary, then all you
|
||||
need is the "Light" installer. If you want to compile rtmpdump yourself,
|
||||
you'll need the full installer.
|
||||
|
||||
|
||||
Example Servers
|
||||
---------------
|
||||
Three different types of servers are also present in this distribution:
|
||||
rtmpsrv - a stub server
|
||||
rtmpsuck - a transparent proxy
|
||||
rtmpgw - an RTMP to HTTP gateway
|
||||
|
||||
rtmpsrv - Note that this is very incomplete code, and I haven't yet decided
|
||||
whether or not to finish it. It is useful for obtaining all the parameters
|
||||
that a real Flash client would send to an RTMP server, so that they can be
|
||||
used with rtmpdump. The current version now invokes rtmpdump automatically
|
||||
after parsing a client request.
|
||||
|
||||
rtmpsuck - proxy server. See below...
|
||||
|
||||
All you need to do is redirect your Flash clients to the machine running this
|
||||
server and it will dump out all the connect / play parameters that the Flash
|
||||
client sent. The simplest way to cause the redirect is by editing /etc/hosts
|
||||
when you know the hostname of the RTMP server, and point it to localhost while
|
||||
running rtmpsrv on your machine. (This approach should work on any OS; on
|
||||
Windows you would edit %SystemRoot%\system32\drivers\etc\hosts.)
|
||||
|
||||
On Linux you can also use iptables to redirect all outbound RTMP traffic. You
|
||||
need to be running as root in order to use the iptables command.
|
||||
|
||||
In my original plan I would have the transparent proxy running as a special
|
||||
user (e.g. user "proxy"), and regular Flash clients running as any other user.
|
||||
In that case the proxy would make the connection to the real RTMP server. The
|
||||
iptables rule would look like this:
|
||||
|
||||
iptables -t nat -A OUTPUT -p tcp --dport 1935 -m owner \! --uid-owner proxy \
|
||||
-j REDIRECT
|
||||
|
||||
A rule like the above will be needed to use rtmpsuck. Note that you should
|
||||
replace "proxy" in the above command with an account that actually exists
|
||||
on your machine.
|
||||
|
||||
Using it in this mode takes advantage of the Linux support for IP redirects;
|
||||
in particular it uses a special getsockopt() call to retrieve the original
|
||||
destination address of the connection. That way the proxy can create the
|
||||
real outbound connection without any other help from the user. The equivalent
|
||||
functionality may exist on other OSs but needs more investigation.
|
||||
|
||||
(Based on reading the BSD ipfw manpage, this rule ought to work on BSD:
|
||||
|
||||
ipfw add 40 fwd 127.0.0.1,1935 tcp from any to any 1935 not uid proxy
|
||||
|
||||
Some confirmation from any BSD users would be nice.)
|
||||
|
||||
(We have a solution for Windows based on a TDI driver; this is known to
|
||||
work on Win2K and WinXP but is assumed to not work on Vista or Win7 as the
|
||||
TDI is no longer used on those OS versions. Also, none of the known
|
||||
solutions are available as freeware.)
|
||||
|
||||
The rtmpsuck command has only one option: "-z" to turn on debug logging.
|
||||
It listens on port 1935 for RTMP sessions, but you can also redirect other
|
||||
ports to it as needed (read the iptables docs). It first performs an RTMP
|
||||
handshake with the client, then waits for the client to send a connect
|
||||
request. It parses and prints the connect parameters, then makes an
|
||||
outbound connection to the real RTMP server. It performs an RTMP handshake
|
||||
with that server, forwards the connect request, and from that point on it
|
||||
just relays packets back and forth between the two endpoints.
|
||||
|
||||
It also checks for a few packets that it treats specially: a play packet
|
||||
from the client will get parsed so that the playpath can be displayed. It
|
||||
also handles SWF Verification requests from the server, without forwarding
|
||||
them to the client. (There would be no point, since the response is tied to
|
||||
each session's handshake.)
|
||||
|
||||
Once the play command is processed, all subsequent audio/video data received
|
||||
from the server will be written to a file, as well as being delivered back
|
||||
to the client.
|
||||
|
||||
The point of all this, instead of just using a sniffer, is that since rtmpsuck
|
||||
has performed real handshakes with both the client and the server, it can
|
||||
negotiate whatever encryption keys are needed and so record the unencrypted
|
||||
data.
|
||||
|
||||
rtmpgw - HTTP gateway: this is an HTTP server that accepts requests that
|
||||
consist of rtmpdump parameters. It then connects to the specified RTMP
|
||||
server and returns the retrieved data in the HTTP response. The only valid
|
||||
HTTP request is "GET /" but additional options can be provided in normal
|
||||
URL-encoded fashion. E.g.
|
||||
GET /?r=rtmp:%2f%2fserver%2fmyapp&y=somefile HTTP/1.0
|
||||
|
||||
is equivalent the rtmpdump parameters "-r rtmp://server/myapp -y somefile".
|
||||
|
||||
Note that only the shortform (single letter) rtmpdump options are supported.
|
|
@ -1,2 +0,0 @@
|
|||
# librtmp
|
||||
Fork from http://git.ffmpeg.org/rtmpdump integrated with srs.
|
|
@ -1,121 +0,0 @@
|
|||
VERSION=v2.4
|
||||
|
||||
prefix=/usr/local
|
||||
|
||||
incdir=$(prefix)/include/librtmp
|
||||
bindir=$(prefix)/bin
|
||||
libdir=$(prefix)/lib
|
||||
mandir=$(prefix)/man
|
||||
BINDIR=$(DESTDIR)$(bindir)
|
||||
INCDIR=$(DESTDIR)$(incdir)
|
||||
LIBDIR=$(DESTDIR)$(libdir)
|
||||
MANDIR=$(DESTDIR)$(mandir)
|
||||
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
LD=$(CROSS_COMPILE)ld
|
||||
AR=$(CROSS_COMPILE)ar
|
||||
|
||||
SYS=posix
|
||||
#CRYPTO=OPENSSL
|
||||
#CRYPTO=GNUTLS
|
||||
#DEF_POLARSSL=-DUSE_POLARSSL
|
||||
#DEF_OPENSSL=-DUSE_OPENSSL
|
||||
#DEF_GNUTLS=-DUSE_GNUTLS
|
||||
DEF_=-DNO_CRYPTO
|
||||
REQ_GNUTLS=gnutls,hogweed,nettle
|
||||
#REQ_OPENSSL=libssl,libcrypto
|
||||
PUB_GNUTLS=-lgmp
|
||||
LIBZ=-lz
|
||||
LIBS_posix=
|
||||
LIBS_darwin=
|
||||
LIBS_mingw=-lws2_32 -lwinmm -lgdi32
|
||||
LIB_GNUTLS=-lgnutls -lhogweed -lnettle -lgmp $(LIBZ)
|
||||
LIB_OPENSSL=-lssl -lcrypto $(LIBZ)
|
||||
LIB_POLARSSL=-lpolarssl $(LIBZ)
|
||||
PRIVATE_LIBS=$(LIBS_$(SYS))
|
||||
CRYPTO_LIB=$(LIB_$(CRYPTO)) $(PRIVATE_LIBS)
|
||||
CRYPTO_REQ=$(REQ_$(CRYPTO))
|
||||
CRYPTO_DEF=$(DEF_$(CRYPTO))
|
||||
PUBLIC_LIBS=$(PUB_$(CRYPTO))
|
||||
|
||||
SO_VERSION=1
|
||||
SOX_posix=so
|
||||
SOX_darwin=dylib
|
||||
SOX_mingw=dll
|
||||
SOX=$(SOX_$(SYS))
|
||||
SO_posix=.$(SOX).$(SO_VERSION)
|
||||
SO_darwin=.$(SO_VERSION).$(SOX)
|
||||
SO_mingw=-$(SO_VERSION).$(SOX)
|
||||
SO_EXT=$(SO_$(SYS))
|
||||
|
||||
SODIR_posix=$(LIBDIR)
|
||||
SODIR_darwin=$(LIBDIR)
|
||||
SODIR_mingw=$(BINDIR)
|
||||
SODIR=$(SODIR_$(SYS))
|
||||
|
||||
SO_LDFLAGS_posix=-shared -Wl,-soname,$@
|
||||
SO_LDFLAGS_darwin=-dynamiclib -twolevel_namespace -undefined dynamic_lookup \
|
||||
-fno-common -headerpad_max_install_names -install_name $(libdir)/$@
|
||||
SO_LDFLAGS_mingw=-shared -Wl,--out-implib,librtmp.dll.a
|
||||
SO_LDFLAGS=$(SO_LDFLAGS_$(SYS))
|
||||
|
||||
INSTALL_IMPLIB_posix=
|
||||
INSTALL_IMPLIB_darwin=
|
||||
INSTALL_IMPLIB_mingw=cp librtmp.dll.a $(LIBDIR)
|
||||
INSTALL_IMPLIB=$(INSTALL_IMPLIB_$(SYS))
|
||||
|
||||
SHARED=yes
|
||||
SODEF_yes=-fPIC
|
||||
SOLIB_yes=librtmp$(SO_EXT)
|
||||
SOINST_yes=install_so
|
||||
SO_DEF=$(SODEF_$(SHARED))
|
||||
SO_LIB=$(SOLIB_$(SHARED))
|
||||
SO_INST=$(SOINST_$(SHARED))
|
||||
|
||||
DEF=-DRTMPDUMP_VERSION=\"$(VERSION)\" $(CRYPTO_DEF) $(XDEF)
|
||||
OPT=-O2
|
||||
CFLAGS=-Wall $(XCFLAGS) $(INC) $(DEF) $(OPT) $(SO_DEF)
|
||||
LDFLAGS=$(XLDFLAGS)
|
||||
|
||||
|
||||
OBJS=rtmp.o log.o amf.o hashswf.o parseurl.o
|
||||
|
||||
all: librtmp.a $(SO_LIB)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.a *.$(SOX) *$(SO_EXT) librtmp.pc
|
||||
|
||||
librtmp.a: $(OBJS)
|
||||
$(AR) rs $@ $?
|
||||
|
||||
librtmp$(SO_EXT): $(OBJS)
|
||||
$(CC) $(SO_LDFLAGS) $(LDFLAGS) -o $@ $^ $> $(CRYPTO_LIB)
|
||||
ln -sf $@ librtmp.$(SOX)
|
||||
|
||||
log.o: log.c log.h Makefile
|
||||
rtmp.o: rtmp.c rtmp.h rtmp_sys.h handshake.h dh.h log.h amf.h Makefile
|
||||
amf.o: amf.c amf.h bytes.h log.h Makefile
|
||||
hashswf.o: hashswf.c http.h rtmp.h rtmp_sys.h Makefile
|
||||
parseurl.o: parseurl.c rtmp.h rtmp_sys.h log.h Makefile
|
||||
|
||||
librtmp.pc: librtmp.pc.in Makefile
|
||||
sed -e "s;@prefix@;$(prefix);" -e "s;@libdir@;$(libdir);" \
|
||||
-e "s;@VERSION@;$(VERSION);" \
|
||||
-e "s;@CRYPTO_REQ@;$(CRYPTO_REQ);" \
|
||||
-e "s;@PUBLIC_LIBS@;$(PUBLIC_LIBS);" \
|
||||
-e "s;@PRIVATE_LIBS@;$(PRIVATE_LIBS);" librtmp.pc.in > $@
|
||||
|
||||
install: install_base $(SO_INST)
|
||||
|
||||
install_base: librtmp.a librtmp.pc
|
||||
-mkdir -p $(INCDIR) $(LIBDIR)/pkgconfig $(MANDIR)/man3 $(SODIR)
|
||||
cp amf.h http.h log.h rtmp.h rtmp_sys.h $(INCDIR)
|
||||
cp librtmp.a $(LIBDIR)
|
||||
cp librtmp.pc $(LIBDIR)/pkgconfig
|
||||
cp librtmp.3 $(MANDIR)/man3
|
||||
|
||||
install_so: librtmp$(SO_EXT)
|
||||
cp librtmp$(SO_EXT) $(SODIR)
|
||||
$(INSTALL_IMPLIB)
|
||||
cd $(SODIR); ln -sf librtmp$(SO_EXT) librtmp.$(SOX)
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,165 +0,0 @@
|
|||
#ifndef __AMF_H__
|
||||
#define __AMF_H__
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Team XBMC
|
||||
* http://www.xbmc.org
|
||||
* Copyright (C) 2008-2009 Andrej Stepanchuk
|
||||
* Copyright (C) 2009-2010 Howard Chu
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{ AMF_NUMBER = 0, AMF_BOOLEAN, AMF_STRING, AMF_OBJECT,
|
||||
AMF_MOVIECLIP, /* reserved, not used */
|
||||
AMF_NULL, AMF_UNDEFINED, AMF_REFERENCE, AMF_ECMA_ARRAY, AMF_OBJECT_END,
|
||||
AMF_STRICT_ARRAY, AMF_DATE, AMF_LONG_STRING, AMF_UNSUPPORTED,
|
||||
AMF_RECORDSET, /* reserved, not used */
|
||||
AMF_XML_DOC, AMF_TYPED_OBJECT,
|
||||
AMF_AVMPLUS, /* switch to AMF3 */
|
||||
AMF_INVALID = 0xff
|
||||
} AMFDataType;
|
||||
|
||||
typedef enum
|
||||
{ AMF3_UNDEFINED = 0, AMF3_NULL, AMF3_FALSE, AMF3_TRUE,
|
||||
AMF3_INTEGER, AMF3_DOUBLE, AMF3_STRING, AMF3_XML_DOC, AMF3_DATE,
|
||||
AMF3_ARRAY, AMF3_OBJECT, AMF3_XML, AMF3_BYTE_ARRAY
|
||||
} AMF3DataType;
|
||||
|
||||
typedef struct AVal
|
||||
{
|
||||
char *av_val;
|
||||
int av_len;
|
||||
} AVal;
|
||||
#define AVC(str) {str,sizeof(str)-1}
|
||||
#define AVMATCH(a1,a2) ((a1)->av_len == (a2)->av_len && !memcmp((a1)->av_val,(a2)->av_val,(a1)->av_len))
|
||||
|
||||
struct AMFObjectProperty;
|
||||
|
||||
typedef struct AMFObject
|
||||
{
|
||||
int o_num;
|
||||
struct AMFObjectProperty *o_props;
|
||||
} AMFObject;
|
||||
|
||||
typedef struct P_vu {
|
||||
double p_number;
|
||||
AVal p_aval;
|
||||
AMFObject p_object;
|
||||
} P_vu;
|
||||
|
||||
typedef struct AMFObjectProperty
|
||||
{
|
||||
AVal p_name;
|
||||
AMFDataType p_type;
|
||||
P_vu p_vu;
|
||||
int16_t p_UTCoffset;
|
||||
} AMFObjectProperty;
|
||||
|
||||
char *AMF_EncodeString(char *output, char *outend, const AVal * str);
|
||||
char *AMF_EncodeNumber(char *output, char *outend, double dVal);
|
||||
char *AMF_EncodeInt16(char *output, char *outend, short nVal);
|
||||
char *AMF_EncodeInt24(char *output, char *outend, int nVal);
|
||||
char *AMF_EncodeInt32(char *output, char *outend, int nVal);
|
||||
char *AMF_EncodeBoolean(char *output, char *outend, int bVal);
|
||||
|
||||
/* Shortcuts for AMFProp_Encode */
|
||||
char *AMF_EncodeNamedString(char *output, char *outend, const AVal * name, const AVal * value);
|
||||
char *AMF_EncodeNamedNumber(char *output, char *outend, const AVal * name, double dVal);
|
||||
char *AMF_EncodeNamedBoolean(char *output, char *outend, const AVal * name, int bVal);
|
||||
|
||||
unsigned short AMF_DecodeInt16(const char *data);
|
||||
unsigned int AMF_DecodeInt24(const char *data);
|
||||
unsigned int AMF_DecodeInt32(const char *data);
|
||||
void AMF_DecodeString(const char *data, AVal * str);
|
||||
void AMF_DecodeLongString(const char *data, AVal * str);
|
||||
int AMF_DecodeBoolean(const char *data);
|
||||
double AMF_DecodeNumber(const char *data);
|
||||
|
||||
char *AMF_Encode(AMFObject * obj, char *pBuffer, char *pBufEnd);
|
||||
char *AMF_EncodeEcmaArray(AMFObject *obj, char *pBuffer, char *pBufEnd);
|
||||
char *AMF_EncodeArray(AMFObject *obj, char *pBuffer, char *pBufEnd);
|
||||
|
||||
int AMF_Decode(AMFObject * obj, const char *pBuffer, int nSize,
|
||||
int bDecodeName);
|
||||
int AMF_DecodeArray(AMFObject * obj, const char *pBuffer, int nSize,
|
||||
int nArrayLen, int bDecodeName);
|
||||
int AMF3_Decode(AMFObject * obj, const char *pBuffer, int nSize,
|
||||
int bDecodeName);
|
||||
void AMF_Dump(AMFObject * obj);
|
||||
void AMF_Reset(AMFObject * obj);
|
||||
|
||||
void AMF_AddProp(AMFObject * obj, const AMFObjectProperty * prop);
|
||||
int AMF_CountProp(AMFObject * obj);
|
||||
AMFObjectProperty *AMF_GetProp(AMFObject * obj, const AVal * name,
|
||||
int nIndex);
|
||||
|
||||
AMFDataType AMFProp_GetType(AMFObjectProperty * prop);
|
||||
void AMFProp_SetNumber(AMFObjectProperty * prop, double dval);
|
||||
void AMFProp_SetBoolean(AMFObjectProperty * prop, int bflag);
|
||||
void AMFProp_SetString(AMFObjectProperty * prop, AVal * str);
|
||||
void AMFProp_SetObject(AMFObjectProperty * prop, AMFObject * obj);
|
||||
|
||||
void AMFProp_GetName(AMFObjectProperty * prop, AVal * name);
|
||||
void AMFProp_SetName(AMFObjectProperty * prop, AVal * name);
|
||||
double AMFProp_GetNumber(AMFObjectProperty * prop);
|
||||
int AMFProp_GetBoolean(AMFObjectProperty * prop);
|
||||
void AMFProp_GetString(AMFObjectProperty * prop, AVal * str);
|
||||
void AMFProp_GetObject(AMFObjectProperty * prop, AMFObject * obj);
|
||||
|
||||
int AMFProp_IsValid(AMFObjectProperty * prop);
|
||||
|
||||
char *AMFProp_Encode(AMFObjectProperty * prop, char *pBuffer, char *pBufEnd);
|
||||
int AMF3Prop_Decode(AMFObjectProperty * prop, const char *pBuffer,
|
||||
int nSize, int bDecodeName);
|
||||
int AMFProp_Decode(AMFObjectProperty * prop, const char *pBuffer,
|
||||
int nSize, int bDecodeName);
|
||||
|
||||
void AMFProp_Dump(AMFObjectProperty * prop);
|
||||
void AMFProp_Reset(AMFObjectProperty * prop);
|
||||
|
||||
typedef struct AMF3ClassDef
|
||||
{
|
||||
AVal cd_name;
|
||||
char cd_externalizable;
|
||||
char cd_dynamic;
|
||||
int cd_num;
|
||||
AVal *cd_props;
|
||||
} AMF3ClassDef;
|
||||
|
||||
void AMF3CD_AddProp(AMF3ClassDef * cd, AVal * prop);
|
||||
AVal *AMF3CD_GetProp(AMF3ClassDef * cd, int idx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __AMF_H__ */
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2008 Team XBMC
|
||||
* http://www.xbmc.org
|
||||
* Copyright (C) 2008-2009 Andrej Stepanchuk
|
||||
* Copyright (C) 2009-2010 Howard Chu
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#ifndef __BYTES_H__
|
||||
#define __BYTES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Windows is little endian only */
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#define __BIG_ENDIAN 4321
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#define __FLOAT_WORD_ORDER __BYTE_ORDER
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
#else /* !_WIN32 */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined(BYTE_ORDER) && !defined(__BYTE_ORDER)
|
||||
#define __BYTE_ORDER BYTE_ORDER
|
||||
#endif
|
||||
|
||||
#if defined(BIG_ENDIAN) && !defined(__BIG_ENDIAN)
|
||||
#define __BIG_ENDIAN BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined(LITTLE_ENDIAN) && !defined(__LITTLE_ENDIAN)
|
||||
#define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
/* define default endianness */
|
||||
#ifndef __LITTLE_ENDIAN
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#endif
|
||||
|
||||
#ifndef __BIG_ENDIAN
|
||||
#define __BIG_ENDIAN 4321
|
||||
#endif
|
||||
|
||||
#ifndef __BYTE_ORDER
|
||||
#warning "Byte order not defined on your system, assuming little endian!"
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
/* ok, we assume to have the same float word order and byte order if float word order is not defined */
|
||||
#ifndef __FLOAT_WORD_ORDER
|
||||
#warning "Float word order not defined, assuming the same as byte order!"
|
||||
#define __FLOAT_WORD_ORDER __BYTE_ORDER
|
||||
#endif
|
||||
|
||||
#if !defined(__BYTE_ORDER) || !defined(__FLOAT_WORD_ORDER)
|
||||
#error "Undefined byte or float word order!"
|
||||
#endif
|
||||
|
||||
#if __FLOAT_WORD_ORDER != __BIG_ENDIAN && __FLOAT_WORD_ORDER != __LITTLE_ENDIAN
|
||||
#error "Unknown/unsupported float word order!"
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER != __BIG_ENDIAN && __BYTE_ORDER != __LITTLE_ENDIAN
|
||||
#error "Unknown/unsupported byte order!"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,376 +0,0 @@
|
|||
/* RTMPDump - Diffie-Hellmann Key Exchange
|
||||
* Copyright (C) 2009 Andrej Stepanchuk
|
||||
* Copyright (C) 2009-2010 Howard Chu
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef USE_POLARSSL
|
||||
#include <polarssl/dhm.h>
|
||||
typedef mpi * MP_t;
|
||||
#define MP_new(m) m = malloc(sizeof(mpi)); mpi_init(m)
|
||||
#define MP_set_w(mpi, w) mpi_lset(mpi, w)
|
||||
#define MP_cmp(u, v) mpi_cmp_mpi(u, v)
|
||||
#define MP_set(u, v) mpi_copy(u, v)
|
||||
#define MP_sub_w(mpi, w) mpi_sub_int(mpi, mpi, w)
|
||||
#define MP_cmp_1(mpi) mpi_cmp_int(mpi, 1)
|
||||
#define MP_modexp(r, y, q, p) mpi_exp_mod(r, y, q, p, NULL)
|
||||
#define MP_free(mpi) mpi_free(mpi); free(mpi)
|
||||
#define MP_gethex(u, hex, res) MP_new(u); res = mpi_read_string(u, 16, hex) == 0
|
||||
#define MP_bytes(u) mpi_size(u)
|
||||
#define MP_setbin(u,buf,len) mpi_write_binary(u,buf,len)
|
||||
#define MP_getbin(u,buf,len) MP_new(u); mpi_read_binary(u,buf,len)
|
||||
|
||||
typedef struct MDH {
|
||||
MP_t p;
|
||||
MP_t g;
|
||||
MP_t pub_key;
|
||||
MP_t priv_key;
|
||||
long length;
|
||||
dhm_context ctx;
|
||||
} MDH;
|
||||
|
||||
#define MDH_new() calloc(1,sizeof(MDH))
|
||||
#define MDH_free(vp) {MDH *_dh = vp; dhm_free(&_dh->ctx); MP_free(_dh->p); MP_free(_dh->g); MP_free(_dh->pub_key); MP_free(_dh->priv_key); free(_dh);}
|
||||
|
||||
static int MDH_generate_key(MDH *dh)
|
||||
{
|
||||
unsigned char out[2];
|
||||
MP_set(&dh->ctx.P, dh->p);
|
||||
MP_set(&dh->ctx.G, dh->g);
|
||||
dh->ctx.len = 128;
|
||||
dhm_make_public(&dh->ctx, 1024, out, 1, havege_random, &RTMP_TLS_ctx->hs);
|
||||
MP_new(dh->pub_key);
|
||||
MP_new(dh->priv_key);
|
||||
MP_set(dh->pub_key, &dh->ctx.GX);
|
||||
MP_set(dh->priv_key, &dh->ctx.X);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh)
|
||||
{
|
||||
MP_set(&dh->ctx.GY, pub);
|
||||
dhm_calc_secret(&dh->ctx, secret, &len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(USE_GNUTLS)
|
||||
#include <gmp.h>
|
||||
#include <nettle/bignum.h>
|
||||
#include <gnutls/crypto.h>
|
||||
typedef mpz_ptr MP_t;
|
||||
#define MP_new(m) m = malloc(sizeof(*m)); mpz_init2(m, 1)
|
||||
#define MP_set_w(mpi, w) mpz_set_ui(mpi, w)
|
||||
#define MP_cmp(u, v) mpz_cmp(u, v)
|
||||
#define MP_set(u, v) mpz_set(u, v)
|
||||
#define MP_sub_w(mpi, w) mpz_sub_ui(mpi, mpi, w)
|
||||
#define MP_cmp_1(mpi) mpz_cmp_ui(mpi, 1)
|
||||
#define MP_modexp(r, y, q, p) mpz_powm(r, y, q, p)
|
||||
#define MP_free(mpi) mpz_clear(mpi); free(mpi)
|
||||
#define MP_gethex(u, hex, res) u = malloc(sizeof(*u)); mpz_init2(u, 1); res = (mpz_set_str(u, hex, 16) == 0)
|
||||
#define MP_bytes(u) (mpz_sizeinbase(u, 2) + 7) / 8
|
||||
#define MP_setbin(u,buf,len) nettle_mpz_get_str_256(len,buf,u)
|
||||
#define MP_getbin(u,buf,len) u = malloc(sizeof(*u)); mpz_init2(u, 1); nettle_mpz_set_str_256_u(u,len,buf)
|
||||
|
||||
typedef struct MDH {
|
||||
MP_t p;
|
||||
MP_t g;
|
||||
MP_t pub_key;
|
||||
MP_t priv_key;
|
||||
long length;
|
||||
} MDH;
|
||||
|
||||
#define MDH_new() calloc(1,sizeof(MDH))
|
||||
#define MDH_free(dh) do {MP_free(((MDH*)(dh))->p); MP_free(((MDH*)(dh))->g); MP_free(((MDH*)(dh))->pub_key); MP_free(((MDH*)(dh))->priv_key); free(dh);} while(0)
|
||||
|
||||
static int MDH_generate_key(MDH *dh)
|
||||
{
|
||||
int num_bytes;
|
||||
uint32_t seed;
|
||||
gmp_randstate_t rs;
|
||||
|
||||
num_bytes = (mpz_sizeinbase(dh->p, 2) + 7) / 8 - 1;
|
||||
if (num_bytes <= 0 || num_bytes > 18000)
|
||||
return 0;
|
||||
|
||||
dh->priv_key = calloc(1, sizeof(*dh->priv_key));
|
||||
if (!dh->priv_key)
|
||||
return 0;
|
||||
mpz_init2(dh->priv_key, 1);
|
||||
gnutls_rnd(GNUTLS_RND_RANDOM, &seed, sizeof(seed));
|
||||
gmp_randinit_mt(rs);
|
||||
gmp_randseed_ui(rs, seed);
|
||||
mpz_urandomb(dh->priv_key, rs, num_bytes);
|
||||
gmp_randclear(rs);
|
||||
|
||||
dh->pub_key = calloc(1, sizeof(*dh->pub_key));
|
||||
if (!dh->pub_key)
|
||||
return 0;
|
||||
mpz_init2(dh->pub_key, 1);
|
||||
if (!dh->pub_key) {
|
||||
mpz_clear(dh->priv_key);
|
||||
free(dh->priv_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mpz_powm(dh->pub_key, dh->g, dh->priv_key, dh->p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh)
|
||||
{
|
||||
mpz_ptr k;
|
||||
int num_bytes;
|
||||
|
||||
num_bytes = (mpz_sizeinbase(dh->p, 2) + 7) / 8;
|
||||
if (num_bytes <= 0 || num_bytes > 18000)
|
||||
return -1;
|
||||
|
||||
k = calloc(1, sizeof(*k));
|
||||
if (!k)
|
||||
return -1;
|
||||
mpz_init2(k, 1);
|
||||
|
||||
mpz_powm(k, pub, dh->priv_key, dh->p);
|
||||
nettle_mpz_get_str_256(len, secret, k);
|
||||
mpz_clear(k);
|
||||
free(k);
|
||||
|
||||
/* return the length of the shared secret key like DH_compute_key */
|
||||
return len;
|
||||
}
|
||||
|
||||
#else /* USE_OPENSSL */
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
typedef BIGNUM * MP_t;
|
||||
#define MP_new(m) m = BN_new()
|
||||
#define MP_set_w(mpi, w) BN_set_word(mpi, w)
|
||||
#define MP_cmp(u, v) BN_cmp(u, v)
|
||||
#define MP_set(u, v) BN_copy(u, v)
|
||||
#define MP_sub_w(mpi, w) BN_sub_word(mpi, w)
|
||||
#define MP_cmp_1(mpi) BN_cmp(mpi, BN_value_one())
|
||||
#define MP_modexp(r, y, q, p) do {BN_CTX *ctx = BN_CTX_new(); BN_mod_exp(r, y, q, p, ctx); BN_CTX_free(ctx);} while(0)
|
||||
#define MP_free(mpi) BN_free(mpi)
|
||||
#define MP_gethex(u, hex, res) res = BN_hex2bn(&u, hex)
|
||||
#define MP_bytes(u) BN_num_bytes(u)
|
||||
#define MP_setbin(u,buf,len) BN_bn2bin(u,buf)
|
||||
#define MP_getbin(u,buf,len) u = BN_bin2bn(buf,len,0)
|
||||
|
||||
#define MDH DH
|
||||
#define MDH_new() DH_new()
|
||||
#define MDH_free(dh) DH_free(dh)
|
||||
#define MDH_generate_key(dh) DH_generate_key(dh)
|
||||
#define MDH_compute_key(secret, seclen, pub, dh) DH_compute_key(secret, pub, dh)
|
||||
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "dhgroups.h"
|
||||
|
||||
/* RFC 2631, Section 2.1.5, http://www.ietf.org/rfc/rfc2631.txt */
|
||||
static int
|
||||
isValidPublicKey(MP_t y, MP_t p, MP_t q)
|
||||
{
|
||||
int ret = TRUE;
|
||||
MP_t bn;
|
||||
assert(y);
|
||||
|
||||
MP_new(bn);
|
||||
assert(bn);
|
||||
|
||||
/* y must lie in [2,p-1] */
|
||||
MP_set_w(bn, 1);
|
||||
if (MP_cmp(y, bn) < 0)
|
||||
{
|
||||
RTMP_Log(RTMP_LOGERROR, "DH public key must be at least 2");
|
||||
ret = FALSE;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* bn = p-2 */
|
||||
MP_set(bn, p);
|
||||
MP_sub_w(bn, 1);
|
||||
if (MP_cmp(y, bn) > 0)
|
||||
{
|
||||
RTMP_Log(RTMP_LOGERROR, "DH public key must be at most p-2");
|
||||
ret = FALSE;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Verify with Sophie-Germain prime
|
||||
*
|
||||
* This is a nice test to make sure the public key position is calculated
|
||||
* correctly. This test will fail in about 50% of the cases if applied to
|
||||
* random data.
|
||||
*/
|
||||
if (q)
|
||||
{
|
||||
/* y must fulfill y^q mod p = 1 */
|
||||
MP_modexp(bn, y, q, p);
|
||||
|
||||
if (MP_cmp_1(bn) != 0)
|
||||
{
|
||||
RTMP_Log(RTMP_LOGWARNING, "DH public key does not fulfill y^q mod p = 1");
|
||||
}
|
||||
}
|
||||
|
||||
failed:
|
||||
MP_free(bn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MDH *
|
||||
DHInit(int nKeyBits)
|
||||
{
|
||||
size_t res;
|
||||
MDH *dh = MDH_new();
|
||||
|
||||
if (!dh)
|
||||
goto failed;
|
||||
|
||||
MP_new(dh->g);
|
||||
|
||||
if (!dh->g)
|
||||
goto failed;
|
||||
|
||||
MP_gethex(dh->p, P1024, res); /* prime P1024, see dhgroups.h */
|
||||
if (!res)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
|
||||
MP_set_w(dh->g, 2); /* base 2 */
|
||||
|
||||
dh->length = nKeyBits;
|
||||
return dh;
|
||||
|
||||
failed:
|
||||
if (dh)
|
||||
MDH_free(dh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
DHGenerateKey(MDH *dh)
|
||||
{
|
||||
size_t res = 0;
|
||||
if (!dh)
|
||||
return 0;
|
||||
|
||||
while (!res)
|
||||
{
|
||||
MP_t q1 = NULL;
|
||||
|
||||
if (!MDH_generate_key(dh))
|
||||
return 0;
|
||||
|
||||
MP_gethex(q1, Q1024, res);
|
||||
assert(res);
|
||||
|
||||
res = isValidPublicKey(dh->pub_key, dh->p, q1);
|
||||
if (!res)
|
||||
{
|
||||
MP_free(dh->pub_key);
|
||||
MP_free(dh->priv_key);
|
||||
dh->pub_key = dh->priv_key = 0;
|
||||
}
|
||||
|
||||
MP_free(q1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* fill pubkey with the public key in BIG ENDIAN order
|
||||
* 00 00 00 00 00 x1 x2 x3 .....
|
||||
*/
|
||||
|
||||
static int
|
||||
DHGetPublicKey(MDH *dh, uint8_t *pubkey, size_t nPubkeyLen)
|
||||
{
|
||||
int len;
|
||||
if (!dh || !dh->pub_key)
|
||||
return 0;
|
||||
|
||||
len = MP_bytes(dh->pub_key);
|
||||
if (len <= 0 || len > (int) nPubkeyLen)
|
||||
return 0;
|
||||
|
||||
memset(pubkey, 0, nPubkeyLen);
|
||||
MP_setbin(dh->pub_key, pubkey + (nPubkeyLen - len), len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0 /* unused */
|
||||
static int
|
||||
DHGetPrivateKey(MDH *dh, uint8_t *privkey, size_t nPrivkeyLen)
|
||||
{
|
||||
if (!dh || !dh->priv_key)
|
||||
return 0;
|
||||
|
||||
int len = MP_bytes(dh->priv_key);
|
||||
if (len <= 0 || len > (int) nPrivkeyLen)
|
||||
return 0;
|
||||
|
||||
memset(privkey, 0, nPrivkeyLen);
|
||||
MP_setbin(dh->priv_key, privkey + (nPrivkeyLen - len), len);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* computes the shared secret key from the private MDH value and the
|
||||
* other party's public key (pubkey)
|
||||
*/
|
||||
static int
|
||||
DHComputeSharedSecretKey(MDH *dh, uint8_t *pubkey, size_t nPubkeyLen,
|
||||
uint8_t *secret)
|
||||
{
|
||||
MP_t q1 = NULL, pubkeyBn = NULL;
|
||||
size_t len;
|
||||
int res;
|
||||
|
||||
if (!dh || !secret || nPubkeyLen >= INT_MAX)
|
||||
return -1;
|
||||
|
||||
MP_getbin(pubkeyBn, pubkey, nPubkeyLen);
|
||||
if (!pubkeyBn)
|
||||
return -1;
|
||||
|
||||
MP_gethex(q1, Q1024, len);
|
||||
assert(len);
|
||||
|
||||
if (isValidPublicKey(pubkeyBn, dh->p, q1))
|
||||
res = MDH_compute_key(secret, nPubkeyLen, pubkeyBn, dh);
|
||||
else
|
||||
res = -1;
|
||||
|
||||
MP_free(q1);
|
||||
MP_free(pubkeyBn);
|
||||
|
||||
return res;
|
||||
}
|
|
@ -1,199 +0,0 @@
|
|||
/* librtmp - Diffie-Hellmann Key Exchange
|
||||
* Copyright (C) 2009 Andrej Stepanchuk
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
/* from RFC 3526, see http://www.ietf.org/rfc/rfc3526.txt */
|
||||
|
||||
/* 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 } */
|
||||
#define P768 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"
|
||||
|
||||
/* 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 } */
|
||||
#define P1024 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \
|
||||
"FFFFFFFFFFFFFFFF"
|
||||
|
||||
/* Group morder largest prime factor: */
|
||||
#define Q1024 \
|
||||
"7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68" \
|
||||
"948127044533E63A0105DF531D89CD9128A5043CC71A026E" \
|
||||
"F7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122" \
|
||||
"F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6" \
|
||||
"F71C35FDAD44CFD2D74F9208BE258FF324943328F67329C0" \
|
||||
"FFFFFFFFFFFFFFFF"
|
||||
|
||||
/* 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } */
|
||||
#define P1536 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
|
||||
"670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
|
||||
|
||||
/* 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } */
|
||||
#define P2048 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
|
||||
"15728E5A8AACAA68FFFFFFFFFFFFFFFF"
|
||||
|
||||
/* 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } */
|
||||
#define P3072 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
|
||||
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
|
||||
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
|
||||
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
|
||||
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
|
||||
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
|
||||
"43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
|
||||
|
||||
/* 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } */
|
||||
#define P4096 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
|
||||
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
|
||||
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
|
||||
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
|
||||
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
|
||||
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
|
||||
"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \
|
||||
"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \
|
||||
"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \
|
||||
"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \
|
||||
"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \
|
||||
"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" \
|
||||
"FFFFFFFFFFFFFFFF"
|
||||
|
||||
/* 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } */
|
||||
#define P6144 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
|
||||
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
|
||||
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
|
||||
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
|
||||
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
|
||||
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
|
||||
"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \
|
||||
"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \
|
||||
"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \
|
||||
"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \
|
||||
"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \
|
||||
"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" \
|
||||
"36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" \
|
||||
"F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" \
|
||||
"179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" \
|
||||
"DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" \
|
||||
"5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" \
|
||||
"D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" \
|
||||
"23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" \
|
||||
"CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" \
|
||||
"06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" \
|
||||
"DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" \
|
||||
"12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF"
|
||||
|
||||
/* 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } */
|
||||
#define P8192 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
|
||||
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
|
||||
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
|
||||
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
|
||||
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
|
||||
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
|
||||
"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \
|
||||
"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \
|
||||
"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \
|
||||
"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \
|
||||
"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \
|
||||
"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" \
|
||||
"36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" \
|
||||
"F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" \
|
||||
"179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" \
|
||||
"DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" \
|
||||
"5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" \
|
||||
"D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" \
|
||||
"23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" \
|
||||
"CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" \
|
||||
"06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" \
|
||||
"DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" \
|
||||
"12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" \
|
||||
"38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" \
|
||||
"741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" \
|
||||
"3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" \
|
||||
"22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" \
|
||||
"4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" \
|
||||
"062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" \
|
||||
"4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" \
|
||||
"B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" \
|
||||
"4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" \
|
||||
"9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" \
|
||||
"60C980DD98EDD3DFFFFFFFFFFFFFFFFF"
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,665 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2010 Howard Chu
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "rtmp_sys.h"
|
||||
#include "log.h"
|
||||
#include "http.h"
|
||||
|
||||
#ifdef CRYPTO
|
||||
#ifdef USE_POLARSSL
|
||||
#include <polarssl/sha2.h>
|
||||
#ifndef SHA256_DIGEST_LENGTH
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#endif
|
||||
#define HMAC_CTX sha2_context
|
||||
#define HMAC_setup(ctx, key, len) sha2_hmac_starts(&ctx, (unsigned char *)key, len, 0)
|
||||
#define HMAC_crunch(ctx, buf, len) sha2_hmac_update(&ctx, buf, len)
|
||||
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; sha2_hmac_finish(&ctx, dig)
|
||||
#define HMAC_close(ctx)
|
||||
#elif defined(USE_GNUTLS)
|
||||
#include <nettle/hmac.h>
|
||||
#ifndef SHA256_DIGEST_LENGTH
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#endif
|
||||
#undef HMAC_CTX
|
||||
#define HMAC_CTX struct hmac_sha256_ctx
|
||||
#define HMAC_setup(ctx, key, len) hmac_sha256_set_key(&ctx, len, key)
|
||||
#define HMAC_crunch(ctx, buf, len) hmac_sha256_update(&ctx, len, buf)
|
||||
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; hmac_sha256_digest(&ctx, SHA256_DIGEST_LENGTH, dig)
|
||||
#define HMAC_close(ctx)
|
||||
#else /* USE_OPENSSL */
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/rc4.h>
|
||||
#define HMAC_setup(ctx, key, len) HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, (unsigned char *)key, len, EVP_sha256(), 0)
|
||||
#define HMAC_crunch(ctx, buf, len) HMAC_Update(&ctx, (unsigned char *)buf, len)
|
||||
#define HMAC_finish(ctx, dig, dlen) HMAC_Final(&ctx, (unsigned char *)dig, &dlen);
|
||||
#define HMAC_close(ctx) HMAC_CTX_cleanup(&ctx)
|
||||
#endif
|
||||
|
||||
extern void RTMP_TLS_Init();
|
||||
extern TLS_CTX RTMP_TLS_ctx;
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#endif /* CRYPTO */
|
||||
|
||||
#define AGENT "Mozilla/5.0"
|
||||
|
||||
HTTPResult
|
||||
HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb)
|
||||
{
|
||||
char *host, *path;
|
||||
char *p1, *p2;
|
||||
char hbuf[256];
|
||||
int port = 80;
|
||||
#ifdef CRYPTO
|
||||
int ssl = 0;
|
||||
#endif
|
||||
int hlen, flen = 0;
|
||||
int rc, i;
|
||||
int len_known;
|
||||
HTTPResult ret = HTTPRES_OK;
|
||||
struct sockaddr_in sa;
|
||||
RTMPSockBuf sb = {0};
|
||||
|
||||
http->status = -1;
|
||||
|
||||
memset(&sa, 0, sizeof(struct sockaddr_in));
|
||||
sa.sin_family = AF_INET;
|
||||
|
||||
/* we only handle http here */
|
||||
if (strncasecmp(url, "http", 4))
|
||||
return HTTPRES_BAD_REQUEST;
|
||||
|
||||
if (url[4] == 's')
|
||||
{
|
||||
#ifdef CRYPTO
|
||||
ssl = 1;
|
||||
port = 443;
|
||||
if (!RTMP_TLS_ctx)
|
||||
RTMP_TLS_Init();
|
||||
#else
|
||||
return HTTPRES_BAD_REQUEST;
|
||||
#endif
|
||||
}
|
||||
|
||||
p1 = strchr(url + 4, ':');
|
||||
if (!p1 || strncmp(p1, "://", 3))
|
||||
return HTTPRES_BAD_REQUEST;
|
||||
|
||||
host = p1 + 3;
|
||||
path = strchr(host, '/');
|
||||
hlen = path - host;
|
||||
strncpy(hbuf, host, hlen);
|
||||
hbuf[hlen] = '\0';
|
||||
host = hbuf;
|
||||
p1 = strrchr(host, ':');
|
||||
if (p1)
|
||||
{
|
||||
*p1++ = '\0';
|
||||
port = atoi(p1);
|
||||
}
|
||||
|
||||
sa.sin_addr.s_addr = inet_addr(host);
|
||||
if (sa.sin_addr.s_addr == INADDR_NONE)
|
||||
{
|
||||
struct hostent *hp = gethostbyname(host);
|
||||
if (!hp || !hp->h_addr)
|
||||
return HTTPRES_LOST_CONNECTION;
|
||||
sa.sin_addr = *(struct in_addr *)hp->h_addr;
|
||||
}
|
||||
sa.sin_port = htons(port);
|
||||
sb.sb_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sb.sb_socket == -1)
|
||||
return HTTPRES_LOST_CONNECTION;
|
||||
i =
|
||||
sprintf(sb.sb_buf,
|
||||
"GET %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\nReferer: %.*s\r\n",
|
||||
path, AGENT, host, (int)(path - url + 1), url);
|
||||
if (http->date[0])
|
||||
i += sprintf(sb.sb_buf + i, "If-Modified-Since: %s\r\n", http->date);
|
||||
i += sprintf(sb.sb_buf + i, "\r\n");
|
||||
|
||||
if (connect
|
||||
(sb.sb_socket, (struct sockaddr *)&sa, sizeof(struct sockaddr)) < 0)
|
||||
{
|
||||
ret = HTTPRES_LOST_CONNECTION;
|
||||
goto leave;
|
||||
}
|
||||
#ifdef CRYPTO
|
||||
if (ssl)
|
||||
{
|
||||
#ifdef NO_SSL
|
||||
RTMP_Log(RTMP_LOGERROR, "%s, No SSL/TLS support", __FUNCTION__);
|
||||
ret = HTTPRES_BAD_REQUEST;
|
||||
goto leave;
|
||||
#else
|
||||
TLS_client(RTMP_TLS_ctx, sb.sb_ssl);
|
||||
TLS_setfd(sb.sb_ssl, sb.sb_socket);
|
||||
if (TLS_connect(sb.sb_ssl) < 0)
|
||||
{
|
||||
RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
|
||||
ret = HTTPRES_LOST_CONNECTION;
|
||||
goto leave;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
RTMPSockBuf_Send(&sb, sb.sb_buf, i);
|
||||
|
||||
/* set timeout */
|
||||
#define HTTP_TIMEOUT 5
|
||||
{
|
||||
SET_RCVTIMEO(tv, HTTP_TIMEOUT);
|
||||
if (setsockopt
|
||||
(sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)))
|
||||
{
|
||||
RTMP_Log(RTMP_LOGERROR, "%s, Setting socket timeout to %ds failed!",
|
||||
__FUNCTION__, HTTP_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
sb.sb_size = 0;
|
||||
sb.sb_timedout = FALSE;
|
||||
if (RTMPSockBuf_Fill(&sb) < 1)
|
||||
{
|
||||
ret = HTTPRES_LOST_CONNECTION;
|
||||
goto leave;
|
||||
}
|
||||
if (strncmp(sb.sb_buf, "HTTP/1", 6))
|
||||
{
|
||||
ret = HTTPRES_BAD_REQUEST;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
p1 = strchr(sb.sb_buf, ' ');
|
||||
rc = atoi(p1 + 1);
|
||||
http->status = rc;
|
||||
|
||||
if (rc >= 300)
|
||||
{
|
||||
if (rc == 304)
|
||||
{
|
||||
ret = HTTPRES_OK_NOT_MODIFIED;
|
||||
goto leave;
|
||||
}
|
||||
else if (rc == 404)
|
||||
ret = HTTPRES_NOT_FOUND;
|
||||
else if (rc >= 500)
|
||||
ret = HTTPRES_SERVER_ERROR;
|
||||
else if (rc >= 400)
|
||||
ret = HTTPRES_BAD_REQUEST;
|
||||
else
|
||||
ret = HTTPRES_REDIRECTED;
|
||||
}
|
||||
|
||||
p1 = memchr(sb.sb_buf, '\n', sb.sb_size);
|
||||
if (!p1)
|
||||
{
|
||||
ret = HTTPRES_BAD_REQUEST;
|
||||
goto leave;
|
||||
}
|
||||
sb.sb_start = p1 + 1;
|
||||
sb.sb_size -= sb.sb_start - sb.sb_buf;
|
||||
|
||||
while ((p2 = memchr(sb.sb_start, '\r', sb.sb_size)))
|
||||
{
|
||||
if (*sb.sb_start == '\r')
|
||||
{
|
||||
sb.sb_start += 2;
|
||||
sb.sb_size -= 2;
|
||||
break;
|
||||
}
|
||||
else
|
||||
if (!strncasecmp
|
||||
(sb.sb_start, "Content-Length: ", sizeof("Content-Length: ") - 1))
|
||||
{
|
||||
flen = atoi(sb.sb_start + sizeof("Content-Length: ") - 1);
|
||||
}
|
||||
else
|
||||
if (!strncasecmp
|
||||
(sb.sb_start, "Last-Modified: ", sizeof("Last-Modified: ") - 1))
|
||||
{
|
||||
*p2 = '\0';
|
||||
strcpy(http->date, sb.sb_start + sizeof("Last-Modified: ") - 1);
|
||||
}
|
||||
p2 += 2;
|
||||
sb.sb_size -= p2 - sb.sb_start;
|
||||
sb.sb_start = p2;
|
||||
if (sb.sb_size < 1)
|
||||
{
|
||||
if (RTMPSockBuf_Fill(&sb) < 1)
|
||||
{
|
||||
ret = HTTPRES_LOST_CONNECTION;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len_known = flen > 0;
|
||||
while ((!len_known || flen > 0) &&
|
||||
(sb.sb_size > 0 || RTMPSockBuf_Fill(&sb) > 0))
|
||||
{
|
||||
cb(sb.sb_start, 1, sb.sb_size, http->data);
|
||||
if (len_known)
|
||||
flen -= sb.sb_size;
|
||||
http->size += sb.sb_size;
|
||||
sb.sb_size = 0;
|
||||
}
|
||||
|
||||
if (flen > 0)
|
||||
ret = HTTPRES_LOST_CONNECTION;
|
||||
|
||||
leave:
|
||||
RTMPSockBuf_Close(&sb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CRYPTO
|
||||
|
||||
#define CHUNK 16384
|
||||
|
||||
struct info
|
||||
{
|
||||
z_stream *zs;
|
||||
HMAC_CTX ctx;
|
||||
int first;
|
||||
int zlib;
|
||||
int size;
|
||||
};
|
||||
|
||||
static size_t
|
||||
swfcrunch(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
struct info *i = stream;
|
||||
char *p = ptr;
|
||||
size_t len = size * nmemb;
|
||||
|
||||
if (i->first)
|
||||
{
|
||||
i->first = 0;
|
||||
/* compressed? */
|
||||
if (!strncmp(p, "CWS", 3))
|
||||
{
|
||||
*p = 'F';
|
||||
i->zlib = 1;
|
||||
}
|
||||
HMAC_crunch(i->ctx, (unsigned char *)p, 8);
|
||||
p += 8;
|
||||
len -= 8;
|
||||
i->size = 8;
|
||||
}
|
||||
|
||||
if (i->zlib)
|
||||
{
|
||||
unsigned char out[CHUNK];
|
||||
i->zs->next_in = (unsigned char *)p;
|
||||
i->zs->avail_in = len;
|
||||
do
|
||||
{
|
||||
i->zs->avail_out = CHUNK;
|
||||
i->zs->next_out = out;
|
||||
inflate(i->zs, Z_NO_FLUSH);
|
||||
len = CHUNK - i->zs->avail_out;
|
||||
i->size += len;
|
||||
HMAC_crunch(i->ctx, out, len);
|
||||
}
|
||||
while (i->zs->avail_out == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
i->size += len;
|
||||
HMAC_crunch(i->ctx, (unsigned char *)p, len);
|
||||
}
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
static int tzoff;
|
||||
static int tzchecked;
|
||||
|
||||
#define JAN02_1980 318340800
|
||||
|
||||
static const char *monthtab[12] = { "Jan", "Feb", "Mar",
|
||||
"Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep",
|
||||
"Oct", "Nov", "Dec"
|
||||
};
|
||||
static const char *days[] =
|
||||
{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
|
||||
/* Parse an HTTP datestamp into Unix time */
|
||||
static time_t
|
||||
make_unix_time(char *s)
|
||||
{
|
||||
struct tm time;
|
||||
int i, ysub = 1900, fmt = 0;
|
||||
char *month;
|
||||
char *n;
|
||||
time_t res;
|
||||
|
||||
if (s[3] != ' ')
|
||||
{
|
||||
fmt = 1;
|
||||
if (s[3] != ',')
|
||||
ysub = 0;
|
||||
}
|
||||
for (n = s; *n; ++n)
|
||||
if (*n == '-' || *n == ':')
|
||||
*n = ' ';
|
||||
|
||||
time.tm_mon = 0;
|
||||
n = strchr(s, ' ');
|
||||
if (fmt)
|
||||
{
|
||||
/* Day, DD-MMM-YYYY HH:MM:SS GMT */
|
||||
time.tm_mday = strtol(n + 1, &n, 0);
|
||||
month = n + 1;
|
||||
n = strchr(month, ' ');
|
||||
time.tm_year = strtol(n + 1, &n, 0);
|
||||
time.tm_hour = strtol(n + 1, &n, 0);
|
||||
time.tm_min = strtol(n + 1, &n, 0);
|
||||
time.tm_sec = strtol(n + 1, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unix ctime() format. Does not conform to HTTP spec. */
|
||||
/* Day MMM DD HH:MM:SS YYYY */
|
||||
month = n + 1;
|
||||
n = strchr(month, ' ');
|
||||
while (isspace(*n))
|
||||
n++;
|
||||
time.tm_mday = strtol(n, &n, 0);
|
||||
time.tm_hour = strtol(n + 1, &n, 0);
|
||||
time.tm_min = strtol(n + 1, &n, 0);
|
||||
time.tm_sec = strtol(n + 1, &n, 0);
|
||||
time.tm_year = strtol(n + 1, NULL, 0);
|
||||
}
|
||||
if (time.tm_year > 100)
|
||||
time.tm_year -= ysub;
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
if (!strncasecmp(month, monthtab[i], 3))
|
||||
{
|
||||
time.tm_mon = i;
|
||||
break;
|
||||
}
|
||||
time.tm_isdst = 0; /* daylight saving is never in effect in GMT */
|
||||
|
||||
/* this is normally the value of extern int timezone, but some
|
||||
* braindead C libraries don't provide it.
|
||||
*/
|
||||
if (!tzchecked)
|
||||
{
|
||||
struct tm *tc;
|
||||
time_t then = JAN02_1980;
|
||||
tc = localtime(&then);
|
||||
tzoff = (12 - tc->tm_hour) * 3600 + tc->tm_min * 60 + tc->tm_sec;
|
||||
tzchecked = 1;
|
||||
}
|
||||
res = mktime(&time);
|
||||
/* Unfortunately, mktime() assumes the input is in local time,
|
||||
* not GMT, so we have to correct it here.
|
||||
*/
|
||||
if (res != -1)
|
||||
res += tzoff;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Convert a Unix time to a network time string
|
||||
* Weekday, DD-MMM-YYYY HH:MM:SS GMT
|
||||
*/
|
||||
static void
|
||||
strtime(time_t * t, char *s)
|
||||
{
|
||||
struct tm *tm;
|
||||
|
||||
tm = gmtime((time_t *) t);
|
||||
sprintf(s, "%s, %02d %s %d %02d:%02d:%02d GMT",
|
||||
days[tm->tm_wday], tm->tm_mday, monthtab[tm->tm_mon],
|
||||
tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
|
||||
#define HEX2BIN(a) (((a)&0x40)?((a)&0xf)+9:((a)&0xf))
|
||||
|
||||
int
|
||||
RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
|
||||
int age)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
char *path, date[64], cctim[64];
|
||||
long pos = 0;
|
||||
time_t ctim = -1, cnow;
|
||||
int i, got = 0, ret = 0;
|
||||
unsigned int hlen;
|
||||
struct info in = { 0 };
|
||||
struct HTTP_ctx http = { 0 };
|
||||
HTTPResult httpres;
|
||||
z_stream zs = { 0 };
|
||||
AVal home, hpre;
|
||||
|
||||
date[0] = '\0';
|
||||
#ifdef _WIN32
|
||||
#ifdef XBMC4XBOX
|
||||
hpre.av_val = "Q:";
|
||||
hpre.av_len = 2;
|
||||
home.av_val = "\\UserData";
|
||||
#else
|
||||
hpre.av_val = getenv("HOMEDRIVE");
|
||||
hpre.av_len = strlen(hpre.av_val);
|
||||
home.av_val = getenv("HOMEPATH");
|
||||
#endif
|
||||
#define DIRSEP "\\"
|
||||
|
||||
#else /* !_WIN32 */
|
||||
hpre.av_val = "";
|
||||
hpre.av_len = 0;
|
||||
home.av_val = getenv("HOME");
|
||||
#define DIRSEP "/"
|
||||
#endif
|
||||
if (!home.av_val)
|
||||
home.av_val = ".";
|
||||
home.av_len = strlen(home.av_val);
|
||||
|
||||
/* SWF hash info is cached in a fixed-format file.
|
||||
* url: <url of SWF file>
|
||||
* ctim: HTTP datestamp of when we last checked it.
|
||||
* date: HTTP datestamp of the SWF's last modification.
|
||||
* size: SWF size in hex
|
||||
* hash: SWF hash in hex
|
||||
*
|
||||
* These fields must be present in this order. All fields
|
||||
* besides URL are fixed size.
|
||||
*/
|
||||
path = malloc(hpre.av_len + home.av_len + sizeof(DIRSEP ".swfinfo"));
|
||||
sprintf(path, "%s%s" DIRSEP ".swfinfo", hpre.av_val, home.av_val);
|
||||
|
||||
f = fopen(path, "r+");
|
||||
while (f)
|
||||
{
|
||||
char buf[4096], *file, *p;
|
||||
|
||||
file = strchr(url, '/');
|
||||
if (!file)
|
||||
break;
|
||||
file += 2;
|
||||
file = strchr(file, '/');
|
||||
if (!file)
|
||||
break;
|
||||
file++;
|
||||
hlen = file - url;
|
||||
p = strrchr(file, '/');
|
||||
if (p)
|
||||
file = p;
|
||||
else
|
||||
file--;
|
||||
|
||||
while (fgets(buf, sizeof(buf), f))
|
||||
{
|
||||
char *r1;
|
||||
|
||||
got = 0;
|
||||
|
||||
if (strncmp(buf, "url: ", 5))
|
||||
continue;
|
||||
if (strncmp(buf + 5, url, hlen))
|
||||
continue;
|
||||
r1 = strrchr(buf, '/');
|
||||
i = strlen(r1);
|
||||
r1[--i] = '\0';
|
||||
if (strncmp(r1, file, i))
|
||||
continue;
|
||||
pos = ftell(f);
|
||||
while (got < 4 && fgets(buf, sizeof(buf), f))
|
||||
{
|
||||
if (!strncmp(buf, "size: ", 6))
|
||||
{
|
||||
*size = strtol(buf + 6, NULL, 16);
|
||||
got++;
|
||||
}
|
||||
else if (!strncmp(buf, "hash: ", 6))
|
||||
{
|
||||
unsigned char *ptr = hash, *in = (unsigned char *)buf + 6;
|
||||
int l = strlen((char *)in) - 1;
|
||||
for (i = 0; i < l; i += 2)
|
||||
*ptr++ = (HEX2BIN(in[i]) << 4) | HEX2BIN(in[i + 1]);
|
||||
got++;
|
||||
}
|
||||
else if (!strncmp(buf, "date: ", 6))
|
||||
{
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
strncpy(date, buf + 6, sizeof(date));
|
||||
got++;
|
||||
}
|
||||
else if (!strncmp(buf, "ctim: ", 6))
|
||||
{
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
ctim = make_unix_time(buf + 6);
|
||||
got++;
|
||||
}
|
||||
else if (!strncmp(buf, "url: ", 5))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cnow = time(NULL);
|
||||
/* If we got a cache time, see if it's young enough to use directly */
|
||||
if (age && ctim > 0)
|
||||
{
|
||||
ctim = cnow - ctim;
|
||||
ctim /= 3600 * 24; /* seconds to days */
|
||||
if (ctim < age) /* ok, it's new enough */
|
||||
goto out;
|
||||
}
|
||||
|
||||
in.first = 1;
|
||||
HMAC_setup(in.ctx, "Genuine Adobe Flash Player 001", 30);
|
||||
inflateInit(&zs);
|
||||
in.zs = &zs;
|
||||
|
||||
http.date = date;
|
||||
http.data = ∈
|
||||
|
||||
httpres = HTTP_get(&http, url, swfcrunch);
|
||||
|
||||
inflateEnd(&zs);
|
||||
|
||||
if (httpres != HTTPRES_OK && httpres != HTTPRES_OK_NOT_MODIFIED)
|
||||
{
|
||||
ret = -1;
|
||||
if (httpres == HTTPRES_LOST_CONNECTION)
|
||||
RTMP_Log(RTMP_LOGERROR, "%s: connection lost while downloading swfurl %s",
|
||||
__FUNCTION__, url);
|
||||
else if (httpres == HTTPRES_NOT_FOUND)
|
||||
RTMP_Log(RTMP_LOGERROR, "%s: swfurl %s not found", __FUNCTION__, url);
|
||||
else
|
||||
RTMP_Log(RTMP_LOGERROR, "%s: couldn't contact swfurl %s (HTTP error %d)",
|
||||
__FUNCTION__, url, http.status);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (got && pos)
|
||||
fseek(f, pos, SEEK_SET);
|
||||
else
|
||||
{
|
||||
char *q;
|
||||
if (!f)
|
||||
f = fopen(path, "w");
|
||||
if (!f)
|
||||
{
|
||||
int err = errno;
|
||||
RTMP_Log(RTMP_LOGERROR,
|
||||
"%s: couldn't open %s for writing, errno %d (%s)",
|
||||
__FUNCTION__, path, err, strerror(err));
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
fseek(f, 0, SEEK_END);
|
||||
q = strchr(url, '?');
|
||||
if (q)
|
||||
i = q - url;
|
||||
else
|
||||
i = strlen(url);
|
||||
|
||||
fprintf(f, "url: %.*s\n", i, url);
|
||||
}
|
||||
strtime(&cnow, cctim);
|
||||
fprintf(f, "ctim: %s\n", cctim);
|
||||
|
||||
if (!in.first)
|
||||
{
|
||||
HMAC_finish(in.ctx, hash, hlen);
|
||||
*size = in.size;
|
||||
|
||||
fprintf(f, "date: %s\n", date);
|
||||
fprintf(f, "size: %08x\n", in.size);
|
||||
fprintf(f, "hash: ");
|
||||
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
|
||||
fprintf(f, "%02x", hash[i]);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
HMAC_close(in.ctx);
|
||||
out:
|
||||
free(path);
|
||||
if (f)
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int
|
||||
RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
|
||||
int age)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
|
@ -1,47 +0,0 @@
|
|||
#ifndef __RTMP_HTTP_H__
|
||||
#define __RTMP_HTTP_H__
|
||||
/*
|
||||
* Copyright (C) 2010 Howard Chu
|
||||
* Copyright (C) 2010 Antti Ajanki
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
HTTPRES_OK, /* result OK */
|
||||
HTTPRES_OK_NOT_MODIFIED, /* not modified since last request */
|
||||
HTTPRES_NOT_FOUND, /* not found */
|
||||
HTTPRES_BAD_REQUEST, /* client error */
|
||||
HTTPRES_SERVER_ERROR, /* server reported an error */
|
||||
HTTPRES_REDIRECTED, /* resource has been moved */
|
||||
HTTPRES_LOST_CONNECTION /* connection lost while waiting for data */
|
||||
} HTTPResult;
|
||||
|
||||
struct HTTP_ctx {
|
||||
char *date;
|
||||
int size;
|
||||
int status;
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef size_t (HTTP_read_callback)(void *ptr, size_t size, size_t nmemb, void *stream);
|
||||
|
||||
HTTPResult HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb);
|
||||
|
||||
#endif
|
|
@ -1,210 +0,0 @@
|
|||
.TH LIBRTMP 3 "2011-07-20" "RTMPDump v2.4"
|
||||
.\" Copyright 2011 Howard Chu.
|
||||
.\" Copying permitted according to the GNU General Public License V2.
|
||||
.SH NAME
|
||||
librtmp \- RTMPDump Real-Time Messaging Protocol API
|
||||
.SH LIBRARY
|
||||
RTMPDump RTMP (librtmp, -lrtmp)
|
||||
.SH SYNOPSIS
|
||||
.B #include <librtmp/rtmp.h>
|
||||
.SH DESCRIPTION
|
||||
The Real-Time Messaging Protocol (RTMP) is used for streaming
|
||||
multimedia content across a TCP/IP network. This API provides most client
|
||||
functions and a few server functions needed to support RTMP, RTMP tunneled
|
||||
in HTTP (RTMPT), encrypted RTMP (RTMPE), RTMP over SSL/TLS (RTMPS) and
|
||||
tunneled variants of these encrypted types (RTMPTE, RTMPTS). The basic
|
||||
RTMP specification has been published by Adobe but this API was
|
||||
reverse-engineered without use of the Adobe specification. As such, it may
|
||||
deviate from any published specifications but it usually duplicates the
|
||||
actual behavior of the original Adobe clients.
|
||||
|
||||
The RTMPDump software package includes a basic client utility program
|
||||
in
|
||||
.BR rtmpdump (1),
|
||||
some sample servers, and a library used to provide programmatic access
|
||||
to the RTMP protocol. This man page gives an overview of the RTMP
|
||||
library routines. These routines are found in the -lrtmp library. Many
|
||||
other routines are also available, but they are not documented yet.
|
||||
|
||||
The basic interaction is as follows. A session handle is created using
|
||||
.BR RTMP_Alloc ()
|
||||
and initialized using
|
||||
.BR RTMP_Init ().
|
||||
All session parameters are provided using
|
||||
.BR RTMP_SetupURL ().
|
||||
The network connection is established using
|
||||
.BR RTMP_Connect (),
|
||||
and then the RTMP session is established using
|
||||
.BR RTMP_ConnectStream ().
|
||||
The stream is read using
|
||||
.BR RTMP_Read ().
|
||||
A client can publish a stream by calling
|
||||
.BR RTMP_EnableWrite ()
|
||||
before the
|
||||
.BR RTMP_Connect ()
|
||||
call, and then using
|
||||
.BR RTMP_Write ()
|
||||
after the session is established.
|
||||
While a stream is playing it may be paused and unpaused using
|
||||
.BR RTMP_Pause ().
|
||||
The stream playback position can be moved using
|
||||
.BR RTMP_Seek ().
|
||||
When
|
||||
.BR RTMP_Read ()
|
||||
returns 0 bytes, the stream is complete and may be closed using
|
||||
.BR RTMP_Close ().
|
||||
The session handle is freed using
|
||||
.BR RTMP_Free ().
|
||||
|
||||
All data is transferred using FLV format. The basic session requires
|
||||
an RTMP URL. The RTMP URL format is of the form
|
||||
.nf
|
||||
rtmp[t][e|s]://hostname[:port][/app[/playpath]]
|
||||
.fi
|
||||
|
||||
Plain rtmp, as well as tunneled and encrypted sessions are supported.
|
||||
|
||||
Additional options may be specified by appending space-separated
|
||||
key=value pairs to the URL. Special characters in values may need
|
||||
to be escaped to prevent misinterpretation by the option parser.
|
||||
The escape encoding uses a backslash followed by two hexadecimal digits
|
||||
representing the ASCII value of the character. E.g., spaces must
|
||||
be escaped as \fB\\20\fP and backslashes must be escaped as \fB\\5c\fP.
|
||||
.SH OPTIONS
|
||||
.SS "Network Parameters"
|
||||
These options define how to connect to the media server.
|
||||
.TP
|
||||
.BI socks= host:port
|
||||
Use the specified SOCKS4 proxy.
|
||||
.SS "Connection Parameters"
|
||||
These options define the content of the RTMP Connect request packet.
|
||||
If correct values are not provided, the media server will reject the
|
||||
connection attempt.
|
||||
.TP
|
||||
.BI app= name
|
||||
Name of application to connect to on the RTMP server. Overrides
|
||||
the app in the RTMP URL. Sometimes the librtmp URL parser cannot
|
||||
determine the app name automatically, so it must be given explicitly
|
||||
using this option.
|
||||
.TP
|
||||
.BI tcUrl= url
|
||||
URL of the target stream. Defaults to rtmp[t][e|s]://host[:port]/app.
|
||||
.TP
|
||||
.BI pageUrl= url
|
||||
URL of the web page in which the media was embedded. By default no
|
||||
value will be sent.
|
||||
.TP
|
||||
.BI swfUrl= url
|
||||
URL of the SWF player for the media. By default no value will be sent.
|
||||
.TP
|
||||
.BI flashVer= version
|
||||
Version of the Flash plugin used to run the SWF player. The
|
||||
default is "LNX 10,0,32,18".
|
||||
.TP
|
||||
.BI conn= type:data
|
||||
Append arbitrary AMF data to the Connect message. The type
|
||||
must be B for Boolean, N for number, S for string, O for object, or Z
|
||||
for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE,
|
||||
respectively. Likewise for Objects the data must be 0 or 1 to end or
|
||||
begin an object, respectively. Data items in subobjects may be named, by
|
||||
prefixing the type with 'N' and specifying the name before the value, e.g.
|
||||
NB:myFlag:1. This option may be used multiple times to construct arbitrary
|
||||
AMF sequences. E.g.
|
||||
.nf
|
||||
conn=B:1 conn=S:authMe conn=O:1 conn=NN:code:1.23 conn=NS:flag:ok conn=O:0
|
||||
.fi
|
||||
.SS "Session Parameters"
|
||||
These options take effect after the Connect request has succeeded.
|
||||
.TP
|
||||
.BI playpath= path
|
||||
Overrides the playpath parsed from the RTMP URL. Sometimes the
|
||||
rtmpdump URL parser cannot determine the correct playpath
|
||||
automatically, so it must be given explicitly using this option.
|
||||
.TP
|
||||
.BI playlist= 0|1
|
||||
If the value is 1 or TRUE, issue a set_playlist command before sending the
|
||||
play command. The playlist will just contain the current playpath. If the
|
||||
value is 0 or FALSE, the set_playlist command will not be sent. The
|
||||
default is FALSE.
|
||||
.TP
|
||||
.BI live= 0|1
|
||||
Specify that the media is a live stream. No resuming or seeking in
|
||||
live streams is possible.
|
||||
.TP
|
||||
.BI subscribe= path
|
||||
Name of live stream to subscribe to. Defaults to
|
||||
.IR playpath .
|
||||
.TP
|
||||
.BI start= num
|
||||
Start at
|
||||
.I num
|
||||
seconds into the stream. Not valid for live streams.
|
||||
.TP
|
||||
.BI stop= num
|
||||
Stop at
|
||||
.I num
|
||||
seconds into the stream.
|
||||
.TP
|
||||
.BI buffer= num
|
||||
Set buffer time to
|
||||
.I num
|
||||
milliseconds. The default is 30000.
|
||||
.TP
|
||||
.BI timeout= num
|
||||
Timeout the session after
|
||||
.I num
|
||||
seconds without receiving any data from the server. The default is 120.
|
||||
.SS "Security Parameters"
|
||||
These options handle additional authentication requests from the server.
|
||||
.TP
|
||||
.BI token= key
|
||||
Key for SecureToken response, used if the server requires SecureToken
|
||||
authentication.
|
||||
.TP
|
||||
.BI jtv= JSON
|
||||
JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
|
||||
.TP
|
||||
.BI swfVfy= 0|1
|
||||
If the value is 1 or TRUE, the SWF player is retrieved from the
|
||||
specified
|
||||
.I swfUrl
|
||||
for performing SWF Verification. The SWF hash and size (used in the
|
||||
verification step) are computed automatically. Also the SWF information is
|
||||
cached in a
|
||||
.I .swfinfo
|
||||
file in the user's home directory, so that it doesn't need to be retrieved
|
||||
and recalculated every time. The .swfinfo file records
|
||||
the SWF URL, the time it was fetched, the modification timestamp of the SWF
|
||||
file, its size, and its hash. By default, the cached info will be used
|
||||
for 30 days before re-checking.
|
||||
.TP
|
||||
.BI swfAge= days
|
||||
Specify how many days to use the cached SWF info before re-checking. Use
|
||||
0 to always check the SWF URL. Note that if the check shows that the
|
||||
SWF file has the same modification timestamp as before, it will not be
|
||||
retrieved again.
|
||||
.SH EXAMPLES
|
||||
An example character string suitable for use with
|
||||
.BR RTMP_SetupURL ():
|
||||
.nf
|
||||
"rtmp://flashserver:1935/ondemand/thefile swfUrl=http://flashserver/player.swf swfVfy=1"
|
||||
.fi
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B HOME
|
||||
The value of
|
||||
.RB $ HOME
|
||||
is used as the location for the
|
||||
.I .swfinfo
|
||||
file.
|
||||
.SH FILES
|
||||
.TP
|
||||
.I $HOME/.swfinfo
|
||||
Cache of SWF Verification information
|
||||
.SH "SEE ALSO"
|
||||
.BR rtmpdump (1),
|
||||
.BR rtmpgw (8)
|
||||
.SH AUTHORS
|
||||
Andrej Stepanchuk, Howard Chu, The Flvstreamer Team
|
||||
.br
|
||||
<http://rtmpdump.mplayerhq.hu>
|
|
@ -1,312 +0,0 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<title>LIBRTMP(3): </title></head>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><td>LIBRTMP(3)<td align="center"><td align="right">LIBRTMP(3)
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr><td>RTMPDump v2.4<td align="center">2011-07-20<td align="right">LIBRTMP(3)
|
||||
</tfoot>
|
||||
<tbody><tr><td colspan="3"><br><br><ul>
|
||||
<!-- Copyright 2011 Howard Chu.
|
||||
Copying permitted according to the GNU General Public License V2.-->
|
||||
</ul>
|
||||
|
||||
<h3>NAME</h3><ul>
|
||||
librtmp − RTMPDump Real-Time Messaging Protocol API
|
||||
</ul>
|
||||
|
||||
<h3>LIBRARY</h3><ul>
|
||||
RTMPDump RTMP (librtmp, -lrtmp)
|
||||
</ul>
|
||||
|
||||
<h3>SYNOPSIS</h3><ul>
|
||||
<b>#include <librtmp/rtmp.h></b>
|
||||
</ul>
|
||||
|
||||
<h3>DESCRIPTION</h3><ul>
|
||||
The Real-Time Messaging Protocol (RTMP) is used for streaming
|
||||
multimedia content across a TCP/IP network. This API provides most client
|
||||
functions and a few server functions needed to support RTMP, RTMP tunneled
|
||||
in HTTP (RTMPT), encrypted RTMP (RTMPE), RTMP over SSL/TLS (RTMPS) and
|
||||
tunneled variants of these encrypted types (RTMPTE, RTMPTS). The basic
|
||||
RTMP specification has been published by Adobe but this API was
|
||||
reverse-engineered without use of the Adobe specification. As such, it may
|
||||
deviate from any published specifications but it usually duplicates the
|
||||
actual behavior of the original Adobe clients.
|
||||
<p>
|
||||
The RTMPDump software package includes a basic client utility program
|
||||
in
|
||||
<a href="../man1/rtmpdump.1"><b>rtmpdump</b></a>(1),
|
||||
some sample servers, and a library used to provide programmatic access
|
||||
to the RTMP protocol. This man page gives an overview of the RTMP
|
||||
library routines. These routines are found in the -lrtmp library. Many
|
||||
other routines are also available, but they are not documented yet.
|
||||
<p>
|
||||
The basic interaction is as follows. A session handle is created using
|
||||
<b>RTMP_Alloc</b>()
|
||||
and initialized using
|
||||
<b>RTMP_Init</b>().
|
||||
All session parameters are provided using
|
||||
<b>RTMP_SetupURL</b>().
|
||||
The network connection is established using
|
||||
<b>RTMP_Connect</b>(),
|
||||
and then the RTMP session is established using
|
||||
<b>RTMP_ConnectStream</b>().
|
||||
The stream is read using
|
||||
<b>RTMP_Read</b>().
|
||||
A client can publish a stream by calling
|
||||
<b>RTMP_EnableWrite</b>()
|
||||
before the
|
||||
<b>RTMP_Connect</b>()
|
||||
call, and then using
|
||||
<b>RTMP_Write</b>()
|
||||
after the session is established.
|
||||
While a stream is playing it may be paused and unpaused using
|
||||
<b>RTMP_Pause</b>().
|
||||
The stream playback position can be moved using
|
||||
<b>RTMP_Seek</b>().
|
||||
When
|
||||
<b>RTMP_Read</b>()
|
||||
returns 0 bytes, the stream is complete and may be closed using
|
||||
<b>RTMP_Close</b>().
|
||||
The session handle is freed using
|
||||
<b>RTMP_Free</b>().
|
||||
<p>
|
||||
All data is transferred using FLV format. The basic session requires
|
||||
an RTMP URL. The RTMP URL format is of the form
|
||||
<pre>
|
||||
rtmp[t][e|s]://hostname[:port][/app[/playpath]]
|
||||
</pre>
|
||||
<p>
|
||||
Plain rtmp, as well as tunneled and encrypted sessions are supported.
|
||||
<p>
|
||||
Additional options may be specified by appending space-separated
|
||||
key=value pairs to the URL. Special characters in values may need
|
||||
to be escaped to prevent misinterpretation by the option parser.
|
||||
The escape encoding uses a backslash followed by two hexadecimal digits
|
||||
representing the ASCII value of the character. E.g., spaces must
|
||||
be escaped as <b>\20</b> and backslashes must be escaped as <b>\5c</b>.
|
||||
</ul>
|
||||
|
||||
<h3>OPTIONS</h3><ul>
|
||||
</ul>
|
||||
|
||||
<h4>Network Parameters</h4><ul>
|
||||
These options define how to connect to the media server.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>socks=</b><i>host:port</i>
|
||||
<dd>
|
||||
Use the specified SOCKS4 proxy.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Connection Parameters</h4><ul>
|
||||
These options define the content of the RTMP Connect request packet.
|
||||
If correct values are not provided, the media server will reject the
|
||||
connection attempt.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>app=</b><i>name</i>
|
||||
<dd>
|
||||
Name of application to connect to on the RTMP server. Overrides
|
||||
the app in the RTMP URL. Sometimes the librtmp URL parser cannot
|
||||
determine the app name automatically, so it must be given explicitly
|
||||
using this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>tcUrl=</b><i>url</i>
|
||||
<dd>
|
||||
URL of the target stream. Defaults to rtmp[t][e|s]://host[:port]/app.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>pageUrl=</b><i>url</i>
|
||||
<dd>
|
||||
URL of the web page in which the media was embedded. By default no
|
||||
value will be sent.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>swfUrl=</b><i>url</i>
|
||||
<dd>
|
||||
URL of the SWF player for the media. By default no value will be sent.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>flashVer=</b><i>version</i>
|
||||
<dd>
|
||||
Version of the Flash plugin used to run the SWF player. The
|
||||
default is "LNX 10,0,32,18".
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>conn=</b><i>type:data</i>
|
||||
<dd>
|
||||
Append arbitrary AMF data to the Connect message. The type
|
||||
must be B for Boolean, N for number, S for string, O for object, or Z
|
||||
for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE,
|
||||
respectively. Likewise for Objects the data must be 0 or 1 to end or
|
||||
begin an object, respectively. Data items in subobjects may be named, by
|
||||
prefixing the type with 'N' and specifying the name before the value, e.g.
|
||||
NB:myFlag:1. This option may be used multiple times to construct arbitrary
|
||||
AMF sequences. E.g.
|
||||
<pre>
|
||||
conn=B:1 conn=S:authMe conn=O:1 conn=NN:code:1.23 conn=NS:flag:ok conn=O:0
|
||||
</pre>
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Session Parameters</h4><ul>
|
||||
These options take effect after the Connect request has succeeded.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>playpath=</b><i>path</i>
|
||||
<dd>
|
||||
Overrides the playpath parsed from the RTMP URL. Sometimes the
|
||||
rtmpdump URL parser cannot determine the correct playpath
|
||||
automatically, so it must be given explicitly using this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>playlist=</b><i>0|1</i>
|
||||
<dd>
|
||||
If the value is 1 or TRUE, issue a set_playlist command before sending the
|
||||
play command. The playlist will just contain the current playpath. If the
|
||||
value is 0 or FALSE, the set_playlist command will not be sent. The
|
||||
default is FALSE.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>live=</b><i>0|1</i>
|
||||
<dd>
|
||||
Specify that the media is a live stream. No resuming or seeking in
|
||||
live streams is possible.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>subscribe=</b><i>path</i>
|
||||
<dd>
|
||||
Name of live stream to subscribe to. Defaults to
|
||||
<i>playpath</i>.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>start=</b><i>num</i>
|
||||
<dd>
|
||||
Start at
|
||||
<i>num</i>
|
||||
seconds into the stream. Not valid for live streams.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>stop=</b><i>num</i>
|
||||
<dd>
|
||||
Stop at
|
||||
<i>num</i>
|
||||
seconds into the stream.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>buffer=</b><i>num</i>
|
||||
<dd>
|
||||
Set buffer time to
|
||||
<i>num</i>
|
||||
milliseconds. The default is 30000.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>timeout=</b><i>num</i>
|
||||
<dd>
|
||||
Timeout the session after
|
||||
<i>num</i>
|
||||
seconds without receiving any data from the server. The default is 120.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Security Parameters</h4><ul>
|
||||
These options handle additional authentication requests from the server.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>token=</b><i>key</i>
|
||||
<dd>
|
||||
Key for SecureToken response, used if the server requires SecureToken
|
||||
authentication.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>jtv=</b><i>JSON</i>
|
||||
<dd>
|
||||
JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>swfVfy=</b><i>0|1</i>
|
||||
<dd>
|
||||
If the value is 1 or TRUE, the SWF player is retrieved from the
|
||||
specified
|
||||
<i>swfUrl</i>
|
||||
for performing SWF Verification. The SWF hash and size (used in the
|
||||
verification step) are computed automatically. Also the SWF information is
|
||||
cached in a
|
||||
<i>.swfinfo</i>
|
||||
file in the user's home directory, so that it doesn't need to be retrieved
|
||||
and recalculated every time. The .swfinfo file records
|
||||
the SWF URL, the time it was fetched, the modification timestamp of the SWF
|
||||
file, its size, and its hash. By default, the cached info will be used
|
||||
for 30 days before re-checking.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>swfAge=</b><i>days</i>
|
||||
<dd>
|
||||
Specify how many days to use the cached SWF info before re-checking. Use
|
||||
0 to always check the SWF URL. Note that if the check shows that the
|
||||
SWF file has the same modification timestamp as before, it will not be
|
||||
retrieved again.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>EXAMPLES</h3><ul>
|
||||
An example character string suitable for use with
|
||||
<b>RTMP_SetupURL</b>():
|
||||
<pre>
|
||||
"rtmp://flashserver:1935/ondemand/thefile swfUrl=<a href="http://flashserver/player.swf">http://flashserver/player.swf</a> swfVfy=1"
|
||||
</pre>
|
||||
</ul>
|
||||
|
||||
<h3>ENVIRONMENT</h3><ul>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>HOME</b>
|
||||
<dd>
|
||||
The value of
|
||||
$<b>HOME</b>
|
||||
is used as the location for the
|
||||
<i>.swfinfo</i>
|
||||
file.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>FILES</h3><ul>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<i>$HOME/.swfinfo</i>
|
||||
<dd>
|
||||
Cache of SWF Verification information
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>SEE ALSO</h3><ul>
|
||||
<a href="../man1/rtmpdump.1"><b>rtmpdump</b></a>(1),
|
||||
<a href="../man8/rtmpgw.8"><b>rtmpgw</b></a>(8)
|
||||
</ul>
|
||||
|
||||
<h3>AUTHORS</h3><ul>
|
||||
Andrej Stepanchuk, Howard Chu, The Flvstreamer Team
|
||||
<br>
|
||||
<<a href="http://rtmpdump.mplayerhq.hu">http://rtmpdump.mplayerhq.hu</a>>
|
||||
</ul></tbody></table></html>
|
|
@ -1,13 +0,0 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=${prefix}
|
||||
libdir=@libdir@
|
||||
incdir=${prefix}/include
|
||||
|
||||
Name: librtmp
|
||||
Description: RTMP implementation
|
||||
Version: @VERSION@
|
||||
Requires: @CRYPTO_REQ@
|
||||
URL: http://rtmpdump.mplayerhq.hu
|
||||
Libs: -L${libdir} -lrtmp -lz @PUBLIC_LIBS@
|
||||
Libs.private: @PRIVATE_LIBS@
|
||||
Cflags: -I${incdir}
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 Andrej Stepanchuk
|
||||
* Copyright (C) 2009-2010 Howard Chu
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "rtmp_sys.h"
|
||||
#include "log.h"
|
||||
|
||||
#define MAX_PRINT_LEN 2048
|
||||
|
||||
RTMP_LogLevel RTMP_debuglevel = RTMP_LOGERROR;
|
||||
|
||||
static int neednl;
|
||||
|
||||
static FILE *fmsg;
|
||||
|
||||
static RTMP_LogCallback rtmp_log_default, *cb = rtmp_log_default;
|
||||
|
||||
static const char *levels[] = {
|
||||
"CRIT", "ERROR", "WARNING", "INFO",
|
||||
"DEBUG", "DEBUG2"
|
||||
};
|
||||
|
||||
static void rtmp_log_default(int level, const char *format, va_list vl)
|
||||
{
|
||||
char str[MAX_PRINT_LEN]="";
|
||||
|
||||
vsnprintf(str, MAX_PRINT_LEN-1, format, vl);
|
||||
|
||||
/* Filter out 'no-name' */
|
||||
if ( RTMP_debuglevel<RTMP_LOGALL && strstr(str, "no-name" ) != NULL )
|
||||
return;
|
||||
|
||||
if ( !fmsg ) fmsg = stderr;
|
||||
|
||||
if ( level <= RTMP_debuglevel ) {
|
||||
if (neednl) {
|
||||
putc('\n', fmsg);
|
||||
neednl = 0;
|
||||
}
|
||||
fprintf(fmsg, "%s: %s\n", levels[level], str);
|
||||
#ifdef _DEBUG
|
||||
fflush(fmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void RTMP_LogSetOutput(FILE *file)
|
||||
{
|
||||
fmsg = file;
|
||||
}
|
||||
|
||||
void RTMP_LogSetLevel(RTMP_LogLevel level)
|
||||
{
|
||||
RTMP_debuglevel = level;
|
||||
}
|
||||
|
||||
void RTMP_LogSetCallback(RTMP_LogCallback *cbp)
|
||||
{
|
||||
cb = cbp;
|
||||
}
|
||||
|
||||
RTMP_LogLevel RTMP_LogGetLevel()
|
||||
{
|
||||
return RTMP_debuglevel;
|
||||
}
|
||||
|
||||
void RTMP_Log(int level, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if ( level > RTMP_debuglevel )
|
||||
return;
|
||||
|
||||
va_start(args, format);
|
||||
cb(level, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static const char hexdig[] = "0123456789abcdef";
|
||||
|
||||
void RTMP_LogHex(int level, const uint8_t *data, unsigned long len)
|
||||
{
|
||||
unsigned long i;
|
||||
char line[50], *ptr;
|
||||
|
||||
if ( level > RTMP_debuglevel )
|
||||
return;
|
||||
|
||||
ptr = line;
|
||||
|
||||
for(i=0; i<len; i++) {
|
||||
*ptr++ = hexdig[0x0f & (data[i] >> 4)];
|
||||
*ptr++ = hexdig[0x0f & data[i]];
|
||||
if ((i & 0x0f) == 0x0f) {
|
||||
*ptr = '\0';
|
||||
ptr = line;
|
||||
RTMP_Log(level, "%s", line);
|
||||
} else {
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
}
|
||||
if (i & 0x0f) {
|
||||
*ptr = '\0';
|
||||
RTMP_Log(level, "%s", line);
|
||||
}
|
||||
}
|
||||
|
||||
void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len)
|
||||
{
|
||||
#define BP_OFFSET 9
|
||||
#define BP_GRAPH 60
|
||||
#define BP_LEN 80
|
||||
char line[BP_LEN];
|
||||
unsigned long i;
|
||||
|
||||
if ( !data || level > RTMP_debuglevel )
|
||||
return;
|
||||
|
||||
/* in case len is zero */
|
||||
line[0] = '\0';
|
||||
|
||||
for ( i = 0 ; i < len ; i++ ) {
|
||||
int n = i % 16;
|
||||
unsigned off;
|
||||
|
||||
if( !n ) {
|
||||
if( i ) RTMP_Log( level, "%s", line );
|
||||
memset( line, ' ', sizeof(line)-2 );
|
||||
line[sizeof(line)-2] = '\0';
|
||||
|
||||
off = i % 0x0ffffU;
|
||||
|
||||
line[2] = hexdig[0x0f & (off >> 12)];
|
||||
line[3] = hexdig[0x0f & (off >> 8)];
|
||||
line[4] = hexdig[0x0f & (off >> 4)];
|
||||
line[5] = hexdig[0x0f & off];
|
||||
line[6] = ':';
|
||||
}
|
||||
|
||||
off = BP_OFFSET + n*3 + ((n >= 8)?1:0);
|
||||
line[off] = hexdig[0x0f & ( data[i] >> 4 )];
|
||||
line[off+1] = hexdig[0x0f & data[i]];
|
||||
|
||||
off = BP_GRAPH + n + ((n >= 8)?1:0);
|
||||
|
||||
if ( isprint( data[i] )) {
|
||||
line[BP_GRAPH + n] = data[i];
|
||||
} else {
|
||||
line[BP_GRAPH + n] = '.';
|
||||
}
|
||||
}
|
||||
|
||||
RTMP_Log( level, "%s", line );
|
||||
}
|
||||
|
||||
/* These should only be used by apps, never by the library itself */
|
||||
void RTMP_LogPrintf(const char *format, ...)
|
||||
{
|
||||
char str[MAX_PRINT_LEN]="";
|
||||
int len;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
len = vsnprintf(str, MAX_PRINT_LEN-1, format, args);
|
||||
va_end(args);
|
||||
|
||||
if ( RTMP_debuglevel==RTMP_LOGCRIT )
|
||||
return;
|
||||
|
||||
if ( !fmsg ) fmsg = stderr;
|
||||
|
||||
if (neednl) {
|
||||
putc('\n', fmsg);
|
||||
neednl = 0;
|
||||
}
|
||||
|
||||
if (len > MAX_PRINT_LEN-1)
|
||||
len = MAX_PRINT_LEN-1;
|
||||
fprintf(fmsg, "%s", str);
|
||||
if (str[len-1] == '\n')
|
||||
fflush(fmsg);
|
||||
}
|
||||
|
||||
void RTMP_LogStatus(const char *format, ...)
|
||||
{
|
||||
char str[MAX_PRINT_LEN]="";
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(str, MAX_PRINT_LEN-1, format, args);
|
||||
va_end(args);
|
||||
|
||||
if ( RTMP_debuglevel==RTMP_LOGCRIT )
|
||||
return;
|
||||
|
||||
if ( !fmsg ) fmsg = stderr;
|
||||
|
||||
fprintf(fmsg, "%s", str);
|
||||
fflush(fmsg);
|
||||
neednl = 1;
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 Andrej Stepanchuk
|
||||
* Copyright (C) 2009-2010 Howard Chu
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#ifndef __RTMP_LOG_H__
|
||||
#define __RTMP_LOG_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Enable this to get full debugging output */
|
||||
/* #define _DEBUG */
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef NODEBUG
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{ RTMP_LOGCRIT=0, RTMP_LOGERROR, RTMP_LOGWARNING, RTMP_LOGINFO,
|
||||
RTMP_LOGDEBUG, RTMP_LOGDEBUG2, RTMP_LOGALL
|
||||
} RTMP_LogLevel;
|
||||
|
||||
extern RTMP_LogLevel RTMP_debuglevel;
|
||||
|
||||
typedef void (RTMP_LogCallback)(int level, const char *fmt, va_list);
|
||||
void RTMP_LogSetCallback(RTMP_LogCallback *cb);
|
||||
void RTMP_LogSetOutput(FILE *file);
|
||||
#ifdef __GNUC__
|
||||
void RTMP_LogPrintf(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
void RTMP_LogStatus(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
void RTMP_Log(int level, const char *format, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
#else
|
||||
void RTMP_LogPrintf(const char *format, ...);
|
||||
void RTMP_LogStatus(const char *format, ...);
|
||||
void RTMP_Log(int level, const char *format, ...);
|
||||
#endif
|
||||
void RTMP_LogHex(int level, const uint8_t *data, unsigned long len);
|
||||
void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len);
|
||||
void RTMP_LogSetLevel(RTMP_LogLevel lvl);
|
||||
RTMP_LogLevel RTMP_LogGetLevel(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,289 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Andrej Stepanchuk
|
||||
* Copyright (C) 2009-2010 Howard Chu
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "rtmp_sys.h"
|
||||
#include "log.h"
|
||||
|
||||
int RTMP_ParseURL(const char *url, int *protocol, AVal *host, unsigned int *port,
|
||||
AVal *playpath, AVal *app)
|
||||
{
|
||||
char *p, *end, *col, *ques, *slash;
|
||||
|
||||
RTMP_Log(RTMP_LOGDEBUG, "Parsing...");
|
||||
|
||||
*protocol = RTMP_PROTOCOL_RTMP;
|
||||
*port = 0;
|
||||
playpath->av_len = 0;
|
||||
playpath->av_val = NULL;
|
||||
app->av_len = 0;
|
||||
app->av_val = NULL;
|
||||
|
||||
/* Old School Parsing */
|
||||
|
||||
/* look for usual :// pattern */
|
||||
p = strstr(url, "://");
|
||||
if(!p) {
|
||||
RTMP_Log(RTMP_LOGERROR, "RTMP URL: No :// in url!");
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
int len = (int)(p-url);
|
||||
|
||||
if(len == 4 && strncasecmp(url, "rtmp", 4)==0)
|
||||
*protocol = RTMP_PROTOCOL_RTMP;
|
||||
else if(len == 5 && strncasecmp(url, "rtmpt", 5)==0)
|
||||
*protocol = RTMP_PROTOCOL_RTMPT;
|
||||
else if(len == 5 && strncasecmp(url, "rtmps", 5)==0)
|
||||
*protocol = RTMP_PROTOCOL_RTMPS;
|
||||
else if(len == 5 && strncasecmp(url, "rtmpe", 5)==0)
|
||||
*protocol = RTMP_PROTOCOL_RTMPE;
|
||||
else if(len == 5 && strncasecmp(url, "rtmfp", 5)==0)
|
||||
*protocol = RTMP_PROTOCOL_RTMFP;
|
||||
else if(len == 6 && strncasecmp(url, "rtmpte", 6)==0)
|
||||
*protocol = RTMP_PROTOCOL_RTMPTE;
|
||||
else if(len == 6 && strncasecmp(url, "rtmpts", 6)==0)
|
||||
*protocol = RTMP_PROTOCOL_RTMPTS;
|
||||
else {
|
||||
RTMP_Log(RTMP_LOGWARNING, "Unknown protocol!\n");
|
||||
goto parsehost;
|
||||
}
|
||||
}
|
||||
|
||||
RTMP_Log(RTMP_LOGDEBUG, "Parsed protocol: %d", *protocol);
|
||||
|
||||
parsehost:
|
||||
/* let's get the hostname */
|
||||
p+=3;
|
||||
|
||||
/* check for sudden death */
|
||||
if(*p==0) {
|
||||
RTMP_Log(RTMP_LOGWARNING, "No hostname in URL!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
end = p + strlen(p);
|
||||
col = strchr(p, ':');
|
||||
ques = strchr(p, '?');
|
||||
slash = strchr(p, '/');
|
||||
|
||||
{
|
||||
int hostlen;
|
||||
if(slash)
|
||||
hostlen = slash - p;
|
||||
else
|
||||
hostlen = end - p;
|
||||
if(col && col -p < hostlen)
|
||||
hostlen = col - p;
|
||||
|
||||
if(hostlen < 256) {
|
||||
host->av_val = p;
|
||||
host->av_len = hostlen;
|
||||
RTMP_Log(RTMP_LOGDEBUG, "Parsed host : %.*s", hostlen, host->av_val);
|
||||
} else {
|
||||
RTMP_Log(RTMP_LOGWARNING, "Hostname exceeds 255 characters!");
|
||||
}
|
||||
|
||||
p+=hostlen;
|
||||
}
|
||||
|
||||
/* get the port number if available */
|
||||
if(*p == ':') {
|
||||
unsigned int p2;
|
||||
p++;
|
||||
p2 = atoi(p);
|
||||
if(p2 > 65535) {
|
||||
RTMP_Log(RTMP_LOGWARNING, "Invalid port number!");
|
||||
} else {
|
||||
*port = p2;
|
||||
}
|
||||
}
|
||||
|
||||
if(!slash) {
|
||||
RTMP_Log(RTMP_LOGWARNING, "No application or playpath in URL!");
|
||||
return TRUE;
|
||||
}
|
||||
p = slash+1;
|
||||
|
||||
{
|
||||
/* parse application
|
||||
*
|
||||
* rtmp://host[:port]/app[/appinstance][/...]
|
||||
* application = app[/appinstance]
|
||||
*/
|
||||
|
||||
char *slash2, *slash3 = NULL, *slash4 = NULL;
|
||||
int applen, appnamelen;
|
||||
|
||||
slash2 = strchr(p, '/');
|
||||
if(slash2)
|
||||
slash3 = strchr(slash2+1, '/');
|
||||
if(slash3)
|
||||
slash4 = strchr(slash3+1, '/');
|
||||
|
||||
applen = end-p; /* ondemand, pass all parameters as app */
|
||||
appnamelen = applen; /* ondemand length */
|
||||
|
||||
if(ques && strstr(p, "slist=")) { /* whatever it is, the '?' and slist= means we need to use everything as app and parse plapath from slist= */
|
||||
appnamelen = ques-p;
|
||||
}
|
||||
else if(strncmp(p, "ondemand/", 9)==0) {
|
||||
/* app = ondemand/foobar, only pass app=ondemand */
|
||||
applen = 8;
|
||||
appnamelen = 8;
|
||||
}
|
||||
else { /* app!=ondemand, so app is app[/appinstance] */
|
||||
if(slash4)
|
||||
appnamelen = slash4-p;
|
||||
else if(slash3)
|
||||
appnamelen = slash3-p;
|
||||
else if(slash2)
|
||||
appnamelen = slash2-p;
|
||||
|
||||
applen = appnamelen;
|
||||
}
|
||||
|
||||
app->av_val = p;
|
||||
app->av_len = applen;
|
||||
RTMP_Log(RTMP_LOGDEBUG, "Parsed app : %.*s", applen, p);
|
||||
|
||||
p += appnamelen;
|
||||
}
|
||||
|
||||
if (*p == '/')
|
||||
p++;
|
||||
|
||||
if (end-p) {
|
||||
AVal av = {p, end-p};
|
||||
RTMP_ParsePlaypath(&av, playpath);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extracts playpath from RTMP URL. playpath is the file part of the
|
||||
* URL, i.e. the part that comes after rtmp://host:port/app/
|
||||
*
|
||||
* Returns the stream name in a format understood by FMS. The name is
|
||||
* the playpath part of the URL with formatting depending on the stream
|
||||
* type:
|
||||
*
|
||||
* mp4 streams: prepend "mp4:", remove extension
|
||||
* mp3 streams: prepend "mp3:", remove extension
|
||||
* flv streams: remove extension
|
||||
*/
|
||||
void RTMP_ParsePlaypath(AVal *in, AVal *out) {
|
||||
int addMP4 = 0;
|
||||
int addMP3 = 0;
|
||||
int subExt = 0;
|
||||
const char *playpath = in->av_val;
|
||||
const char *temp, *q, *ext = NULL;
|
||||
const char *ppstart = playpath;
|
||||
char *streamname, *destptr, *p;
|
||||
|
||||
int pplen = in->av_len;
|
||||
|
||||
out->av_val = NULL;
|
||||
out->av_len = 0;
|
||||
|
||||
if ((*ppstart == '?') &&
|
||||
(temp=strstr(ppstart, "slist=")) != 0) {
|
||||
ppstart = temp+6;
|
||||
pplen = strlen(ppstart);
|
||||
|
||||
temp = strchr(ppstart, '&');
|
||||
if (temp) {
|
||||
pplen = temp-ppstart;
|
||||
}
|
||||
}
|
||||
|
||||
q = strchr(ppstart, '?');
|
||||
if (pplen >= 4) {
|
||||
if (q)
|
||||
ext = q-4;
|
||||
else
|
||||
ext = &ppstart[pplen-4];
|
||||
if ((strncmp(ext, ".f4v", 4) == 0) ||
|
||||
(strncmp(ext, ".mp4", 4) == 0)) {
|
||||
addMP4 = 1;
|
||||
subExt = 1;
|
||||
/* Only remove .flv from rtmp URL, not slist params */
|
||||
} else if ((ppstart == playpath) &&
|
||||
(strncmp(ext, ".flv", 4) == 0)) {
|
||||
subExt = 1;
|
||||
} else if (strncmp(ext, ".mp3", 4) == 0) {
|
||||
addMP3 = 1;
|
||||
subExt = 1;
|
||||
}
|
||||
}
|
||||
|
||||
streamname = (char *)malloc((pplen+4+1)*sizeof(char));
|
||||
if (!streamname)
|
||||
return;
|
||||
|
||||
destptr = streamname;
|
||||
if (addMP4) {
|
||||
if (strncmp(ppstart, "mp4:", 4)) {
|
||||
strcpy(destptr, "mp4:");
|
||||
destptr += 4;
|
||||
} else {
|
||||
subExt = 0;
|
||||
}
|
||||
} else if (addMP3) {
|
||||
if (strncmp(ppstart, "mp3:", 4)) {
|
||||
strcpy(destptr, "mp3:");
|
||||
destptr += 4;
|
||||
} else {
|
||||
subExt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (p=(char *)ppstart; pplen >0;) {
|
||||
/* skip extension */
|
||||
if (subExt && p == ext) {
|
||||
p += 4;
|
||||
pplen -= 4;
|
||||
continue;
|
||||
}
|
||||
if (*p == '%') {
|
||||
unsigned int c;
|
||||
sscanf(p+1, "%02x", &c);
|
||||
*destptr++ = c;
|
||||
pplen -= 3;
|
||||
p += 3;
|
||||
} else {
|
||||
*destptr++ = *p++;
|
||||
pplen--;
|
||||
}
|
||||
}
|
||||
*destptr = '\0';
|
||||
|
||||
out->av_val = streamname;
|
||||
out->av_len = destptr - streamname;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,401 +0,0 @@
|
|||
#ifndef __RTMP_H__
|
||||
#define __RTMP_H__
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Team XBMC
|
||||
* http://www.xbmc.org
|
||||
* Copyright (C) 2008-2009 Andrej Stepanchuk
|
||||
* Copyright (C) 2009-2010 Howard Chu
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#if !defined(NO_CRYPTO) && !defined(CRYPTO)
|
||||
#define CRYPTO
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "amf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define RTMP_LIB_VERSION 0x020300 /* 2.3 */
|
||||
|
||||
#define RTMP_FEATURE_HTTP 0x01
|
||||
#define RTMP_FEATURE_ENC 0x02
|
||||
#define RTMP_FEATURE_SSL 0x04
|
||||
#define RTMP_FEATURE_MFP 0x08 /* not yet supported */
|
||||
#define RTMP_FEATURE_WRITE 0x10 /* publish, not play */
|
||||
#define RTMP_FEATURE_HTTP2 0x20 /* server-side rtmpt */
|
||||
|
||||
#define RTMP_PROTOCOL_UNDEFINED -1
|
||||
#define RTMP_PROTOCOL_RTMP 0
|
||||
#define RTMP_PROTOCOL_RTMPE RTMP_FEATURE_ENC
|
||||
#define RTMP_PROTOCOL_RTMPT RTMP_FEATURE_HTTP
|
||||
#define RTMP_PROTOCOL_RTMPS RTMP_FEATURE_SSL
|
||||
#define RTMP_PROTOCOL_RTMPTE (RTMP_FEATURE_HTTP|RTMP_FEATURE_ENC)
|
||||
#define RTMP_PROTOCOL_RTMPTS (RTMP_FEATURE_HTTP|RTMP_FEATURE_SSL)
|
||||
#define RTMP_PROTOCOL_RTMFP RTMP_FEATURE_MFP
|
||||
|
||||
#define RTMP_DEFAULT_CHUNKSIZE 128
|
||||
|
||||
/* needs to fit largest number of bytes recv() may return */
|
||||
#define RTMP_BUFFER_CACHE_SIZE (16*1024)
|
||||
|
||||
#define RTMP_CHANNELS 65600
|
||||
|
||||
extern const char RTMPProtocolStringsLower[][7];
|
||||
extern const AVal RTMP_DefaultFlashVer;
|
||||
extern int RTMP_ctrlC;
|
||||
|
||||
uint32_t RTMP_GetTime(void);
|
||||
|
||||
/* RTMP_PACKET_TYPE_... 0x00 */
|
||||
#define RTMP_PACKET_TYPE_CHUNK_SIZE 0x01
|
||||
/* RTMP_PACKET_TYPE_... 0x02 */
|
||||
#define RTMP_PACKET_TYPE_BYTES_READ_REPORT 0x03
|
||||
#define RTMP_PACKET_TYPE_CONTROL 0x04
|
||||
#define RTMP_PACKET_TYPE_SERVER_BW 0x05
|
||||
#define RTMP_PACKET_TYPE_CLIENT_BW 0x06
|
||||
/* RTMP_PACKET_TYPE_... 0x07 */
|
||||
#define RTMP_PACKET_TYPE_AUDIO 0x08
|
||||
#define RTMP_PACKET_TYPE_VIDEO 0x09
|
||||
/* RTMP_PACKET_TYPE_... 0x0A */
|
||||
/* RTMP_PACKET_TYPE_... 0x0B */
|
||||
/* RTMP_PACKET_TYPE_... 0x0C */
|
||||
/* RTMP_PACKET_TYPE_... 0x0D */
|
||||
/* RTMP_PACKET_TYPE_... 0x0E */
|
||||
#define RTMP_PACKET_TYPE_FLEX_STREAM_SEND 0x0F
|
||||
#define RTMP_PACKET_TYPE_FLEX_SHARED_OBJECT 0x10
|
||||
#define RTMP_PACKET_TYPE_FLEX_MESSAGE 0x11
|
||||
#define RTMP_PACKET_TYPE_INFO 0x12
|
||||
#define RTMP_PACKET_TYPE_SHARED_OBJECT 0x13
|
||||
#define RTMP_PACKET_TYPE_INVOKE 0x14
|
||||
/* RTMP_PACKET_TYPE_... 0x15 */
|
||||
#define RTMP_PACKET_TYPE_FLASH_VIDEO 0x16
|
||||
|
||||
#define RTMP_MAX_HEADER_SIZE 18
|
||||
|
||||
#define RTMP_PACKET_SIZE_LARGE 0
|
||||
#define RTMP_PACKET_SIZE_MEDIUM 1
|
||||
#define RTMP_PACKET_SIZE_SMALL 2
|
||||
#define RTMP_PACKET_SIZE_MINIMUM 3
|
||||
|
||||
typedef struct RTMPChunk
|
||||
{
|
||||
int c_headerSize;
|
||||
int c_chunkSize;
|
||||
char *c_chunk;
|
||||
char c_header[RTMP_MAX_HEADER_SIZE];
|
||||
} RTMPChunk;
|
||||
|
||||
typedef struct RTMPPacket
|
||||
{
|
||||
uint8_t m_headerType;
|
||||
uint8_t m_packetType;
|
||||
uint8_t m_hasAbsTimestamp; /* timestamp absolute or relative? */
|
||||
int m_nChannel;
|
||||
uint32_t m_nTimeStamp; /* timestamp */
|
||||
int32_t m_nInfoField2; /* last 4 bytes in a long header */
|
||||
uint32_t m_nBodySize;
|
||||
uint32_t m_nBytesRead;
|
||||
RTMPChunk *m_chunk;
|
||||
char *m_body;
|
||||
} RTMPPacket;
|
||||
|
||||
typedef struct RTMPSockBuf
|
||||
{
|
||||
int sb_socket;
|
||||
int sb_size; /* number of unprocessed bytes in buffer */
|
||||
char *sb_start; /* pointer into sb_pBuffer of next byte to process */
|
||||
char sb_buf[RTMP_BUFFER_CACHE_SIZE]; /* data read from socket */
|
||||
int sb_timedout;
|
||||
void *sb_ssl;
|
||||
} RTMPSockBuf;
|
||||
|
||||
void RTMPPacket_Reset(RTMPPacket *p);
|
||||
void RTMPPacket_Dump(RTMPPacket *p);
|
||||
int RTMPPacket_Alloc(RTMPPacket *p, uint32_t nSize);
|
||||
void RTMPPacket_Free(RTMPPacket *p);
|
||||
|
||||
#define RTMPPacket_IsReady(a) ((a)->m_nBytesRead == (a)->m_nBodySize)
|
||||
|
||||
typedef struct RTMP_LNK
|
||||
{
|
||||
AVal hostname;
|
||||
AVal sockshost;
|
||||
|
||||
AVal playpath0; /* parsed from URL */
|
||||
AVal playpath; /* passed in explicitly */
|
||||
AVal tcUrl;
|
||||
AVal swfUrl;
|
||||
AVal pageUrl;
|
||||
AVal app;
|
||||
AVal auth;
|
||||
AVal flashVer;
|
||||
AVal subscribepath;
|
||||
AVal usherToken;
|
||||
AVal token;
|
||||
AVal pubUser;
|
||||
AVal pubPasswd;
|
||||
AMFObject extras;
|
||||
int edepth;
|
||||
|
||||
int seekTime;
|
||||
int stopTime;
|
||||
|
||||
#define RTMP_LF_AUTH 0x0001 /* using auth param */
|
||||
#define RTMP_LF_LIVE 0x0002 /* stream is live */
|
||||
#define RTMP_LF_SWFV 0x0004 /* do SWF verification */
|
||||
#define RTMP_LF_PLST 0x0008 /* send playlist before play */
|
||||
#define RTMP_LF_BUFX 0x0010 /* toggle stream on BufferEmpty msg */
|
||||
#define RTMP_LF_FTCU 0x0020 /* free tcUrl on close */
|
||||
#define RTMP_LF_FAPU 0x0040 /* free app on close */
|
||||
int lFlags;
|
||||
|
||||
int swfAge;
|
||||
|
||||
int protocol;
|
||||
int timeout; /* connection timeout in seconds */
|
||||
|
||||
int pFlags; /* unused, but kept to avoid breaking ABI */
|
||||
|
||||
unsigned short socksport;
|
||||
unsigned short port;
|
||||
|
||||
#ifdef CRYPTO
|
||||
#define RTMP_SWF_HASHLEN 32
|
||||
void *dh; /* for encryption */
|
||||
void *rc4keyIn;
|
||||
void *rc4keyOut;
|
||||
|
||||
uint32_t SWFSize;
|
||||
uint8_t SWFHash[RTMP_SWF_HASHLEN];
|
||||
char SWFVerificationResponse[RTMP_SWF_HASHLEN+10];
|
||||
#endif
|
||||
} RTMP_LNK;
|
||||
|
||||
/* state for read() wrapper */
|
||||
typedef struct RTMP_READ
|
||||
{
|
||||
char *buf;
|
||||
char *bufpos;
|
||||
unsigned int buflen;
|
||||
uint32_t timestamp;
|
||||
uint8_t dataType;
|
||||
uint8_t flags;
|
||||
#define RTMP_READ_HEADER 0x01
|
||||
#define RTMP_READ_RESUME 0x02
|
||||
#define RTMP_READ_NO_IGNORE 0x04
|
||||
#define RTMP_READ_GOTKF 0x08
|
||||
#define RTMP_READ_GOTFLVK 0x10
|
||||
#define RTMP_READ_SEEKING 0x20
|
||||
int8_t status;
|
||||
#define RTMP_READ_COMPLETE -3
|
||||
#define RTMP_READ_ERROR -2
|
||||
#define RTMP_READ_EOF -1
|
||||
#define RTMP_READ_IGNORE 0
|
||||
|
||||
/* if bResume == TRUE */
|
||||
uint8_t initialFrameType;
|
||||
uint32_t nResumeTS;
|
||||
char *metaHeader;
|
||||
char *initialFrame;
|
||||
uint32_t nMetaHeaderSize;
|
||||
uint32_t nInitialFrameSize;
|
||||
uint32_t nIgnoredFrameCounter;
|
||||
uint32_t nIgnoredFlvFrameCounter;
|
||||
} RTMP_READ;
|
||||
|
||||
typedef struct RTMP_METHOD
|
||||
{
|
||||
AVal name;
|
||||
int num;
|
||||
} RTMP_METHOD;
|
||||
|
||||
typedef struct RTMP
|
||||
{
|
||||
int m_inChunkSize;
|
||||
int m_outChunkSize;
|
||||
int m_nBWCheckCounter;
|
||||
int m_nBytesIn;
|
||||
int m_nBytesInSent;
|
||||
int m_nBufferMS;
|
||||
int m_stream_id; /* returned in _result from createStream */
|
||||
int m_mediaChannel;
|
||||
uint32_t m_mediaStamp;
|
||||
uint32_t m_pauseStamp;
|
||||
int m_pausing;
|
||||
int m_nServerBW;
|
||||
int m_nClientBW;
|
||||
uint8_t m_nClientBW2;
|
||||
uint8_t m_bPlaying;
|
||||
uint8_t m_bSendEncoding;
|
||||
uint8_t m_bSendCounter;
|
||||
|
||||
int m_numInvokes;
|
||||
int m_numCalls;
|
||||
RTMP_METHOD *m_methodCalls; /* remote method calls queue */
|
||||
|
||||
int m_channelsAllocatedIn;
|
||||
int m_channelsAllocatedOut;
|
||||
RTMPPacket **m_vecChannelsIn;
|
||||
RTMPPacket **m_vecChannelsOut;
|
||||
int *m_channelTimestamp; /* abs timestamp of last packet */
|
||||
|
||||
double m_fAudioCodecs; /* audioCodecs for the connect packet */
|
||||
double m_fVideoCodecs; /* videoCodecs for the connect packet */
|
||||
double m_fEncoding; /* AMF0 or AMF3 */
|
||||
|
||||
double m_fDuration; /* duration of stream in seconds */
|
||||
|
||||
int m_msgCounter; /* RTMPT stuff */
|
||||
int m_polling;
|
||||
int m_resplen;
|
||||
int m_unackd;
|
||||
AVal m_clientID;
|
||||
|
||||
RTMP_READ m_read;
|
||||
RTMPPacket m_write;
|
||||
RTMPSockBuf m_sb;
|
||||
RTMP_LNK Link;
|
||||
} RTMP;
|
||||
|
||||
int RTMP_ParseURL(const char *url, int *protocol, AVal *host,
|
||||
unsigned int *port, AVal *playpath, AVal *app);
|
||||
|
||||
void RTMP_ParsePlaypath(AVal *in, AVal *out);
|
||||
void RTMP_SetBufferMS(RTMP *r, int size);
|
||||
void RTMP_UpdateBufferMS(RTMP *r);
|
||||
|
||||
void AV_clear(RTMP_METHOD *vals, int num);
|
||||
|
||||
void SocksSetup(RTMP *r, AVal *sockshost);
|
||||
int SocksNegotiate(RTMP *r);
|
||||
int SendFCUnpublish(RTMP *r);
|
||||
int HandShake(RTMP *r, int FP9HandShake);
|
||||
int DecodeInt32LE(const char *data);
|
||||
int SendBytesReceived(RTMP *r);
|
||||
int SendConnectPacket(RTMP *r, RTMPPacket *cp);
|
||||
int SendDeleteStream(RTMP *r, double dStreamId);
|
||||
int ReadN(RTMP *r, char *buffer, int n);
|
||||
int HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize);
|
||||
int HandleMetadata(RTMP *r, char *body, unsigned int len);
|
||||
void HandleChangeChunkSize(RTMP *r, const RTMPPacket *packet);
|
||||
void HandleAudio(RTMP *r, const RTMPPacket *packet);
|
||||
void HandleVideo(RTMP *r, const RTMPPacket *packet);
|
||||
void HandleCtrl(RTMP *r, const RTMPPacket *packet);
|
||||
void HandleServerBW(RTMP *r, const RTMPPacket *packet);
|
||||
void HandleClientBW(RTMP *r, const RTMPPacket *packet);
|
||||
int RTMP_SetOpt(RTMP *r, const AVal *opt, AVal *arg);
|
||||
int RTMP_SetupURL(RTMP *r, char *url);
|
||||
void RTMP_SetupStream(RTMP *r, int protocol,
|
||||
AVal *hostname,
|
||||
unsigned int port,
|
||||
AVal *sockshost,
|
||||
AVal *playpath,
|
||||
AVal *tcUrl,
|
||||
AVal *swfUrl,
|
||||
AVal *pageUrl,
|
||||
AVal *app,
|
||||
AVal *auth,
|
||||
AVal *swfSHA256Hash,
|
||||
uint32_t swfSize,
|
||||
AVal *flashVer,
|
||||
AVal *subscribepath,
|
||||
AVal *usherToken,
|
||||
int dStart,
|
||||
int dStop, int bLiveStream, long int timeout);
|
||||
int RTMP_Connect(RTMP *r, RTMPPacket *cp);
|
||||
struct sockaddr;
|
||||
int RTMP_Connect0(RTMP *r, struct sockaddr *svc);
|
||||
int RTMP_Connect1(RTMP *r, RTMPPacket *cp);
|
||||
int RTMP_Serve(RTMP *r);
|
||||
int RTMP_TLS_Accept(RTMP *r, void *ctx);
|
||||
int SendCheckBW(RTMP *r);
|
||||
int SendCheckBWResult(RTMP *r, double txn);
|
||||
int SendDeleteStream(RTMP *r, double dStreamId);
|
||||
int SendFCSubscribe(RTMP *r, AVal *subscribepath);
|
||||
int SendPlay(RTMP *r);
|
||||
int SendBytesReceived(RTMP *r);
|
||||
int SendUsherToken(RTMP *r, AVal *usherToken);
|
||||
int RTMP_ReadPacket(RTMP *r, RTMPPacket *packet);
|
||||
int RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue);
|
||||
int RTMP_SendChunk(RTMP *r, RTMPChunk *chunk);
|
||||
int RTMP_IsConnected(RTMP *r);
|
||||
int RTMP_Socket(RTMP *r);
|
||||
int RTMP_IsTimedout(RTMP *r);
|
||||
double RTMP_GetDuration(RTMP *r);
|
||||
int RTMP_ToggleStream(RTMP *r);
|
||||
int RTMP_ConnectStream(RTMP *r, int seekTime);
|
||||
int RTMP_ReconnectStream(RTMP *r, int seekTime);
|
||||
void RTMP_DeleteStream(RTMP *r);
|
||||
int RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet);
|
||||
int RTMP_ClientPacket(RTMP *r, RTMPPacket *packet);
|
||||
void RTMP_Init(RTMP *r);
|
||||
void RTMP_Close(RTMP *r);
|
||||
RTMP *RTMP_Alloc(void);
|
||||
void RTMP_Free(RTMP *r);
|
||||
void RTMP_EnableWrite(RTMP *r);
|
||||
void *RTMP_TLS_AllocServerContext(const char* cert, const char* key);
|
||||
void RTMP_TLS_FreeServerContext(void *ctx);
|
||||
int RTMP_LibVersion(void);
|
||||
void RTMP_UserInterrupt(void); /* user typed Ctrl-C */
|
||||
int RTMP_SendCtrl(RTMP *r, short nType, unsigned int nObject,
|
||||
unsigned int nTime);
|
||||
|
||||
/* caller probably doesn't know current timestamp, should
|
||||
* just use RTMP_Pause instead
|
||||
*/
|
||||
int RTMP_SendPause(RTMP *r, int DoPause, int dTime);
|
||||
int RTMP_Pause(RTMP *r, int DoPause);
|
||||
int RTMP_FindFirstMatchingProperty(AMFObject *obj, const AVal *name,
|
||||
AMFObjectProperty * p);
|
||||
int RTMPSockBuf_Fill(RTMPSockBuf *sb);
|
||||
int RTMPSockBuf_Send(RTMPSockBuf *sb, const char *buf, int len);
|
||||
int RTMPSockBuf_Close(RTMPSockBuf *sb);
|
||||
int RTMP_SendCreateStream(RTMP *r);
|
||||
int RTMP_SendSeek(RTMP *r, int dTime);
|
||||
int RTMP_SendServerBW(RTMP *r);
|
||||
int RTMP_SendClientBW(RTMP *r);
|
||||
void RTMP_DropRequest(RTMP *r, int i, int freeit);
|
||||
int RTMP_Read(RTMP *r, char *buf, int size);
|
||||
int RTMP_Write(RTMP *r, const char *buf, int size);
|
||||
void AV_erase(RTMP_METHOD *vals, int *num, int i, int freeit);
|
||||
void DecodeTEA(AVal *key, AVal *text);
|
||||
int SendFCPublish(RTMP *r);
|
||||
int SendPlaylist(RTMP *r);
|
||||
int SendPong(RTMP *r, double txn);
|
||||
int SendPublish(RTMP *r);
|
||||
int SendReleaseStream(RTMP *r);
|
||||
int SendSecureTokenResponse(RTMP *r, AVal *resp);
|
||||
/* hashswf.c */
|
||||
int RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
|
||||
int age);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,139 +0,0 @@
|
|||
#ifndef __RTMP_SYS_H__
|
||||
#define __RTMP_SYS_H__
|
||||
/*
|
||||
* Copyright (C) 2010 Howard Chu
|
||||
*
|
||||
* This file is part of librtmp.
|
||||
*
|
||||
* librtmp is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* librtmp is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with librtmp see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#ifdef _MSC_VER /* MSVC */
|
||||
#define snprintf _snprintf
|
||||
#define strcasecmp stricmp
|
||||
#define strncasecmp strnicmp
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
#define GetSockError() WSAGetLastError()
|
||||
#define SetSockError(e) WSASetLastError(e)
|
||||
#define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e)
|
||||
#define EWOULDBLOCK WSAETIMEDOUT /* we don't use nonblocking, but we do use timeouts */
|
||||
#define sleep(n) Sleep(n*1000)
|
||||
#define msleep(n) Sleep(n)
|
||||
#define SET_RCVTIMEO(tv,s) int tv = s*1000
|
||||
#else /* !_WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/times.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#define GetSockError() errno
|
||||
#define SetSockError(e) errno = e
|
||||
#undef closesocket
|
||||
#define closesocket(s) close(s)
|
||||
#define msleep(n) usleep(n*1000)
|
||||
#define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0}
|
||||
#endif
|
||||
|
||||
#include "rtmp.h"
|
||||
|
||||
#ifdef USE_POLARSSL
|
||||
#include <polarssl/version.h>
|
||||
#include <polarssl/net.h>
|
||||
#include <polarssl/ssl.h>
|
||||
#include <polarssl/havege.h>
|
||||
#if POLARSSL_VERSION_NUMBER < 0x01010000
|
||||
#define havege_random havege_rand
|
||||
#endif
|
||||
#if POLARSSL_VERSION_NUMBER >= 0x01020000
|
||||
#define SSL_SET_SESSION(S,resume,timeout,ctx) ssl_set_session(S,ctx)
|
||||
#else
|
||||
#define SSL_SET_SESSION(S,resume,timeout,ctx) ssl_set_session(S,resume,timeout,ctx)
|
||||
#endif
|
||||
typedef struct tls_ctx {
|
||||
havege_state hs;
|
||||
ssl_session ssn;
|
||||
} tls_ctx;
|
||||
typedef struct tls_server_ctx {
|
||||
havege_state *hs;
|
||||
x509_cert cert;
|
||||
rsa_context key;
|
||||
ssl_session ssn;
|
||||
const char *dhm_P, *dhm_G;
|
||||
} tls_server_ctx;
|
||||
|
||||
#define TLS_CTX tls_ctx *
|
||||
#define TLS_client(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\
|
||||
ssl_set_endpoint(s, SSL_IS_CLIENT); ssl_set_authmode(s, SSL_VERIFY_NONE);\
|
||||
ssl_set_rng(s, havege_random, &ctx->hs);\
|
||||
ssl_set_ciphersuites(s, ssl_default_ciphersuites);\
|
||||
SSL_SET_SESSION(s, 1, 600, &ctx->ssn)
|
||||
#define TLS_server(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\
|
||||
ssl_set_endpoint(s, SSL_IS_SERVER); ssl_set_authmode(s, SSL_VERIFY_NONE);\
|
||||
ssl_set_rng(s, havege_random, ((tls_server_ctx*)ctx)->hs);\
|
||||
ssl_set_ciphersuites(s, ssl_default_ciphersuites);\
|
||||
SSL_SET_SESSION(s, 1, 600, &((tls_server_ctx*)ctx)->ssn);\
|
||||
ssl_set_own_cert(s, &((tls_server_ctx*)ctx)->cert, &((tls_server_ctx*)ctx)->key);\
|
||||
ssl_set_dh_param(s, ((tls_server_ctx*)ctx)->dhm_P, ((tls_server_ctx*)ctx)->dhm_G)
|
||||
#define TLS_setfd(s,fd) ssl_set_bio(s, net_recv, &fd, net_send, &fd)
|
||||
#define TLS_connect(s) ssl_handshake(s)
|
||||
#define TLS_accept(s) ssl_handshake(s)
|
||||
#define TLS_read(s,b,l) ssl_read(s,(unsigned char *)b,l)
|
||||
#define TLS_write(s,b,l) ssl_write(s,(unsigned char *)b,l)
|
||||
#define TLS_shutdown(s) ssl_close_notify(s)
|
||||
#define TLS_close(s) ssl_free(s); free(s)
|
||||
|
||||
#elif defined(USE_GNUTLS)
|
||||
#include <gnutls/gnutls.h>
|
||||
typedef struct tls_ctx {
|
||||
gnutls_certificate_credentials_t cred;
|
||||
gnutls_priority_t prios;
|
||||
} tls_ctx;
|
||||
#define TLS_CTX tls_ctx *
|
||||
#define TLS_client(ctx,s) gnutls_init((gnutls_session_t *)(&s), GNUTLS_CLIENT); gnutls_priority_set(s, ctx->prios); gnutls_credentials_set(s, GNUTLS_CRD_CERTIFICATE, ctx->cred)
|
||||
#define TLS_server(ctx,s) gnutls_init((gnutls_session_t *)(&s), GNUTLS_SERVER); gnutls_priority_set_direct(s, "NORMAL", NULL); gnutls_credentials_set(s, GNUTLS_CRD_CERTIFICATE, ctx)
|
||||
#define TLS_setfd(s,fd) gnutls_transport_set_ptr(s, (gnutls_transport_ptr_t)(long)fd)
|
||||
#define TLS_connect(s) gnutls_handshake(s)
|
||||
#define TLS_accept(s) gnutls_handshake(s)
|
||||
#define TLS_read(s,b,l) gnutls_record_recv(s,b,l)
|
||||
#define TLS_write(s,b,l) gnutls_record_send(s,b,l)
|
||||
#define TLS_shutdown(s) gnutls_bye(s, GNUTLS_SHUT_RDWR)
|
||||
#define TLS_close(s) gnutls_deinit(s)
|
||||
|
||||
#else /* USE_OPENSSL */
|
||||
#define TLS_CTX SSL_CTX *
|
||||
#define TLS_client(ctx,s) s = SSL_new(ctx)
|
||||
#define TLS_server(ctx,s) s = SSL_new(ctx)
|
||||
#define TLS_setfd(s,fd) SSL_set_fd(s,fd)
|
||||
#define TLS_connect(s) SSL_connect(s)
|
||||
#define TLS_accept(s) SSL_accept(s)
|
||||
#define TLS_read(s,b,l) SSL_read(s,b,l)
|
||||
#define TLS_write(s,b,l) SSL_write(s,b,l)
|
||||
#define TLS_shutdown(s) SSL_shutdown(s)
|
||||
#define TLS_close(s) SSL_free(s)
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
de62b43dfcd858e66a74bee1c834e959
|
|
@ -1,311 +0,0 @@
|
|||
.TH RTMPDUMP 1 "2012-07-24" "RTMPDump v2.4"
|
||||
.\" Copyright 2011 Howard Chu.
|
||||
.\" Copying permitted according to the GNU General Public License V2.
|
||||
.SH NAME
|
||||
rtmpdump \- RTMP streaming media client
|
||||
.SH SYNOPSIS
|
||||
.B rtmpdump
|
||||
.BI \-r \ url
|
||||
[\c
|
||||
.BI \-n \ hostname\fR]
|
||||
[\c
|
||||
.BI \-c \ port\fR]
|
||||
[\c
|
||||
.BI \-l \ protocol\fR]
|
||||
[\c
|
||||
.BI \-S \ host:port\fR]
|
||||
[\c
|
||||
.BI \-a \ app\fR]
|
||||
[\c
|
||||
.BI \-t \ tcUrl\fR]
|
||||
[\c
|
||||
.BI \-p \ pageUrl\fR]
|
||||
[\c
|
||||
.BI \-s \ swfUrl\fR]
|
||||
[\c
|
||||
.BI \-f \ flashVer\fR]
|
||||
[\c
|
||||
.BI \-u \ auth\fR]
|
||||
[\c
|
||||
.BI \-C \ conndata\fR]
|
||||
[\c
|
||||
.BI \-y \ playpath\fR]
|
||||
[\c
|
||||
.BR \-Y ]
|
||||
[\c
|
||||
.BR \-v ]
|
||||
[\c
|
||||
.BI \-d \ subscription\fR]
|
||||
[\c
|
||||
.BR \-e ]
|
||||
[\c
|
||||
.BI \-k \ skip\fR]
|
||||
[\c
|
||||
.BI \-A \ start\fR]
|
||||
[\c
|
||||
.BI \-B \ stop\fR]
|
||||
[\c
|
||||
.BI \-b \ buffer\fR]
|
||||
[\c
|
||||
.BI \-m \ timeout\fR]
|
||||
[\c
|
||||
.BI \-T \ key\fR]
|
||||
[\c
|
||||
.BI \-j \ JSON\fR]
|
||||
[\c
|
||||
.BI \-w \ swfHash\fR]
|
||||
[\c
|
||||
.BI \-x \ swfSize\fR]
|
||||
[\c
|
||||
.BI \-W \ swfUrl\fR]
|
||||
[\c
|
||||
.BI \-X \ swfAge\fR]
|
||||
[\c
|
||||
.BI \-o \ output\fR]
|
||||
[\c
|
||||
.BR \-# ]
|
||||
[\c
|
||||
.BR \-q ]
|
||||
[\c
|
||||
.BR \-V ]
|
||||
[\c
|
||||
.BR \-z ]
|
||||
.br
|
||||
.B rtmpdump \-h
|
||||
.SH DESCRIPTION
|
||||
.B rtmpdump
|
||||
is a tool for dumping media content streamed over RTMP.
|
||||
.LP
|
||||
.B rtmpdump
|
||||
makes a connection to the specified RTMP server and plays the media
|
||||
specified by the given
|
||||
.IR url .
|
||||
The url should be of the form
|
||||
.nf
|
||||
rtmp[t][e]://hostname[:port][/app[/playpath]]
|
||||
.fi
|
||||
|
||||
Plain rtmp, as well as tunneled and encrypted sessions are supported.
|
||||
.SH OPTIONS
|
||||
.SS "Network Parameters"
|
||||
These options define how to connect to the media server.
|
||||
.TP
|
||||
\fB\-\-rtmp \-r\fP\ \fIurl\fP
|
||||
URL of the server and media content.
|
||||
.TP
|
||||
\fB\-\-host \-n\fP\ \fIhostname\fP
|
||||
Overrides the hostname in the RTMP URL.
|
||||
.TP
|
||||
\fB\-\-port \-c\fP\ \fIport\fP
|
||||
Overrides the port number in the RTMP URL.
|
||||
.TP
|
||||
\fB\-\-protocol \-l\fP\ \fInumber\fP
|
||||
Overrides the protocol in the RTMP URL.
|
||||
.nf
|
||||
0 = rtmp
|
||||
1 = rtmpt
|
||||
2 = rtmpe
|
||||
3 = rtmpte
|
||||
4 = rtmps
|
||||
5 = rtmpts
|
||||
.fi
|
||||
.TP
|
||||
\fB\-\-socks \-S\fP\ \fIhost:port\fP
|
||||
Use the specified SOCKS4 proxy.
|
||||
.SS "Connection Parameters"
|
||||
These options define the content of the RTMP Connect request packet.
|
||||
If correct values are not provided, the media server will reject the
|
||||
connection attempt.
|
||||
.TP
|
||||
\fB\-\-app \-a\fP\ \fIapp\fP
|
||||
Name of application to connect to on the RTMP server. Overrides
|
||||
the app in the RTMP URL. Sometimes the rtmpdump URL parser cannot
|
||||
determine the app name automatically, so it must be given explicitly
|
||||
using this option.
|
||||
.TP
|
||||
\fB\-\-tcUrl \-t\fP\ \fIurl\fP
|
||||
URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath.
|
||||
.TP
|
||||
\fB\-\-pageUrl \-p\fP\ \fIurl\fP
|
||||
URL of the web page in which the media was embedded. By default no
|
||||
value will be sent.
|
||||
.TP
|
||||
\fB\-\-swfUrl \-s\fP\ \fIurl\fP
|
||||
URL of the SWF player for the media. By default no value will be sent.
|
||||
.TP
|
||||
\fB\-\-flashVer \-f\fP\ \fIversion\fP
|
||||
Version of the Flash plugin used to run the SWF player. The
|
||||
default is "LNX 10,0,32,18".
|
||||
.TP
|
||||
\fB\-\-auth \-u\fP\ \fIstring\fP
|
||||
An authentication string to be appended to the Connect message. Using
|
||||
this option will append a Boolean TRUE and then the specified string.
|
||||
This option is only used by some particular servers and is
|
||||
deprecated. The more general
|
||||
.B \-\-conn
|
||||
option should be used instead.
|
||||
.TP
|
||||
\fB\-\-conn \-C\fP\ \fItype:data\fP
|
||||
Append arbitrary AMF data to the Connect message. The type
|
||||
must be B for Boolean, N for number, S for string, O for object, or Z
|
||||
for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE,
|
||||
respectively. Likewise for Objects the data must be 0 or 1 to end or
|
||||
begin an object, respectively. Data items in subobjects may be named, by
|
||||
prefixing the type with 'N' and specifying the name before the value, e.g.
|
||||
NB:myFlag:1. This option may be used multiple times to construct arbitrary
|
||||
AMF sequences. E.g.
|
||||
.nf
|
||||
\-C B:1 \-C S:authMe \-C O:1 \-C NN:code:1.23 \-C NS:flag:ok \-C O:0
|
||||
.fi
|
||||
.SS "Session Parameters"
|
||||
These options take effect after the Connect request has succeeded.
|
||||
.TP
|
||||
\fB\-\-playpath \-y\fP\ \fIpath\fP
|
||||
Overrides the playpath parsed from the RTMP URL. Sometimes the
|
||||
rtmpdump URL parser cannot determine the correct playpath
|
||||
automatically, so it must be given explicitly using this option.
|
||||
.TP
|
||||
.B \-\-playlist \-Y
|
||||
Issue a set_playlist command before sending the play command. The
|
||||
playlist will just contain the current playpath.
|
||||
.TP
|
||||
.B \-\-live \-v
|
||||
Specify that the media is a live stream. No resuming or seeking in
|
||||
live streams is possible.
|
||||
.TP
|
||||
\fB\-\-subscribe \-d\fP\ \fIstream\fP
|
||||
Name of live stream to subscribe to. Defaults to
|
||||
.IR playpath .
|
||||
.TP
|
||||
.B \-\-realtime \-R
|
||||
Download approximately in realtime, without attempting to speed up via
|
||||
Pause/Unpause commands ("the BUFX hack").
|
||||
Useful for servers that jump backwards in time at the Unpause command.
|
||||
Resuming and seeking in realtime streams is still possible.
|
||||
.TP
|
||||
.B \-\-resume \-e
|
||||
Resume an incomplete RTMP download.
|
||||
.TP
|
||||
\fB\-\-skip \-k\fP\ \fInum\fP
|
||||
Skip
|
||||
.I num
|
||||
keyframes when looking for the last keyframe from which to resume. This
|
||||
may be useful if a regular attempt to resume fails. The default is 0.
|
||||
.TP
|
||||
\fB\-\-start \-A\fP\ \fInum\fP
|
||||
Start at
|
||||
.I num
|
||||
seconds into the stream. Not valid for live streams.
|
||||
.TP
|
||||
\fB\-\-stop \-B\fP\ \fInum\fP
|
||||
Stop at
|
||||
.I num
|
||||
seconds into the stream.
|
||||
.TP
|
||||
\fB\-\-buffer \-b\fP\ \fInum\fP
|
||||
Set buffer time to
|
||||
.I num
|
||||
milliseconds. The default is 36000000.
|
||||
.TP
|
||||
\fB\-\-timeout \-m\fP\ \fInum\fP
|
||||
Timeout the session after
|
||||
.I num
|
||||
seconds without receiving any data from the server. The default is 120.
|
||||
.SS "Security Parameters"
|
||||
These options handle additional authentication requests from the server.
|
||||
.TP
|
||||
\fB\-\-token \-T\fP\ \fIkey\fP
|
||||
Key for SecureToken response, used if the server requires SecureToken
|
||||
authentication.
|
||||
.TP
|
||||
\fB\-\-jtv \-j\fP\ \fIJSON\fP
|
||||
JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
|
||||
.TP
|
||||
\fB\-\-swfhash \-w\fP\ \fIhexstring\fP
|
||||
SHA256 hash of the decompressed SWF file. This option may be needed if
|
||||
the server uses SWF Verification, but see the
|
||||
.B \-\-swfVfy
|
||||
option below. The hash is 32 bytes, and must be
|
||||
given in hexadecimal. The
|
||||
.B \-\-swfsize
|
||||
option must always be used with this option.
|
||||
.TP
|
||||
\fB\-\-swfsize \-x\fP\ \fInum\fP
|
||||
Size of the decompressed SWF file. This option may be needed if the
|
||||
server uses SWF Verification, but see the
|
||||
.B \-\-swfVfy
|
||||
option below. The
|
||||
.B \-\-swfhash
|
||||
option must always be used with this option.
|
||||
.TP
|
||||
\fB\-\-swfVfy \-W\fP\ \fIurl\fP
|
||||
URL of the SWF player for this media. This option replaces all three
|
||||
of the
|
||||
.BR \-\-swfUrl ,
|
||||
.BR \-\-swfhash ,
|
||||
and
|
||||
.B \-\-swfsize
|
||||
options. When this option is used, the SWF player is retrieved from the
|
||||
specified URL and the hash and size are computed automatically. Also
|
||||
the information is cached in a
|
||||
.I .swfinfo
|
||||
file in the user's home directory, so that it doesn't need to be retrieved
|
||||
and recalculated every time rtmpdump is run. The .swfinfo file records
|
||||
the URL, the time it was fetched, the modification timestamp of the SWF
|
||||
file, its size, and its hash. By default, the cached info will be used
|
||||
for 30 days before re-checking.
|
||||
.TP
|
||||
\fB\-\-swfAge \-X\fP\ \fIdays\fP
|
||||
Specify how many days to use the cached SWF info before re-checking. Use
|
||||
0 to always check the SWF URL. Note that if the check shows that the
|
||||
SWF file has the same modification timestamp as before, it will not be
|
||||
retrieved again.
|
||||
.SS Miscellaneous
|
||||
.TP
|
||||
\fB\-\-flv \-o\fP\ \fIoutput\fP
|
||||
Specify the output file name. If the name is \- or is omitted, the
|
||||
stream is written to stdout.
|
||||
.TP
|
||||
.B \-\-hashes \-#
|
||||
Display streaming progress with a hash mark for each 1% of progress, instead
|
||||
of a byte counter.
|
||||
.TP
|
||||
.B \-\-quiet \-q
|
||||
Suppress all command output.
|
||||
.TP
|
||||
.B \-\-verbose \-V
|
||||
Verbose command output.
|
||||
.TP
|
||||
.B \-\-debug \-z
|
||||
Debug level output. Extremely verbose, including hex dumps of all packet data.
|
||||
.TP
|
||||
.B \-\-help \-h
|
||||
Print a summary of command options.
|
||||
.SH EXIT STATUS
|
||||
.TP
|
||||
.B 0
|
||||
Successful program execution.
|
||||
.TP
|
||||
.B 1
|
||||
Unrecoverable error.
|
||||
.TP
|
||||
.B 2
|
||||
Incomplete transfer, resuming may get further.
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B HOME
|
||||
The value of
|
||||
.RB $ HOME
|
||||
is used as the location for the
|
||||
.I .swfinfo
|
||||
file.
|
||||
.SH FILES
|
||||
.TP
|
||||
.I $HOME/.swfinfo
|
||||
Cache of SWF Verification information
|
||||
.SH "SEE ALSO"
|
||||
.BR rtmpgw (8)
|
||||
.SH AUTHORS
|
||||
Andrej Stepanchuk, Howard Chu, The Flvstreamer Team
|
||||
.br
|
||||
<http://rtmpdump.mplayerhq.hu>
|
|
@ -1,439 +0,0 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<title>RTMPDUMP(1): </title></head>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><td>RTMPDUMP(1)<td align="center"><td align="right">RTMPDUMP(1)
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr><td>RTMPDump v2.4<td align="center">2012-07-24<td align="right">RTMPDUMP(1)
|
||||
</tfoot>
|
||||
<tbody><tr><td colspan="3"><br><br><ul>
|
||||
<!-- Copyright 2011 Howard Chu.
|
||||
Copying permitted according to the GNU General Public License V2.-->
|
||||
</ul>
|
||||
|
||||
<h3>NAME</h3><ul>
|
||||
rtmpdump − RTMP streaming media client
|
||||
</ul>
|
||||
|
||||
<h3>SYNOPSIS</h3><ul>
|
||||
<b>rtmpdump</b>
|
||||
<b>−r</b><i> url</i>
|
||||
[<b>−n</b><i> hostname</i>]
|
||||
[<b>−c</b><i> port</i>]
|
||||
[<b>−l</b><i> protocol</i>]
|
||||
[<b>−S</b><i> host:port</i>]
|
||||
[<b>−a</b><i> app</i>]
|
||||
[<b>−t</b><i> tcUrl</i>]
|
||||
[<b>−p</b><i> pageUrl</i>]
|
||||
[<b>−s</b><i> swfUrl</i>]
|
||||
[<b>−f</b><i> flashVer</i>]
|
||||
[<b>−u</b><i> auth</i>]
|
||||
[<b>−C</b><i> conndata</i>]
|
||||
[<b>−y</b><i> playpath</i>]
|
||||
[<b>−Y</b>]
|
||||
[<b>−v</b>]
|
||||
[<b>−R</b>]
|
||||
[<b>−d</b><i> subscription</i>]
|
||||
[<b>−e</b>]
|
||||
[<b>−k</b><i> skip</i>]
|
||||
[<b>−A</b><i> start</i>]
|
||||
[<b>−B</b><i> stop</i>]
|
||||
[<b>−b</b><i> buffer</i>]
|
||||
[<b>−m</b><i> timeout</i>]
|
||||
[<b>−T</b><i> key</i>]
|
||||
[<b>−j</b><i> JSON</i>]
|
||||
[<b>−w</b><i> swfHash</i>]
|
||||
[<b>−x</b><i> swfSize</i>]
|
||||
[<b>−W</b><i> swfUrl</i>]
|
||||
[<b>−X</b><i> swfAge</i>]
|
||||
[<b>−o</b><i> output</i>]
|
||||
[<b>−#</b>]
|
||||
[<b>−q</b>]
|
||||
[<b>−V</b>]
|
||||
[<b>−z</b>]
|
||||
<br>
|
||||
<b>rtmpdump −h</b>
|
||||
</ul>
|
||||
|
||||
<h3>DESCRIPTION</h3><ul>
|
||||
<b>rtmpdump</b>
|
||||
is a tool for dumping media content streamed over RTMP.
|
||||
<p>
|
||||
<b>rtmpdump</b>
|
||||
makes a connection to the specified RTMP server and plays the media
|
||||
specified by the given
|
||||
<i>url</i>.
|
||||
The url should be of the form
|
||||
<pre>
|
||||
rtmp[t][e]://hostname[:port][/app[/playpath]]
|
||||
</pre>
|
||||
<p>
|
||||
Plain rtmp, as well as tunneled and encrypted sessions are supported.
|
||||
</ul>
|
||||
|
||||
<h3>OPTIONS</h3><ul>
|
||||
</ul>
|
||||
|
||||
<h4>Network Parameters</h4><ul>
|
||||
These options define how to connect to the media server.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−rtmp −r</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the server and media content.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−host −n</b> <i>hostname</i>
|
||||
<dd>
|
||||
Overrides the hostname in the RTMP URL.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−port −c</b> <i>port</i>
|
||||
<dd>
|
||||
Overrides the port number in the RTMP URL.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−protocol −l</b> <i>number</i>
|
||||
<dd>
|
||||
Overrides the protocol in the RTMP URL.
|
||||
<pre>
|
||||
0 = rtmp
|
||||
1 = rtmpt
|
||||
2 = rtmpe
|
||||
3 = rtmpte
|
||||
4 = rtmps
|
||||
5 = rtmpts
|
||||
</pre>
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−socks −S</b> <i>host:port</i>
|
||||
<dd>
|
||||
Use the specified SOCKS4 proxy.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Connection Parameters</h4><ul>
|
||||
These options define the content of the RTMP Connect request packet.
|
||||
If correct values are not provided, the media server will reject the
|
||||
connection attempt.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−app −a</b> <i>app</i>
|
||||
<dd>
|
||||
Name of application to connect to on the RTMP server. Overrides
|
||||
the app in the RTMP URL. Sometimes the rtmpdump URL parser cannot
|
||||
determine the app name automatically, so it must be given explicitly
|
||||
using this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−tcUrl −t</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−pageUrl −p</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the web page in which the media was embedded. By default no
|
||||
value will be sent.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfUrl −s</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the SWF player for the media. By default no value will be sent.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−flashVer −f</b> <i>version</i>
|
||||
<dd>
|
||||
Version of the Flash plugin used to run the SWF player. The
|
||||
default is "LNX 10,0,32,18".
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−auth −u</b> <i>string</i>
|
||||
<dd>
|
||||
An authentication string to be appended to the Connect message. Using
|
||||
this option will append a Boolean TRUE and then the specified string.
|
||||
This option is only used by some particular servers and is
|
||||
deprecated. The more general
|
||||
<b>−−conn</b>
|
||||
option should be used instead.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−conn −C</b> <i>type:data</i>
|
||||
<dd>
|
||||
Append arbitrary AMF data to the Connect message. The type
|
||||
must be B for Boolean, N for number, S for string, O for object, or Z
|
||||
for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE,
|
||||
respectively. Likewise for Objects the data must be 0 or 1 to end or
|
||||
begin an object, respectively. Data items in subobjects may be named, by
|
||||
prefixing the type with 'N' and specifying the name before the value, e.g.
|
||||
NB:myFlag:1. This option may be used multiple times to construct arbitrary
|
||||
AMF sequences. E.g.
|
||||
<pre>
|
||||
−C B:1 −C S:authMe −C O:1 −C NN:code:1.23 −C NS:flag:ok −C O:0
|
||||
</pre>
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Session Parameters</h4><ul>
|
||||
These options take effect after the Connect request has succeeded.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−playpath −y</b> <i>path</i>
|
||||
<dd>
|
||||
Overrides the playpath parsed from the RTMP URL. Sometimes the
|
||||
rtmpdump URL parser cannot determine the correct playpath
|
||||
automatically, so it must be given explicitly using this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−playlist −Y</b>
|
||||
<dd>
|
||||
Issue a set_playlist command before sending the play command. The
|
||||
playlist will just contain the current playpath.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−live −v</b>
|
||||
<dd>
|
||||
Specify that the media is a live stream. No resuming or seeking in
|
||||
live streams is possible.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−subscribe −d</b> <i>stream</i>
|
||||
<dd>
|
||||
Name of live stream to subscribe to. Defaults to
|
||||
<i>playpath</i>.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−realtime −R</b>
|
||||
<dd>
|
||||
Download approximately in realtime, without attempting to speed up via
|
||||
Pause/Unpause commands ("the BUFX hack").
|
||||
Useful for servers that jump backwards in time at the Unpause command.
|
||||
Resuming and seeking in realtime streams is still possible.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−resume −e</b>
|
||||
<dd>
|
||||
Resume an incomplete RTMP download.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−skip −k</b> <i>num</i>
|
||||
<dd>
|
||||
Skip
|
||||
<i>num</i>
|
||||
keyframes when looking for the last keyframe from which to resume. This
|
||||
may be useful if a regular attempt to resume fails. The default is 0.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−start −A</b> <i>num</i>
|
||||
<dd>
|
||||
Start at
|
||||
<i>num</i>
|
||||
seconds into the stream. Not valid for live streams.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−stop −B</b> <i>num</i>
|
||||
<dd>
|
||||
Stop at
|
||||
<i>num</i>
|
||||
seconds into the stream.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−buffer −b</b> <i>num</i>
|
||||
<dd>
|
||||
Set buffer time to
|
||||
<i>num</i>
|
||||
milliseconds. The default is 36000000.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−timeout −m</b> <i>num</i>
|
||||
<dd>
|
||||
Timeout the session after
|
||||
<i>num</i>
|
||||
seconds without receiving any data from the server. The default is 120.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Security Parameters</h4><ul>
|
||||
These options handle additional authentication requests from the server.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−token −T</b> <i>key</i>
|
||||
<dd>
|
||||
Key for SecureToken response, used if the server requires SecureToken
|
||||
authentication.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−jtv −j</b> <i>JSON</i>
|
||||
<dd>
|
||||
JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfhash −w</b> <i>hexstring</i>
|
||||
<dd>
|
||||
SHA256 hash of the decompressed SWF file. This option may be needed if
|
||||
the server uses SWF Verification, but see the
|
||||
<b>−−swfVfy</b>
|
||||
option below. The hash is 32 bytes, and must be
|
||||
given in hexadecimal. The
|
||||
<b>−−swfsize</b>
|
||||
option must always be used with this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfsize −x</b> <i>num</i>
|
||||
<dd>
|
||||
Size of the decompressed SWF file. This option may be needed if the
|
||||
server uses SWF Verification, but see the
|
||||
<b>−−swfVfy</b>
|
||||
option below. The
|
||||
<b>−−swfhash</b>
|
||||
option must always be used with this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfVfy −W</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the SWF player for this media. This option replaces all three
|
||||
of the
|
||||
<b>−−swfUrl</b>,
|
||||
<b>−−swfhash</b>,
|
||||
and
|
||||
<b>−−swfsize</b>
|
||||
options. When this option is used, the SWF player is retrieved from the
|
||||
specified URL and the hash and size are computed automatically. Also
|
||||
the information is cached in a
|
||||
<i>.swfinfo</i>
|
||||
file in the user's home directory, so that it doesn't need to be retrieved
|
||||
and recalculated every time rtmpdump is run. The .swfinfo file records
|
||||
the URL, the time it was fetched, the modification timestamp of the SWF
|
||||
file, its size, and its hash. By default, the cached info will be used
|
||||
for 30 days before re-checking.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfAge −X</b> <i>days</i>
|
||||
<dd>
|
||||
Specify how many days to use the cached SWF info before re-checking. Use
|
||||
0 to always check the SWF URL. Note that if the check shows that the
|
||||
SWF file has the same modification timestamp as before, it will not be
|
||||
retrieved again.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Miscellaneous</h4><ul>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−flv −o</b> <i>output</i>
|
||||
<dd>
|
||||
Specify the output file name. If the name is − or is omitted, the
|
||||
stream is written to stdout.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−hashes −#</b>
|
||||
<dd>
|
||||
Display streaming progress with a hash mark for each 1% of progress, instead
|
||||
of a byte counter.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−quiet −q</b>
|
||||
<dd>
|
||||
Suppress all command output.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−verbose −V</b>
|
||||
<dd>
|
||||
Verbose command output.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−debug −z</b>
|
||||
<dd>
|
||||
Debug level output. Extremely verbose, including hex dumps of all packet data.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−help −h</b>
|
||||
<dd>
|
||||
Print a summary of command options.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>EXIT STATUS</h3><ul>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>0</b>
|
||||
<dd>
|
||||
Successful program execution.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>1</b>
|
||||
<dd>
|
||||
Unrecoverable error.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>2</b>
|
||||
<dd>
|
||||
Incomplete transfer, resuming may get further.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>ENVIRONMENT</h3><ul>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>HOME</b>
|
||||
<dd>
|
||||
The value of
|
||||
$<b>HOME</b>
|
||||
is used as the location for the
|
||||
<i>.swfinfo</i>
|
||||
file.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>FILES</h3><ul>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<i>$HOME/.swfinfo</i>
|
||||
<dd>
|
||||
Cache of SWF Verification information
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>SEE ALSO</h3><ul>
|
||||
<a href="../man8/rtmpgw.8"><b>rtmpgw</b></a>(8)
|
||||
</ul>
|
||||
|
||||
<h3>AUTHORS</h3><ul>
|
||||
Andrej Stepanchuk, Howard Chu, The Flvstreamer Team
|
||||
<br>
|
||||
<<a href="http://rtmpdump.mplayerhq.hu">http://rtmpdump.mplayerhq.hu</a>>
|
||||
</ul></tbody></table></html>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,289 +0,0 @@
|
|||
.TH RTMPGW 8 "2011-07-20" "RTMPDump v2.4"
|
||||
.\" Copyright 2011 Howard Chu.
|
||||
.\" Copying permitted according to the GNU General Public License V2.
|
||||
.SH NAME
|
||||
rtmpgw \- RTMP streaming media gateway
|
||||
.SH SYNOPSIS
|
||||
.B rtmpgw
|
||||
[\c
|
||||
.BI \-r \ url\fR]
|
||||
[\c
|
||||
.BI \-n \ hostname\fR]
|
||||
[\c
|
||||
.BI \-c \ port\fR]
|
||||
[\c
|
||||
.BI \-l \ protocol\fR]
|
||||
[\c
|
||||
.BI \-S \ host:port\fR]
|
||||
[\c
|
||||
.BI \-a \ app\fR]
|
||||
[\c
|
||||
.BI \-t \ tcUrl\fR]
|
||||
[\c
|
||||
.BI \-p \ pageUrl\fR]
|
||||
[\c
|
||||
.BI \-s \ swfUrl\fR]
|
||||
[\c
|
||||
.BI \-f \ flashVer\fR]
|
||||
[\c
|
||||
.BI \-u \ auth\fR]
|
||||
[\c
|
||||
.BI \-C \ conndata\fR]
|
||||
[\c
|
||||
.BI \-y \ playpath\fR]
|
||||
[\c
|
||||
.BR \-v ]
|
||||
[\c
|
||||
.BI \-d \ subscription\fR]
|
||||
[\c
|
||||
.BR \-e ]
|
||||
[\c
|
||||
.BI \-k \ skip\fR]
|
||||
[\c
|
||||
.BI \-A \ start\fR]
|
||||
[\c
|
||||
.BI \-B \ stop\fR]
|
||||
[\c
|
||||
.BI \-b \ buffer\fR]
|
||||
[\c
|
||||
.BI \-m \ timeout\fR]
|
||||
[\c
|
||||
.BI \-T \ key\fR]
|
||||
[\c
|
||||
.BI \-j \ JSON\fR]
|
||||
[\c
|
||||
.BI \-w \ swfHash\fR]
|
||||
[\c
|
||||
.BI \-x \ swfSize\fR]
|
||||
[\c
|
||||
.BI \-W \ swfUrl\fR]
|
||||
[\c
|
||||
.BI \-X \ swfAge\fR]
|
||||
[\c
|
||||
.BI \-D \ address\fR]
|
||||
[\c
|
||||
.BI \-g \ port\fR]
|
||||
[\c
|
||||
.BR \-q ]
|
||||
[\c
|
||||
.BR \-V ]
|
||||
[\c
|
||||
.BR \-z ]
|
||||
.br
|
||||
.B rtmpgw \-h
|
||||
.SH DESCRIPTION
|
||||
.B rtmpgw
|
||||
is a server for streaming media content from RTMP out to HTTP.
|
||||
.LP
|
||||
.B rtmpgw
|
||||
listens for HTTP requests that specify RTMP stream parameters and
|
||||
then returns the RTMP data in the HTTP response. The only valid
|
||||
HTTP request is "GET /" but additional options can be provided
|
||||
in URL-encoded fashion. Options specified on the command line will
|
||||
be used as defaults, which can be overridden by options in the HTTP
|
||||
request.
|
||||
.SH OPTIONS
|
||||
.SS "Network Parameters"
|
||||
These options define how to connect to the media server.
|
||||
.TP
|
||||
\fB\-\-rtmp \-r\fP\ \fIurl\fP
|
||||
URL of the server and media content.
|
||||
.TP
|
||||
\fB\-\-host \-n\fP\ \fIhostname\fP
|
||||
Overrides the hostname in the RTMP URL.
|
||||
.TP
|
||||
\fB\-\-port \-c\fP\ \fIport\fP
|
||||
Overrides the port number in the RTMP URL.
|
||||
.TP
|
||||
\fB\-\-protocol \-l\fP\ \fInumber\fP
|
||||
Overrides the protocol in the RTMP URL.
|
||||
.nf
|
||||
0 = rtmp
|
||||
1 = rtmpt
|
||||
2 = rtmpe
|
||||
3 = rtmpte
|
||||
4 = rtmps
|
||||
5 = rtmpts
|
||||
.fi
|
||||
.TP
|
||||
\fB\-\-socks \-S\fP\ \fIhost:port\fP
|
||||
Use the specified SOCKS4 proxy.
|
||||
.SS "Connection Parameters"
|
||||
These options define the content of the RTMP Connect request packet.
|
||||
If correct values are not provided, the media server will reject the
|
||||
connection attempt.
|
||||
.TP
|
||||
\fB\-\-app \-a\fP\ \fIapp\fP
|
||||
Name of application to connect to on the RTMP server. Overrides
|
||||
the app in the RTMP URL. Sometimes the rtmpdump URL parser cannot
|
||||
determine the app name automatically, so it must be given explicitly
|
||||
using this option.
|
||||
.TP
|
||||
\fB\-\-tcUrl \-t\fP\ \fIurl\fP
|
||||
URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath.
|
||||
.TP
|
||||
\fB\-\-pageUrl \-p\fP\ \fIurl\fP
|
||||
URL of the web page in which the media was embedded. By default no
|
||||
value will be sent.
|
||||
.TP
|
||||
\fB\-\-swfUrl \-s\fP\ \fIurl\fP
|
||||
URL of the SWF player for the media. By default no value will be sent.
|
||||
.TP
|
||||
\fB\-\-flashVer \-f\fP\ \fIversion\fP
|
||||
Version of the Flash plugin used to run the SWF player. The
|
||||
default is "LNX 10,0,32,18".
|
||||
.TP
|
||||
\fB\-\-auth \-u\fP\ \fIstring\fP
|
||||
An authentication string to be appended to the Connect message. Using
|
||||
this option will append a Boolean TRUE and then the specified string.
|
||||
This option is only used by some particular servers and is
|
||||
deprecated. The more general
|
||||
.B \-\-conn
|
||||
option should be used instead.
|
||||
.TP
|
||||
\fB\-\-conn \-C\fP\ \fItype:data\fP
|
||||
Append arbitrary AMF data to the Connect message. The type
|
||||
must be B for Boolean, N for number, S for string, O for object, or Z
|
||||
for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE,
|
||||
respectively. Likewise for Objects the data must be 0 or 1 to end or
|
||||
begin an object, respectively. Data items in subobjects may be named, by
|
||||
prefixing the type with 'N' and specifying the name before the value, e.g.
|
||||
NB:myFlag:1. This option may be used multiple times to construct arbitrary
|
||||
AMF sequences. E.g.
|
||||
.nf
|
||||
\-C B:1 \-C S:authMe \-C O:1 \-C NN:code:1.23 \-C NS:flag:ok \-C O:0
|
||||
.fi
|
||||
.SS "Session Parameters"
|
||||
These options take effect after the Connect request has succeeded.
|
||||
.TP
|
||||
\fB\-\-playpath \-y\fP\ \fIpath\fP
|
||||
Overrides the playpath parsed from the RTMP URL. Sometimes the
|
||||
rtmpdump URL parser cannot determine the correct playpath
|
||||
automatically, so it must be given explicitly using this option.
|
||||
.TP
|
||||
.B \-\-live \-v
|
||||
Specify that the media is a live stream. No resuming or seeking in
|
||||
live streams is possible.
|
||||
.TP
|
||||
\fB\-\-subscribe \-d\fP\ \fIstream\fP
|
||||
Name of live stream to subscribe to. Defaults to
|
||||
.IR playpath .
|
||||
.TP
|
||||
\fB\-\-start \-A\fP\ \fInum\fP
|
||||
Start at
|
||||
.I num
|
||||
seconds into the stream. Not valid for live streams.
|
||||
.TP
|
||||
\fB\-\-stop \-B\fP\ \fInum\fP
|
||||
Stop at
|
||||
.I num
|
||||
seconds into the stream.
|
||||
.TP
|
||||
\fB\-\-buffer \-b\fP\ \fInum\fP
|
||||
Set buffer time to
|
||||
.I num
|
||||
milliseconds. The default is 20000.
|
||||
.TP
|
||||
\fB\-\-timeout \-m\fP\ \fInum\fP
|
||||
Timeout the session after
|
||||
.I num
|
||||
seconds without receiving any data from the server. The default is 120.
|
||||
.SS "Security Parameters"
|
||||
These options handle additional authentication requests from the server.
|
||||
.TP
|
||||
\fB\-\-token \-T\fP\ \fIkey\fP
|
||||
Key for SecureToken response, used if the server requires SecureToken
|
||||
authentication.
|
||||
.TP
|
||||
\fB\-\-jtv \-j\fP\ \fIJSON\fP
|
||||
JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
|
||||
.TP
|
||||
\fB\-\-swfhash \-w\fP\ \fIhexstring\fP
|
||||
SHA256 hash of the decompressed SWF file. This option may be needed if
|
||||
the server uses SWF Verification, but see the
|
||||
.B \-\-swfVfy
|
||||
option below. The hash is 32 bytes, and must be
|
||||
given in hexadecimal. The
|
||||
.B \-\-swfsize
|
||||
option must always be used with this option.
|
||||
.TP
|
||||
\fB\-\-swfsize \-x\fP\ \fInum\fP
|
||||
Size of the decompressed SWF file. This option may be needed if the
|
||||
server uses SWF Verification, but see the
|
||||
.B \-\-swfVfy
|
||||
option below. The
|
||||
.B \-\-swfhash
|
||||
option must always be used with this option.
|
||||
.TP
|
||||
\fB\-\-swfVfy \-W\fP\ \fIurl\fP
|
||||
URL of the SWF player for this media. This option replaces all three
|
||||
of the
|
||||
.BR \-\-swfUrl ,
|
||||
.BR \-\-swfhash ,
|
||||
and
|
||||
.B \-\-swfsize
|
||||
options. When this option is used, the SWF player is retrieved from the
|
||||
specified URL and the hash and size are computed automatically. Also
|
||||
the information is cached in a
|
||||
.I .swfinfo
|
||||
file in the user's home directory, so that it doesn't need to be retrieved
|
||||
and recalculated every time rtmpdump is run. The .swfinfo file records
|
||||
the URL, the time it was fetched, the modification timestamp of the SWF
|
||||
file, its size, and its hash. By default, the cached info will be used
|
||||
for 30 days before re-checking.
|
||||
.TP
|
||||
\fB\-\-swfAge \-X\fP\ \fIdays\fP
|
||||
Specify how many days to use the cached SWF info before re-checking. Use
|
||||
0 to always check the SWF URL. Note that if the check shows that the
|
||||
SWF file has the same modification timestamp as before, it will not be
|
||||
retrieved again.
|
||||
.SS Miscellaneous
|
||||
.TP
|
||||
\fB\-\-device \-D\fP\ \fIaddress\fP
|
||||
Listener IP address. The default is 0.0.0.0, i.e., any IP address.
|
||||
.TP
|
||||
\fB\-\-sport \-g\fP\ \fIport\fP
|
||||
Listener port. The default is 80.
|
||||
.TP
|
||||
.B \-\-quiet \-q
|
||||
Suppress all command output.
|
||||
.TP
|
||||
.B \-\-verbose \-V
|
||||
Verbose command output.
|
||||
.TP
|
||||
.B \-\-debug \-z
|
||||
Debug level output. Extremely verbose, including hex dumps of all packet data.
|
||||
.TP
|
||||
.B \-\-help \-h
|
||||
Print a summary of command options.
|
||||
.SH EXAMPLES
|
||||
The HTTP request
|
||||
.nf
|
||||
GET /?r=rtmp:%2f%2fserver%2fmyapp&y=somefile HTTP/1.0
|
||||
.fi
|
||||
is equivalent to the
|
||||
.BR rtrmpdump (1)
|
||||
invocation
|
||||
.nf
|
||||
rtmpdump \-r rtmp://server/myapp \-y somefile
|
||||
.fi
|
||||
|
||||
Note that only the shortform (single letter) options are supported.
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B HOME
|
||||
The value of
|
||||
.RB $ HOME
|
||||
is used as the location for the
|
||||
.I .swfinfo
|
||||
file.
|
||||
.SH FILES
|
||||
.TP
|
||||
.I $HOME/.swfinfo
|
||||
Cache of SWF Verification information
|
||||
.SH "SEE ALSO"
|
||||
.BR rtmpdump (1)
|
||||
.SH AUTHORS
|
||||
Andrej Stepanchuk, Howard Chu, The Flvstreamer Team
|
||||
.br
|
||||
<http://rtmpdump.mplayerhq.hu>
|
|
@ -1,395 +0,0 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<title>RTMPGW(8): </title></head>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><td>RTMPGW(8)<td align="center"><td align="right">RTMPGW(8)
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr><td>RTMPDump v2.4<td align="center">2011-07-20<td align="right">RTMPGW(8)
|
||||
</tfoot>
|
||||
<tbody><tr><td colspan="3"><br><br><ul>
|
||||
<!-- Copyright 2011 Howard Chu.
|
||||
Copying permitted according to the GNU General Public License V2.-->
|
||||
</ul>
|
||||
|
||||
<h3>NAME</h3><ul>
|
||||
rtmpgw − RTMP streaming media gateway
|
||||
</ul>
|
||||
|
||||
<h3>SYNOPSIS</h3><ul>
|
||||
<b>rtmpgw</b>
|
||||
[<b>−r</b><i> url</i>]
|
||||
[<b>−n</b><i> hostname</i>]
|
||||
[<b>−c</b><i> port</i>]
|
||||
[<b>−l</b><i> protocol</i>]
|
||||
[<b>−S</b><i> host:port</i>]
|
||||
[<b>−a</b><i> app</i>]
|
||||
[<b>−t</b><i> tcUrl</i>]
|
||||
[<b>−p</b><i> pageUrl</i>]
|
||||
[<b>−s</b><i> swfUrl</i>]
|
||||
[<b>−f</b><i> flashVer</i>]
|
||||
[<b>−u</b><i> auth</i>]
|
||||
[<b>−C</b><i> conndata</i>]
|
||||
[<b>−y</b><i> playpath</i>]
|
||||
[<b>−v</b>]
|
||||
[<b>−d</b><i> subscription</i>]
|
||||
[<b>−e</b>]
|
||||
[<b>−k</b><i> skip</i>]
|
||||
[<b>−A</b><i> start</i>]
|
||||
[<b>−B</b><i> stop</i>]
|
||||
[<b>−b</b><i> buffer</i>]
|
||||
[<b>−m</b><i> timeout</i>]
|
||||
[<b>−T</b><i> key</i>]
|
||||
[<b>−j</b><i> JSON</i>]
|
||||
[<b>−w</b><i> swfHash</i>]
|
||||
[<b>−x</b><i> swfSize</i>]
|
||||
[<b>−W</b><i> swfUrl</i>]
|
||||
[<b>−X</b><i> swfAge</i>]
|
||||
[<b>−D</b><i> address</i>]
|
||||
[<b>−g</b><i> port</i>]
|
||||
[<b>−q</b>]
|
||||
[<b>−V</b>]
|
||||
[<b>−z</b>]
|
||||
<br>
|
||||
<b>rtmpgw −h</b>
|
||||
</ul>
|
||||
|
||||
<h3>DESCRIPTION</h3><ul>
|
||||
<b>rtmpgw</b>
|
||||
is a server for streaming media content from RTMP out to HTTP.
|
||||
<p>
|
||||
<b>rtmpgw</b>
|
||||
listens for HTTP requests that specify RTMP stream parameters and
|
||||
then returns the RTMP data in the HTTP response. The only valid
|
||||
HTTP request is "GET /" but additional options can be provided
|
||||
in URL-encoded fashion. Options specified on the command line will
|
||||
be used as defaults, which can be overridden by options in the HTTP
|
||||
request.
|
||||
</ul>
|
||||
|
||||
<h3>OPTIONS</h3><ul>
|
||||
</ul>
|
||||
|
||||
<h4>Network Parameters</h4><ul>
|
||||
These options define how to connect to the media server.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−rtmp −r</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the server and media content.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−host −n</b> <i>hostname</i>
|
||||
<dd>
|
||||
Overrides the hostname in the RTMP URL.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−port −c</b> <i>port</i>
|
||||
<dd>
|
||||
Overrides the port number in the RTMP URL.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−protocol −l</b> <i>number</i>
|
||||
<dd>
|
||||
Overrides the protocol in the RTMP URL.
|
||||
<pre>
|
||||
0 = rtmp
|
||||
1 = rtmpt
|
||||
2 = rtmpe
|
||||
3 = rtmpte
|
||||
4 = rtmps
|
||||
5 = rtmpts
|
||||
</pre>
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−socks −S</b> <i>host:port</i>
|
||||
<dd>
|
||||
Use the specified SOCKS4 proxy.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Connection Parameters</h4><ul>
|
||||
These options define the content of the RTMP Connect request packet.
|
||||
If correct values are not provided, the media server will reject the
|
||||
connection attempt.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−app −a</b> <i>app</i>
|
||||
<dd>
|
||||
Name of application to connect to on the RTMP server. Overrides
|
||||
the app in the RTMP URL. Sometimes the rtmpdump URL parser cannot
|
||||
determine the app name automatically, so it must be given explicitly
|
||||
using this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−tcUrl −t</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−pageUrl −p</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the web page in which the media was embedded. By default no
|
||||
value will be sent.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfUrl −s</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the SWF player for the media. By default no value will be sent.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−flashVer −f</b> <i>version</i>
|
||||
<dd>
|
||||
Version of the Flash plugin used to run the SWF player. The
|
||||
default is "LNX 10,0,32,18".
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−auth −u</b> <i>string</i>
|
||||
<dd>
|
||||
An authentication string to be appended to the Connect message. Using
|
||||
this option will append a Boolean TRUE and then the specified string.
|
||||
This option is only used by some particular servers and is
|
||||
deprecated. The more general
|
||||
<b>−−conn</b>
|
||||
option should be used instead.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−conn −C</b> <i>type:data</i>
|
||||
<dd>
|
||||
Append arbitrary AMF data to the Connect message. The type
|
||||
must be B for Boolean, N for number, S for string, O for object, or Z
|
||||
for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE,
|
||||
respectively. Likewise for Objects the data must be 0 or 1 to end or
|
||||
begin an object, respectively. Data items in subobjects may be named, by
|
||||
prefixing the type with 'N' and specifying the name before the value, e.g.
|
||||
NB:myFlag:1. This option may be used multiple times to construct arbitrary
|
||||
AMF sequences. E.g.
|
||||
<pre>
|
||||
−C B:1 −C S:authMe −C O:1 −C NN:code:1.23 −C NS:flag:ok −C O:0
|
||||
</pre>
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Session Parameters</h4><ul>
|
||||
These options take effect after the Connect request has succeeded.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−playpath −y</b> <i>path</i>
|
||||
<dd>
|
||||
Overrides the playpath parsed from the RTMP URL. Sometimes the
|
||||
rtmpdump URL parser cannot determine the correct playpath
|
||||
automatically, so it must be given explicitly using this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−live −v</b>
|
||||
<dd>
|
||||
Specify that the media is a live stream. No resuming or seeking in
|
||||
live streams is possible.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−subscribe −d</b> <i>stream</i>
|
||||
<dd>
|
||||
Name of live stream to subscribe to. Defaults to
|
||||
<i>playpath</i>.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−start −A</b> <i>num</i>
|
||||
<dd>
|
||||
Start at
|
||||
<i>num</i>
|
||||
seconds into the stream. Not valid for live streams.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−stop −B</b> <i>num</i>
|
||||
<dd>
|
||||
Stop at
|
||||
<i>num</i>
|
||||
seconds into the stream.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−buffer −b</b> <i>num</i>
|
||||
<dd>
|
||||
Set buffer time to
|
||||
<i>num</i>
|
||||
milliseconds. The default is 20000.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−timeout −m</b> <i>num</i>
|
||||
<dd>
|
||||
Timeout the session after
|
||||
<i>num</i>
|
||||
seconds without receiving any data from the server. The default is 120.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Security Parameters</h4><ul>
|
||||
These options handle additional authentication requests from the server.
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−token −T</b> <i>key</i>
|
||||
<dd>
|
||||
Key for SecureToken response, used if the server requires SecureToken
|
||||
authentication.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−jtv −j</b> <i>JSON</i>
|
||||
<dd>
|
||||
JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfhash −w</b> <i>hexstring</i>
|
||||
<dd>
|
||||
SHA256 hash of the decompressed SWF file. This option may be needed if
|
||||
the server uses SWF Verification, but see the
|
||||
<b>−−swfVfy</b>
|
||||
option below. The hash is 32 bytes, and must be
|
||||
given in hexadecimal. The
|
||||
<b>−−swfsize</b>
|
||||
option must always be used with this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfsize −x</b> <i>num</i>
|
||||
<dd>
|
||||
Size of the decompressed SWF file. This option may be needed if the
|
||||
server uses SWF Verification, but see the
|
||||
<b>−−swfVfy</b>
|
||||
option below. The
|
||||
<b>−−swfhash</b>
|
||||
option must always be used with this option.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfVfy −W</b> <i>url</i>
|
||||
<dd>
|
||||
URL of the SWF player for this media. This option replaces all three
|
||||
of the
|
||||
<b>−−swfUrl</b>,
|
||||
<b>−−swfhash</b>,
|
||||
and
|
||||
<b>−−swfsize</b>
|
||||
options. When this option is used, the SWF player is retrieved from the
|
||||
specified URL and the hash and size are computed automatically. Also
|
||||
the information is cached in a
|
||||
<i>.swfinfo</i>
|
||||
file in the user's home directory, so that it doesn't need to be retrieved
|
||||
and recalculated every time rtmpdump is run. The .swfinfo file records
|
||||
the URL, the time it was fetched, the modification timestamp of the SWF
|
||||
file, its size, and its hash. By default, the cached info will be used
|
||||
for 30 days before re-checking.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−swfAge −X</b> <i>days</i>
|
||||
<dd>
|
||||
Specify how many days to use the cached SWF info before re-checking. Use
|
||||
0 to always check the SWF URL. Note that if the check shows that the
|
||||
SWF file has the same modification timestamp as before, it will not be
|
||||
retrieved again.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h4>Miscellaneous</h4><ul>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−device −D</b> <i>address</i>
|
||||
<dd>
|
||||
Listener IP address. The default is 0.0.0.0, i.e., any IP address.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−sport −g</b> <i>port</i>
|
||||
<dd>
|
||||
Listener port. The default is 80.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−quiet −q</b>
|
||||
<dd>
|
||||
Suppress all command output.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−verbose −V</b>
|
||||
<dd>
|
||||
Verbose command output.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−debug −z</b>
|
||||
<dd>
|
||||
Debug level output. Extremely verbose, including hex dumps of all packet data.
|
||||
</dl>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>−−help −h</b>
|
||||
<dd>
|
||||
Print a summary of command options.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>EXAMPLES</h3><ul>
|
||||
The HTTP request
|
||||
<pre>
|
||||
GET /?r=rtmp:%2f%2fserver%2fmyapp&y=somefile HTTP/1.0
|
||||
</pre>
|
||||
is equivalent to the
|
||||
<a href="../man1/rtrmpdump.1"><b>rtrmpdump</b></a>(1)
|
||||
invocation
|
||||
<pre>
|
||||
rtmpdump −r rtmp://server/myapp −y somefile
|
||||
</pre>
|
||||
<p>
|
||||
Note that only the shortform (single letter) options are supported.
|
||||
</ul>
|
||||
|
||||
<h3>ENVIRONMENT</h3><ul>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<b>HOME</b>
|
||||
<dd>
|
||||
The value of
|
||||
$<b>HOME</b>
|
||||
is used as the location for the
|
||||
<i>.swfinfo</i>
|
||||
file.
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>FILES</h3><ul>
|
||||
<p>
|
||||
<dl compact><dt>
|
||||
<i>$HOME/.swfinfo</i>
|
||||
<dd>
|
||||
Cache of SWF Verification information
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<h3>SEE ALSO</h3><ul>
|
||||
<a href="../man1/rtmpdump.1"><b>rtmpdump</b></a>(1)
|
||||
</ul>
|
||||
|
||||
<h3>AUTHORS</h3><ul>
|
||||
Andrej Stepanchuk, Howard Chu, The Flvstreamer Team
|
||||
<br>
|
||||
<<a href="http://rtmpdump.mplayerhq.hu">http://rtmpdump.mplayerhq.hu</a>>
|
||||
</ul></tbody></table></html>
|
1211
rtmp/rtmp_c/rtmpgw.c
1211
rtmp/rtmp_c/rtmpgw.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,58 +0,0 @@
|
|||
/* Thread compatibility glue
|
||||
* Copyright (C) 2009 Howard Chu
|
||||
*
|
||||
* This Program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This Program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with RTMPDump; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
#include "librtmp/log.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
HANDLE
|
||||
ThreadCreate(thrfunc *routine, void *args)
|
||||
{
|
||||
HANDLE thd;
|
||||
|
||||
thd = (HANDLE) _beginthread(routine, 0, args);
|
||||
if (thd == -1L)
|
||||
RTMP_LogPrintf("%s, _beginthread failed with %d\n", __FUNCTION__, errno);
|
||||
|
||||
return thd;
|
||||
}
|
||||
#else
|
||||
pthread_t
|
||||
ThreadCreate(thrfunc *routine, void *args)
|
||||
{
|
||||
pthread_t id = 0;
|
||||
pthread_attr_t attributes;
|
||||
int ret;
|
||||
|
||||
pthread_attr_init(&attributes);
|
||||
pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
ret =
|
||||
pthread_create(&id, &attributes, routine, args);
|
||||
if (ret != 0)
|
||||
RTMP_LogPrintf("%s, pthread_create failed with %d\n", __FUNCTION__, ret);
|
||||
|
||||
return id;
|
||||
}
|
||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||
/* Thread compatibility glue
|
||||
* Copyright (C) 2009 Howard Chu
|
||||
*
|
||||
* This Program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This Program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with RTMPDump; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __THREAD_H__
|
||||
#define __THREAD_H__ 1
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#define TFTYPE void
|
||||
#define TFRET()
|
||||
#define THANDLE HANDLE
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#define TFTYPE void *
|
||||
#define TFRET() return 0
|
||||
#define THANDLE pthread_t
|
||||
#endif
|
||||
typedef TFTYPE (thrfunc)(void *arg);
|
||||
|
||||
THANDLE ThreadCreate(thrfunc *routine, void *args);
|
||||
#endif /* __THREAD_H__ */
|
Loading…
Reference in New Issue