From b15fc60d635e01a02d8f63222f3997c912a7d5fc Mon Sep 17 00:00:00 2001 From: pkv Date: Sat, 13 May 2023 18:13:10 +0200 Subject: [PATCH] obs-ffmpeg: Fix rendezvous mode with SRT Rendezvous mode with SRT protocol is used to punch through firewalls. Although caller or listener mode are much more widespread, it is sometimes in use. The rendezvous mode was broken in obs because we would bind to the remote IP, instead of a local IP. This fixes the bug. Note that there is also a bug in libsrt preventing our code to work. But Version 1.5.2+ of libsrt fixes that. Signed-off-by: pkv --- plugins/obs-ffmpeg/obs-ffmpeg-srt.h | 32 ++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-srt.h b/plugins/obs-ffmpeg/obs-ffmpeg-srt.h index cbd5f294f..41a0a64e7 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-srt.h +++ b/plugins/obs-ffmpeg/obs-ffmpeg-srt.h @@ -73,6 +73,8 @@ typedef struct SRTContext { char *smoother; int messageapi; SRT_TRANSTYPE transtype; + char *localip; + char *localport; int linger; int tsbpd; double time; // time in s in order to post logs at definite intervals @@ -458,6 +460,7 @@ static int libsrt_setup(URLContext *h, const char *uri) char portstr[10]; int64_t open_timeout = 0; int eid, write_eid; + struct sockaddr_in la; av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); @@ -500,7 +503,24 @@ static int libsrt_setup(URLContext *h, const char *uri) } cur_ai = ai; - + if (s->mode == SRT_MODE_RENDEZVOUS) { + if (s->localip == NULL || s->localport == NULL) { + blog(LOG_ERROR, "Invalid adapter configuration\n"); + return OBS_OUTPUT_CONNECT_FAILED; + } + blog(LOG_DEBUG, + "[obs-ffmpeg mpegts muxer / libsrt]: Adapter options %s:%s\n", + s->localip, s->localport); + int lp = strtol(s->localport, NULL, 10); + if (lp <= 0 || lp >= 65536) { + blog(LOG_ERROR, + "[obs-ffmpeg mpegts muxer / libsrt]: Local port missing in URL\n"); + return OBS_OUTPUT_CONNECT_FAILED; + } + la.sin_family = AF_INET; + la.sin_port = htons(port); + inet_pton(AF_INET, s->localip, &la.sin_addr.s_addr); + } restart: fd = srt_create_socket(); @@ -544,8 +564,8 @@ restart: fd = ret; } else { if (s->mode == SRT_MODE_RENDEZVOUS) { - if (srt_bind(fd, cur_ai->ai_addr, - (int)(cur_ai->ai_addrlen))) { + if (srt_bind(fd, (struct sockaddr *)&la, + sizeof(struct sockaddr_in))) { ret = libsrt_neterrno(h); srt_epoll_release(write_eid); goto fail1; @@ -780,6 +800,12 @@ static int libsrt_open(URLContext *h, const char *uri) if (av_find_info_tag(buf, sizeof(buf), "linger", p)) { s->linger = strtol(buf, NULL, 10); } + if (av_find_info_tag(buf, sizeof(buf), "localip", p)) { + s->localip = av_strndup(buf, strlen(buf)); + } + if (av_find_info_tag(buf, sizeof(buf), "localport", p)) { + s->localport = av_strndup(buf, strlen(buf)); + } } ret = libsrt_setup(h, uri); if (ret < 0)