Merge pull request #56 from pidarped/bug/WEAV-3155
Bind connection to interface/src address only if destination address is not link-local
diff --git a/src/inet/TCPEndPoint.cpp b/src/inet/TCPEndPoint.cpp
index a7765a4..3621615 100644
--- a/src/inet/TCPEndPoint.cpp
+++ b/src/inet/TCPEndPoint.cpp
@@ -396,34 +396,39 @@
{
// Try binding to the interface
+ // If destination is link-local then there is no need to bind to
+ // interface or address on the interface.
+
+ if (!addr.IsIPv6LinkLocal())
+ {
#ifdef SO_BINDTODEVICE
- struct ::ifreq ifr;
- memset(&ifr, 0, sizeof(ifr));
+ struct ::ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
- res = GetInterfaceName(intf, ifr.ifr_name, sizeof(ifr.ifr_name));
- if (res != INET_NO_ERROR)
- return res;
-
- // Attempt to bind to the interface using SO_BINDTODEVICE which requires privileged access.
- // If the permission is denied(EACCES) because Weave is running in a context
- // that does not have privileged access, choose a source address on the
- // interface to bind the connetion to.
- int r = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
- if (r < 0 && errno != EACCES)
- {
- return res = Weave::System::MapErrorPOSIX(errno);
- }
-
- if (r < 0)
-#endif // SO_BINDTODEVICE
- {
-
- // Attempting to initiate a connection via a specific interface is not allowed.
- // The only way to do this is to bind the local to an address on the desired
- // interface.
- res = BindSrcAddrFromIntf(addrType, intf);
+ res = GetInterfaceName(intf, ifr.ifr_name, sizeof(ifr.ifr_name));
if (res != INET_NO_ERROR)
return res;
+
+ // Attempt to bind to the interface using SO_BINDTODEVICE which requires privileged access.
+ // If the permission is denied(EACCES) because Weave is running in a context
+ // that does not have privileged access, choose a source address on the
+ // interface to bind the connetion to.
+ int r = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
+ if (r < 0 && errno != EACCES)
+ {
+ return res = Weave::System::MapErrorPOSIX(errno);
+ }
+
+ if (r < 0)
+#endif // SO_BINDTODEVICE
+ {
+ // Attempting to initiate a connection via a specific interface is not allowed.
+ // The only way to do this is to bind the local to an address on the desired
+ // interface.
+ res = BindSrcAddrFromIntf(addrType, intf);
+ if (res != INET_NO_ERROR)
+ return res;
+ }
}
}