Resolve target hostnames to IPv4 before connecting the OSC sender - #48
Open
i2pi wants to merge 1 commit into
Open
Resolve target hostnames to IPv4 before connecting the OSC sender#48i2pi wants to merge 1 commit into
i2pi wants to merge 1 commit into
Conversation
Sending to a hostname that resolves to an IPv6 address first — most
commonly an mDNS ".local" name — fails silently: no packets are sent,
but nothing reports an error.
JUCE creates its datagram socket as IPv4-only:
handle = (int) socket (AF_INET, SOCK_DGRAM, 0); // juce_Socket.cpp
yet SocketHelpers::getAddressInfo() resolves with
hints.ai_family = AF_UNSPEC;
and DatagramSocket::write() then calls sendto() on info->ai_addr, the
first entry of the returned list, without walking it. When that first
entry is IPv6 it is handed to an AF_INET socket and every write fails.
Nothing surfaces the failure. OSCSender::connect() only binds a local
port and never resolves the target, so it returns true regardless, and
both call sites discard the bool that send() returns. The plugin loads,
controls move, host automation runs, and no packets leave the machine.
Resolve the host to an IPv4 literal before handing it to JUCE. A
dotted-quad can only ever produce an AF_INET result, so the mismatch
cannot arise. If the lookup fails or returns no IPv4 address the input
is passed through unchanged, leaving behaviour no worse than before, and
addresses that are already literals are unaffected.
Applied at both connect sites: initializeHeadless() for preset-built
plugins and PresetPage::connectOsc() for the GUI build.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfUqNJxtEHdgeKitDnNktr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Sending to a hostname that resolves to an IPv6 address first — most commonly an mDNS
.localname — fails silently. The plugin loads, controls move, host automation runs, and no packets leave the machine.I hit this driving a device at
foo.localfrom a preset-built plugin. Everything looked correct; nothing was being sent.Cause
JUCE creates its datagram socket as IPv4-only (
juce_Socket.cpp):but resolves target names with:
hints.ai_family = AF_UNSPEC;and
DatagramSocket::write()then callssendto()oninfo->ai_addr— the first entry of the returned list, without walking it:When that first entry is IPv6 it is handed to an
AF_INETsocket and every write fails. mDNS names hit this routinely, since they commonly resolve to an IPv6 link-local address ahead of the IPv4 one.Nothing surfaces the failure.
OSCSender::connect()only binds a local port and never resolves the target, so it returnstrueregardless, and both call sites discard theboolthatsend()returns.Fix
Resolve the host to an IPv4 literal before handing it to JUCE. A dotted-quad can only ever produce an
AF_INETresult, so the mismatch cannot arise.Applied at both connect sites —
initializeHeadless()for preset-built plugins andPresetPage::connectOsc()for the GUI build.The helper fails soft: if the lookup fails or returns no IPv4 address, the input is passed through unchanged, so behaviour is never worse than before. Addresses that are already literals are unaffected.
Verification
Reproduced and confirmed with the same preset text, changing only the
host:field:host:foo.local(before fix)foo.local(after fix)Verified on macOS with both the GUI build and a preset-built headless plugin, hosted in a DAW. Builds clean.
Notes
getaddrinfois available on all three platforms; includes are guarded for Windows viaws2tcpip.h.lastServerAddressin JUCE.connect()andsend()return values are discarded, which is what made this silent. Surfacing them would turn this class of failure into something visible.