OLD | NEW |
(Empty) | |
| 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2013 Magister Solutions |
| 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: Budiarto Herman <budiarto.herman@magister.fi> |
| 19 * |
| 20 */ |
| 21 |
| 22 #ifndef THREE_GPP_HTTP_SERVER_H |
| 23 #define THREE_GPP_HTTP_SERVER_H |
| 24 |
| 25 #include <ns3/ptr.h> |
| 26 #include <ns3/simple-ref-count.h> |
| 27 #include <ns3/nstime.h> |
| 28 #include <ns3/event-id.h> |
| 29 #include <ns3/three-gpp-http-header.h> |
| 30 #include <ns3/application.h> |
| 31 #include <ns3/address.h> |
| 32 #include <ns3/traced-callback.h> |
| 33 #include <map> |
| 34 #include <ostream> |
| 35 |
| 36 |
| 37 namespace ns3 { |
| 38 |
| 39 |
| 40 class Socket; |
| 41 class Packet; |
| 42 class ThreeGppHttpVariables; |
| 43 class ThreeGppHttpServerTxBuffer; |
| 44 |
| 45 |
| 46 /** |
| 47 * \ingroup http |
| 48 * Model application which simulates the traffic of a web server. This |
| 49 * application works in conjunction with ThreeGppHttpClient applications. |
| 50 * |
| 51 * The application works by responding to requests. Each request is a small |
| 52 * packet of data which contains ThreeGppHttpHeader. The value of the *content |
| 53 * type* field of the header determines the type of object that the client is |
| 54 * requesting. The possible type is either a *main object* or an *embedded |
| 55 * object*. |
| 56 * |
| 57 * The application is responsible to generate the right type of object and send |
| 58 * it back to the client. The size of each object to be sent is randomly |
| 59 * determined (see ThreeGppHttpVariables). Each object may be sent as multiple p
ackets |
| 60 * due to limited socket buffer space. |
| 61 * |
| 62 * To assist with the transmission, the application maintains several instances |
| 63 * of ThreeGppHttpServerTxBuffer. Each instance keeps track of the object type t
o be |
| 64 * served and the number of bytes left to be sent. |
| 65 * |
| 66 * The application accepts connection request from clients. Every connection is |
| 67 * kept open until the client disconnects. |
| 68 */ |
| 69 class ThreeGppHttpServer : public Application |
| 70 { |
| 71 public: |
| 72 /** |
| 73 * Creates a new instance of HTTP server application. |
| 74 * |
| 75 * After creation, the application must be further configured through |
| 76 * attributes. To avoid having to do this process manually, please use |
| 77 * ThreeGppHttpServerHelper. |
| 78 * |
| 79 * Upon creation, the application randomly determines the MTU size that it |
| 80 * will use (either 536 or 1460 bytes). The chosen size will be used while |
| 81 * creating the listener socket. |
| 82 */ |
| 83 ThreeGppHttpServer (); |
| 84 |
| 85 /** |
| 86 * Returns the object TypeId. |
| 87 * \return The object TypeId. |
| 88 */ |
| 89 static TypeId GetTypeId (); |
| 90 |
| 91 /** |
| 92 * Sets the maximum transmission unit (MTU) size used by the application. |
| 93 * |
| 94 * This overrides the MTU size which is randomly determined once the |
| 95 * application is created. Values other than the standard 536 and 1460 bytes |
| 96 * can be set using this method. |
| 97 * |
| 98 * \param mtuSize MTU size in bytes. |
| 99 */ |
| 100 void SetMtuSize (uint32_t mtuSize); |
| 101 |
| 102 /** |
| 103 * Returns a pointer to the listening socket. |
| 104 * \return Pointer to the listening socket |
| 105 */ |
| 106 Ptr<Socket> GetSocket () const; |
| 107 |
| 108 /// The possible states of the application. |
| 109 enum State_t |
| 110 { |
| 111 NOT_STARTED = 0, ///< Before StartApplication() is invoked. |
| 112 STARTED, ///< Passively listening and responding to requests. |
| 113 STOPPED ///< After StopApplication() is invoked. |
| 114 }; |
| 115 |
| 116 /** |
| 117 * Returns the current state of the application. |
| 118 * \return The current state of the application. |
| 119 */ |
| 120 State_t GetState () const; |
| 121 |
| 122 /** |
| 123 * Returns the current state of the application in string format. |
| 124 * \return The current state of the application in string format. |
| 125 */ |
| 126 std::string GetStateString () const; |
| 127 |
| 128 /** |
| 129 * Returns the given state in string format. |
| 130 * \param state An arbitrary state of an application. |
| 131 * \return The given state equivalently expressed in string format. |
| 132 */ |
| 133 static std::string GetStateString (State_t state); |
| 134 |
| 135 /** |
| 136 * Common callback signature for `MainObject` and `EmbeddedObject` trace |
| 137 * sources. |
| 138 * \param size Size of the generated object in bytes. |
| 139 */ |
| 140 typedef void (*ThreeGppHttpObjectCallback)(uint32_t size); |
| 141 |
| 142 /** |
| 143 * Callback signature for `ConnectionEstablished` trace source. |
| 144 * \param httpServer Pointer to this instance of ThreeGppHttpServer, which is
where |
| 145 * the trace originated. |
| 146 * \param socket Pointer to the socket where the connection is established. |
| 147 */ |
| 148 typedef void (*ConnectionEstablishedCallback)(Ptr<const ThreeGppHttpServer> ht
tpServer, |
| 149 Ptr<Socket> so
cket); |
| 150 |
| 151 protected: |
| 152 // Inherited from Object base class |
| 153 virtual void DoDispose (); |
| 154 |
| 155 // Inherited from Application base class |
| 156 virtual void StartApplication (); |
| 157 virtual void StopApplication (); |
| 158 |
| 159 private: |
| 160 // SOCKET CALLBACK METHODS |
| 161 |
| 162 /** |
| 163 * Invoked when #m_initialSocket receives a connection request. |
| 164 * \param socket Pointer to the socket where the event originates from. |
| 165 * \param address The address of the remote client where the connection |
| 166 * request comes from. |
| 167 * \return Always true, to indicate to the other end that the connection |
| 168 * request is accepted. |
| 169 */ |
| 170 bool ConnectionRequestCallback (Ptr<Socket> socket, |
| 171 const Address &address); |
| 172 /** |
| 173 * Invoked when a new connection has been established. |
| 174 * \param socket Pointer to the socket that maintains the connection to the |
| 175 * remote client. This socket will be saved to the Tx buffer. |
| 176 * \param address The address the connection is incoming from. |
| 177 */ |
| 178 void NewConnectionCreatedCallback (Ptr<Socket> socket, |
| 179 const Address &address); |
| 180 /** |
| 181 * Invoked when a connection with a web client is terminated. The |
| 182 * corresponding socket will be removed from Tx buffer. |
| 183 * \param socket Pointer to the socket where the event originates from. |
| 184 */ |
| 185 void NormalCloseCallback (Ptr<Socket> socket); |
| 186 /** |
| 187 * Invoked when a connection with a web client is terminated. The |
| 188 * corresponding socket will be removed from Tx buffer. |
| 189 * \param socket Pointer to the socket where the event originates from. |
| 190 */ |
| 191 void ErrorCloseCallback (Ptr<Socket> socket); |
| 192 /** |
| 193 * Invoked when #m_initialSocket receives some packet data. It will check the |
| 194 * packet for ThreeGppHttpHeader. It also fires the `Rx` trace source. |
| 195 * |
| 196 * Depending on the type of object requested, the method will trigger |
| 197 * ServeMainObject() or ServeEmbeddedObject() after some delays. |
| 198 * |
| 199 * \param socket Pointer to the socket where the event originates from. |
| 200 */ |
| 201 void ReceivedDataCallback (Ptr<Socket> socket); |
| 202 /** |
| 203 * Invoked when more buffer space for transmission is added to a socket. The |
| 204 * method will invoke ServeFromTxBuffer() to start some transmission using |
| 205 * the socket. |
| 206 * \param socket Pointer to the socket where the event originates from. |
| 207 * \param availableBufferSize The number of bytes available in the socket's |
| 208 * transmission buffer. |
| 209 */ |
| 210 void SendCallback (Ptr<Socket> socket, uint32_t availableBufferSize); |
| 211 |
| 212 // TX-RELATED METHODS |
| 213 |
| 214 /** |
| 215 * Generates a new main object and push it into the Tx buffer. |
| 216 * |
| 217 * The size of the object is randomly determined by ThreeGppHttpVariables. |
| 218 * Fires the `MainObject` trace source. It then immediately triggers |
| 219 * ServeFromTxBuffer() to send the object. |
| 220 * |
| 221 * \param socket Pointer to the socket which is associated with the |
| 222 * destination client. |
| 223 */ |
| 224 void ServeNewMainObject (Ptr<Socket> socket); |
| 225 /** |
| 226 * Generates a new embedded object and push it into the Tx buffer. |
| 227 * |
| 228 * The size of the object is randomly determined by ThreeGppHttpVariables. |
| 229 * Fires the `EmbeddedObject` trace source. It then immediately triggers |
| 230 * ServeFromTxBuffer() to send the object. |
| 231 * |
| 232 * \param socket Pointer to the socket which is associated with the |
| 233 * destination client. |
| 234 */ |
| 235 void ServeNewEmbeddedObject (Ptr<Socket> socket); |
| 236 /** |
| 237 * Creates a packet out of a pending object in the Tx buffer send it over the |
| 238 * given socket. If the socket capacity is smaller than the object size, then |
| 239 * the method only convert a part of the object into a packet. |
| 240 * |
| 241 * ThreeGppHttpHeader will be attached in the beginning of each application |
| 242 * layer packet - if a packet is split, then then the following parts will |
| 243 * not have the header. The method fires the `Tx` trace source after sending |
| 244 * the packet to the socket. |
| 245 * |
| 246 * This method is invoked when a new object is generated by |
| 247 * ServeNewMainObject() or ServeNewEmbeddedObject(). It's also invoked when |
| 248 * the socket informs (through SendCallback()) that more buffer space for |
| 249 * transmission has become available. |
| 250 * |
| 251 * \param socket Pointer to the socket which is associated with the |
| 252 * destination client. |
| 253 * \return Size of the packet sent (in bytes). |
| 254 */ |
| 255 uint32_t ServeFromTxBuffer (Ptr<Socket> socket); |
| 256 |
| 257 /** |
| 258 * Change the state of the server. Fires the `StateTransition` trace source. |
| 259 * \param state The new state. |
| 260 */ |
| 261 void SwitchToState (State_t state); |
| 262 |
| 263 /// The current state of the client application. Begins with NOT_STARTED. |
| 264 State_t m_state; |
| 265 /// The listening socket, for receiving connection requests from clients. |
| 266 Ptr<Socket> m_initialSocket; |
| 267 /// Pointer to the transmission buffer. |
| 268 Ptr<ThreeGppHttpServerTxBuffer> m_txBuffer; |
| 269 |
| 270 // ATTRIBUTES |
| 271 |
| 272 /// The `Variables` attribute. A random number generator. |
| 273 Ptr<ThreeGppHttpVariables> m_httpVariables; |
| 274 /// The `LocalAddress` attribute. |
| 275 Address m_localAddress; |
| 276 /// The `LocalPort` attribute. |
| 277 uint16_t m_localPort; |
| 278 /// The `Mtu` attribute. |
| 279 uint32_t m_mtuSize; |
| 280 |
| 281 // TRACE SOURCES |
| 282 |
| 283 /// The `ConnectionEstablished` trace source. |
| 284 TracedCallback<Ptr<const ThreeGppHttpServer>, Ptr<Socket> > m_connectionEstabl
ishedTrace; |
| 285 /// The `MainObject` trace source. |
| 286 TracedCallback<uint32_t> m_mainObjectTrace; |
| 287 /// The `EmbeddedObject` trace source. |
| 288 TracedCallback<uint32_t> m_embeddedObjectTrace; |
| 289 /// The `Tx` trace source. |
| 290 TracedCallback<Ptr<const Packet> > m_txTrace; |
| 291 /// The `Rx` trace source. |
| 292 TracedCallback<Ptr<const Packet>, const Address &> m_rxTrace; |
| 293 /// The `RxDelay` trace source. |
| 294 TracedCallback<const Time &, const Address &> m_rxDelayTrace; |
| 295 /// The `StateTransition` trace source. |
| 296 TracedCallback<const std::string &, const std::string &> m_stateTransitionTrac
e; |
| 297 |
| 298 }; // end of `class ThreeGppHttpServer` |
| 299 |
| 300 |
| 301 /** |
| 302 * \internal |
| 303 * \ingroup http |
| 304 * Transmission buffer used by an HTTP server instance. |
| 305 * |
| 306 * The class handles the sockets which face the connected HTTP clients. An |
| 307 * individual buffer is allocated for each socket. The buffer indicates the |
| 308 * length (in bytes) and the type of the data within, i.e., it does *not* |
| 309 * contain the actual packet data. |
| 310 * |
| 311 * Types of data are expressed using the ThreeGppHttpHeader::ContentType_t type.
Only one |
| 312 * type of data can be active for one client at a time, i.e., the current |
| 313 * content of a buffer has to be removed before a different type of data can |
| 314 * be added. |
| 315 */ |
| 316 class ThreeGppHttpServerTxBuffer : public SimpleRefCount<ThreeGppHttpServerTxBuf
fer> |
| 317 { |
| 318 public: |
| 319 /// Create an empty instance of transmission buffer. |
| 320 ThreeGppHttpServerTxBuffer (); |
| 321 |
| 322 // SOCKET MANAGEMENT |
| 323 |
| 324 /** |
| 325 * This method is typically used before calling other methods. For example, |
| 326 * AddSocket() requires that the given socket does not exist among the stored |
| 327 * buffers. On the other hand, all the other methods that accept a pointer to |
| 328 * a socket as an argument require the existence of a buffer allocated to the |
| 329 * given socket. |
| 330 * \param socket Pointer to the socket to be found. |
| 331 * \return True if the given socket is found within the buffer. |
| 332 */ |
| 333 bool IsSocketAvailable (Ptr<Socket> socket) const; |
| 334 |
| 335 /** |
| 336 * Add a new socket and create an empty transmission buffer for it. After the |
| 337 * method is completed, IsSocketAvailable() for the same pointer of socket |
| 338 * shall return true. |
| 339 * \param socket Pointer to the new socket to be added (must not exist in the |
| 340 * buffer). |
| 341 * \warning Must be called only when IsSocketAvailable() for the given socket |
| 342 * is false. |
| 343 */ |
| 344 void AddSocket (Ptr<Socket> socket); |
| 345 |
| 346 /** |
| 347 * Remove a socket and its associated transmission buffer, and then unset the |
| 348 * socket's callbacks to prevent further interaction with the socket. If the |
| 349 * socket has a pending transmission event, it will be canceled. |
| 350 * |
| 351 * This method is useful for discarding a socket which is already closed, |
| 352 * e.g., by the HTTP client. This is due to the fact that double closing of a |
| 353 * socket may introduce undefined behaviour. |
| 354 * |
| 355 * After the method is completed, IsSocketAvailable() for the same pointer of |
| 356 * socket shall return false. |
| 357 * |
| 358 * \param socket Pointer to the socket to be removed. |
| 359 * \warning Must be called only when IsSocketAvailable() for the given socket |
| 360 * is true. |
| 361 */ |
| 362 void RemoveSocket (Ptr<Socket> socket); |
| 363 |
| 364 /** |
| 365 * Close and remove a socket and its associated transmission buffer, and then |
| 366 * unset the socket's callback to prevent further interaction with the |
| 367 * socket. |
| 368 * |
| 369 * This method is similar with RemoveSocket(), except that the latter does |
| 370 * not close the socket. |
| 371 * |
| 372 * After the method is completed, IsSocketAvailable() for the same pointer of |
| 373 * socket shall return false. |
| 374 * |
| 375 * \param socket Pointer to the socket to be closed and removed. |
| 376 * \warning Must be called only when IsSocketAvailable() for the given socket |
| 377 * is true. |
| 378 */ |
| 379 void CloseSocket (Ptr<Socket> socket); |
| 380 |
| 381 /** |
| 382 * Close and remove all stored sockets, hence clearing the buffer. |
| 383 */ |
| 384 void CloseAllSockets (); |
| 385 |
| 386 // BUFFER MANAGEMENT |
| 387 |
| 388 /** |
| 389 * \param socket Pointer to the socket which is associated with the |
| 390 * transmission buffer of interest. |
| 391 * \return True if the current length of the transmission buffer is zero, |
| 392 * i.e., no pending packet. |
| 393 * \warning Must be called only when IsSocketAvailable() for the given socket |
| 394 * is true. |
| 395 */ |
| 396 bool IsBufferEmpty (Ptr<Socket> socket) const; |
| 397 |
| 398 /** |
| 399 * \param socket Pointer to the socket which is associated with the |
| 400 * transmission buffer of interest |
| 401 * \return The client time stamp that comes from the last request packet |
| 402 * received by the given socket. It indicates the time the request |
| 403 * packet was transmitted by the client. |
| 404 */ |
| 405 Time GetClientTs (Ptr<Socket> socket) const; |
| 406 |
| 407 /** |
| 408 * Returns ThreeGppHttpHeader::NOT_SET when the buffer is new and never been f
illed |
| 409 * with any data before. Otherwise, returns either ThreeGppHttpHeader::MAIN_OB
JECT |
| 410 * or ThreeGppHttpHeader::EMBEDDED_OBJECT. |
| 411 * \param socket Pointer to the socket which is associated with the |
| 412 * transmission buffer of interest |
| 413 * \return The content type of the current data inside the transmission |
| 414 * buffer. |
| 415 * \warning Must be called only when IsSocketAvailable() for the given socket |
| 416 * is true. |
| 417 */ |
| 418 ThreeGppHttpHeader::ContentType_t GetBufferContentType (Ptr<Socket> socket) co
nst; |
| 419 |
| 420 /** |
| 421 * \param socket Pointer to the socket which is associated with the |
| 422 * transmission buffer of interest |
| 423 * \return The length (in bytes) of the current data inside the transmission |
| 424 * buffer. |
| 425 * \warning Must be called only when IsSocketAvailable() for the given socket |
| 426 * is true. |
| 427 */ |
| 428 uint32_t GetBufferSize (Ptr<Socket> socket) const; |
| 429 |
| 430 /** |
| 431 * Writes a data representing a new main object or embedded object to the |
| 432 * transmission buffer. |
| 433 * |
| 434 * The stored data can be later consumed wholly of partially by |
| 435 * DepleteBufferSize() method. |
| 436 * |
| 437 * \param socket Pointer to the socket which is associated with the |
| 438 * transmission buffer of interest. |
| 439 * \param contentType The content-type of the data to be written (must not |
| 440 * equal to ThreeGppHttpHeader:NOT_SET). |
| 441 * \param objectSize The length (in bytes) of the new object to be created |
| 442 * (must be greater than zero). |
| 443 * \warning Must be called only when both IsSocketAvailable() and |
| 444 * IsBufferEmpty() for the given socket are true. |
| 445 */ |
| 446 void WriteNewObject (Ptr<Socket> socket, |
| 447 ThreeGppHttpHeader::ContentType_t contentType, |
| 448 uint32_t objectSize); |
| 449 |
| 450 /** |
| 451 * Informs about a pending transmission event associated with the socket, so |
| 452 * that it would be automatically canceled in case the socket is closed. |
| 453 * |
| 454 * The method also indicates the time stamp given by the client. The time |
| 455 * stamp will be included in every packet sent. |
| 456 * |
| 457 * \param socket pointer to the socket which is associated with the |
| 458 * transmission buffer of interest |
| 459 * \param eventId the event to be recorded, e.g., the return value of |
| 460 * Simulator::Schedule function |
| 461 * \param clientTs client time stamp |
| 462 * |
| 463 * \warning Must be called only when IsSocketAvailable() for the given socket |
| 464 * is true. |
| 465 */ |
| 466 void RecordNextServe (Ptr<Socket> socket, |
| 467 const EventId &eventId, |
| 468 const Time &clientTs); |
| 469 |
| 470 /** |
| 471 * Decrements a buffer size by a given amount. |
| 472 * |
| 473 * The content type of the object to be consumed can be inquired beforehand |
| 474 * by the GetBufferContentType() method. |
| 475 * |
| 476 * If the method has consumed all the remaining bytes within the buffer, |
| 477 * IsBufferEmpty() for the buffer shall return true. |
| 478 * |
| 479 * \param socket Pointer to the socket which is associated with the |
| 480 * transmission buffer of interest. |
| 481 * \param amount The length (in bytes) to be consumed (must be greater than |
| 482 * zero). |
| 483 * |
| 484 * \warning Must be called only when IsSocketAvailable() for the given socket |
| 485 * is true. In addition, the requested amount must be larger than |
| 486 * the current buffer size, which can be checked by calling the |
| 487 * GetBufferSize() method. |
| 488 */ |
| 489 void DepleteBufferSize (Ptr<Socket> socket, uint32_t amount); |
| 490 |
| 491 /** |
| 492 * Tell the buffer to close the associated socket once the buffer becomes |
| 493 * empty. |
| 494 * \param socket Pointer to the socket which is associated with the |
| 495 * transmission buffer of interest. |
| 496 * \warning Must be called only when IsSocketAvailable() for the given socket |
| 497 * is true. |
| 498 */ |
| 499 void PrepareClose (Ptr<Socket> socket); |
| 500 |
| 501 private: |
| 502 /** |
| 503 * Set of fields representing a single transmission buffer, which will be |
| 504 * associated with a socket. |
| 505 */ |
| 506 struct TxBuffer_t |
| 507 { |
| 508 /** |
| 509 * Pending transmission event which will be automatically canceled when the |
| 510 * associated socket is closed. |
| 511 */ |
| 512 EventId nextServe; |
| 513 /** |
| 514 * The client time stamp that comes from the request packet. This value |
| 515 * will be set in ThreeGppHttpHeader of every corresponding response packet
sent, to |
| 516 * be used by the client to compute round trip delay time (RTT). |
| 517 */ |
| 518 Time clientTs; |
| 519 /** |
| 520 * The content type of the current data inside the transmission buffer. |
| 521 * Accessible using the GetBufferContentType() method. |
| 522 */ |
| 523 ThreeGppHttpHeader::ContentType_t txBufferContentType; |
| 524 /** |
| 525 * The length (in bytes) of the current data inside the transmission |
| 526 * buffer. Accessible using the GetBufferSize() method. |
| 527 */ |
| 528 uint32_t txBufferSize; |
| 529 /** |
| 530 * True if the remote end has issued a request to close, which means that |
| 531 * this socket will immediately closes itself once the buffer becomes |
| 532 * empty. |
| 533 */ |
| 534 bool isClosing; |
| 535 }; |
| 536 |
| 537 /// Collection of accepted sockets and its individual transmission buffer. |
| 538 std::map<Ptr<Socket>, TxBuffer_t> m_txBuffer; |
| 539 |
| 540 }; // end of `class ThreeGppHttpServerTxBuffer` |
| 541 |
| 542 |
| 543 } // end of `namespace ns3` |
| 544 |
| 545 |
| 546 #endif /* THREE_GPP_HTTP_SERVER_H */ |
OLD | NEW |