Skip to content

Instantly share code, notes, and snippets.

@malte-v
Created April 11, 2021 13:18
Show Gist options
  • Save malte-v/1e0c910953b006701356df8ba7b20c04 to your computer and use it in GitHub Desktop.
Save malte-v/1e0c910953b006701356df8ba7b20c04 to your computer and use it in GitHub Desktop.
diff --git a/libtransmission/announcer-http.c b/libtransmission/announcer-http.c
index 8f99dfce6..34a651b3a 100644
--- a/libtransmission/announcer-http.c
+++ b/libtransmission/announcer-http.c
@@ -109,7 +109,7 @@ static char* announce_url_new(tr_session const* session, tr_announce_request con
announce twice. At any rate, we're already computing our IPv6
address (for the LTEP handshake), so this comes for free. */
- ipv6 = tr_globalIPv6();
+ ipv6 = tr_globalIPv6(session);
if (ipv6 != NULL)
{
diff --git a/libtransmission/net.c b/libtransmission/net.c
index 2f65e27e2..ffc09d99e 100644
--- a/libtransmission/net.c
+++ b/libtransmission/net.c
@@ -706,12 +706,14 @@ static int tr_globalAddress(int af, void* addr, int* addr_len)
}
/* Return our global IPv6 address, with caching. */
-unsigned char const* tr_globalIPv6(void)
+unsigned char const* tr_globalIPv6(tr_session const* session)
{
static unsigned char ipv6[16];
static time_t last_time = 0;
static bool have_ipv6 = false;
time_t const now = tr_time();
+ bool is_default;
+ const tr_address *ipv6_bindaddr;
/* Re-check every half hour */
if (last_time < now - 1800)
@@ -722,7 +724,23 @@ unsigned char const* tr_globalIPv6(void)
last_time = now;
}
- return have_ipv6 ? ipv6 : NULL;
+ if (!have_ipv6)
+ return NULL; /* No IPv6 address at all. */
+
+ /* Return the default address. This is useful for checking
+ for connectivity in general. */
+ if (session == NULL)
+ return ipv6;
+
+ /* We have some sort of address, now make sure that we return
+ our bound address if non-default. */
+
+ ipv6_bindaddr = tr_sessionGetPublicAddress(session, TR_AF_INET6, &is_default);
+ if (ipv6_bindaddr != NULL && !is_default)
+ /* Explicitly bound. Return that address. */
+ memcpy(ipv6, ipv6_bindaddr->addr.addr6.s6_addr, 16);
+
+ return ipv6;
}
/***
diff --git a/libtransmission/net.h b/libtransmission/net.h
index 8f2abdf7f..ee5056bfd 100644
--- a/libtransmission/net.h
+++ b/libtransmission/net.h
@@ -155,6 +155,6 @@ bool tr_net_hasIPv6(tr_port);
*/
char* tr_net_strerror(char* buf, size_t buflen, int err);
-unsigned char const* tr_globalIPv6(void);
+unsigned char const* tr_globalIPv6(tr_session const* session);
TR_END_DECLS
diff --git a/libtransmission/peer-msgs.c b/libtransmission/peer-msgs.c
index e0b8b11a5..79d3f7e71 100644
--- a/libtransmission/peer-msgs.c
+++ b/libtransmission/peer-msgs.c
@@ -862,7 +862,7 @@ static void sendLtepHandshake(tr_peerMsgs* msgs)
bool allow_pex;
struct evbuffer* payload;
struct evbuffer* out = msgs->outMessages;
- unsigned char const* ipv6 = tr_globalIPv6();
+ unsigned char const* ipv6 = tr_globalIPv6(msgs->io->session);
static tr_quark version_quark = 0;
if (msgs->clientSentLtepHandshake)
@@ -2743,7 +2743,7 @@ tr_peerMsgs* tr_peerMsgsNew(struct tr_torrent* torrent, struct tr_peerIo* io, tr
/* Only send PORT over IPv6 when the IPv6 DHT is running (BEP-32). */
struct tr_address const* addr = tr_peerIoGetAddress(m->io, NULL);
- if (addr->type == TR_AF_INET || tr_globalIPv6() != NULL)
+ if (addr->type == TR_AF_INET || tr_globalIPv6(NULL) != NULL)
{
protocolSendPort(m, tr_dhtPort(torrent->session));
}
diff --git a/libtransmission/tr-udp.c b/libtransmission/tr-udp.c
index 17d569d3c..fcb783946 100644
--- a/libtransmission/tr-udp.c
+++ b/libtransmission/tr-udp.c
@@ -132,9 +132,8 @@ void tr_udpSetSocketBuffers(tr_session* session)
static void rebind_ipv6(tr_session* ss, bool force)
{
bool is_default;
- struct tr_address const* public_addr;
struct sockaddr_in6 sin6;
- unsigned char const* ipv6 = tr_globalIPv6();
+ unsigned char const* ipv6 = tr_globalIPv6(ss);
tr_socket_t s = TR_BAD_SOCKET;
int rc;
int one = 1;
@@ -179,12 +178,6 @@ static void rebind_ipv6(tr_session* ss, bool force)
}
sin6.sin6_port = htons(ss->udp_port);
- public_addr = tr_sessionGetPublicAddress(ss, TR_AF_INET6, &is_default);
-
- if (public_addr != NULL && !is_default)
- {
- sin6.sin6_addr = public_addr->addr.addr6;
- }
rc = bind(s, (struct sockaddr*)&sin6, sizeof(sin6));
@@ -349,7 +342,7 @@ void tr_udpInit(tr_session* ss)
}
IPV6:
- if (tr_globalIPv6() != NULL)
+ if (tr_globalIPv6(NULL) != NULL)
{
rebind_ipv6(ss, true);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment