[FFmpeg-devel] TCP socket descriptor leak on listen and interrupt
Michael Niedermayer
michaelni at gmx.at
Fri Sep 11 22:01:09 CEST 2015
On Fri, Sep 11, 2015 at 09:27:11PM +0200, Stephan Holljes wrote:
> On Fri, Sep 11, 2015 at 8:48 AM, Alexander Drozdov <adrozdoff at gmail.com> wrote:
> > Hi all!
> >
> > We are found another descriptors leak :-)
> >
> > If we try to listen on TCP port and ff_listen() fails on
> > interrupt callback, socket (bind) descriptor overwrites at the tcp_open()
> > and does not closed at all.
> >
> > As a result, we can't rebind to the same port.
> >
> > Minimal sample for issue (sorry for C++ in some places :-), also sample
> > code assumes that librtmp does not used - it does not allow to listen):
> > ```
> > #include <iostream>
> > #include <unistd.h>
> >
> > extern "C" {
> > #ifndef __STDC_CONSTANT_MACROS
> > #define __STDC_CONSTANT_MACROS
> > #endif
> >
> > #include <libavcodec/avcodec.h>
> > #include <libavformat/avformat.h>
> > #include <libavfilter/avfilter.h>
> > #include <libswscale/swscale.h>
> > #include <libavdevice/avdevice.h>
> > #include <libswresample/swresample.h>
> > #include <libavutil/log.h>
> > }
> >
> > int openInputInterruptCallBack(void *ctx)
> > {
> > // I know, stupid code :-) in real code more complex logic here
> > return 1;
> > }
> >
> > int main(int argc, char **argv) {
> > std::cout << "Hello, world!" << std::endl;
> >
> > avdevice_register_all();
> > avcodec_register_all();
> > avfilter_register_all();
> > av_register_all();
> > avformat_network_init();
> >
> > AVFormatContext *mpFormatCtx = avformat_alloc_context();
> > mpFormatCtx->interrupt_callback.callback = &openInputInterruptCallBack;
> > mpFormatCtx->interrupt_callback.opaque = mpFormatCtx;
> >
> > AVDictionary * dict = nullptr;
> > av_dict_set_int(&dict, "rtmp_listen", 1, 0);
> > av_dict_set_int(&dict, "timeout", -1, 0);
> > av_dict_set(&dict, "rtmp_live", "live", 0);
> > char* inputFileName = "rtmp://0.0.0.0:1936/live/mystream";
> > AVInputFormat *pInAvFormat = av_find_input_format(inputFileName);
> >
> > int err = avformat_open_input(&mpFormatCtx, inputFileName, pInAvFormat,
> > &dict);
> > // avformat_open_input() fails here but bind socket descriptor still
> > open.
> > // we can check it via `ls -l /proc/PID/fd`
> >
> > if(err != 0) {
> > char errMsg[100];
> > av_strerror(err, errMsg, 100);
> > std::cout << "Couldn't open input source: " << inputFileName <<",
> > err : " << errMsg << std::endl;
> > avformat_network_deinit();
> >
> > for (;;)
> > sleep(1);
> >
> > return -1;
> > } else {
> > avformat_close_input(&mpFormatCtx);
> > avformat_network_deinit();
> > }
> >
> > return 0;
> > }
> > ```
> >
> > Fix is attached to the letter.
> >
> > --
> > WBR, Alexander Drozdov
> > http://htrd.su
> >
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel at ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
>
> I worked on this code and patch LGTM. I can follow where and how the
> filedescriptor is lost/leaked.
> Minor thing: the second line of the if-clause should line up with the
> parenthesis.
fixed
applied
thanks
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Let us carefully observe those good qualities wherein our enemies excel us
and endeavor to excel them, by avoiding what is faulty, and imitating what
is excellent in them. -- Plutarch
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150911/93fbaec4/attachment.sig>
More information about the ffmpeg-devel
mailing list