From: Marvin Scholz <epirat07@gmail.com> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: Re: [FFmpeg-devel] [PATCH] avformat/http: Handle IPv6 Zone ID in hostname Date: Wed, 04 Jun 2025 15:00:51 +0200 Message-ID: <E04814AF-EE58-4788-A4F0-417E218EA752@gmail.com> (raw) In-Reply-To: <2002494.PYKUYFuaPT@basile.remlab.net> On 2 Jun 2025, at 22:29, Rémi Denis-Courmont wrote: > Le torstaina 22. toukokuuta 2025, 21.38.32 Itä-Euroopan kesäaika Marvin Scholz > a écrit : >> When using a literal IPv6 address as hostname, >> it can contain a Zone ID >> especially in the case of link-local addresses. Sending this to the >> server in the Host header is not useful to the server and in some cases >> servers refuse such requests. >> >> To prevent any such issues, strip the Zone ID from the address if it's >> an IPv6 address. This also removes it for the Cookies lookup. >> >> Based on a patch by: Daniel N Pettersson <danielnp@axis.com> >> --- >> libavformat/http.c | 60 +++++++++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 59 insertions(+), 1 deletion(-) >> >> diff --git a/libavformat/http.c b/libavformat/http.c >> index f7b2a8a029..3bde616b43 100644 >> --- a/libavformat/http.c >> +++ b/libavformat/http.c >> @@ -24,6 +24,7 @@ >> #include "config.h" >> #include "config_components.h" >> >> +#include <string.h> >> #include <time.h> >> #if CONFIG_ZLIB >> #include <zlib.h> >> @@ -209,6 +210,63 @@ void ff_http_init_auth_state(URLContext *dest, const >> URLContext *src) sizeof(HTTPAuthState)); >> } >> >> +static bool host_is_numeric_ipv6(const char *host) >> +{ >> + bool res = false; >> +#if defined(AF_INET6) >> + struct addrinfo hints = { .ai_flags = AI_NUMERICHOST }, *ai; >> + if (getaddrinfo(host, NULL, &hints, &ai) == 0) { >> + if (ai->ai_family == AF_INET6) >> + res = true; >> + freeaddrinfo(ai); >> + } >> +#else >> + // Just guess based on if the host contains a ':' >> + if (strchr(host, ':') != NULL) >> + res = true; >> +#endif >> + return res; >> +} Hi, thanks for the review. > > At least in a URL, the distinction is done by the presence of surrounding > brackets, not actually parsing the address. And on the flip side, to my > knowledge, there are no guarantees that getaddrinfo() even copes well with > scope IDs. That's platform-dependent. Given the first thing that is done to the URL is to split it into components, that removes the [] so I can't just check for those, sadly. Anyway if this does not work, it is a pre-existing issue as this is essentially the same that ff_url_join did internally before. Not saying we should not fix it, but apparently no one ran into this till now. I guess I can just check for presence of : though as I cant think of any valid case where a non-IPv6 host would contain a :? > >> + >> +/** >> + * Copy the normalized host to the given buffer >> + * >> + * If the host is a normal hostname, this just returns >> + * host:port. However in case of an IPv6 address, it >> + * ensures proper escaping with [] and removes the >> + * zone identifier, if any, making the return suitable >> + * for example for use in the HTTP Host header. >> + */ >> +static unsigned copy_normalized_host(char *out, unsigned size, >> + const char *host, const int port) >> +{ >> + AVBPrint bp; >> + av_bprint_init_for_buffer(&bp, out, size); >> + >> + if (host_is_numeric_ipv6(host)) { >> + // This is an IPv6 address, so we need to strip the Zone ID, >> + // if any. >> + // While technically we could have percent encoding even in >> + // the Zone ID, this doesn't seem to be a relevant case in >> + // the real world on any platform. >> + char *percent = strrchr(host, '%'); > > Uh, doesn't Linux actually use % in interface names sometimes? I never encountered that, but I can just use strchr here anyway I just realized as percent encoding is not used in other cases anyway, in the hostname. > >> + if (percent) { >> + int len = (percent - host); >> + av_bprintf(&bp, "[%.*s]", len, host); >> + } else { >> + av_bprintf(&bp, "[%s]", host); >> + } >> + } else { >> + // Host is not an IPv6 address, so just use as-is >> + av_bprintf(&bp, "%s", host); >> + } > > This looks like reverse abstraction and kinda sketchy. How do you end up with > a scope ID in the input? Simplest example is a user providing a URL with a IPv6 literal that has a scope ID. > > While it's true that it shouldn't be sent to the server, it's also so that it > shouldn't appear in the URL. There is RFC 6874 that solely focuses an how to represent a scope ID in a URI, why is that invalid? And if it were, how would the user tell ffmpeg which interface to use for link local IPv6? > In other words, it should have been stripped > earlier than the HTTP input module. The Host field should be the same as the > host in the absolute URL. I don't think there is an earlier point that makes sense to strip it? I am stripping it in the internal http context open function, I can not strip it before that as the underlying connection still needs to know the proper zone id to correctly establish the connection using the right interface. Unless I am missing something or misunderstand what you meant, I am not sure how I can change this. > > -- > Rémi Denis-Courmont > Villeneuve de Tapiola, ex-République finlandaise d´Uusimaa > > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
prev parent reply other threads:[~2025-06-04 13:01 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2025-05-22 18:38 Marvin Scholz 2025-06-02 20:29 ` Rémi Denis-Courmont 2025-06-04 13:00 ` Marvin Scholz [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=E04814AF-EE58-4788-A4F0-417E218EA752@gmail.com \ --to=epirat07@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git