--- a/CHANGES.html Fri Sep 12 10:18:55 2014 -0700
+++ b/CHANGES.html Fri Sep 12 20:47:17 2014 +0200
@@ -114,6 +114,9 @@
Data or Control channel and RbId can be configured by new attributes in RadioEnvironmentMapHelper </li>
<li> lte-sinr-chunk-processor refactored to lte-chunk-processor. Removed all lte-xxx-chunk-processor
implementations</li>
+ <li> BindToNetDevice affects also sockets using IPv6.</li>
+ <li> BindToNetDevice now calls implicitly Bind (). To bind a socket to a NetDevice and to a specific address,
+ the correct sequence is Bind (address) - BindToNetDevice (device). The opposite will raise an error.</li>
</ul>
<h2>Changes to build system:</h2>
--- a/RELEASE_NOTES Fri Sep 12 10:18:55 2014 -0700
+++ b/RELEASE_NOTES Fri Sep 12 20:47:17 2014 +0200
@@ -52,6 +52,7 @@
- Bug 1762 - UE stuck in IDLE_CONNECTING because RRC CONN REQ is not transmitted
- Bug 1811 - basic traffic generator for network module
+- Bug 1824 - L4 protocol sockets should support BindToNetDevice over IPv6
- Bug 1831 - TcpSocket SlowStartThreshold is not a TraceSource
- Bug 1851 - WifiRadioEnergyModel energy consumption values are taken from a 802.15.4 chip
- Bug 1854 - std::out_of_range Problem
--- a/src/dsdv/model/dsdv-routing-protocol.cc Fri Sep 12 10:18:55 2014 -0700
+++ b/src/dsdv/model/dsdv-routing-protocol.cc Fri Sep 12 20:47:17 2014 +0200
@@ -956,8 +956,8 @@
Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvDsdv,this));
+ socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), DSDV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
- socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), DSDV_PORT));
socket->SetAllowBroadcast (true);
socket->SetAttribute ("IpTtl",UintegerValue (1));
m_socketAddresses.insert (std::make_pair (socket,iface));
@@ -1013,9 +1013,9 @@
Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvDsdv,this));
- socket->BindToNetDevice (l3->GetNetDevice (i));
// Bind to any IP address so that broadcasts can be received
socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), DSDV_PORT));
+ socket->BindToNetDevice (l3->GetNetDevice (i));
socket->SetAllowBroadcast (true);
m_socketAddresses.insert (std::make_pair (socket,iface));
Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
--- a/src/internet/doc/internet-stack.rst Fri Sep 12 10:18:55 2014 -0700
+++ b/src/internet/doc/internet-stack.rst Fri Sep 12 20:47:17 2014 +0200
@@ -204,6 +204,35 @@
a :cpp:class:`Ipv4Address` or :cpp:class:`Ipv6Address`, these functions will
return an error. The ``Bind (void)`` and ``Bind6 (void)`` functions bind to
"0.0.0.0" and "::" respectively.
+
+The socket can also be bound to a specific NetDevice though the
+``BindToNetDevice (Ptr<NetDevice> netdevice)`` function.
+``BindToNetDevice (Ptr<NetDevice> netdevice)`` will bind the socket
+to "0.0.0.0" and "::" (equivalent to calling ``Bind ()`` and ``Bind6 ()``,
+unless the socket has been already bound to a specific address.
+Summarizing, the correct sequence is::
+
+ Ptr<Udp> udpSocketFactory = GetNode ()->GetObject<Udp> ();
+ Ptr<Socket> m_socket = socketFactory->CreateSocket ();
+ m_socket->BindToNetDevice (n_netDevice);
+ ...
+
+or::
+
+ Ptr<Udp> udpSocketFactory = GetNode ()->GetObject<Udp> ();
+ Ptr<Socket> m_socket = socketFactory->CreateSocket ();
+ m_socket->Bind (m_local_address);
+ m_socket->BindToNetDevice (n_netDevice);
+ ...
+
+The following raises an error::
+
+ Ptr<Udp> udpSocketFactory = GetNode ()->GetObject<Udp> ();
+ Ptr<Socket> m_socket = socketFactory->CreateSocket ();
+ m_socket->BindToNetDevice (n_netDevice);
+ m_socket->Bind (m_local_address);
+ ...
+
See the chapter on |ns3| sockets for more information.
We have described so far a socket factory (e.g. ``class Udp``) and a socket,
--- a/src/internet/model/tcp-socket-base.cc Fri Sep 12 10:18:55 2014 -0700
+++ b/src/internet/model/tcp-socket-base.cc Fri Sep 12 20:47:17 2014 +0200
@@ -686,21 +686,28 @@
{
NS_LOG_FUNCTION (netdevice);
Socket::BindToNetDevice (netdevice); // Includes sanity check
- if (m_endPoint == 0 && m_endPoint6 == 0)
+ if (m_endPoint == 0)
{
if (Bind () == -1)
{
- NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
+ NS_ASSERT (m_endPoint == 0);
return;
}
- NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
+ NS_ASSERT (m_endPoint != 0);
}
+ m_endPoint->BindToNetDevice (netdevice);
- if (m_endPoint != 0)
+ if (m_endPoint6 == 0)
{
- m_endPoint->BindToNetDevice (netdevice);
+ if (Bind6 () == -1)
+ {
+ NS_ASSERT (m_endPoint6 == 0);
+ return;
+ }
+ NS_ASSERT (m_endPoint6 != 0);
}
- // No BindToNetDevice() for Ipv6EndPoint
+ m_endPoint6->BindToNetDevice (netdevice);
+
return;
}
--- a/src/internet/model/udp-socket-impl.cc Fri Sep 12 10:18:55 2014 -0700
+++ b/src/internet/model/udp-socket-impl.cc Fri Sep 12 20:47:17 2014 +0200
@@ -247,6 +247,8 @@
if (InetSocketAddress::IsMatchingType (address))
{
+ NS_ASSERT_MSG (m_endPoint == 0, "Endpoint already allocated (maybe you used BindToNetDevice before Bind).");
+
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
@@ -274,6 +276,8 @@
}
else if (Inet6SocketAddress::IsMatchingType (address))
{
+ NS_ASSERT_MSG (m_endPoint == 0, "Endpoint already allocated (maybe you used BindToNetDevice before Bind).");
+
Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
Ipv6Address ipv6 = transport.GetIpv6 ();
uint16_t port = transport.GetPort ();
@@ -917,6 +921,7 @@
UdpSocketImpl::BindToNetDevice (Ptr<NetDevice> netdevice)
{
NS_LOG_FUNCTION (netdevice);
+
Socket::BindToNetDevice (netdevice); // Includes sanity check
if (m_endPoint == 0)
{
@@ -928,6 +933,17 @@
NS_ASSERT (m_endPoint != 0);
}
m_endPoint->BindToNetDevice (netdevice);
+
+ if (m_endPoint6 == 0)
+ {
+ if (Bind6 () == -1)
+ {
+ NS_ASSERT (m_endPoint6 == 0);
+ return;
+ }
+ NS_ASSERT (m_endPoint6 != 0);
+ }
+ m_endPoint6->BindToNetDevice (netdevice);
return;
}
--- a/src/network/model/socket.h Fri Sep 12 10:18:55 2014 -0700
+++ b/src/network/model/socket.h Fri Sep 12 20:47:17 2014 +0200
@@ -576,6 +576,9 @@
* is also possible to bind to mismatching device and address, even if
* the socket can not receive any packets as a result.
*
+ * \warning BindToNetDevice should be used \a after Bind. Otherwise
+ * it will perform a Bind itself.
+ *
* \param netdevice Pointer to Netdevice of desired interface
* \returns nothing
*/