1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2007 Georgia Tech Research Corporation 4 * 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 7 * published by the Free Software Foundation; 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 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 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * 18 * Author: Raj Bhattacharjea <raj.b@gatech.edu> 19 */ 20 21 #ifndef TCP_L4_PROTOCOL_H 22 #define TCP_L4_PROTOCOL_H 23 24 #include <stdint.h> 25 26 #include "ns3/ipv4-address.h" 27 #include "ns3/ipv6-address.h" 28 #include "ns3/sequence-number.h" 29 #include "ip-l4-protocol.h" 30 31 32 namespace ns3 { 33 34 class Node; 35 class Socket; 36 class TcpHeader; 37 class Ipv4EndPointDemux; 38 class Ipv6EndPointDemux; 39 class Ipv4Interface; 40 class TcpSocketBase; 41 class Ipv4EndPoint; 42 class Ipv6EndPoint; 43 class NetDevice; 44 45 46 /** 47 * \ingroup internet 48 * \defgroup tcp TCP 49 * 50 * This is an implementation of various Transmission Control Protocol flavors. 51 * 52 * Each TCP flavors is studied to match a specific environment, and they 53 * differ mainly in the congestion control algorithms used. 54 * 55 * See \RFC{793} and others. 56 */ 57 58 /** 59 * \ingroup tcp 60 * \brief TCP socket creation and multiplexing/demultiplexing 61 * 62 * A single instance of this class is held by one instance of class Node. 63 * 64 * The creation of TcpSocket are handled in the method CreateSocket, which is 65 * called by TcpSocketFactory. Upon creation, this class is responsible to 66 * the socket initialization and handle multiplexing/demultiplexing of data 67 * between node's TCP sockets. Demultiplexing is done by receiving 68 * packets from IP, and forwards them up to the right socket. Multiplexing 69 * is done through the SendPacket function, which sends the packet down the stack. 70 * 71 * Moreover, this class allocates "endpoint" objects (ns3::Ipv4EndPoint) for TCP, 72 * and SHOULD checksum packets its receives from the socket layer going down 73 * the stack, but currently checksumming is disabled. 74 * 75 * \see CreateSocket 76 * \see NotifyNewAggregate 77 * \see SendPacket 78 */ 79 80 class TcpL4Protocol : public IpL4Protocol { 81 public: 82 /** 83 * \brief Get the type ID. 84 * \return the object TypeId 85 */ 86 static TypeId GetTypeId (void); 87 static const uint8_t PROT_NUMBER; //!< protocol number (0x6) 88 89 TcpL4Protocol (); 90 virtual ~TcpL4Protocol (); 91 92 /** 93 * Set node associated with this stack 94 * \param node the node 95 */ 96 void SetNode (Ptr<Node> node); 97 98 // NOTE: API from here should not be removed, only added. Be backward-compatible! 99 100 /** 101 * \brief Create a TCP socket using the TypeId set by SocketType attribute 102 * 103 * \return A smart Socket pointer to a TcpSocket allocated by this instance 104 * of the TCP protocol 105 */ 106 Ptr<Socket> CreateSocket (void); 107 108 /** 109 * \brief Create a TCP socket using the specified congestion control algorithm TypeId 110 * 111 * \return A smart Socket pointer to a TcpSocket allocated by this instance 112 * of the TCP protocol 113 * 114 * \warning using a congestionTypeId other than TCP is a bad idea. 115 * 116 * \param congestionTypeId the congestion control algorithm TypeId 117 * \param recoveryTypeId the recovery algorithm TypeId 118 */ 119 Ptr<Socket> CreateSocket (TypeId congestionTypeId, TypeId recoveryTypeId); 120 121 /** 122 * \brief Create a TCP socket using the specified congestion control algorithm 123 * \return A smart Socket pointer to a TcpSocket allocated by this instance 124 * of the TCP protocol 125 * 126 * \param congestionTypeId the congestion control algorithm TypeId 127 * 128 */ 129 Ptr<Socket> CreateSocket (TypeId congestionTypeId); 130 131 /** 132 * \brief Allocate an IPv4 Endpoint 133 * \return the Endpoint 134 */ 135 Ipv4EndPoint *Allocate (void); 136 /** 137 * \brief Allocate an IPv4 Endpoint 138 * \param address address to use 139 * \return the Endpoint 140 */ 141 Ipv4EndPoint *Allocate (Ipv4Address address); 142 /** 143 * \brief Allocate an IPv4 Endpoint 144 * \param boundNetDevice Bound NetDevice (if any) 145 * \param port port to use 146 * \return the Endpoint 147 */ 148 Ipv4EndPoint *Allocate (Ptr<NetDevice> boundNetDevice, uint16_t port); 149 /** 150 * \brief Allocate an IPv4 Endpoint 151 * \param boundNetDevice Bound NetDevice (if any) 152 * \param address address to use 153 * \param port port to use 154 * \return the Endpoint 155 */ 156 Ipv4EndPoint *Allocate (Ptr<NetDevice> boundNetDevice, Ipv4Address address, uint16_t port); 157 /** 158 * \brief Allocate an IPv4 Endpoint 159 * \param boundNetDevice Bound NetDevice (if any) 160 * \param localAddress local address to use 161 * \param localPort local port to use 162 * \param peerAddress remote address to use 163 * \param peerPort remote port to use 164 * \return the Endpoint 165 */ 166 Ipv4EndPoint *Allocate (Ptr<NetDevice> boundNetDevice, 167 Ipv4Address localAddress, uint16_t localPort, 168 Ipv4Address peerAddress, uint16_t peerPort); 169 /** 170 * \brief Allocate an IPv6 Endpoint 171 * \return the Endpoint 172 */ 173 Ipv6EndPoint *Allocate6 (void); 174 /** 175 * \brief Allocate an IPv6 Endpoint 176 * \param address address to use 177 * \return the Endpoint 178 */ 179 Ipv6EndPoint *Allocate6 (Ipv6Address address); 180 /** 181 * \brief Allocate an IPv6 Endpoint 182 * \param boundNetDevice Bound NetDevice (if any) 183 * \param port port to use 184 * \return the Endpoint 185 */ 186 Ipv6EndPoint *Allocate6 (Ptr<NetDevice> boundNetDevice, uint16_t port); 187 /** 188 * \brief Allocate an IPv6 Endpoint 189 * \param boundNetDevice Bound NetDevice (if any) 190 * \param address address to use 191 * \param port port to use 192 * \return the Endpoint 193 */ 194 Ipv6EndPoint *Allocate6 (Ptr<NetDevice> boundNetDevice, Ipv6Address address, uint16_t port); 195 /** 196 * \brief Allocate an IPv6 Endpoint 197 * \param boundNetDevice Bound NetDevice (if any) 198 * \param localAddress local address to use 199 * \param localPort local port to use 200 * \param peerAddress remote address to use 201 * \param peerPort remote port to use 202 * \return the Endpoint 203 */ 204 Ipv6EndPoint *Allocate6 (Ptr<NetDevice> boundNetDevice, 205 Ipv6Address localAddress, uint16_t localPort, 206 Ipv6Address peerAddress, uint16_t peerPort); 207 208 /** 209 * \brief Send a packet via TCP (IP-agnostic) 210 * 211 * \param pkt The packet to send 212 * \param outgoing The packet header 213 * \param saddr The source Ipv4Address 214 * \param daddr The destination Ipv4Address 215 * \param oif The output interface bound. Defaults to null (unspecified). 216 */ 217 void SendPacket (Ptr<Packet> pkt, const TcpHeader &outgoing, 218 const Address &saddr, const Address &daddr, 219 Ptr<NetDevice> oif = 0) const; 220 221 /** 222 * \brief Make a socket fully operational 223 * 224 * Called after a socket has been bound, it is inserted in an internal vector. 225 * 226 * \param socket Socket to be added 227 */ 228 void AddSocket (Ptr<TcpSocketBase> socket); 229 230 /** 231 * \brief Remove a socket from the internal list 232 * 233 * \param socket socket to Remove 234 * \return true if the socket has been removed 235 */ 236 bool RemoveSocket (Ptr<TcpSocketBase> socket); 237 238 /** 239 * \brief Remove an IPv4 Endpoint. 240 * \param endPoint the end point to remove 241 */ 242 void DeAllocate (Ipv4EndPoint *endPoint); 243 /** 244 * \brief Remove an IPv6 Endpoint. 245 * \param endPoint the end point to remove 246 */ 247 void DeAllocate (Ipv6EndPoint *endPoint); 248 249 // From IpL4Protocol 250 virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p, 251 Ipv4Header const &incomingIpHeader, 252 Ptr<Ipv4Interface> incomingInterface); 253 virtual enum IpL4Protocol::RxStatus Receive (Ptr<Packet> p, 254 Ipv6Header const &incomingIpHeader, 255 Ptr<Ipv6Interface> incomingInterface); 256 257 virtual void ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, 258 uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo, 259 Ipv4Address payloadSource,Ipv4Address payloadDestination, 260 const uint8_t payload[8]); 261 virtual void ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl, 262 uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo, 263 Ipv6Address payloadSource,Ipv6Address payloadDestination, 264 const uint8_t payload[8]); 265 266 virtual void SetDownTarget (IpL4Protocol::DownTargetCallback cb); 267 virtual void SetDownTarget6 (IpL4Protocol::DownTargetCallback6 cb); 268 virtual int GetProtocolNumber (void) const; 269 virtual IpL4Protocol::DownTargetCallback GetDownTarget (void) const; 270 virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6 (void) const; 271 272 protected: 273 virtual void DoDispose (void); 274 275 /** 276 * \brief Setup socket factory and callbacks when aggregated to a node 277 * 278 * This function will notify other components connected to the node that a 279 * new stack member is now connected. This will be used to notify Layer 3 280 * protocol of layer 4 protocol stack to connect them together. 281 * The aggregation is completed by setting the node in the TCP stack, link 282 * it to the ipv4 or ipv6 stack and adding TCP socket factory to the node. 283 */ 284 virtual void NotifyNewAggregate (); 285 286 /** 287 * \brief Get the tcp header of the incoming packet and checks its checksum if needed 288 * 289 * \param packet Received packet 290 * \param incomingTcpHeader Overwritten with the tcp header of the packet 291 * \param source Source address (an underlying Ipv4Address or Ipv6Address) 292 * \param destination Destination address (an underlying Ipv4Address or Ipv6Address) 293 * 294 * \return RX_CSUM_FAILED if the checksum check fails, RX_OK otherwise 295 */ 296 enum IpL4Protocol::RxStatus 297 PacketReceived (Ptr<Packet> packet, TcpHeader &incomingTcpHeader, 298 const Address &source, const Address &destination); 299 300 /** 301 * \brief Check if RST packet should be sent, and in case, send it 302 * 303 * The function is called when no endpoint is found for the received 304 * packet. So TcpL4Protocol do not know to who the packet should be 305 * given to. An RST packet is sent out as reply unless the received packet 306 * has the RST flag set. 307 * 308 * \param incomingHeader TCP header of the incoming packet 309 * \param incomingSAddr Source address of the incoming packet 310 * \param incomingDAddr Destination address of the incoming packet 311 * 312 */ 313 void NoEndPointsFound (const TcpHeader &incomingHeader, const Address &incomingSAddr, 314 const Address &incomingDAddr); 315 316 private: 317 Ptr<Node> m_node; //!< the node this stack is associated with 318 Ipv4EndPointDemux *m_endPoints; //!< A list of IPv4 end points. 319 Ipv6EndPointDemux *m_endPoints6; //!< A list of IPv6 end points. 320 TypeId m_rttTypeId; //!< The RTT Estimator TypeId 321 TypeId m_congestionTypeId; //!< The socket TypeId 322 TypeId m_recoveryTypeId; //!< The recovery TypeId 323 std::vector<Ptr<TcpSocketBase> > m_sockets; //!< list of sockets 324 IpL4Protocol::DownTargetCallback m_downTarget; //!< Callback to send packets over IPv4 325 IpL4Protocol::DownTargetCallback6 m_downTarget6; //!< Callback to send packets over IPv6 326 327 /** 328 * \brief Copy constructor 329 * 330 * Defined and not implemented to avoid misuse 331 */ 332 TcpL4Protocol (const TcpL4Protocol &); 333 /** 334 * \brief Copy constructor 335 * 336 * Defined and not implemented to avoid misuse 337 * \returns 338 */ 339 TcpL4Protocol &operator = (const TcpL4Protocol &); 340 341 /** 342 * \brief Send a packet via TCP (IPv4) 343 * 344 * \param pkt The packet to send 345 * \param outgoing The packet header 346 * \param saddr The source Ipv4Address 347 * \param daddr The destination Ipv4Address 348 * \param oif The output interface bound. Defaults to null (unspecified). 349 */ 350 void SendPacketV4 (Ptr<Packet> pkt, const TcpHeader &outgoing, 351 const Ipv4Address &saddr, const Ipv4Address &daddr, 352 Ptr<NetDevice> oif = 0) const; 353 354 /** 355 * \brief Send a packet via TCP (IPv6) 356 * 357 * \param pkt The packet to send 358 * \param outgoing The packet header 359 * \param saddr The source Ipv4Address 360 * \param daddr The destination Ipv4Address 361 * \param oif The output interface bound. Defaults to null (unspecified). 362 */ 363 void SendPacketV6 (Ptr<Packet> pkt, const TcpHeader &outgoing, 364 const Ipv6Address &saddr, const Ipv6Address &daddr, 365 Ptr<NetDevice> oif = 0) const; 366 }; 367 368 } // namespace ns3 369 370 #endif /* TCP_L4_PROTOCOL_H */ 371