OLD | NEW |
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2007 INRIA | 3 * Copyright (c) 2007 INRIA |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 5 * This program is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 2 as | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with this program; if not, write to the Free Software | 15 * along with this program; if not, write to the Free Software |
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 * | 17 * |
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> | 18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
19 */ | 19 */ |
20 | 20 |
21 #include "ns3/log.h" | 21 #include "ns3/log.h" |
22 #include "ns3/node.h" | 22 #include "ns3/node.h" |
23 #include "ns3/inet-socket-address.h" | 23 #include "ns3/inet-socket-address.h" |
24 #include "ns3/ipv4-route.h" | 24 #include "ns3/ipv4-route.h" |
25 #include "ns3/ipv4.h" | 25 #include "ns3/ipv4.h" |
| 26 #include "ns3/ipv4-header.h" |
| 27 #include "ns3/ipv4-routing-protocol.h" |
26 #include "ns3/udp-socket-factory.h" | 28 #include "ns3/udp-socket-factory.h" |
27 #include "ns3/trace-source-accessor.h" | 29 #include "ns3/trace-source-accessor.h" |
28 #include "udp-socket-impl.h" | 30 #include "udp-socket-impl.h" |
29 #include "udp-l4-protocol.h" | 31 #include "udp-l4-protocol.h" |
30 #include "ipv4-end-point.h" | 32 #include "ipv4-end-point.h" |
31 #include <limits> | 33 #include <limits> |
32 | 34 |
33 NS_LOG_COMPONENT_DEFINE ("UdpSocketImpl"); | 35 NS_LOG_COMPONENT_DEFINE ("UdpSocketImpl"); |
34 | 36 |
35 namespace ns3 { | 37 namespace ns3 { |
(...skipping 27 matching lines...) Expand all Loading... |
63 m_connected (false), | 65 m_connected (false), |
64 m_rxAvailable (0) | 66 m_rxAvailable (0) |
65 { | 67 { |
66 NS_LOG_FUNCTION_NOARGS (); | 68 NS_LOG_FUNCTION_NOARGS (); |
67 } | 69 } |
68 | 70 |
69 UdpSocketImpl::~UdpSocketImpl () | 71 UdpSocketImpl::~UdpSocketImpl () |
70 { | 72 { |
71 NS_LOG_FUNCTION_NOARGS (); | 73 NS_LOG_FUNCTION_NOARGS (); |
72 | 74 |
| 75 // XXX todo: leave any multicast groups that have been joined |
73 m_node = 0; | 76 m_node = 0; |
74 if (m_endPoint != 0) | 77 if (m_endPoint != 0) |
75 { | 78 { |
76 NS_ASSERT (m_udp != 0); | 79 NS_ASSERT (m_udp != 0); |
77 /** | 80 /** |
78 * Note that this piece of code is a bit tricky: | 81 * Note that this piece of code is a bit tricky: |
79 * when DeAllocate is called, it will call into | 82 * when DeAllocate is called, it will call into |
80 * Ipv4EndPointDemux::Deallocate which triggers | 83 * Ipv4EndPointDemux::Deallocate which triggers |
81 * a delete of the associated endPoint which triggers | 84 * a delete of the associated endPoint which triggers |
82 * in turn a call to the method ::Destroy below | 85 * in turn a call to the method ::Destroy below |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 m_errno = ERROR_SHUTDOWN; | 304 m_errno = ERROR_SHUTDOWN; |
302 return -1; | 305 return -1; |
303 } | 306 } |
304 | 307 |
305 if (p->GetSize () > GetTxAvailable () ) | 308 if (p->GetSize () > GetTxAvailable () ) |
306 { | 309 { |
307 m_errno = ERROR_MSGSIZE; | 310 m_errno = ERROR_MSGSIZE; |
308 return -1; | 311 return -1; |
309 } | 312 } |
310 | 313 |
311 uint32_t localInterface; | |
312 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> (); | 314 Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> (); |
313 | 315 |
314 // Locally override the IP TTL for this socket | 316 // Locally override the IP TTL for this socket |
315 // We cannot directly modify the TTL at this stage, so we set a Packet tag | 317 // We cannot directly modify the TTL at this stage, so we set a Packet tag |
316 // The destination can be either multicast, unicast/anycast, or | 318 // The destination can be either multicast, unicast/anycast, or |
317 // either all-hosts broadcast or limited (subnet-directed) broadcast. | 319 // either all-hosts broadcast or limited (subnet-directed) broadcast. |
318 // For the latter two broadcast types, the TTL will later be set to one | 320 // For the latter two broadcast types, the TTL will later be set to one |
319 // irrespective of what is set in these socket options. So, this tagging·· | 321 // irrespective of what is set in these socket options. So, this tagging·· |
320 // may end up setting the TTL of a limited broadcast packet to be | 322 // may end up setting the TTL of a limited broadcast packet to be |
321 // the same as a unicast, but it will be fixed further down the stack | 323 // the same as a unicast, but it will be fixed further down the stack |
322 //NS_LOG_UNCOND ("IPttl: " << m_ipTtl); | |
323 if (m_ipMulticastTtl != 0 && dest.IsMulticast ()) | 324 if (m_ipMulticastTtl != 0 && dest.IsMulticast ()) |
324 { | 325 { |
325 SocketIpTtlTag tag; | 326 SocketIpTtlTag tag; |
326 tag.SetTtl (m_ipMulticastTtl); | 327 tag.SetTtl (m_ipMulticastTtl); |
327 p->AddTag (tag); | 328 p->AddTag (tag); |
328 } | 329 } |
329 else if (m_ipTtl != 0 && !dest.IsMulticast () && !dest.IsBroadcast ()) | 330 else if (m_ipTtl != 0 && !dest.IsMulticast () && !dest.IsBroadcast ()) |
330 { | 331 { |
331 SocketIpTtlTag tag; | 332 SocketIpTtlTag tag; |
332 tag.SetTtl (m_ipTtl); | 333 tag.SetTtl (m_ipTtl); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 << " (mask is " << maski << ")"); | 385 << " (mask is " << maski << ")"); |
385 m_udp->Send (p->Copy (), addri, bcast, | 386 m_udp->Send (p->Copy (), addri, bcast, |
386 m_endPoint->GetLocalPort (), port); | 387 m_endPoint->GetLocalPort (), port); |
387 NotifyDataSent (p->GetSize ()); | 388 NotifyDataSent (p->GetSize ()); |
388 NotifySend (GetTxAvailable ()); | 389 NotifySend (GetTxAvailable ()); |
389 } | 390 } |
390 } | 391 } |
391 NS_LOG_LOGIC ("Limited broadcast end."); | 392 NS_LOG_LOGIC ("Limited broadcast end."); |
392 return p->GetSize(); | 393 return p->GetSize(); |
393 } | 394 } |
394 else if (ipv4->GetInterfaceForDestination(dest, localInterface)) | 395 else if (ipv4->GetRoutingProtocol ()) |
395 { | 396 { |
396 NS_LOG_LOGIC ("Route exists"); | 397 Ipv4Header header; |
397 m_udp->Send (p->Copy (), ipv4->GetSourceAddress (dest), dest, | 398 header.SetDestination (dest); |
398 » » m_endPoint->GetLocalPort (), port); | 399 Socket::SocketErrno errno; |
399 NotifyDataSent (p->GetSize ()); | 400 Ptr<Ipv4Route> route; |
400 NotifySend (GetTxAvailable ()); | 401 uint32_t oif = 0; //specify non-zero if bound to a source address |
401 return p->GetSize();; | 402 // TBD-- we could cache the route and just check its validity |
| 403 route = ipv4->GetRoutingProtocol ()->RouteOutput (header, oif, errno);· |
| 404 if (route != 0) |
| 405 { |
| 406 NS_LOG_LOGIC ("Route exists"); |
| 407 header.SetSource (route->GetSource ()); |
| 408 m_udp->Send (p->Copy (), header.GetSource (), header.GetDestination ()
, |
| 409 m_endPoint->GetLocalPort (), port, route); |
| 410 NotifyDataSent (p->GetSize ()); |
| 411 return p->GetSize(); |
| 412 } |
| 413 else· |
| 414 { |
| 415 NS_LOG_LOGIC ("No route to destination"); |
| 416 NS_LOG_ERROR (errno); |
| 417 m_errno = errno; |
| 418 return -1; |
| 419 } |
402 } | 420 } |
403 else | 421 else |
404 { | 422 { |
405 NS_LOG_ERROR ("ERROR_NOROUTETOHOST"); | 423 NS_LOG_ERROR ("ERROR_NOROUTETOHOST"); |
406 m_errno = ERROR_NOROUTETOHOST; | 424 m_errno = ERROR_NOROUTETOHOST; |
407 return -1; | 425 return -1; |
408 } | 426 } |
409 | 427 |
410 return 0; | 428 return 0; |
411 } | 429 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 { | 505 { |
488 address = InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->G
etLocalPort()); | 506 address = InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->G
etLocalPort()); |
489 } | 507 } |
490 else | 508 else |
491 { | 509 { |
492 address = InetSocketAddress(Ipv4Address::GetZero(), 0); | 510 address = InetSocketAddress(Ipv4Address::GetZero(), 0); |
493 } | 511 } |
494 return 0; | 512 return 0; |
495 } | 513 } |
496 | 514 |
| 515 int· |
| 516 UdpSocketImpl::MulticastJoinGroup (uint32_t interface, const Address &groupAddre
ss) |
| 517 { |
| 518 NS_LOG_FUNCTION (interface << groupAddress); |
| 519 /* |
| 520 1) sanity check interface |
| 521 2) sanity check that it has not been called yet on this interface/group |
| 522 3) determine address family of groupAddress |
| 523 4) locally store a list of (interface, groupAddress) |
| 524 5) call ipv4->MulticastJoinGroup () or Ipv6->MulticastJoinGroup () |
| 525 */ |
| 526 return 0; |
| 527 }· |
| 528 |
| 529 int· |
| 530 UdpSocketImpl::MulticastLeaveGroup (uint32_t interface, const Address &groupAddr
ess)· |
| 531 { |
| 532 NS_LOG_FUNCTION (interface << groupAddress); |
| 533 /* |
| 534 1) sanity check interface |
| 535 2) determine address family of groupAddress |
| 536 3) delete from local list of (interface, groupAddress); raise a LOG_WARN |
| 537 if not already present (but return 0)· |
| 538 5) call ipv4->MulticastLeaveGroup () or Ipv6->MulticastLeaveGroup () |
| 539 */ |
| 540 return 0; |
| 541 } |
| 542 |
497 void· | 543 void· |
498 UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port) | 544 UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port) |
499 { | 545 { |
500 NS_LOG_FUNCTION (this << packet << ipv4 << port); | 546 NS_LOG_FUNCTION (this << packet << ipv4 << port); |
501 | 547 |
502 if (m_shutdownRecv) | 548 if (m_shutdownRecv) |
503 { | 549 { |
504 return; | 550 return; |
505 } | 551 } |
506 if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize) | 552 if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 m_rcvBufSize = size; | 591 m_rcvBufSize = size; |
546 } | 592 } |
547 | 593 |
548 uint32_t· | 594 uint32_t· |
549 UdpSocketImpl::GetRcvBufSize (void) const | 595 UdpSocketImpl::GetRcvBufSize (void) const |
550 { | 596 { |
551 return m_rcvBufSize; | 597 return m_rcvBufSize; |
552 } | 598 } |
553 | 599 |
554 void· | 600 void· |
555 UdpSocketImpl::SetIpTtl (uint32_t ipTtl) | 601 UdpSocketImpl::SetIpTtl (uint8_t ipTtl) |
556 { | 602 { |
557 m_ipTtl = ipTtl; | 603 m_ipTtl = ipTtl; |
558 } | 604 } |
559 | 605 |
560 uint32_t· | 606 uint8_t· |
561 UdpSocketImpl::GetIpTtl (void) const | 607 UdpSocketImpl::GetIpTtl (void) const |
562 { | 608 { |
563 return m_ipTtl; | 609 return m_ipTtl; |
564 } | 610 } |
565 | 611 |
566 void· | 612 void· |
567 UdpSocketImpl::SetIpMulticastTtl (uint32_t ipTtl) | 613 UdpSocketImpl::SetIpMulticastTtl (uint8_t ipTtl) |
568 { | 614 { |
569 m_ipMulticastTtl = ipTtl; | 615 m_ipMulticastTtl = ipTtl; |
570 } | 616 } |
571 | 617 |
572 uint32_t· | 618 uint8_t· |
573 UdpSocketImpl::GetIpMulticastTtl (void) const | 619 UdpSocketImpl::GetIpMulticastTtl (void) const |
574 { | 620 { |
575 return m_ipMulticastTtl; | 621 return m_ipMulticastTtl; |
576 } | 622 } |
577 | 623 |
578 void· | 624 void· |
| 625 UdpSocketImpl::SetIpMulticastIf (int32_t ipIf) |
| 626 { |
| 627 m_ipMulticastIf = ipIf; |
| 628 } |
| 629 |
| 630 int32_t· |
| 631 UdpSocketImpl::GetIpMulticastIf (void) const |
| 632 { |
| 633 return m_ipMulticastIf; |
| 634 } |
| 635 |
| 636 void· |
| 637 UdpSocketImpl::SetIpMulticastLoop (bool loop) |
| 638 { |
| 639 m_ipMulticastLoop = loop; |
| 640 } |
| 641 |
| 642 bool· |
| 643 UdpSocketImpl::GetIpMulticastLoop (void) const |
| 644 { |
| 645 return m_ipMulticastLoop; |
| 646 } |
| 647 |
| 648 void· |
579 UdpSocketImpl::SetMtuDiscover (bool discover) | 649 UdpSocketImpl::SetMtuDiscover (bool discover) |
580 { | 650 { |
581 m_mtuDiscover = discover; | 651 m_mtuDiscover = discover; |
582 } | 652 } |
583 bool· | 653 bool· |
584 UdpSocketImpl::GetMtuDiscover (void) const | 654 UdpSocketImpl::GetMtuDiscover (void) const |
585 { | 655 { |
586 return m_mtuDiscover; | 656 return m_mtuDiscover; |
587 } | 657 } |
588 | 658 |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 Simulator::Destroy (); | 855 Simulator::Destroy (); |
786 | 856 |
787 return result; | 857 return result; |
788 } | 858 } |
789 | 859 |
790 static UdpSocketImplTest gUdpSocketImplTest; | 860 static UdpSocketImplTest gUdpSocketImplTest; |
791 | 861 |
792 }; // namespace ns3 | 862 }; // namespace ns3 |
793 | 863 |
794 #endif /* RUN_SELF_TESTS */ | 864 #endif /* RUN_SELF_TESTS */ |
OLD | NEW |