lliosocket.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /**
  2. * @file lliosocket.h
  3. * @author Phoenix
  4. * @date 2005-07-31
  5. * @brief Declaration of files used for handling sockets and associated pipes
  6. *
  7. * $LicenseInfo:firstyear=2005&license=viewergpl$
  8. *
  9. * Copyright (c) 2005-2009, Linden Research, Inc.
  10. *
  11. * Second Life Viewer Source Code
  12. * The source code in this file ("Source Code") is provided by Linden Lab
  13. * to you under the terms of the GNU General Public License, version 2.0
  14. * ("GPL"), unless you have obtained a separate licensing agreement
  15. * ("Other License"), formally executed by you and Linden Lab. Terms of
  16. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18. *
  19. * There are special exceptions to the terms and conditions of the GPL as
  20. * it is applied to this Source Code. View the full text of the exception
  21. * in the file doc/FLOSS-exception.txt in this software distribution, or
  22. * online at
  23. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24. *
  25. * By copying, modifying or distributing this software, you acknowledge
  26. * that you have read and understood your obligations described above,
  27. * and agree to abide by those obligations.
  28. *
  29. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31. * COMPLETENESS OR PERFORMANCE.
  32. * $/LicenseInfo$
  33. */
  34. #ifndef LL_LLIOSOCKET_H
  35. #define LL_LLIOSOCKET_H
  36. // The socket interface provided here is a simple wraper around apr sockets,
  37. // with a pipe source and sink to read and write off of the socket. Every
  38. // socket only performs non-blocking operations except the server socket which
  39. // only performs blocking operations when an OS poll indicates it will not
  40. // block.
  41. #include "apr_pools.h"
  42. #include "apr_network_io.h"
  43. #include "lliopipe.h"
  44. class LLHost;
  45. // LLSocket
  46. // Implementation of a wrapper around a socket.
  47. // An instance of this class represents a single socket over it's entire life -
  48. // from uninitialized, to connected, to a listening socket depending on it's
  49. // purpose. This class simplifies our access into the socket interface by only
  50. // providing stream/tcp and datagram/udp sockets - the only types we are
  51. // interested in, since those are the only properly supported by all of our
  52. // platforms.
  53. class LLSocket
  54. {
  55. protected:
  56. LOG_CLASS(LLSocket);
  57. public:
  58. // Reference counted shared pointers to sockets.
  59. typedef std::shared_ptr<LLSocket> ptr_t;
  60. // Type of socket to create.
  61. enum EType
  62. {
  63. STREAM_TCP,
  64. DATAGRAM_UDP,
  65. };
  66. // Anonymous enumeration to help identify ports
  67. enum
  68. {
  69. PORT_INVALID = (U16)-1,
  70. PORT_EPHEMERAL = 0,
  71. };
  72. // Creates a socket.
  73. // This is the call you would use if you intend to create a listen socket.
  74. // If you intend the socket to be known to external clients without prior
  75. // port notification, do not use PORT_EPHEMERAL.
  76. // - pool: the apr pool to use. A child pool will be created and associated
  77. // with the socket.
  78. // - type: the type of socket to create
  79. // - port: the port for the socket
  80. // Returns a valid socket shared pointer if the call worked.
  81. static ptr_t create(apr_pool_t* pool, EType type,
  82. U16 port = PORT_EPHEMERAL);
  83. // Creates a LLSocket when you already have an apr socket.
  84. // This method assumes an ephemeral port. This is typically used by calls
  85. // which spawn a socket such as a call to <code>accept()</code> as in the
  86. // server socket. This call should not fail if you have a valid apr socket.
  87. // Because of the nature of how accept() works, you are expected to create
  88. // a new pool for the socket, use that pool for the accept, and pass it in
  89. // here where it will be bound with the socket and destroyed at the same
  90. // time.
  91. // - socket: the apr socket to use
  92. // - pool: the pool used to create the socket. *NOTE: The pool passed
  93. // in will be DESTROYED.
  94. // Returns a valid socket shared pointer if the call worked.
  95. static ptr_t create(apr_socket_t* socket, apr_pool_t* pool);
  96. // Performs a blocking connect to a host. Do not use in production.
  97. // - host: the host to connect this socket to.
  98. // Returns true if the connect was successful.
  99. bool blockingConnect(const LLHost& host);
  100. // Gets the port. This will return PORT_EPHEMERAL if bind was never called.
  101. // Else, returns the port associated with this socket.
  102. LL_INLINE U16 getPort() const { return mPort; }
  103. // Gets the apr socket implementation. Returns the raw apr socket.
  104. LL_INLINE apr_socket_t* getSocket() const { return mSocket; }
  105. // Sets default socket options, with SO_NONBLOCK = 0 and a timeout in µs.
  106. // - timeout Number of microseconds to wait on this socket. Any
  107. // negative number means block-forever. TIMEOUT OF 0 IS NON-PORTABLE.
  108. void setBlocking(S32 timeout);
  109. // Sets default socket options, with SO_NONBLOCK = 1 and timeout = 0.
  110. void setNonBlocking();
  111. protected:
  112. // Protected constructor since should only make sockets with one of the two
  113. // <code>create()</code> calls.
  114. LLSocket(apr_socket_t* socket, apr_pool_t* pool);
  115. public:
  116. // Do not call this directly.
  117. ~LLSocket();
  118. protected:
  119. // The apr socket.
  120. apr_socket_t* mSocket;
  121. // Our memory pool.
  122. apr_pool_t* mPool;
  123. // The port if we know it.
  124. U16 mPort;
  125. };
  126. // LLIOSocketReader
  127. // An LLIOPipe implementation which reads from a socket.
  128. // An instance of a socket reader wraps around an LLSocket and performs
  129. // non-blocking reads and passes it to the next pipe in the chain.
  130. class LLIOSocketReader final : public LLIOPipe
  131. {
  132. protected:
  133. LOG_CLASS(LLIOSocketReader);
  134. public:
  135. LLIOSocketReader(LLSocket::ptr_t socket);
  136. protected:
  137. // Processes the data coming in the socket.
  138. // Since the socket and next pipe must exist for process to make any sense,
  139. // this method will return STATUS_PRECONDITION_NOT_MET unless if they are
  140. // not known. If a STATUS_STOP returned by the next link in the chain, this
  141. // reader will turn of the socket polling.
  142. // - buffer: pointer to a buffer which needs processing. Probably NULL.
  143. // - context: a data structure to pass structured data
  144. // - eos: true if this function is the last. Almost always false.
  145. // - pump: the pump which is calling process. May be NULL.
  146. // Returns STATUS_OK unless the preconditions are not met.
  147. EStatus process_impl(const LLChannelDescriptors& channels,
  148. buffer_ptr_t& buffer, bool& eos, LLSD& context,
  149. LLPumpIO* pump) override;
  150. protected:
  151. LLSocket::ptr_t mSource;
  152. std::vector<U8> mBuffer;
  153. bool mInitialized;
  154. };
  155. // LLIOSocketWriter
  156. // An LLIOPipe implementation which writes to a socket
  157. // An instance of a socket writer wraps around an LLSocket and performs
  158. // non-blocking writes of the data passed in.
  159. class LLIOSocketWriter final : public LLIOPipe
  160. {
  161. protected:
  162. LOG_CLASS(LLIOSocketWriter);
  163. public:
  164. LLIOSocketWriter(LLSocket::ptr_t socket);
  165. protected:
  166. // Writeq the data in buffer to the socket.
  167. // Since the socket and next pipe must exist for process to make any sense,
  168. // this method will return STATUS_PRECONDITION_NOT_MET unless if they are
  169. // not known.
  170. // - buffer: pointer to a buffer which needs processing.
  171. // - context: a data structure to pass structured data
  172. // - eos: true if this function is the last.
  173. // - pump: the pump which is calling process. May be NULL.
  174. // Returns STATUS_OK unless the preconditions are not met.
  175. EStatus process_impl(const LLChannelDescriptors& channels,
  176. buffer_ptr_t& buffer, bool& eos,
  177. LLSD& context, LLPumpIO* pump) override;
  178. protected:
  179. LLSocket::ptr_t mDestination;
  180. U8* mLastWritten;
  181. bool mInitialized;
  182. };
  183. #endif // LL_LLIOSOCKET_H