From 564ea8dbf8e07519808ddedbafa90a0b61df9840 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Sun, 15 Nov 2015 19:11:04 +0100 Subject: [PATCH] Bug 2211 - Ipv{4,6}EndPoint can cause memory corruption --- RELEASE_NOTES | 1 + src/internet/bindings/modulegen__gcc_ILP32.py | 111 ++++++++++++++ src/internet/bindings/modulegen__gcc_LP64.py | 111 ++++++++++++++ src/internet/model/ipv4-end-point.cc | 29 +--- src/internet/model/ipv4-end-point.h | 21 --- src/internet/model/ipv6-end-point.cc | 17 +-- src/internet/model/ipv6-end-point.h | 20 --- src/internet/test/tcp-endpoint-bug2211.cc | 139 ++++++++++++++++++ src/internet/wscript | 1 + 9 files changed, 366 insertions(+), 84 deletions(-) create mode 100644 src/internet/test/tcp-endpoint-bug2211.cc diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 8cf286761..d5c3eb748 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -52,6 +52,7 @@ Bugs fixed - Bug 2207 - Print node ID and time when printing routing tables - Bug 2206 - Split internet-apps from applications - Bug 2208 - Interface index based L4 protocols +- Bug 2211 - Ipv{4,6}EndPoint can cause memory corruption - Bug 2219 - SixLowPanNetDevice hangs trying to decode a IPv6 Fragment extension header Known issues diff --git a/src/internet/bindings/modulegen__gcc_ILP32.py b/src/internet/bindings/modulegen__gcc_ILP32.py index 6bc9b8473..3199290b0 100644 --- a/src/internet/bindings/modulegen__gcc_ILP32.py +++ b/src/internet/bindings/modulegen__gcc_ILP32.py @@ -690,6 +690,10 @@ def register_types(module): module.add_class('StringChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker']) ## string.h (module 'core'): ns3::StringValue [class] module.add_class('StringValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue']) + ## tcp-highspeed.h (module 'internet'): ns3::TcpHighSpeed [class] + module.add_class('TcpHighSpeed', parent=root_module['ns3::TcpNewReno']) + ## tcp-hybla.h (module 'internet'): ns3::TcpHybla [class] + module.add_class('TcpHybla', parent=root_module['ns3::TcpNewReno']) ## tcp-l4-protocol.h (module 'internet'): ns3::TcpL4Protocol [class] module.add_class('TcpL4Protocol', parent=root_module['ns3::IpL4Protocol']) ## nstime.h (module 'core'): ns3::TimeValue [class] @@ -1128,6 +1132,8 @@ def register_methods(root_module): register_Ns3RipNg_methods(root_module, root_module['ns3::RipNg']) register_Ns3StringChecker_methods(root_module, root_module['ns3::StringChecker']) register_Ns3StringValue_methods(root_module, root_module['ns3::StringValue']) + register_Ns3TcpHighSpeed_methods(root_module, root_module['ns3::TcpHighSpeed']) + register_Ns3TcpHybla_methods(root_module, root_module['ns3::TcpHybla']) register_Ns3TcpL4Protocol_methods(root_module, root_module['ns3::TcpL4Protocol']) register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue']) register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker']) @@ -12407,6 +12413,11 @@ def register_Ns3Ipv4L3Protocol_methods(root_module, cls): 'ns3::Ptr< ns3::IpL4Protocol >', [param('int', 'protocolNumber')], is_const=True, is_virtual=True) + ## ipv4-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv4L3Protocol::GetProtocol(int protocolNumber, int32_t interfaceIndex) const [member function] + cls.add_method('GetProtocol', + 'ns3::Ptr< ns3::IpL4Protocol >', + [param('int', 'protocolNumber'), param('int32_t', 'interfaceIndex')], + is_const=True, is_virtual=True) ## ipv4-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv4L3Protocol::GetRoutingProtocol() const [member function] cls.add_method('GetRoutingProtocol', 'ns3::Ptr< ns3::Ipv4RoutingProtocol >', @@ -12422,6 +12433,10 @@ def register_Ns3Ipv4L3Protocol_methods(root_module, cls): 'void', [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol')], is_virtual=True) + ## ipv4-l3-protocol.h (module 'internet'): void ns3::Ipv4L3Protocol::Insert(ns3::Ptr protocol, uint32_t interfaceIndex) [member function] + cls.add_method('Insert', + 'void', + [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol'), param('uint32_t', 'interfaceIndex')]) ## ipv4-l3-protocol.h (module 'internet'): bool ns3::Ipv4L3Protocol::IsDestinationAddress(ns3::Ipv4Address address, uint32_t iif) const [member function] cls.add_method('IsDestinationAddress', 'bool', @@ -12450,6 +12465,10 @@ def register_Ns3Ipv4L3Protocol_methods(root_module, cls): cls.add_method('Remove', 'void', [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol')]) + ## ipv4-l3-protocol.h (module 'internet'): void ns3::Ipv4L3Protocol::Remove(ns3::Ptr protocol, uint32_t interfaceIndex) [member function] + cls.add_method('Remove', + 'void', + [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol'), param('uint32_t', 'interfaceIndex')]) ## ipv4-l3-protocol.h (module 'internet'): bool ns3::Ipv4L3Protocol::RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex) [member function] cls.add_method('RemoveAddress', 'bool', @@ -13862,15 +13881,28 @@ def register_Ns3Ipv6L3Protocol_methods(root_module, cls): cls.add_method('Insert', 'void', [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol')]) + ## ipv6-l3-protocol.h (module 'internet'): void ns3::Ipv6L3Protocol::Insert(ns3::Ptr protocol, uint32_t interfaceIndex) [member function] + cls.add_method('Insert', + 'void', + [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol'), param('uint32_t', 'interfaceIndex')]) ## ipv6-l3-protocol.h (module 'internet'): void ns3::Ipv6L3Protocol::Remove(ns3::Ptr protocol) [member function] cls.add_method('Remove', 'void', [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol')]) + ## ipv6-l3-protocol.h (module 'internet'): void ns3::Ipv6L3Protocol::Remove(ns3::Ptr protocol, uint32_t interfaceIndex) [member function] + cls.add_method('Remove', + 'void', + [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol'), param('uint32_t', 'interfaceIndex')]) ## ipv6-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv6L3Protocol::GetProtocol(int protocolNumber) const [member function] cls.add_method('GetProtocol', 'ns3::Ptr< ns3::IpL4Protocol >', [param('int', 'protocolNumber')], is_const=True, is_virtual=True) + ## ipv6-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv6L3Protocol::GetProtocol(int protocolNumber, int32_t interfaceIndex) const [member function] + cls.add_method('GetProtocol', + 'ns3::Ptr< ns3::IpL4Protocol >', + [param('int', 'protocolNumber'), param('int32_t', 'interfaceIndex')], + is_const=True, is_virtual=True) ## ipv6-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv6L3Protocol::CreateRawSocket() [member function] cls.add_method('CreateRawSocket', 'ns3::Ptr< ns3::Socket >', @@ -15500,6 +15532,85 @@ def register_Ns3StringValue_methods(root_module, cls): [param('std::string const &', 'value')]) return +def register_Ns3TcpHighSpeed_methods(root_module, cls): + ## tcp-highspeed.h (module 'internet'): ns3::TcpHighSpeed::TcpHighSpeed() [constructor] + cls.add_constructor([]) + ## tcp-highspeed.h (module 'internet'): ns3::TcpHighSpeed::TcpHighSpeed(ns3::TcpHighSpeed const & sock) [copy constructor] + cls.add_constructor([param('ns3::TcpHighSpeed const &', 'sock')]) + ## tcp-highspeed.h (module 'internet'): ns3::Ptr ns3::TcpHighSpeed::Fork() [member function] + cls.add_method('Fork', + 'ns3::Ptr< ns3::TcpCongestionOps >', + [], + is_virtual=True) + ## tcp-highspeed.h (module 'internet'): std::string ns3::TcpHighSpeed::GetName() const [member function] + cls.add_method('GetName', + 'std::string', + [], + is_const=True, is_virtual=True) + ## tcp-highspeed.h (module 'internet'): uint32_t ns3::TcpHighSpeed::GetSsThresh(ns3::Ptr tcb, uint32_t bytesInFlight) [member function] + cls.add_method('GetSsThresh', + 'uint32_t', + [param('ns3::Ptr< ns3::TcpSocketState const >', 'tcb'), param('uint32_t', 'bytesInFlight')], + is_virtual=True) + ## tcp-highspeed.h (module 'internet'): static ns3::TypeId ns3::TcpHighSpeed::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## tcp-highspeed.h (module 'internet'): static uint32_t ns3::TcpHighSpeed::TableLookupA(uint32_t w) [member function] + cls.add_method('TableLookupA', + 'uint32_t', + [param('uint32_t', 'w')], + is_static=True) + ## tcp-highspeed.h (module 'internet'): static double ns3::TcpHighSpeed::TableLookupB(uint32_t w) [member function] + cls.add_method('TableLookupB', + 'double', + [param('uint32_t', 'w')], + is_static=True) + ## tcp-highspeed.h (module 'internet'): void ns3::TcpHighSpeed::CongestionAvoidance(ns3::Ptr tcb, uint32_t segmentsAcked) [member function] + cls.add_method('CongestionAvoidance', + 'void', + [param('ns3::Ptr< ns3::TcpSocketState >', 'tcb'), param('uint32_t', 'segmentsAcked')], + visibility='protected', is_virtual=True) + return + +def register_Ns3TcpHybla_methods(root_module, cls): + ## tcp-hybla.h (module 'internet'): ns3::TcpHybla::TcpHybla() [constructor] + cls.add_constructor([]) + ## tcp-hybla.h (module 'internet'): ns3::TcpHybla::TcpHybla(ns3::TcpHybla const & sock) [copy constructor] + cls.add_constructor([param('ns3::TcpHybla const &', 'sock')]) + ## tcp-hybla.h (module 'internet'): ns3::Ptr ns3::TcpHybla::Fork() [member function] + cls.add_method('Fork', + 'ns3::Ptr< ns3::TcpCongestionOps >', + [], + is_virtual=True) + ## tcp-hybla.h (module 'internet'): std::string ns3::TcpHybla::GetName() const [member function] + cls.add_method('GetName', + 'std::string', + [], + is_const=True, is_virtual=True) + ## tcp-hybla.h (module 'internet'): static ns3::TypeId ns3::TcpHybla::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## tcp-hybla.h (module 'internet'): void ns3::TcpHybla::PktsAcked(ns3::Ptr tcb, uint32_t segmentsAcked, ns3::Time const & rtt) [member function] + cls.add_method('PktsAcked', + 'void', + [param('ns3::Ptr< ns3::TcpSocketState >', 'tcb'), param('uint32_t', 'segmentsAcked'), param('ns3::Time const &', 'rtt')], + is_virtual=True) + ## tcp-hybla.h (module 'internet'): void ns3::TcpHybla::CongestionAvoidance(ns3::Ptr tcb, uint32_t segmentsAcked) [member function] + cls.add_method('CongestionAvoidance', + 'void', + [param('ns3::Ptr< ns3::TcpSocketState >', 'tcb'), param('uint32_t', 'segmentsAcked')], + visibility='protected', is_virtual=True) + ## tcp-hybla.h (module 'internet'): uint32_t ns3::TcpHybla::SlowStart(ns3::Ptr tcb, uint32_t segmentsAcked) [member function] + cls.add_method('SlowStart', + 'uint32_t', + [param('ns3::Ptr< ns3::TcpSocketState >', 'tcb'), param('uint32_t', 'segmentsAcked')], + visibility='protected', is_virtual=True) + return + def register_Ns3TcpL4Protocol_methods(root_module, cls): ## tcp-l4-protocol.h (module 'internet'): ns3::TcpL4Protocol::PROT_NUMBER [variable] cls.add_static_attribute('PROT_NUMBER', 'uint8_t const', is_const=True) diff --git a/src/internet/bindings/modulegen__gcc_LP64.py b/src/internet/bindings/modulegen__gcc_LP64.py index 6bc9b8473..3199290b0 100644 --- a/src/internet/bindings/modulegen__gcc_LP64.py +++ b/src/internet/bindings/modulegen__gcc_LP64.py @@ -690,6 +690,10 @@ def register_types(module): module.add_class('StringChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker']) ## string.h (module 'core'): ns3::StringValue [class] module.add_class('StringValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue']) + ## tcp-highspeed.h (module 'internet'): ns3::TcpHighSpeed [class] + module.add_class('TcpHighSpeed', parent=root_module['ns3::TcpNewReno']) + ## tcp-hybla.h (module 'internet'): ns3::TcpHybla [class] + module.add_class('TcpHybla', parent=root_module['ns3::TcpNewReno']) ## tcp-l4-protocol.h (module 'internet'): ns3::TcpL4Protocol [class] module.add_class('TcpL4Protocol', parent=root_module['ns3::IpL4Protocol']) ## nstime.h (module 'core'): ns3::TimeValue [class] @@ -1128,6 +1132,8 @@ def register_methods(root_module): register_Ns3RipNg_methods(root_module, root_module['ns3::RipNg']) register_Ns3StringChecker_methods(root_module, root_module['ns3::StringChecker']) register_Ns3StringValue_methods(root_module, root_module['ns3::StringValue']) + register_Ns3TcpHighSpeed_methods(root_module, root_module['ns3::TcpHighSpeed']) + register_Ns3TcpHybla_methods(root_module, root_module['ns3::TcpHybla']) register_Ns3TcpL4Protocol_methods(root_module, root_module['ns3::TcpL4Protocol']) register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue']) register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker']) @@ -12407,6 +12413,11 @@ def register_Ns3Ipv4L3Protocol_methods(root_module, cls): 'ns3::Ptr< ns3::IpL4Protocol >', [param('int', 'protocolNumber')], is_const=True, is_virtual=True) + ## ipv4-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv4L3Protocol::GetProtocol(int protocolNumber, int32_t interfaceIndex) const [member function] + cls.add_method('GetProtocol', + 'ns3::Ptr< ns3::IpL4Protocol >', + [param('int', 'protocolNumber'), param('int32_t', 'interfaceIndex')], + is_const=True, is_virtual=True) ## ipv4-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv4L3Protocol::GetRoutingProtocol() const [member function] cls.add_method('GetRoutingProtocol', 'ns3::Ptr< ns3::Ipv4RoutingProtocol >', @@ -12422,6 +12433,10 @@ def register_Ns3Ipv4L3Protocol_methods(root_module, cls): 'void', [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol')], is_virtual=True) + ## ipv4-l3-protocol.h (module 'internet'): void ns3::Ipv4L3Protocol::Insert(ns3::Ptr protocol, uint32_t interfaceIndex) [member function] + cls.add_method('Insert', + 'void', + [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol'), param('uint32_t', 'interfaceIndex')]) ## ipv4-l3-protocol.h (module 'internet'): bool ns3::Ipv4L3Protocol::IsDestinationAddress(ns3::Ipv4Address address, uint32_t iif) const [member function] cls.add_method('IsDestinationAddress', 'bool', @@ -12450,6 +12465,10 @@ def register_Ns3Ipv4L3Protocol_methods(root_module, cls): cls.add_method('Remove', 'void', [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol')]) + ## ipv4-l3-protocol.h (module 'internet'): void ns3::Ipv4L3Protocol::Remove(ns3::Ptr protocol, uint32_t interfaceIndex) [member function] + cls.add_method('Remove', + 'void', + [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol'), param('uint32_t', 'interfaceIndex')]) ## ipv4-l3-protocol.h (module 'internet'): bool ns3::Ipv4L3Protocol::RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex) [member function] cls.add_method('RemoveAddress', 'bool', @@ -13862,15 +13881,28 @@ def register_Ns3Ipv6L3Protocol_methods(root_module, cls): cls.add_method('Insert', 'void', [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol')]) + ## ipv6-l3-protocol.h (module 'internet'): void ns3::Ipv6L3Protocol::Insert(ns3::Ptr protocol, uint32_t interfaceIndex) [member function] + cls.add_method('Insert', + 'void', + [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol'), param('uint32_t', 'interfaceIndex')]) ## ipv6-l3-protocol.h (module 'internet'): void ns3::Ipv6L3Protocol::Remove(ns3::Ptr protocol) [member function] cls.add_method('Remove', 'void', [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol')]) + ## ipv6-l3-protocol.h (module 'internet'): void ns3::Ipv6L3Protocol::Remove(ns3::Ptr protocol, uint32_t interfaceIndex) [member function] + cls.add_method('Remove', + 'void', + [param('ns3::Ptr< ns3::IpL4Protocol >', 'protocol'), param('uint32_t', 'interfaceIndex')]) ## ipv6-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv6L3Protocol::GetProtocol(int protocolNumber) const [member function] cls.add_method('GetProtocol', 'ns3::Ptr< ns3::IpL4Protocol >', [param('int', 'protocolNumber')], is_const=True, is_virtual=True) + ## ipv6-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv6L3Protocol::GetProtocol(int protocolNumber, int32_t interfaceIndex) const [member function] + cls.add_method('GetProtocol', + 'ns3::Ptr< ns3::IpL4Protocol >', + [param('int', 'protocolNumber'), param('int32_t', 'interfaceIndex')], + is_const=True, is_virtual=True) ## ipv6-l3-protocol.h (module 'internet'): ns3::Ptr ns3::Ipv6L3Protocol::CreateRawSocket() [member function] cls.add_method('CreateRawSocket', 'ns3::Ptr< ns3::Socket >', @@ -15500,6 +15532,85 @@ def register_Ns3StringValue_methods(root_module, cls): [param('std::string const &', 'value')]) return +def register_Ns3TcpHighSpeed_methods(root_module, cls): + ## tcp-highspeed.h (module 'internet'): ns3::TcpHighSpeed::TcpHighSpeed() [constructor] + cls.add_constructor([]) + ## tcp-highspeed.h (module 'internet'): ns3::TcpHighSpeed::TcpHighSpeed(ns3::TcpHighSpeed const & sock) [copy constructor] + cls.add_constructor([param('ns3::TcpHighSpeed const &', 'sock')]) + ## tcp-highspeed.h (module 'internet'): ns3::Ptr ns3::TcpHighSpeed::Fork() [member function] + cls.add_method('Fork', + 'ns3::Ptr< ns3::TcpCongestionOps >', + [], + is_virtual=True) + ## tcp-highspeed.h (module 'internet'): std::string ns3::TcpHighSpeed::GetName() const [member function] + cls.add_method('GetName', + 'std::string', + [], + is_const=True, is_virtual=True) + ## tcp-highspeed.h (module 'internet'): uint32_t ns3::TcpHighSpeed::GetSsThresh(ns3::Ptr tcb, uint32_t bytesInFlight) [member function] + cls.add_method('GetSsThresh', + 'uint32_t', + [param('ns3::Ptr< ns3::TcpSocketState const >', 'tcb'), param('uint32_t', 'bytesInFlight')], + is_virtual=True) + ## tcp-highspeed.h (module 'internet'): static ns3::TypeId ns3::TcpHighSpeed::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## tcp-highspeed.h (module 'internet'): static uint32_t ns3::TcpHighSpeed::TableLookupA(uint32_t w) [member function] + cls.add_method('TableLookupA', + 'uint32_t', + [param('uint32_t', 'w')], + is_static=True) + ## tcp-highspeed.h (module 'internet'): static double ns3::TcpHighSpeed::TableLookupB(uint32_t w) [member function] + cls.add_method('TableLookupB', + 'double', + [param('uint32_t', 'w')], + is_static=True) + ## tcp-highspeed.h (module 'internet'): void ns3::TcpHighSpeed::CongestionAvoidance(ns3::Ptr tcb, uint32_t segmentsAcked) [member function] + cls.add_method('CongestionAvoidance', + 'void', + [param('ns3::Ptr< ns3::TcpSocketState >', 'tcb'), param('uint32_t', 'segmentsAcked')], + visibility='protected', is_virtual=True) + return + +def register_Ns3TcpHybla_methods(root_module, cls): + ## tcp-hybla.h (module 'internet'): ns3::TcpHybla::TcpHybla() [constructor] + cls.add_constructor([]) + ## tcp-hybla.h (module 'internet'): ns3::TcpHybla::TcpHybla(ns3::TcpHybla const & sock) [copy constructor] + cls.add_constructor([param('ns3::TcpHybla const &', 'sock')]) + ## tcp-hybla.h (module 'internet'): ns3::Ptr ns3::TcpHybla::Fork() [member function] + cls.add_method('Fork', + 'ns3::Ptr< ns3::TcpCongestionOps >', + [], + is_virtual=True) + ## tcp-hybla.h (module 'internet'): std::string ns3::TcpHybla::GetName() const [member function] + cls.add_method('GetName', + 'std::string', + [], + is_const=True, is_virtual=True) + ## tcp-hybla.h (module 'internet'): static ns3::TypeId ns3::TcpHybla::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## tcp-hybla.h (module 'internet'): void ns3::TcpHybla::PktsAcked(ns3::Ptr tcb, uint32_t segmentsAcked, ns3::Time const & rtt) [member function] + cls.add_method('PktsAcked', + 'void', + [param('ns3::Ptr< ns3::TcpSocketState >', 'tcb'), param('uint32_t', 'segmentsAcked'), param('ns3::Time const &', 'rtt')], + is_virtual=True) + ## tcp-hybla.h (module 'internet'): void ns3::TcpHybla::CongestionAvoidance(ns3::Ptr tcb, uint32_t segmentsAcked) [member function] + cls.add_method('CongestionAvoidance', + 'void', + [param('ns3::Ptr< ns3::TcpSocketState >', 'tcb'), param('uint32_t', 'segmentsAcked')], + visibility='protected', is_virtual=True) + ## tcp-hybla.h (module 'internet'): uint32_t ns3::TcpHybla::SlowStart(ns3::Ptr tcb, uint32_t segmentsAcked) [member function] + cls.add_method('SlowStart', + 'uint32_t', + [param('ns3::Ptr< ns3::TcpSocketState >', 'tcb'), param('uint32_t', 'segmentsAcked')], + visibility='protected', is_virtual=True) + return + def register_Ns3TcpL4Protocol_methods(root_module, cls): ## tcp-l4-protocol.h (module 'internet'): ns3::TcpL4Protocol::PROT_NUMBER [variable] cls.add_static_attribute('PROT_NUMBER', 'uint8_t const', is_const=True) diff --git a/src/internet/model/ipv4-end-point.cc b/src/internet/model/ipv4-end-point.cc index 51c5e2029..f82eae606 100644 --- a/src/internet/model/ipv4-end-point.cc +++ b/src/internet/model/ipv4-end-point.cc @@ -134,19 +134,6 @@ Ipv4EndPoint::ForwardUp (Ptr p, const Ipv4Header& header, uint16_t sport { NS_LOG_FUNCTION (this << p << &header << sport << incomingInterface); - if (!m_rxCallback.IsNull ()) - { - Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardUp, this, p, header, sport, - incomingInterface); - } -} - -void -Ipv4EndPoint::DoForwardUp (Ptr p, const Ipv4Header& header, uint16_t sport, - Ptr incomingInterface) -{ - NS_LOG_FUNCTION (this << p << &header << sport << incomingInterface); - if (!m_rxCallback.IsNull ()) { m_rxCallback (p, header, sport, incomingInterface); @@ -162,21 +149,7 @@ Ipv4EndPoint::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, (uint32_t)icmpCode << icmpInfo); if (!m_icmpCallback.IsNull ()) { - Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardIcmp, this, - icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo); - } -} - -void -Ipv4EndPoint::DoForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, - uint8_t icmpType, uint8_t icmpCode, - uint32_t icmpInfo) -{ - NS_LOG_FUNCTION (this << icmpSource << static_cast (icmpTtl) << static_cast (icmpType) << static_cast (icmpCode) << icmpInfo); - - if (!m_icmpCallback.IsNull ()) - { - m_icmpCallback (icmpSource,icmpTtl,icmpType,icmpCode,icmpInfo); + m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo); } } diff --git a/src/internet/model/ipv4-end-point.h b/src/internet/model/ipv4-end-point.h index b85788a27..7c780b897 100644 --- a/src/internet/model/ipv4-end-point.h +++ b/src/internet/model/ipv4-end-point.h @@ -181,27 +181,6 @@ public: bool IsRxEnabled (void); private: - /** - * \brief ForwardUp wrapper. - * \param p packet - * \param header the packet header - * \param sport source port - * \param incomingInterface incoming interface - */ - void DoForwardUp (Ptr p, const Ipv4Header& header, uint16_t sport, - Ptr incomingInterface); - /** - * \brief ForwardIcmp wrapper. - * \param icmpSource source IP address - * \param icmpTtl time-to-live - * \param icmpType ICMP type - * \param icmpCode ICMP code - * \param icmpInfo ICMP info - */ - void DoForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, - uint8_t icmpType, uint8_t icmpCode, - uint32_t icmpInfo); - /** * \brief The local address. */ diff --git a/src/internet/model/ipv6-end-point.cc b/src/internet/model/ipv6-end-point.cc index 862816469..5b9773990 100644 --- a/src/internet/model/ipv6-end-point.cc +++ b/src/internet/model/ipv6-end-point.cc @@ -115,8 +115,7 @@ void Ipv6EndPoint::ForwardUp (Ptr p, Ipv6Header header, uint16_t port, P { if (!m_rxCallback.IsNull ()) { - Simulator::ScheduleNow (&Ipv6EndPoint::DoForwardUp, this, p, header, port, - incomingInterface); + m_rxCallback (p, header, port, incomingInterface); } } @@ -125,22 +124,10 @@ void Ipv6EndPoint::ForwardIcmp (Ipv6Address src, uint8_t ttl, uint8_t type, { if (!m_icmpCallback.IsNull ()) { - Simulator::ScheduleNow (&Ipv6EndPoint::DoForwardIcmp, this, - src, ttl, type, code, info); + m_icmpCallback (src, ttl, type, code, info); } } -void Ipv6EndPoint::DoForwardUp (Ptr p, Ipv6Header header, uint16_t sport, Ptr incomingInterface) -{ - m_rxCallback (p, header, sport, incomingInterface); -} - -void Ipv6EndPoint::DoForwardIcmp (Ipv6Address src, uint8_t ttl, uint8_t type, - uint8_t code, uint32_t info) -{ - m_icmpCallback (src, ttl, type, code, info); -} - void Ipv6EndPoint::SetRxEnabled (bool enabled) { m_rxEnabled = enabled; diff --git a/src/internet/model/ipv6-end-point.h b/src/internet/model/ipv6-end-point.h index 5c10fe28d..4e6a52383 100644 --- a/src/internet/model/ipv6-end-point.h +++ b/src/internet/model/ipv6-end-point.h @@ -190,26 +190,6 @@ public: bool IsRxEnabled (void); private: - /** - * \brief ForwardUp wrapper. - * \param p packet - * \param header the packet header - * \param sport source port - * \param incomingInterface incoming interface - */ - void DoForwardUp (Ptr p, Ipv6Header header, uint16_t sport, Ptr incomingInterface); - - /** - * \brief ForwardIcmp wrapper. - * \param src source IPv6 address - * \param ttl time-to-live - * \param type ICMPv6 type - * \param code ICMPv6 code - * \param info ICMPv6 info - */ - void DoForwardIcmp (Ipv6Address src, uint8_t ttl, uint8_t type, - uint8_t code, uint32_t info); - /** * \brief The local address. */ diff --git a/src/internet/test/tcp-endpoint-bug2211.cc b/src/internet/test/tcp-endpoint-bug2211.cc new file mode 100644 index 000000000..e316facb6 --- /dev/null +++ b/src/internet/test/tcp-endpoint-bug2211.cc @@ -0,0 +1,139 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2015 Alexander Krotov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * Test for bug 2211 + * https://www.nsnam.org/bugzilla/show_bug.cgi?id=2211 + * + * NOTE: It is a valgrind testcase, it contains no ASSERTs. + * + * Test creates one node and sets up two TCP sockets on the loopback + * with default parameters: CWND = 1, MTU = 536. + * Sender socket sends 3 segments. + * When first segment is acknowledged, cwnd is raised to 2. + * Then, two segments are sent and arrive into receive buffer. + * Until bugfix, the following happened: + * Ipv4EndPoint::ForwardUp was called for both second and third segment. + * These calls scheduled two Ipv4EndPoint::DoForwardUp events. + * To demonstrate the bug, test case closes the receiver socket after + * receiving the second segment. As a result, Ipv4EndPoint is destroyed. + * However, Ipv4EndPoint::DoForwardUp is already scheduled for third segment. + * It is a use-after-free bug. + */ +#include + +#include "ns3/test.h" +#include "ns3/core-module.h" +#include "ns3/network-module.h" +#include "ns3/internet-module.h" + +namespace ns3 { + +class TcpEndPointBug2211Test : public TestCase +{ +public: + TcpEndPointBug2211Test (std::string desc, bool ipVersion); + + void Recv (Ptr socket); + void HandleAccept (Ptr s, const Address &from); + void HandleConnect (Ptr socket); + virtual void DoRun (); +private: + bool m_v6; +}; + +void +TcpEndPointBug2211Test::Recv (Ptr socket) +{ + if (socket->GetRxAvailable() == 536 * 2) + { + socket->Close(); + } +} + +void +TcpEndPointBug2211Test::HandleAccept (Ptr s, const Address &from) +{ + s->SetRecvCallback (MakeCallback (&TcpEndPointBug2211Test::Recv, this)); +} + +void +TcpEndPointBug2211Test::HandleConnect (Ptr socket) +{ + socket->Send (Create (536)); + socket->Send (Create (536)); + socket->Send (Create (536)); + socket->Close (); +} + +TcpEndPointBug2211Test::TcpEndPointBug2211Test (std::string desc, bool ipVersion) : TestCase (desc) +{ + m_v6 = ipVersion; +} + +void +TcpEndPointBug2211Test::DoRun () +{ + Ptr node = CreateObject (); + + InternetStackHelper internet; + internet.Install (node); + + TypeId tid = TcpSocketFactory::GetTypeId (); + Ptr sink = Socket::CreateSocket (node, tid); + if (m_v6 == false) + { + sink->Bind (InetSocketAddress (Ipv4Address::GetAny (), 9)); + } + else + { + sink->Bind (Inet6SocketAddress (Ipv6Address::GetAny (), 9)); + } + sink->Listen (); + sink->SetAcceptCallback (MakeNullCallback, const Address &> (), + MakeCallback (&TcpEndPointBug2211Test::HandleAccept, this)); + + Ptr source = Socket::CreateSocket (node, tid); + source->Bind (); + source->SetConnectCallback (MakeCallback (&TcpEndPointBug2211Test::HandleConnect, this), + MakeNullCallback >()); + if (m_v6 == false) + { + source->Connect (InetSocketAddress (Ipv4Address::GetLoopback (), 9)); + } + else + { + source->Connect (Inet6SocketAddress (Ipv6Address::GetLoopback (), 9)); + } + + Simulator::Run (); + Simulator::Destroy (); +} + +class TcpEndpointBug2211TestSuite : public TestSuite +{ +public: + TcpEndpointBug2211TestSuite () : TestSuite ("tcp-endpoint-bug2211-test", UNIT) + { + AddTestCase (new TcpEndPointBug2211Test ("Bug 2211 testcase IPv4", false), TestCase::QUICK); + AddTestCase (new TcpEndPointBug2211Test ("Bug 2211 testcase IPv6", true), TestCase::QUICK); + } +} g_TcpEndPoint2211TestSuite; + +} // namespace ns3 diff --git a/src/internet/wscript b/src/internet/wscript index b4c2e89e0..fafe9f853 100644 --- a/src/internet/wscript +++ b/src/internet/wscript @@ -251,6 +251,7 @@ def build(bld): 'test/ipv6-address-helper-test-suite.cc', 'test/rtt-test.cc', 'test/codel-queue-test-suite.cc', + 'test/tcp-endpoint-bug2211.cc', ] privateheaders = bld(features='ns3privateheader') privateheaders.module = 'internet'