[Ns-developers] TCP and UDP layer refactoring
Sébastien Vincent
vincent at clarinet.u-strasbg.fr
Fri Jul 4 04:43:02 PDT 2008
Sébastien Vincent wrote:
> Hi,
>
> Here is one solution for a design about the refactoring UDP/TCP layer.
> It will be decomposed in several part.
>
> I) Tags
>
> Add the following tags :
>
> - Ipv6SocketAddressesTag
> -> Ipv6Address src;
> -> Ipv6Address dst;
>
> - Ipv4SocketAddressesTag
> -> Ipv4Address src;
> -> Ipv4Address dst;
>
> - LocalIpv6InterfaceTag
> -> Ipv6Address addr;
> -> Ipv6Prefix mask;
>
> - LocalIpv4InterfaceTag
> -> Ipv4Address addr;
> -> Ipv4Mask mask;
> -> uint32_t ifIndex ???;
>
> The LocaIpv*InterfaceTag will be used to avoid having the
> Ptr<Ipv*Interface> in *L4Protocol::Receive.
> In facts in the *EndPointDemux::Lookup, we use the interface to get
> its address and netmask.
>
> II) Independant EndPoint
>
> - Have a single class EndPoint (and remove Ipv6EndPoint and
> Ipv4EndPoint).
> - The members m_localAddr an m_peerAddress will be stored as Address
> - Remove Ipv4Address argument from m_rxCallBack and SetRxCallback (see
> VI)).
> - Add a AfType (AF_INET or AF_INET6) to know the type of address.
>
> III) StorageSocketAddress
>
> Some functions in *SocketImpl use InetSocketAddress or
> Inet6SocketAddress. We can avoid this by having a class that have the
> same methods
> than InetSocketAddress but with Address attributes called
> StorageSocketAddress. This is similar to the "struct sockaddr_storage"
> in C.
>
> StorageSocketAddress
> -> AfType type
> -> Address addr
> -> uint16_t port
> -> ConvertToInetSocketAddress (???)
> -> ConvertToInet6SocketAddress (???)
>
> The InetSocketAddress and Inet6SocketAddress should have a operator
> StorageSocketAddress() to map automatically its contents to a
> StorageSocketAddress and set the AfType.
> -> No changes to existing applications.
>
> OR
>
> we can also remove InetSocketAddress and Inet6SocketAddress and use
> only StorageSocketAddress.
>
>
> IV) *SocketImpl
>
> - Use StorageSocketAddress;
> - Use Address instead of Ipv*Address;
> - In DoSendTo (Ptr<Packet> p, Address daddr, uint16_t dport), after
>
> if (m_endPoint == 0)
> {
> if (Bind () == -1)
> {
> NS_ASSERT (m_endPoint == 0);
> return -1;
> }
> NS_ASSERT (m_endPoint != 0);
> }
> if (m_shutdownSend)
> {
> m_errno = ERROR_SHUTDOWN;
> return -1;
> }
>
> check m_endPoint->GetAfType() and do IPv6 or IPv4 stuff;
>
> - Add Ipv*SocketAddressesTag before sending to UdpL4Protocol.
>
>
> V) Ipv*L3Protocol
>
> - Add the Ipv*SocketAddressesTag in ::ForwardUp();
> - Add Ipv*InterfaceTag in ::ForwardUp().
>
> VI) *L4Protocol
>
> - Have Ipv6EndPointDemux and Ipv4EndPointDemux or one EndPointDemux
> (see VII));
> - Remove Ipv*Address in ::Receive signature, use tag instead (added in
> Ipv*L3Protocol);
> - Remove Ipv*Address in ::Send() signature, use tag instead (added in
> *SocketImpl::DoSendTo());
> - Check tag (if/else) in ::Receive, and do appropriate behavior
> (checksum, *EndPointDemux);
> - Check tag (if/else) in ::Send, and do appropriate behavior
> (checksum, send to the right L3 stack);
> - Remove Ipv*Address in ::ForwardUp() signature, check
> Ipv*SocketAddressesTag and get the source addresse, create a
> StorageSocketAddress, and put in SocketAddressTag;
> - Allocate() method takes Address arguments and return EndPoint*.
I forgot one thing :
In *L4Protocol::Allocate(void) and *L4Protocol::Allocate(uint16_t port)
we could not determine which L3 protocol we want and set the according
Ipv*EndPointDemux (to allocate).
Two solutions to solve the problem :
1)
Have the following prototypes instead :
EndPoint *L4Protocol::Allocate(Ipv4Address addr = Ipv4Address::Any());
EndPoint *L4Protocol::Allocate(uint16_t port, Ipv4Address addr =
Ipv4Address::Any());
EndPoint *L4Protocol::Allocate(Ipv6Address addr = Ipv6Address::Any());
EndPoint *L4Protocol::Allocate(uint16_t port, Ipv6Address addr =
Ipv6Address::Any());
Not very aesthetic!
2)
Don't use Allocate(void) and Allocate(uint16_t port).
Replace them in the *SocketImpl code by Allocate(Ipv*Address::Any()) and
Allocate(Ipv*Address::Any(), port).
Remove Ipv*EndPointDemux::Allocate (void).
Easy to do!
>
> VII) Ipv*EndPointDemux
>
> First solution :
> - Keep Ipv6EndPointDemux and Ipv4EndPointDemux;
> - In ::Lookup(), get the Ipv*InterfaceTag, remove incomingInterface
> and do stuff as usual with the address/netmask in the tag.
>
> Second solution
> - Have a single EndPointDemux;
> - Overload Lookup function (one for IPv6 and one for IPv4);
> - Two set of EndPoints list (one for IPv6 and one for IPv4);
> - Have a AllocateEphemeralPort() and AllocateEphemeralPort6() (because
> a service can be associated for a distinct IPv4 socket and a IPv6
> socket);
> - Remove Ipv6EndPointDemux and Ipv4EndPointDemux.
>
> VIII) Other
>
> - When we *L4Protocol::CreateSocket(), it will give a socket that
> could be bound in IPv4 or IPv6 so no need to add Udp6/Tcp6SocketFactory;
> - Have a single InternetL4Protocol class and remove Ipv6L4Protocol and
> Ipv4L4Protocol (since the ::Receive method signature will not have
> Ipv*Interface).
>
> What do you think ?
>
> I hope together, we can find a good solution for this issue.
>
> Regards,
> --
> Sebastien Vincent
> Network and Protocol Team, University of Strasbourg, France
>
>
More information about the Ns-developers
mailing list