[FFmpeg-devel] TCP socket descriptor leak on listen and interrupt
Stephan Holljes
klaxa1337 at googlemail.com
Fri Sep 11 21:27:11 CEST 2015
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.
Regards,
Stephan
More information about the ffmpeg-devel
mailing list