# HG changeset patch # User Tom Henderson # Date 1463685414 25200 # Thu May 19 12:16:54 2016 -0700 # Node ID 5e19d533b37c4d67a4e5e1ce534f2dcc1274ff6c # Parent f64b70f1005152107cd8845765180683342c107b internet: (fixes #231) Avoid adding SocketAddressTag twice SocketAddressTag is added to Packet objects as a packet tag by transport protocols. Packet tags of the same type cannot be added twice to the same Packet. In certain tunneling situations (e.g. UDP tunneled over UDP), the packet may traverse the UDP receive chain twice before being delivered to an application, triggering an assert. The issue can be resolved by using Packet::ReplacePacketTag() instead of Packet::AddPacketTag() in transport protocols, as ReplacePacketTag will overwrite any pre-existing tag of the same type without error, or fall back to the semantics of AddPacketTag. This also seems to preserve the intended semantics in a tunneling situation, since the application will be more concerned with the inner (and not outer, tunnelled) address (see RFC 1853 sec. 2 for inner/outer definition). diff -r f64b70f10051 -r 5e19d533b37c src/internet/model/nsc-tcp-socket-impl.cc --- a/src/internet/model/nsc-tcp-socket-impl.cc Thu May 19 00:57:32 2016 +0200 +++ b/src/internet/model/nsc-tcp-socket-impl.cc Thu May 19 12:16:54 2016 -0700 @@ -633,7 +633,7 @@ SocketAddressTag tag; tag.SetAddress (m_peerAddress); - p->AddPacketTag (tag); + p->ReplacePacketTag (tag); m_deliveryQueue.push (p); m_rxAvailable += p->GetSize (); diff -r f64b70f10051 -r 5e19d533b37c src/internet/model/tcp-socket-base.cc --- a/src/internet/model/tcp-socket-base.cc Thu May 19 00:57:32 2016 +0200 +++ b/src/internet/model/tcp-socket-base.cc Thu May 19 12:16:54 2016 -0700 @@ -874,7 +874,7 @@ { tag.SetAddress (Inet6SocketAddress (m_endPoint6->GetPeerAddress (), m_endPoint6->GetPeerPort ())); } - outPacket->AddPacketTag (tag); + outPacket->ReplacePacketTag (tag); } return outPacket; } diff -r f64b70f10051 -r 5e19d533b37c src/internet/model/tcp-socket.h --- a/src/internet/model/tcp-socket.h Thu May 19 00:57:32 2016 +0200 +++ b/src/internet/model/tcp-socket.h Thu May 19 12:16:54 2016 -0700 @@ -42,6 +42,15 @@ * * This class exists solely for hosting TcpSocket attributes that can * be reused across different implementations. + * + * Socket data that is read from this socket using the methods returing + * an ns3::Packet object (i.e., Recv (), RecvMsg (), RecvFrom ()) will + * return Packet objects with a SocketAddressTag attached as a packet tag. + * The address, of underlying type InetSocketAddress, contains the address + * and port of the sender. Applications may safely remove this tag from + * the Packet. + * + * \see class SocketAddresssTag */ class TcpSocket : public Socket { diff -r f64b70f10051 -r 5e19d533b37c src/internet/model/udp-socket-impl.cc --- a/src/internet/model/udp-socket-impl.cc Thu May 19 00:57:32 2016 +0200 +++ b/src/internet/model/udp-socket-impl.cc Thu May 19 12:16:54 2016 -0700 @@ -1036,7 +1036,7 @@ Address address = InetSocketAddress (header.GetSource (), port); SocketAddressTag tag; tag.SetAddress (address); - packet->AddPacketTag (tag); + packet->ReplacePacketTag (tag); m_deliveryQueue.push (packet); m_rxAvailable += packet->GetSize (); NotifyDataRecv (); @@ -1092,7 +1092,7 @@ Address address = Inet6SocketAddress (header.GetSourceAddress (), port); SocketAddressTag tag; tag.SetAddress (address); - packet->AddPacketTag (tag); + packet->ReplacePacketTag (tag); m_deliveryQueue.push (packet); m_rxAvailable += packet->GetSize (); NotifyDataRecv (); diff -r f64b70f10051 -r 5e19d533b37c src/internet/model/udp-socket.h --- a/src/internet/model/udp-socket.h Thu May 19 00:57:32 2016 +0200 +++ b/src/internet/model/udp-socket.h Thu May 19 12:16:54 2016 -0700 @@ -42,6 +42,15 @@ * This class exists solely for hosting UdpSocket attributes that can * be reused across different implementations, and for declaring * UDP-specific multicast API. + * + * Socket data that is read from this socket using the methods returing + * an ns3::Packet object (i.e., Recv (), RecvMsg (), RecvFrom ()) will + * return Packet objects with a SocketAddressTag attached as a packet tag. + * The address, of underlying type InetSocketAddress, contains the address + * and port of the sender. Applications may safely remove this tag from + * the Packet. + * + * \see class SocketAddresssTag */ class UdpSocket : public Socket { diff -r f64b70f10051 -r 5e19d533b37c src/network/utils/packet-socket.h --- a/src/network/utils/packet-socket.h Thu May 19 00:57:32 2016 +0200 +++ b/src/network/utils/packet-socket.h Thu May 19 12:16:54 2016 -0700 @@ -74,6 +74,24 @@ * - Accept: not allowed * * - Listen: returns -1 (OPNOTSUPP) + * + * Socket data that is read from this socket using the methods returing + * an ns3::Packet object (i.e., Recv (), RecvMsg (), RecvFrom ()) will + * return Packet objects with three PacketTag objects attached. + * Applications may wish to read the extra out-of-band data provided in + * these tags, and may safely remove the tags from the Packet. + * + * - PacketSocketTag: contains destination address (type PacketSocketAddress) + * and packet type of the received packet + * + * - SocketAddressTag: contains source address (type PacketSocketAddress) + * of the received packet + * + * - DeviceNameTag: contains the TypeId string of the relevant NetDevice + * + * \see class PacketSocketTag + * \see class SocketAddresssTag + * \see class DeviceNameTag */ class PacketSocket : public Socket {