Skip to content

Conversation

@Nardol
Copy link
Contributor

@Nardol Nardol commented Dec 12, 2025

Fixes #1987

Context
The Android client could not connect to an IPv6-only TeamTalk server. On some Android devices/networks, name resolution via getaddrinfo() can also fail transiently (EAI_AGAIN), making connections unreliable even when IPv6 connectivity is available.

What this changes

  • Fix UDP socket creation to match the resolved address family (AF_INET/AF_INET6) instead of always forcing IPv4.
  • Make native resolution more robust on Android: retry on EAI_AGAIN, avoid problematic getaddrinfo() flags/constraints, and handle numeric IPv4/IPv6 literals without relying on the platform resolver.
  • On Android, prefer DnsResolver (system ordering) and only fall back to UDP/53 DNS as a last resort (resolver timeouts/failures), with caching and logs limited to the fallback path.

Compatibility / Risk

  • Keeps IPv4-only and dual-stack working.
  • The UDP/53 fallback is intentionally last-resort (unencrypted) to avoid total failure when the system/NDK resolver is flaky.

Testing

  • Verified on device: connects to IPv6-only server, dual-stack hostname (respects system preference), and IPv4-only server.

@Nardol Nardol force-pushed the android-ipv6-udp branch 2 times, most recently from 062df2a to d8224e4 Compare December 12, 2025 22:36
@hwangsihu hwangsihu requested a review from Copilot December 13, 2025 06:35
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Fix native UDP socket family for IPv6 (Android)
- Make address resolution robust on Android (IPv6 literals + getaddrinfo quirks)
- Add Android-side DNS fallback for Private DNS resolver timeouts (udp/53)
- Respect system address ordering and cache DNS results

Signed-off-by: Patrick ZAJDA <patrick@zajda.fr>
@Nardol
Copy link
Contributor Author

Nardol commented Dec 14, 2025

Copilot Review suggestions applied, except hostname and port are two different fields and a TeamTalk server can be on a local network.

@bear101
Copy link
Contributor

bear101 commented Dec 15, 2025

Is there a way to avoid changing files in TeamTalk DLL? It appears strange that it works on all other platform than Android.

Is it possible to make the DNS lookup in TeamTalkAndroid and always pass an IP-address (instead of a hostname) to TT_Connect()?

@Nardol
Copy link
Contributor Author

Nardol commented Dec 15, 2025

I tried an Android-only approach (no changes in TeamTalk DLL / TeamTalkLib): resolve hostnames in TeamTalkAndroid (DnsResolver on API 29+, fallback to InetAddress) and always pass IP literals to TT_Connect().
Result: even when we successfully resolve and pass an IPv6 literal, the connection still fails on Android.
Example logs:

DNS: Candidates for ipv6.hostname.tld -> [2001:xxxx:yyyy:zzzz::]
connect() to 2001:xxxx:yyyy:zzzz:: ... -> false

And even when entering the IPv6 literal directly:

connect(): host=2001:xxxx:yyyy:zzzz:: candidates=[2001:xxxx:yyyy:zzzz::]
connect() ... -> false

So this is not just a hostname/DNS issue. The Android native layer (JNI / underlying socket/connect path) appears to fail for IPv6, meaning an Android-only DNS workaround cannot fix #1987 on its own.

I pushed a branch called android-ipv6-java-only to test.

Proposed compromise:
We could keep the Android-side hostname resolution as a fallback to improve dual-stack hostname handling (and avoid DNS issues/timeouts), but it won’t fix IPv6-only/IPv6 literal connects.
The actual fix should be in the native layer so that TT_Connect() works with IPv6 literals on Android (proper IPv6 parsing + socket connect), ideally with additional Android-native logging (errno/family/address) to validate the fix.

bear101 added a commit that referenced this pull request Dec 30, 2025
This change addresses the issue #3045 where getaddrinfo() may return
EAI_AGAIN on Android. By continuously calling TeamTalk5.connect() in
TeamTalkService it has the same effect as calling getaddrinfo()
multiple times.

Hopefully this change resolves #3045.
bear101 added a commit that referenced this pull request Jan 2, 2026
This change addresses the issue #3045 where getaddrinfo() may return
EAI_AGAIN on Android. By continuously calling TeamTalk5.connect() in
TeamTalkService it has the same effect as calling getaddrinfo()
multiple times.

Hopefully this change resolves #3045.
bear101 added a commit that referenced this pull request Jan 4, 2026
This change addresses the issue #3045 where getaddrinfo() may return
EAI_AGAIN on Android. By continuously calling TeamTalk5.connect() in
TeamTalkService it has the same effect as calling getaddrinfo()
multiple times.

Hopefully this change resolves #3045.
bear101 added a commit that referenced this pull request Jan 4, 2026
This change addresses the issue #3045 where getaddrinfo() may return
EAI_AGAIN on Android. By continuously calling TeamTalk5.connect() in
TeamTalkService it has the same effect as calling getaddrinfo()
multiple times.

Hopefully this change resolves #3045.
@bear101
Copy link
Contributor

bear101 commented Jan 7, 2026

I'll resolve the conflicts with master but I plan to put #ifdef ANDROID around the new code in this merge-request. The new code complicates the code a lot and the problems with IPv6 are only related to Android.

Should there also be a check on Android platform level? In other words does newer Android devices also have this issue?

// IPv6 literals may include a zone index, e.g. "fe80::1%wlan0".
std::string v6addr = host_utf8;
std::string v6scope;
auto percent = host_utf8.find('%');
Copy link
Contributor

@bear101 bear101 Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v6addr and v6scope extraction could be simplified a lot by using a regular expression.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regex would add complexity and has known perf/portability issues on Android/NDK; I’d prefer the current simple split.

@Nardol
Copy link
Contributor Author

Nardol commented Jan 7, 2026

Should there also be a check on Android platform level? In other words does newer Android devices also have this issue?

Yes, I’m using a Pixel 8a running Android 16, and I’m experiencing this issue.

@bear101
Copy link
Contributor

bear101 commented Jan 7, 2026

@beqabeqa473 are you ok with the changes in this PR? In the TeamTalk DLL I've isolated the Android code, so none of the other platforms are affected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TeamTalk for Android cannot connect to IPv6 servers

2 participants