From 0ad768c938418cbe506098328b8c9d4a243d027b Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Wed, 23 Jul 2008 16:09:17 -0400 Subject: [PATCH 1/3] Make PacketSink multitasking for TCP (closes bug 244) --- src/applications/packet-sink/packet-sink.cc | 14 +++++++++++++- src/applications/packet-sink/packet-sink.h | 7 ++++++- src/internet-stack/tcp-socket-impl.cc | 5 ++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/applications/packet-sink/packet-sink.cc b/src/applications/packet-sink/packet-sink.cc index 1b4e14bad..a05b5e075 100644 --- a/src/applications/packet-sink/packet-sink.cc +++ b/src/applications/packet-sink/packet-sink.cc @@ -88,11 +88,17 @@ void PacketSink::StartApplication() // Called at time specified by Start m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this)); m_socket->SetAcceptCallback ( MakeNullCallback, const Address &> (), - MakeNullCallback, const Address&> ()); + MakeCallback(&PacketSink::HandleAccept, this)); } void PacketSink::StopApplication() // Called at time specified by Stop { + while(!m_socketList.empty()) //these are accepted sockets, close them + { + Ptr acceptedSocket = m_socketList.front(); + m_socketList.pop_front(); + acceptedSocket->Close(); + } if (m_socket) { m_socket->Close (); @@ -117,4 +123,10 @@ void PacketSink::HandleRead (Ptr socket) } } +void PacketSink::HandleAccept (Ptr s, const Address& from) +{ + s->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this)); + m_socketList.push_back (s); +} + } // Namespace ns3 diff --git a/src/applications/packet-sink/packet-sink.h b/src/applications/packet-sink/packet-sink.h index 440af90cd..f8a9a3c1a 100644 --- a/src/applications/packet-sink/packet-sink.h +++ b/src/applications/packet-sink/packet-sink.h @@ -81,8 +81,13 @@ private: virtual void StopApplication (void); // Called at time specified by Stop void HandleRead (Ptr socket); + void HandleAccept (Ptr, const Address& from); + + // In the case of TCP, each socket accept returns a new socket, so the + // listening socket is stored seperately from the accepted sockets + Ptr m_socket; // Listening socket + std::list > m_socketList; //the accepted sockets - Ptr m_socket; // Associated socket Address m_local; // Local address to bind to TypeId m_tid; // Protocol TypeId TracedCallback, const Address &> m_rxTrace; diff --git a/src/internet-stack/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc index fc0cf1b8b..cb970df79 100644 --- a/src/internet-stack/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -86,7 +86,7 @@ TcpSocketImpl::GetTypeId () } TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock) - : TcpSocket(sock), //copy the base class callbacks + : TcpSocket(sock), //copy object::m_tid, copy socket::callbacks m_skipRetxResched (sock.m_skipRetxResched), m_dupAckCount (sock.m_dupAckCount), m_delAckCount (0), @@ -140,6 +140,9 @@ TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock) { m_rtt = sock.m_rtt->Copy(); } + //null out the socket base class recvcallback, + //make user of the socket register this explicitly + SetRecvCallback (MakeNullCallback > () ); //can't "copy" the endpoint just yes, must do this when we know the peer info //too; this is in SYN_ACK_TX } From dbb7f0f738a28a65bccf97090044312de54799e6 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 23 Jul 2008 17:09:12 -0700 Subject: [PATCH 2/3] begin sorting out mtu woes --- src/devices/csma/csma-net-device.cc | 202 +++++++++++++++++++--------- src/devices/csma/csma-net-device.h | 20 ++- 2 files changed, 156 insertions(+), 66 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 15c353f94..b43ca9b6f 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -27,6 +27,7 @@ #include "ns3/error-model.h" #include "ns3/enum.h" #include "ns3/boolean.h" +#include "ns3/uinteger.h" #include "ns3/pointer.h" #include "ns3/trace-source-accessor.h" #include "csma-net-device.h" @@ -45,52 +46,61 @@ CsmaNetDevice::GetTypeId (void) .SetParent () .AddConstructor () .AddAttribute ("Address", - "The address of this device.", - Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")), - MakeMac48AddressAccessor (&CsmaNetDevice::m_address), - MakeMac48AddressChecker ()) + "The MAC address of this device.", + Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")), + MakeMac48AddressAccessor (&CsmaNetDevice::m_address), + MakeMac48AddressChecker ()) + .AddAttribute ("PayloadLength", + "The max PHY-level payload length of packets sent over this device.", + UintegerValue (DEFAULT_FRAME_LENGTH), + MakeUintegerAccessor (&CsmaNetDevice::m_maxPayloadLength), + MakeUintegerChecker ()) + .AddAttribute ("MTU", + "The MAC-level MTU (client payload) of packets sent over this device.", + UintegerValue (DEFAULT_MTU), + MakeUintegerAccessor (&CsmaNetDevice::m_mtu), + MakeUintegerChecker ()) .AddAttribute ("EncapsulationMode", - "The link-layer encapsulation type to use.", - EnumValue (LLC), - MakeEnumAccessor (&CsmaNetDevice::m_encapMode), - MakeEnumChecker (ETHERNET_V1, "EthernetV1", - IP_ARP, "IpArp", - RAW, "Raw", - LLC, "Llc")) + "The link-layer encapsulation type to use.", + EnumValue (LLC), + MakeEnumAccessor (&CsmaNetDevice::m_encapMode), + MakeEnumChecker (ETHERNET_V1, "EthernetV1", + IP_ARP, "IpArp", + RAW, "Raw", + LLC, "Llc")) .AddAttribute ("SendEnable", - "Enable or disable the transmitter section of the device.", - BooleanValue (true), - MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable), - MakeBooleanChecker ()) + "Enable or disable the transmitter section of the device.", + BooleanValue (true), + MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable), + MakeBooleanChecker ()) .AddAttribute ("ReceiveEnable", - "Enable or disable the receiver section of the device.", - BooleanValue (true), - MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable), - MakeBooleanChecker ()) + "Enable or disable the receiver section of the device.", + BooleanValue (true), + MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable), + MakeBooleanChecker ()) .AddAttribute ("RxErrorModel", - "The receiver error model used to simulate packet loss", - PointerValue (), - MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel), - MakePointerChecker ()) + "The receiver error model used to simulate packet loss", + PointerValue (), + MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel), + MakePointerChecker ()) .AddAttribute ("TxQueue", - "A queue to use as the transmit queue in the device.", - PointerValue (), - MakePointerAccessor (&CsmaNetDevice::m_queue), - MakePointerChecker ()) + "A queue to use as the transmit queue in the device.", + PointerValue (), + MakePointerAccessor (&CsmaNetDevice::m_queue), + MakePointerChecker ()) .AddTraceSource ("Rx", - "Trace source to fire on reception of a MAC packet.", - MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace)) + "The trace source to fire on reception of a MAC packet.", + MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace)) .AddTraceSource ("Drop", - "Trace source to fire on when a MAC packet is dropped.", - MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace)) + "Trace source to fire on when a MAC packet is dropped.", + MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace)) ; return tid; } CsmaNetDevice::CsmaNetDevice () : m_name (""), - m_linkUp (false), - m_mtu (0xffff) + m_linkUp (false) { NS_LOG_FUNCTION (this); m_txMachineState = READY; @@ -116,20 +126,21 @@ CsmaNetDevice::DoDispose () void CsmaNetDevice::SetAddress (Mac48Address self) { + NS_LOG_FUNCTION (self); m_address = self; } void CsmaNetDevice::SetSendEnable (bool sendEnable) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (sendEnable); m_sendEnable = sendEnable; } void CsmaNetDevice::SetReceiveEnable (bool receiveEnable) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (receiveEnable); m_receiveEnable = receiveEnable; } @@ -150,7 +161,7 @@ CsmaNetDevice::IsReceiveEnabled (void) void CsmaNetDevice::SetInterframeGap (Time t) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (t); m_tInterframeGap = t; } @@ -162,7 +173,7 @@ CsmaNetDevice::SetBackoffParams ( uint32_t ceiling, uint32_t maxRetries) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (slotTime << minSlots << maxSlots << ceiling << maxRetries); m_backoff.m_slotTime = slotTime; m_backoff.m_minSlots = minSlots; m_backoff.m_maxSlots = maxSlots; @@ -177,7 +188,7 @@ CsmaNetDevice::AddHeader ( Mac48Address dest, uint16_t protocolNumber) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (p << source << dest << protocolNumber); if (m_encapMode == RAW) { @@ -190,28 +201,58 @@ CsmaNetDevice::AddHeader ( EthernetTrailer trailer; + NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ()); + NS_LOG_LOGIC ("m_mtu = " << m_mtu); + NS_LOG_LOGIC ("m_maxPayloadLength = " << m_maxPayloadLength); + uint16_t lengthType = 0; switch (m_encapMode) { - case ETHERNET_V1: - lengthType = p->GetSize () + header.GetSerializedSize () + - trailer.GetSerializedSize (); - break; case IP_ARP: + NS_LOG_LOGIC ("Encapsulating packet as IP_ARP (type interpretation)"); +// +// This corresponds to the type interpretation of the lengthType field. +// lengthType = protocolNumber; break; - case LLC: { - lengthType = p->GetSize () + header.GetSerializedSize () + - trailer.GetSerializedSize (); - LlcSnapHeader llc; - llc.SetType (protocolNumber); - p->AddHeader (llc); - } break; + case ETHERNET_V1: + NS_LOG_LOGIC ("Encapsulating packet as ETHERNET_V1 " + "(length interpretation)"); +// +// This corresponds to the length interpretation of the lengthType field. +// The ethernet header and trailer are not counted, see RFC 1042 and +// http://standards.ieee.org/getieee802/download/802.3-2005_section1.pdf, +// Section 3.2.6 a. We just include the size of the "payload." +// + lengthType = p->GetSize (); + NS_ASSERT_MSG (lengthType <= m_maxPayloadLength, + "CsmaNetDevice::AddHeader(): 802.3 Length/Type field: " + "length interpretation must not exceed device max payload length"); + break; + case LLC: + { + NS_LOG_LOGIC ("Encapsulating packet as LLC (length interpretation)"); + + LlcSnapHeader llc; + llc.SetType (protocolNumber); + p->AddHeader (llc); +// +// This corresponds to the length interpretation of the lengthType field, +// but with an LLC/SNAP header added to the payload. +// + lengthType = llc.GetSerializedSize () + p->GetSize (); + NS_ASSERT_MSG (lengthType <= m_maxPayloadLength, + "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: " + "length interpretation must not exceed device max payload length"); + } + break; case RAW: + NS_LOG_LOGIC ("Encapsulating packet as RAW"); NS_ASSERT (false); break; } + NS_LOG_LOGIC ("header.SetLengthType (" << lengthType << ")"); header.SetLengthType (lengthType); p->AddHeader (header); @@ -222,7 +263,8 @@ CsmaNetDevice::AddHeader ( bool CsmaNetDevice::ProcessHeader (Ptr p, uint16_t & param) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (p << param); + if (m_encapMode == RAW) { return true; @@ -264,6 +306,7 @@ CsmaNetDevice::ProcessHeader (Ptr p, uint16_t & param) CsmaNetDevice::TransmitStart () { NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt); NS_LOG_LOGIC ("UID is " << m_currentPkt->GetUid ()); // @@ -344,6 +387,7 @@ CsmaNetDevice::TransmitStart () CsmaNetDevice::TransmitAbort (void) { NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")"); // @@ -366,6 +410,7 @@ CsmaNetDevice::TransmitAbort (void) CsmaNetDevice::TransmitCompleteEvent (void) { NS_LOG_FUNCTION_NOARGS (); + // // This function is called to finish the process of transmitting a packet. // We need to tell the channel that we've stopped wiggling the wire and @@ -390,6 +435,7 @@ CsmaNetDevice::TransmitCompleteEvent (void) CsmaNetDevice::TransmitReadyEvent (void) { NS_LOG_FUNCTION_NOARGS (); + // // This function is called to enable the transmitter after the interframe // gap has passed. If there are pending transmissions, we use this opportunity @@ -398,7 +444,9 @@ CsmaNetDevice::TransmitReadyEvent (void) NS_ASSERT_MSG (m_txMachineState == GAP, "Must be in interframe gap"); m_txMachineState = READY; - // Get the next packet from the queue for transmitting +// +// Get the next packet from the queue for transmitting +// if (m_queue->IsEmpty ()) { return; @@ -412,7 +460,7 @@ CsmaNetDevice::TransmitReadyEvent (void) } } -bool + bool CsmaNetDevice::Attach (Ptr ch) { NS_LOG_FUNCTION (this << &ch); @@ -441,7 +489,7 @@ CsmaNetDevice::Attach (Ptr ch) void CsmaNetDevice::SetQueue (Ptr q) { - NS_LOG_FUNCTION (this << q); + NS_LOG_FUNCTION (q); m_queue = q; } @@ -455,15 +503,14 @@ CsmaNetDevice::SetReceiveErrorModel (Ptr em) void CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (packet << senderDevice); NS_LOG_LOGIC ("UID is " << packet->GetUid ()); - - // - // We never forward up packets that we sent. Real devices don't do this since - // their receivers are disabled during send, so we don't. Drop the packet - // silently (no tracing) since it would really never get here in a real device. - // +// +// We never forward up packets that we sent. Real devices don't do this since +// their receivers are disabled during send, so we don't. Drop the packet +// silently (no tracing) since it would really never get here in a real device. +// if (senderDevice == this) { return; @@ -483,7 +530,8 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) m_rxTrace (packet); if (!m_promiscRxCallback.IsNull ()) { - m_promiscRxCallback (this, packet, 0, GetBroadcast (), GetAddress (), PACKET_HOST); + m_promiscRxCallback (this, packet, 0, GetBroadcast (), + GetAddress (), PACKET_HOST); } m_rxCallback (this, packet, 0, GetBroadcast ()); return; @@ -581,7 +629,8 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) if (!m_promiscRxCallback.IsNull ()) { - m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType); + m_promiscRxCallback (this, packet, protocol, header.GetSource (), + header.GetDestination (), packetType); } if (packetType != PACKET_OTHERHOST) @@ -601,6 +650,8 @@ CsmaNetDevice::GetQueue (void) const void CsmaNetDevice::NotifyLinkUp (void) { + NS_LOG_FUNCTION_NOARGS (); + m_linkUp = true; if (m_linkChangeCallback.IsNull () == false) { @@ -611,42 +662,49 @@ CsmaNetDevice::NotifyLinkUp (void) void CsmaNetDevice::SetName (const std::string name) { + NS_LOG_FUNCTION (name); m_name = name; } std::string CsmaNetDevice::GetName (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_name; } void CsmaNetDevice::SetIfIndex (const uint32_t index) { + NS_LOG_FUNCTION (index); m_ifIndex = index; } uint32_t CsmaNetDevice::GetIfIndex (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_ifIndex; } Ptr CsmaNetDevice::GetChannel (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_channel; } Address CsmaNetDevice::GetAddress (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_address; } bool CsmaNetDevice::SetMtu (const uint16_t mtu) { + NS_LOG_FUNCTION (mtu); m_mtu = mtu; return true; } @@ -654,49 +712,56 @@ CsmaNetDevice::SetMtu (const uint16_t mtu) uint16_t CsmaNetDevice::GetMtu (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_mtu; } bool CsmaNetDevice::IsLinkUp (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_linkUp; } void CsmaNetDevice::SetLinkChangeCallback (Callback callback) { + NS_LOG_FUNCTION (&callback); m_linkChangeCallback = callback; } bool CsmaNetDevice::IsBroadcast (void) const { + NS_LOG_FUNCTION_NOARGS (); return true; } Address CsmaNetDevice::GetBroadcast (void) const { + NS_LOG_FUNCTION_NOARGS (); return Mac48Address ("ff:ff:ff:ff:ff:ff"); } bool CsmaNetDevice::IsMulticast (void) const { + NS_LOG_FUNCTION_NOARGS (); return true; } Address CsmaNetDevice::GetMulticast (void) const { + NS_LOG_FUNCTION_NOARGS (); return Mac48Address ("01:00:5e:00:00:00"); } Address CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const { - NS_LOG_FUNCTION (this << multicastGroup); + NS_LOG_FUNCTION (multicastGroup); // // First, get the generic multicast address. // @@ -748,6 +813,7 @@ CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const bool CsmaNetDevice::IsPointToPoint (void) const { + NS_LOG_FUNCTION_NOARGS (); return false; } @@ -756,6 +822,7 @@ CsmaNetDevice::Send (Ptr packet, const Address& dest, uint16_t protocolNumber) { + NS_LOG_FUNCTION (packet << dest << protocolNumber); return SendFrom (packet, m_address, dest, protocolNumber); } @@ -765,7 +832,7 @@ CsmaNetDevice::SendFrom (Ptr packet, const Address& dest, uint16_t protocolNumber) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (packet << src << dest << protocolNumber); NS_LOG_LOGIC ("p=" << packet); NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")"); @@ -812,12 +879,15 @@ CsmaNetDevice::SendFrom (Ptr packet, Ptr CsmaNetDevice::GetNode (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_node; } void CsmaNetDevice::SetNode (Ptr node) { + NS_LOG_FUNCTION (node); + m_node = node; int count = -1; if (m_name.size () == 0) @@ -843,6 +913,7 @@ CsmaNetDevice::SetNode (Ptr node) bool CsmaNetDevice::NeedsArp (void) const { + NS_LOG_FUNCTION_NOARGS (); if ((m_encapMode == IP_ARP) || (m_encapMode == LLC)) { return true; @@ -856,18 +927,21 @@ CsmaNetDevice::NeedsArp (void) const void CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) { + NS_LOG_FUNCTION (&cb); m_rxCallback = cb; } void CsmaNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb) { + NS_LOG_FUNCTION (&cb); m_promiscRxCallback = cb; } bool CsmaNetDevice::SupportsPromiscuous () const { + NS_LOG_FUNCTION_NOARGS (); return true; } diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index db22d7065..f84b2eb9b 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -332,6 +332,10 @@ protected: bool ProcessHeader (Ptr p, uint16_t & param); private: + + static const uint16_t DEFAULT_FRAME_LENGTH = 1500; + static const uint16_t DEFAULT_MTU = 1492; + /** * Operator = is declared but not implemented. This disables the assigment * operator for CsmaNetDevice objects. @@ -565,10 +569,22 @@ private: Callback m_linkChangeCallback; /** - * The maximum transmission unit (biggest packet) allowed to be sent or - * received by this network device. + * The MAC-level maximum transmission unit allowed to be sent or received by + * this network device. This corresponds to the maximum payload the device + * can accept for transmission. This is distinct from the PHY-level maximum + * as found in the 802.3 header Type/Length field. For example, if you + * choose "Llc" as your encapsulation mode, this will be reduced by the eight + * bytes consumed by the LLC/SNAP header. */ uint16_t m_mtu; + + /** + * The PHY-level maximum payload size. This corresponds to the maximum + * number of bytes that can be transmitted as a payload over a channel. + * This corresponds to the 1500 byte limit often seen on Ethernet in the + * length interpretation of the Type/Length field of the 802.3 header. + */ + uint32_t m_maxPayloadLength; }; }; // namespace ns3 From c51f635cfb2504bfa33dac43d1c589ac8de9b394 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 23 Jul 2008 18:29:13 -0700 Subject: [PATCH 3/3] fix supidity in mtu stuff --- src/devices/csma/csma-net-device.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index b43ca9b6f..32be6215a 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -240,7 +240,7 @@ CsmaNetDevice::AddHeader ( // This corresponds to the length interpretation of the lengthType field, // but with an LLC/SNAP header added to the payload. // - lengthType = llc.GetSerializedSize () + p->GetSize (); + lengthType = p->GetSize (); NS_ASSERT_MSG (lengthType <= m_maxPayloadLength, "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: " "length interpretation must not exceed device max payload length");