LCOV - code coverage report
Current view: top level - util/io - socketsession.h (source / functions) Hit Total Coverage
Test: report.info Lines: 3 11 27.3 %
Date: 2012-05-15 Functions: 2 11 18.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #ifndef __SOCKETSESSION_H_
      16                 :            : #define __SOCKETSESSION_H_ 1
      17                 :            : 
      18                 :            : #include <string>
      19                 :            : 
      20                 :            : #include <boost/noncopyable.hpp>
      21                 :            : 
      22                 :            : #include <exceptions/exceptions.h>
      23                 :            : 
      24                 :            : namespace isc {
      25                 :            : namespace util {
      26                 :            : namespace io {
      27                 :            : 
      28                 :            : /// \page SocketSessionUtility Socket session utility
      29                 :            : ///
      30                 :            : /// This utility defines a set of classes that support forwarding a
      31                 :            : /// "socket session" from one process to another.  A socket session is a
      32                 :            : /// conceptual tuple of the following elements:
      33                 :            : /// - A network socket
      34                 :            : /// - The local and remote endpoints of a (IP) communication taking place on
      35                 :            : ///   the socket.  In practice an endpoint is a pair of an IP address and
      36                 :            : ///   TCP or UDP port number.
      37                 :            : /// - Some amount of data sent from the remote endpoint and received on the
      38                 :            : ///   socket.  We call it (socket) session data in this documentation.
      39                 :            : ///
      40                 :            : /// Note that this is a conceptual definition.  Depending on the underlying
      41                 :            : /// implementation and/or the network protocol, some of the elements could be
      42                 :            : /// part of others; for example, if it's an established TCP connection,
      43                 :            : /// the local and remote endpoints would be able to be retrieved from the
      44                 :            : /// socket using the standard \c getsockname() and \c getpeername() system
      45                 :            : /// calls.  But in this definition we separate these to be more generic.
      46                 :            : /// Also, as a matter of fact our intended usage includes non-connected UDP
      47                 :            : /// communications, in which case at least the remote endpoint should be
      48                 :            : /// provided separately from the socket.
      49                 :            : ///
      50                 :            : /// In the actual implementation we represent a socket as a tuple of
      51                 :            : /// socket's file descriptor, address family (e.g. \c AF_INET6),
      52                 :            : /// socket type (e.g. \c SOCK_STREAM), and protocol (e.g. \c IPPROTO_TCP).
      53                 :            : /// The latter three are included in the representation of a socket in order
      54                 :            : /// to provide complete information of how the socket would be created
      55                 :            : /// by the \c socket(2) system call.  More specifically in practice, these
      56                 :            : /// parameters could be used to construct a Python socket object from the
      57                 :            : /// file descriptor.
      58                 :            : ///
      59                 :            : /// We use the standard \c sockaddr structure to represent endpoints.
      60                 :            : ///
      61                 :            : /// Socket session data is an opaque memory region of an arbitrary length
      62                 :            : /// (possibly with some reasonable upper limit).
      63                 :            : ///
      64                 :            : /// To forward a socket session between processes, we use connected UNIX
      65                 :            : /// domain sockets established between the processes.  The file descriptor
      66                 :            : /// will be forwarded through the sockets as an ancillary data item of
      67                 :            : /// type \c SCM_RIGHTS.  Other elements of the session will be transferred
      68                 :            : /// as normal data over the connection.
      69                 :            : ///
      70                 :            : /// We provide three classes to help applications forward socket sessions:
      71                 :            : /// \c SocketSessionForwarder is the sender of the UNIX domain connection,
      72                 :            : /// while \c SocketSessionReceiver is the receiver (this interface assumes
      73                 :            : /// one direction of forwarding); \c SocketSession represents a single
      74                 :            : /// socket session.
      75                 :            : ///
      76                 :            : /// \c SocketSessionForwarder and \c SocketSessionReceiver objects use a
      77                 :            : /// straightforward protocol to pass elements of socket sessions.
      78                 :            : /// Once the connection is established, the forwarder object first forwards
      79                 :            : /// the file descriptor with 1-byte dummy data.  It then forwards a
      80                 :            : /// "(socket) session header", which contains all other elements of the session
      81                 :            : /// except the file descriptor (already forwarded) and session data.
      82                 :            : /// The wire format of the header is as follows:
      83                 :            : /// - The length of the header (16-bit unsigned integer)
      84                 :            : /// - Address family
      85                 :            : /// - Socket type
      86                 :            : /// - Protocol
      87                 :            : /// - Size of the local endpoint in bytes
      88                 :            : /// - Local endpoint (a copy of the memory image of the corresponding
      89                 :            : ///   \c sockaddr)
      90                 :            : /// - Size of the remote endpoint in bytes
      91                 :            : /// - Remote endpoint (same as local endpoint)
      92                 :            : /// - Size of session data in bytes
      93                 :            : ///
      94                 :            : /// The type of the fields is 32-bit unsigned integer unless explicitly
      95                 :            : /// noted, and all fields are formatted in the network byte order.
      96                 :            : ///
      97                 :            : /// The socket session data immediately follows the session header.
      98                 :            : ///
      99                 :            : /// Note that the fields do not necessarily be in the network byte order
     100                 :            : /// because they are expected to be exchanged on the same machine.  Likewise,
     101                 :            : /// integer elements such as address family do not necessarily be represented
     102                 :            : /// as an fixed-size value (i.e., 32-bit).  But fixed size fields are used
     103                 :            : /// in order to ensure maximum portability in such a (rare) case where the
     104                 :            : /// forwarder and the receiver are built with different compilers that have
     105                 :            : /// different definitions of \c int.  Also, since \c sockaddr fields are
     106                 :            : /// generally formatted in the network byte order, other fields are defined
     107                 :            : /// so to be consistent.
     108                 :            : ///
     109                 :            : /// One basic assumption in the API of this utility is socket sessions should
     110                 :            : /// be forwarded without blocking, thus eliminating the need for incremental
     111                 :            : /// read/write or blocking other important services such as responding to
     112                 :            : /// requests from the application's clients.  This assumption should be held
     113                 :            : /// as long as both the forwarder and receiver have sufficient resources
     114                 :            : /// to handle the forwarding process since the communication is local.
     115                 :            : /// But a forward attempt could still block if the receiver is busy (or even
     116                 :            : /// hang up) and cannot keep up with the volume of incoming sessions.
     117                 :            : ///
     118                 :            : /// So, in this implementation, the forwarder uses non blocking writes to
     119                 :            : /// forward sessions.  If a write attempt could block, it immediately gives
     120                 :            : /// up the operation with an exception.  The corresponding application is
     121                 :            : /// expected to catch it, close the connection, and perform any necessary
     122                 :            : /// recovery for that application (that would normally be re-establish the
     123                 :            : /// connection with a new receiver, possibly after confirming the receiving
     124                 :            : /// side is still alive).  On the other hand, the receiver implementation
     125                 :            : /// assumes it's possible that it only receive incomplete elements of a
     126                 :            : /// session (such as in the case where the forwarder writes part of the
     127                 :            : /// entire session and gives up the connection).  The receiver implementation
     128                 :            : /// throws an exception when it encounters an incomplete session.  Like the
     129                 :            : /// case of the forwarder application, the receiver application is expected
     130                 :            : /// to catch it, close the connection, and perform any necessary recovery
     131                 :            : /// steps.
     132                 :            : ///
     133                 :            : /// Note that the receiver implementation uses blocking read.  So it's
     134                 :            : /// application's responsibility to ensure that there's at least some data
     135                 :            : /// in the connection when the receiver object is requested to receive a
     136                 :            : /// session (unless this operation can be blocking, e.g., by the use of
     137                 :            : /// a separate thread).  Also, if the forwarder implementation or application
     138                 :            : /// is malicious or extremely buggy and intentionally sends partial session
     139                 :            : /// and keeps the connection, the receiver could block in receiving a session.
     140                 :            : /// In general, we assume the forwarder doesn't do intentional blocking
     141                 :            : /// as it's a local node and is generally a module of the same (BIND 10)
     142                 :            : /// system.  The minimum requirement for the forwarder implementation (and
     143                 :            : /// application) is to make sure the connection is closed once it detects
     144                 :            : /// an error on it.  Even a naive implementation that simply dies due to
     145                 :            : /// the exception will meet this requirement.
     146                 :            : 
     147                 :            : /// An exception indicating general errors that takes place in the
     148                 :            : /// socket session related class objects.
     149                 :            : ///
     150                 :            : /// In general the errors are unusual but possible failures such as unexpected
     151                 :            : /// connection reset, and suggest the application to close the connection and
     152                 :            : /// (if necessary) reestablish it.
     153                 :         24 : class SocketSessionError: public Exception {
     154                 :            : public:
     155                 :         24 :     SocketSessionError(const char *file, size_t line, const char *what):
     156                 :         24 :         isc::Exception(file, line, what) {}
     157                 :            : };
     158                 :            : 
     159                 :            : /// The forwarder of socket sessions
     160                 :            : ///
     161                 :            : /// An object of this class maintains a UNIX domain socket (normally expected
     162                 :            : /// to be connected to a \c SocketSessionReceiver object) and forwards
     163                 :            : /// socket sessions to the receiver.
     164                 :            : ///
     165                 :            : /// See the description of \ref SocketSessionUtility for other details of how
     166                 :            : /// the session forwarding works.
     167                 :            : class SocketSessionForwarder : boost::noncopyable {
     168                 :            : public:
     169                 :            :     /// The constructor.
     170                 :            :     ///
     171                 :            :     /// It's constructed with path information of the intended receiver,
     172                 :            :     /// but does not immediately establish a connection to the receiver;
     173                 :            :     /// \c connectToReceiver() must be called to establish it.  These are
     174                 :            :     /// separated so that an object of class can be initialized (possibly
     175                 :            :     /// as an attribute of a higher level application class object) without
     176                 :            :     /// knowing the receiver is ready for accepting new forwarders.  The
     177                 :            :     /// separate connect interface allows the object to be reused when it
     178                 :            :     /// detects connection failure and tries to re-establish it after closing
     179                 :            :     /// the failed one.
     180                 :            :     ///
     181                 :            :     /// On construction, it also installs a signal filter for SIGPIPE to
     182                 :            :     /// ignore it.  Since this class uses a stream-type connected UNIX domain
     183                 :            :     /// socket, if the receiver (abruptly) closes the connection a subsequent
     184                 :            :     /// write operation on the socket would trigger a SIGPIPE signal, which
     185                 :            :     /// kills the caller process by default.   This behavior would be
     186                 :            :     /// undesirable in many cases, so this implementation always disables
     187                 :            :     /// the signal.
     188                 :            :     ///
     189                 :            :     /// This approach has some drawbacks, however; first, since signal handling
     190                 :            :     /// is process (or thread) wide, ignoring it may not what the application
     191                 :            :     /// wants.  On the other hand, if the application changes how the signal is
     192                 :            :     /// handled after instantiating this class, the new behavior affects the
     193                 :            :     /// class operation.  Secondly, even if ignoring the signal is the desired
     194                 :            :     /// operation, it's a waste to set the filter every time this class object
     195                 :            :     /// is constructed.  It's sufficient to do it once.  We still adopt this
     196                 :            :     /// behavior based on the observation that in most cases applications would
     197                 :            :     /// like to ignore SIGPIPE (or simply doesn't care about it) and that this
     198                 :            :     /// class is not instantiated so often (so the wasteful setting overhead
     199                 :            :     /// should be marginal).  On the other hand, doing it every time is
     200                 :            :     /// beneficial if the application is threaded and different threads
     201                 :            :     /// create different forwarder objects (and if signals work per thread).
     202                 :            :     ///
     203                 :            :     /// \exception SocketSessionError \c unix_file is invalid as a path name
     204                 :            :     /// of a UNIX domain socket.
     205                 :            :     /// \exception Unexpected Error in setting a filter for SIGPIPE (see above)
     206                 :            :     /// \exception std::bad_alloc resource allocation failure
     207                 :            :     ///
     208                 :            :     /// \param unix_file Path name of the receiver.
     209                 :            :     explicit SocketSessionForwarder(const std::string& unix_file);
     210                 :            : 
     211                 :            :     /// The destructor.
     212                 :            :     ///
     213                 :            :     /// If a connection has been established, it's automatically closed in
     214                 :            :     /// the destructor.
     215                 :            :     ~SocketSessionForwarder();
     216                 :            : 
     217                 :            :     /// Establish a connection to the receiver.
     218                 :            :     ///
     219                 :            :     /// This method establishes a connection to the receiver at the path
     220                 :            :     /// given on construction.  It makes the underlying UNIX domain socket
     221                 :            :     /// non blocking, so this method (or subsequent \c push() calls) does not
     222                 :            :     /// block.
     223                 :            :     ///
     224                 :            :     /// \exception BadValue The method is called while an already
     225                 :            :     /// established connection is still active.
     226                 :            :     /// \exception SocketSessionError A system error in socket operation.
     227                 :            :     void connectToReceiver();
     228                 :            : 
     229                 :            :     /// Close the connection to the receiver.
     230                 :            :     ///
     231                 :            :     /// The connection must have been established by \c connectToReceiver().
     232                 :            :     /// As long as it's met this method is exception free.
     233                 :            :     ///
     234                 :            :     /// \exception BadValue The connection hasn't been established.
     235                 :            :     void close();
     236                 :            : 
     237                 :            :     /// Forward a socket session to the receiver.
     238                 :            :     ///
     239                 :            :     /// This method takes a set of parameters that represent a single socket
     240                 :            :     /// session, renders them in the "wire" format according to the internal
     241                 :            :     /// protocol (see \ref SocketSessionUtility) and forwards them to
     242                 :            :     /// the receiver through the UNIX domain connection.
     243                 :            :     ///
     244                 :            :     /// The connection must have been established by \c connectToReceiver().
     245                 :            :     ///
     246                 :            :     /// For simplicity and for the convenience of detecting application
     247                 :            :     /// errors, this method imposes some restrictions on the parameters:
     248                 :            :     /// - Socket family must be either \c AF_INET or \c AF_INET6
     249                 :            :     /// - The address family (\c sa_family) member of the local and remote
     250                 :            :     ///   end points must be equal to the \c family parameter
     251                 :            :     /// - Socket session data must not be empty (\c data_len must not be 0
     252                 :            :     ///   and \c data must not be NULL)
     253                 :            :     /// - Data length must not exceed 65535
     254                 :            :     /// These are not architectural limitation, and might be loosened in
     255                 :            :     /// future versions as we see the need for flexibility.
     256                 :            :     ///
     257                 :            :     /// Since the underlying UNIX domain socket is non blocking
     258                 :            :     /// (see the description for the constructor), a call to this method
     259                 :            :     /// should either return immediately or result in exception (in case of
     260                 :            :     /// "would block").
     261                 :            :     ///
     262                 :            :     /// \exception BadValue The method is called before establishing a
     263                 :            :     /// connection or given parameters are invalid.
     264                 :            :     /// \exception SocketSessionError A system error in socket operation,
     265                 :            :     /// including the case where the write operation would block.
     266                 :            :     ///
     267                 :            :     /// \param sock The socket file descriptor
     268                 :            :     /// \param family The address family (such as AF_INET6) of the socket
     269                 :            :     /// \param type The socket type (such as SOCK_DGRAM) of the socket
     270                 :            :     /// \param protocol The transport protocol (such as IPPROTO_UDP) of the
     271                 :            :     ///        socket
     272                 :            :     /// \param local_end The local end point of the session in the form of
     273                 :            :     ///        \c sockaddr.
     274                 :            :     /// \param remote_end The remote end point of the session in the form of
     275                 :            :     ///        \c sockaddr.
     276                 :            :     /// \param data A pointer to the beginning of the memory region for the
     277                 :            :     ///             session data
     278                 :            :     /// \param data_len The size of the session data in bytes.
     279                 :            :     void push(int sock, int family, int type, int protocol,
     280                 :            :               const struct sockaddr& local_end,
     281                 :            :               const struct sockaddr& remote_end,
     282                 :            :               const void* data, size_t data_len);
     283                 :            : 
     284                 :            : private:
     285                 :            :     struct ForwarderImpl;
     286                 :            :     ForwarderImpl* impl_;
     287                 :            : };
     288                 :            : 
     289                 :            : /// Socket session object.
     290                 :            : ///
     291                 :            : /// The \c SocketSession class provides a convenient encapsulation
     292                 :            : /// for the notion of a socket session.  It's instantiated with straightforward
     293                 :            : /// parameters corresponding to a socket session, and provides read only
     294                 :            : /// accessors to the parameters to ensure data integrity.
     295                 :            : ///
     296                 :            : /// In the initial design and implementation it's only used as a return type
     297                 :            : /// of \c SocketSessionReceiver::pop(), but it could also be used by
     298                 :            : /// the \c SocketSessionForwarder class or for other purposes.
     299                 :            : ///
     300                 :            : /// It is assumed that the original owner of a \c SocketSession object
     301                 :            : /// (e.g. a class or a function that constructs it) is responsible for validity
     302                 :            : /// of the data passed to the object.  See the description of
     303                 :            : /// \c SocketSessionReceiver::pop() for the specific case of that usage.
     304                 :            : class SocketSession {
     305                 :            : public:
     306                 :            :     /// The constructor.
     307                 :            :     ///
     308                 :            :     /// This is a trivial constructor, taking a straightforward representation
     309                 :            :     /// of session parameters and storing them internally to ensure integrity.
     310                 :            :     ///
     311                 :            :     /// As long as the given parameters are valid it never throws an exception.
     312                 :            :     ///
     313                 :            :     /// \exception BadValue Given parameters don't meet the requirement
     314                 :            :     /// (see the parameter descriptions).
     315                 :            :     ///
     316                 :            :     /// \param sock The socket file descriptor
     317                 :            :     /// \param family The address family (such as AF_INET6) of the socket
     318                 :            :     /// \param type The socket type (such as SOCK_DGRAM) of the socket
     319                 :            :     /// \param protocol The transport protocol (such as IPPROTO_UDP) of the
     320                 :            :     ///        socket.
     321                 :            :     /// \param local_end The local end point of the session in the form of
     322                 :            :     ///        \c sockaddr.  Must not be NULL.
     323                 :            :     /// \param remote_end The remote end point of the session in the form of
     324                 :            :     ///        \c sockaddr.  Must not be NULL.
     325                 :            :     /// \param data A pointer to the beginning of the memory region for the
     326                 :            :     /// session data.  Must not be NULL, and the subsequent \c data_len bytes
     327                 :            :     /// must be valid.
     328                 :            :     /// \param data_len The size of the session data in bytes.  Must not be 0.
     329                 :            :     SocketSession(int sock, int family, int type, int protocol,
     330                 :            :                   const sockaddr* local_end, const sockaddr* remote_end,
     331                 :            :                   const void* data, size_t data_len);
     332                 :            : 
     333                 :            :     /// Return the socket file descriptor.
     334                 :          0 :     int getSocket() const { return (sock_); }
     335                 :            : 
     336                 :            :     /// Return the address family (such as AF_INET6) of the socket.
     337                 :          0 :     int getFamily() const { return (family_); }
     338                 :            : 
     339                 :            :     /// Return the socket type (such as SOCK_DGRAM) of the socket.
     340                 :          0 :     int getType() const { return (type_); }
     341                 :            : 
     342                 :            :     /// Return the transport protocol (such as IPPROTO_UDP) of the socket.
     343                 :          0 :     int getProtocol() const { return (protocol_); }
     344                 :            : 
     345                 :            :     /// Return the local end point of the session in the form of \c sockaddr.
     346                 :          0 :     const sockaddr& getLocalEndpoint() const { return (*local_end_); }
     347                 :            : 
     348                 :            :     /// Return the remote end point of the session in the form of \c sockaddr.
     349                 :          0 :     const sockaddr& getRemoteEndpoint() const { return (*remote_end_); }
     350                 :            : 
     351                 :            :     /// Return a pointer to the beginning of the memory region for the session
     352                 :            :     /// data.
     353                 :            :     ///
     354                 :            :     /// In the current implementation it should never be NULL, and the region
     355                 :            :     /// of the size returned by \c getDataLength() is expected to be valid.
     356                 :          0 :     const void* getData() const { return (data_); }
     357                 :            : 
     358                 :            :     /// Return the size of the session data in bytes.
     359                 :            :     ///
     360                 :            :     /// In the current implementation it should be always larger than 0.
     361                 :          0 :     size_t getDataLength() const { return (data_len_); }
     362                 :            : 
     363                 :            : private:
     364                 :            :     const int sock_;
     365                 :            :     const int family_;
     366                 :            :     const int type_;
     367                 :            :     const int protocol_;
     368                 :            :     const sockaddr* local_end_;
     369                 :            :     const sockaddr* remote_end_;
     370                 :            :     const void* const data_;
     371                 :            :     const size_t data_len_;
     372                 :            : };
     373                 :            : 
     374                 :            : /// The receiver of socket sessions
     375                 :            : ///
     376                 :            : /// An object of this class holds a UNIX domain socket for an
     377                 :            : /// <em>established connection</em>, receives socket sessions from
     378                 :            : /// the remote forwarder, and provides the session to the application
     379                 :            : /// in the form of a \c SocketSession object.
     380                 :            : ///
     381                 :            : /// Note that this class is instantiated with an already connected socket;
     382                 :            : /// it's not a listening socket that is accepting connection requests from
     383                 :            : /// forwarders.  It's application's responsibility to create the listening
     384                 :            : /// socket, listen on it and accept connections.  Once the connection is
     385                 :            : /// established, the application would construct a \c SocketSessionReceiver
     386                 :            : /// object with the socket for the newly established connection.
     387                 :            : /// This behavior is based on the design decision that the application should
     388                 :            : /// decide when it performs (possibly) blocking operations (see \ref
     389                 :            : /// SocketSessionUtility for more details).
     390                 :            : ///
     391                 :            : /// See the description of \ref SocketSessionUtility for other details of how
     392                 :            : /// the session forwarding works.
     393                 :            : class SocketSessionReceiver : boost::noncopyable {
     394                 :            : public:
     395                 :            :     /// The constructor.
     396                 :            :     ///
     397                 :            :     /// \exception SocketSessionError Any error on an operation that is
     398                 :            :     /// performed on the given socket as part of initialization.
     399                 :            :     /// \exception std::bad_alloc Resource allocation failure
     400                 :            :     ///
     401                 :            :     /// \param fd A UNIX domain socket for an established connection with
     402                 :            :     /// a forwarder.
     403                 :            :     explicit SocketSessionReceiver(int fd);
     404                 :            : 
     405                 :            :     /// The destructor.
     406                 :            :     ///
     407                 :            :     /// The destructor does \c not close the socket given on construction.
     408                 :            :     /// It's up to the application what to do with it (note that the
     409                 :            :     /// application would have to maintain the socket itself for detecting
     410                 :            :     /// the existence of a new socket session asynchronously).
     411                 :            :     ~SocketSessionReceiver();
     412                 :            : 
     413                 :            :     /// Receive a socket session from the forwarder.
     414                 :            :     ///
     415                 :            :     /// This method receives wire-format data (see \ref SocketSessionUtility)
     416                 :            :     /// for a socket session on the UNIX domain socket, performs some
     417                 :            :     /// validation on the data, and returns the session information in the
     418                 :            :     /// form of a \c SocketSession object.
     419                 :            :     ///
     420                 :            :     /// The returned SocketSession object is valid only until the next time
     421                 :            :     /// this method is called or until the \c SocketSessionReceiver object is
     422                 :            :     /// destructed.
     423                 :            :     ///
     424                 :            :     /// The caller is responsible for closing the received socket (whose
     425                 :            :     /// file descriptor is accessible via \c SocketSession::getSocket()).
     426                 :            :     /// If the caller copies the returned \c SocketSession object, it's also
     427                 :            :     /// responsible for making sure the descriptor is closed at most once.
     428                 :            :     /// On the other hand, the caller is not responsible for freeing the
     429                 :            :     /// socket session data (accessible via \c SocketSession::getData());
     430                 :            :     /// the \c SocketSessionReceiver object will clean it up automatically.
     431                 :            :     ///
     432                 :            :     /// It ensures the following:
     433                 :            :     /// - The address family is either \c AF_INET or \c AF_INET6
     434                 :            :     /// - The address family (\c sa_family) member of the local and remote
     435                 :            :     ///   end points must be equal to the \c family parameter
     436                 :            :     /// - The socket session data is not empty and does not exceed 65535
     437                 :            :     ///   bytes.
     438                 :            :     /// If the validation fails or an unexpected system error happens
     439                 :            :     /// (including a connection close in the meddle of reception), it throws
     440                 :            :     /// an SocketSessionError exception.  When this happens, it's very
     441                 :            :     /// unlikely that a subsequent call to this method succeeds, so in reality
     442                 :            :     /// the application is expected to destruct it and close the socket in
     443                 :            :     /// such a case.
     444                 :            :     ///
     445                 :            :     /// \exception SocketSessionError Invalid data is received or a system
     446                 :            :     /// error on socket operation happens.
     447                 :            :     /// \exception std::bad_alloc Resource allocation failure
     448                 :            :     ///
     449                 :            :     /// \return A \c SocketSession object corresponding to the extracted
     450                 :            :     /// socket session.
     451                 :            :     SocketSession pop();
     452                 :            : 
     453                 :            : private:
     454                 :            :     struct ReceiverImpl;
     455                 :            :     ReceiverImpl* impl_;
     456                 :            : };
     457                 :            : 
     458                 :            : }
     459                 :            : }
     460                 :            : }
     461                 :            : 
     462                 :            : #endif  // __SOCKETSESSION_H_
     463                 :            : 
     464                 :            : // Local Variables:
     465                 :            : // mode: c++
     466                 :            : // End:

Generated by: LCOV version 1.9