View | Details | Raw Unified | Return to bug 2758
Collapse All | Expand All

(-)a/CHANGES.html (+11 lines)
 Lines 119-124    Link Here 
119
    and <b>WifiPhy::MaxSupportedRxSpatialStreams</b>. A new attribute <b>WifiPhy::Antennas</b>
119
    and <b>WifiPhy::MaxSupportedRxSpatialStreams</b>. A new attribute <b>WifiPhy::Antennas</b>
120
    was added to allow users to define the number of physical antennas on the device.
120
    was added to allow users to define the number of physical antennas on the device.
121
</li>
121
</li>
122
<li>Sockets do not receive anymore broadcast packets, unless they are bound to an "Any" address (0.0.0.0)
123
    or to a subnet-directed broadcast packet (e.g., x.y.z.0 for a /24 noterok).
124
    As in Linux, the following rules are now enforced:
125
    <ul>
126
    <li> A socket bound to 0.0.0.0 will receive everything.</li>
127
    <li> A socket bound to x.y.z.0/24 will receive subnet-directed broadcast (x.y.z.255) and unicast packets.</li>
128
    <li> A socket bound to x.y.z.w will only receive unicast packets.</li>
129
    </ul> 
130
    <b>Previously, a socket bound to an unicast address received also subnet-directed broadcast packets. 
131
    This is not anymore possible</b>.
132
</li>
122
</ul>
133
</ul>
123
<h2>Changes to build system:</h2>
134
<h2>Changes to build system:</h2>
124
<ul>
135
<ul>
(-)a/src/internet/model/ipv4-end-point-demux.cc (-52 / +76 lines)
 Lines 205-211    Link Here 
205
  EndPoints retval3; // Matches all but local address
205
  EndPoints retval3; // Matches all but local address
206
  EndPoints retval4; // Exact match on all 4
206
  EndPoints retval4; // Exact match on all 4
207
207
208
  NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
208
  NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr << ":" << dport);
209
  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
209
  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
210
    {
210
    {
211
      Ipv4EndPoint* endP = *i;
211
      Ipv4EndPoint* endP = *i;
 Lines 241-313    Link Here 
241
              continue;
241
              continue;
242
            }
242
            }
243
        }
243
        }
244
      bool subnetDirected = false;
244
245
      Ipv4Address incomingInterfaceAddr = daddr;  // may be a broadcast
245
      bool localAddressMatchesExact = false;
246
      for (uint32_t i = 0; i < incomingInterface->GetNAddresses (); i++)
246
      bool localAddressIsAny = false;
247
      bool localAddressIsSubnetAny = false;
248
249
      // We have 3 cases:
250
      // 1) Exact local / destination address match
251
      // 2) Local endpoint bound to Any -> matches anything
252
      // 3) Local endpoint bound to x.y.z.0 -> matches Subnet-directed broadcast packet (e.g., x.y.z.255 in a /24 net) and direct destination match.
253
254
      if (endP->GetLocalAddress () == daddr)
255
        {
256
          // Case 1:
257
          localAddressMatchesExact = true;
258
        }
259
      else if (endP->GetLocalAddress () == Ipv4Address::GetAny ())
247
        {
260
        {
248
          Ipv4InterfaceAddress addr = incomingInterface->GetAddress (i);
261
          // Case 2:
249
          if (addr.GetLocal ().CombineMask (addr.GetMask ()) == daddr.CombineMask (addr.GetMask ()) &&
262
          localAddressIsAny = true;
250
              daddr.IsSubnetDirectedBroadcast (addr.GetMask ()))
263
        }
264
      else
265
        {
266
          // Case 3:
267
          for (uint32_t i = 0; i < incomingInterface->GetNAddresses (); i++)
251
            {
268
            {
252
              subnetDirected = true;
269
              Ipv4InterfaceAddress addr = incomingInterface->GetAddress (i);
253
              incomingInterfaceAddr = addr.GetLocal ();
270
271
              Ipv4Address addrNetpart = addr.GetLocal ().CombineMask (addr.GetMask ());
272
              if (endP->GetLocalAddress () == addrNetpart)
273
                {
274
                  NS_LOG_LOGIC ("Endpoint is SubnetDirectedAny " << endP->GetLocalAddress () << "/" << addr.GetMask ().GetPrefixLength ());
275
276
                  Ipv4Address daddrNetPart = daddr.CombineMask (addr.GetMask ());
277
                  if (addrNetpart == daddrNetPart)
278
                    {
279
                      localAddressIsSubnetAny = true;
280
                    }
281
                }
254
            }
282
            }
255
        }
256
      bool isBroadcast = (daddr.IsBroadcast () || subnetDirected == true);
257
      NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast);
258
      bool localAddressMatchesWildCard = 
259
        endP->GetLocalAddress () == Ipv4Address::GetAny ();
260
      bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;
261
283
262
      if (isBroadcast)
284
          // if no match here, keep looking
263
        {
285
          if (!localAddressIsSubnetAny)
264
          NS_LOG_DEBUG ("Found bcast, localaddr " << endP->GetLocalAddress ());
286
            continue;
265
        }
287
        }
266
288
267
      if (isBroadcast && (endP->GetLocalAddress () != Ipv4Address::GetAny ()))
289
      bool remotePortMatchesExact = endP->GetPeerPort () == sport;
268
        {
290
      bool remotePortMatchesWildCard = endP->GetPeerPort () == 0;
269
          localAddressMatchesExact = (endP->GetLocalAddress () ==
270
                                      incomingInterfaceAddr);
271
        }
272
      // if no match here, keep looking
273
      if (!(localAddressMatchesExact || localAddressMatchesWildCard))
274
        continue; 
275
      bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
276
      bool remotePeerMatchesWildCard = endP->GetPeerPort () == 0;
277
      bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
291
      bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
278
      bool remoteAddressMatchesWildCard = endP->GetPeerAddress () ==
292
      bool remoteAddressMatchesWildCard = endP->GetPeerAddress () == Ipv4Address::GetAny ();
279
        Ipv4Address::GetAny ();
293
280
      // If remote does not match either with exact or wildcard,
294
      // If remote does not match either with exact or wildcard,
281
      // skip this one
295
      // skip this one
282
      if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
296
      if (!(remotePortMatchesExact || remotePortMatchesWildCard))
283
        continue;
297
        continue;
284
      if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
298
      if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
285
        continue;
299
        continue;
286
300
287
      // Now figure out which return list to add this one to
301
      bool localAddressMatchesWildCard = localAddressIsAny || localAddressIsSubnetAny;
288
      if (localAddressMatchesWildCard &&
302
289
          remotePeerMatchesWildCard &&
303
//      std::cout << " *** Last checks " << endP->GetLocalAddress () << ":" << endP->GetLocalPort () <<
290
          remoteAddressMatchesWildCard)
304
//          " " << localAddressMatchesExact <<
291
        { // Only local port matches exactly
305
//          " " << localAddressMatchesWildCard <<
292
          retval1.push_back (endP);
306
//          " " << remoteAddressMatchesExact <<
307
//          " " << remoteAddressMatchesWildCard <<
308
//          " " << remotePortMatchesExact <<
309
//          " " << remotePortMatchesWildCard << std::endl;
310
311
312
      if (localAddressMatchesExact && remoteAddressMatchesExact && remotePortMatchesExact)
313
        { // All 4 match - this is the case of an open TCP connection, for example.
314
          NS_LOG_LOGIC ("Found an endpoint for case 4, adding " << endP->GetLocalAddress () << ":" << endP->GetLocalPort ());
315
//          std::cout << "Found an endpoint for case 4, adding " << endP->GetLocalAddress () << ":" << endP->GetLocalPort () << std::endl;
316
          retval4.push_back (endP);
293
        }
317
        }
294
      if ((localAddressMatchesExact || (isBroadcast && localAddressMatchesWildCard))&&
318
      if (localAddressMatchesWildCard && remoteAddressMatchesExact && remotePortMatchesExact)
295
          remotePeerMatchesWildCard &&
319
        { // All but local address - no idea what this case could be.
296
          remoteAddressMatchesWildCard)
320
          NS_LOG_LOGIC ("Found an endpoint for case 3, adding " << endP->GetLocalAddress () << ":" << endP->GetLocalPort ());
297
        { // Only local port and local address matches exactly
321
//          std::cout << "Found an endpoint for case 3, adding " << endP->GetLocalAddress () << ":" << endP->GetLocalPort () << std::endl;
322
          retval3.push_back (endP);
323
        }
324
      if (localAddressMatchesExact && remoteAddressMatchesWildCard && remotePortMatchesWildCard)
325
        { // Only local port and local address matches exactly - Not yet opened connection
326
          NS_LOG_LOGIC ("Found an endpoint for case 2, adding " << endP->GetLocalAddress () << ":" << endP->GetLocalPort ());
327
//          std::cout << "Found an endpoint for case 2, adding " << endP->GetLocalAddress () << ":" << endP->GetLocalPort () << std::endl;
298
          retval2.push_back (endP);
328
          retval2.push_back (endP);
299
        }
329
        }
300
      if (localAddressMatchesWildCard &&
330
      if (localAddressMatchesWildCard && remoteAddressMatchesWildCard && remotePortMatchesWildCard)
301
          remotePeerMatchesExact &&
331
        { // Only local port matches exactly - Endpoint open to "any" connection
302
          remoteAddressMatchesExact)
332
          NS_LOG_LOGIC ("Found an endpoint for case 1, adding " << endP->GetLocalAddress () << ":" << endP->GetLocalPort ());
303
        { // All but local address
333
//          std::cout << "Found an endpoint for case 1, adding " << endP->GetLocalAddress () << ":" << endP->GetLocalPort () << std::endl;
304
          retval3.push_back (endP);
334
          retval1.push_back (endP);
305
        }
306
      if (localAddressMatchesExact &&
307
          remotePeerMatchesExact &&
308
          remoteAddressMatchesExact)
309
        { // All 4 match
310
          retval4.push_back (endP);
311
        }
335
        }
312
    }
336
    }
313
337
(-)a/src/internet/model/udp-socket-impl.cc (-22 / +5 lines)
 Lines 572-599    Link Here 
572
              if (ipv4->GetNetDevice (i) != m_boundnetdevice)
572
              if (ipv4->GetNetDevice (i) != m_boundnetdevice)
573
                continue;
573
                continue;
574
            }
574
            }
575
          Ipv4Mask maski = iaddr.GetMask ();
575
          NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << dest);
576
          if (maski == Ipv4Mask::GetOnes ())
576
          m_udp->Send (p->Copy (), addri, dest,
577
            {
577
                       m_endPoint->GetLocalPort (), port);
578
              // if the network mask is 255.255.255.255, do not convert dest
578
          NotifyDataSent (p->GetSize ());
579
              NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << dest
579
          NotifySend (GetTxAvailable ());
580
                                                     << " (mask is " << maski << ")");
581
              m_udp->Send (p->Copy (), addri, dest,
582
                           m_endPoint->GetLocalPort (), port);
583
              NotifyDataSent (p->GetSize ());
584
              NotifySend (GetTxAvailable ());
585
            }
586
          else
587
            {
588
              // Convert to subnet-directed broadcast
589
              Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
590
              NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast
591
                                                     << " (mask is " << maski << ")");
592
              m_udp->Send (p->Copy (), addri, bcast,
593
                           m_endPoint->GetLocalPort (), port);
594
              NotifyDataSent (p->GetSize ());
595
              NotifySend (GetTxAvailable ());
596
            }
597
        }
580
        }
598
      NS_LOG_LOGIC ("Limited broadcast end.");
581
      NS_LOG_LOGIC ("Limited broadcast end.");
599
      return p->GetSize ();
582
      return p->GetSize ();
(-)a/src/internet/test/udp-test.cc (-9 / +10 lines)
 Lines 342-377    Link Here 
342
  // Receiver Node
342
  // Receiver Node
343
  ipv4 = rxNode->GetObject<Ipv4> ();
343
  ipv4 = rxNode->GetObject<Ipv4> ();
344
  netdev_idx = ipv4->AddInterface (net1.Get (0));
344
  netdev_idx = ipv4->AddInterface (net1.Get (0));
345
  ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.1"), Ipv4Mask (0xffff0000U));
345
  ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.1"), Ipv4Mask ("/24"));
346
  ipv4->AddAddress (netdev_idx, ipv4Addr);
346
  ipv4->AddAddress (netdev_idx, ipv4Addr);
347
  ipv4->SetUp (netdev_idx);
347
  ipv4->SetUp (netdev_idx);
348
348
349
  netdev_idx = ipv4->AddInterface (net2.Get (0));
349
  netdev_idx = ipv4->AddInterface (net2.Get (0));
350
  ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.1.1"), Ipv4Mask (0xffff0000U));
350
  ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.1.1"), Ipv4Mask ("/24"));
351
  ipv4->AddAddress (netdev_idx, ipv4Addr);
351
  ipv4->AddAddress (netdev_idx, ipv4Addr);
352
  ipv4->SetUp (netdev_idx);
352
  ipv4->SetUp (netdev_idx);
353
353
354
  // Sender Node
354
  // Sender Node
355
  ipv4 = txNode->GetObject<Ipv4> ();
355
  ipv4 = txNode->GetObject<Ipv4> ();
356
  netdev_idx = ipv4->AddInterface (net1.Get (1));
356
  netdev_idx = ipv4->AddInterface (net1.Get (1));
357
  ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.2"), Ipv4Mask (0xffff0000U));
357
  ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.2"), Ipv4Mask ("/24"));
358
  ipv4->AddAddress (netdev_idx, ipv4Addr);
358
  ipv4->AddAddress (netdev_idx, ipv4Addr);
359
  ipv4->SetUp (netdev_idx);
359
  ipv4->SetUp (netdev_idx);
360
360
361
  netdev_idx = ipv4->AddInterface (net2.Get (1));
361
  netdev_idx = ipv4->AddInterface (net2.Get (1));
362
  ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.1.2"), Ipv4Mask (0xffff0000U));
362
  ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.1.2"), Ipv4Mask ("/24"));
363
  ipv4->AddAddress (netdev_idx, ipv4Addr);
363
  ipv4->AddAddress (netdev_idx, ipv4Addr);
364
  ipv4->SetUp (netdev_idx);
364
  ipv4->SetUp (netdev_idx);
365
365
366
  // Create the UDP sockets
366
  // Create the UDP sockets
367
  Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
367
  Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
368
368
  Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
369
  Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
369
  NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.1"), 1234)), 0, "trivial");
370
  NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.1"), 1234)), 0, "trivial");
370
  rxSocket->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt, this));
371
  rxSocket->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt, this));
371
372
372
  Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket ();
373
  Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket ();
374
  NS_TEST_EXPECT_MSG_EQ (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("10.0.1.1"), 1234)), 0, "trivial");
373
  rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt2, this));
375
  rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt2, this));
374
  NS_TEST_EXPECT_MSG_EQ (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("10.0.1.1"), 1234)), 0, "trivial");
375
376
376
  Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
377
  Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
377
  Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
378
  Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
 Lines 382-388    Link Here 
382
  // Unicast test
383
  // Unicast test
383
  SendDataTo (txSocket, "10.0.0.1");
384
  SendDataTo (txSocket, "10.0.0.1");
384
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "trivial");
385
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "trivial");
385
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 0, "second interface should receive it");
386
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 0, "second interface should not receive it");
386
387
387
  m_receivedPacket->RemoveAllByteTags ();
388
  m_receivedPacket->RemoveAllByteTags ();
388
  m_receivedPacket2->RemoveAllByteTags ();
389
  m_receivedPacket2->RemoveAllByteTags ();
 Lines 390-396    Link Here 
390
  // Simple broadcast test
391
  // Simple broadcast test
391
392
392
  SendDataTo (txSocket, "255.255.255.255");
393
  SendDataTo (txSocket, "255.255.255.255");
393
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "trivial");
394
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 0, "first socket should not receive it (it is bound specifically to the first interface's address");
394
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 0, "second socket should not receive it (it is bound specifically to the second interface's address");
395
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 0, "second socket should not receive it (it is bound specifically to the second interface's address");
395
396
396
  m_receivedPacket->RemoveAllByteTags ();
397
  m_receivedPacket->RemoveAllByteTags ();
 Lines 407-413    Link Here 
407
  NS_TEST_EXPECT_MSG_EQ (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0, "trivial");
408
  NS_TEST_EXPECT_MSG_EQ (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0, "trivial");
408
409
409
  SendDataTo (txSocket, "255.255.255.255");
410
  SendDataTo (txSocket, "255.255.255.255");
410
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "trivial");
411
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 0, "first socket should not receive it (it is bound specifically to the first interface's address");
411
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 123, "trivial");
412
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 123, "trivial");
412
413
413
  m_receivedPacket = 0;
414
  m_receivedPacket = 0;
 Lines 417-423    Link Here 
417
418
418
  txSocket->BindToNetDevice (net1.Get (1));
419
  txSocket->BindToNetDevice (net1.Get (1));
419
  SendDataTo (txSocket, "224.0.0.9");
420
  SendDataTo (txSocket, "224.0.0.9");
420
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 0, "first socket should not receive it (it is bound specifically to the second interface's address");
421
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 0, "first socket should not receive it (it is bound specifically to the first interface's address");
421
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 123, "recv2: 224.0.0.9");
422
  NS_TEST_EXPECT_MSG_EQ (m_receivedPacket2->GetSize (), 123, "recv2: 224.0.0.9");
422
423
423
  m_receivedPacket->RemoveAllByteTags ();
424
  m_receivedPacket->RemoveAllByteTags ();

Return to bug 2758