Home | History | Annotate | Download | only in Server
      1 /** @addtogroup MCD_MCDIMPL_DAEMON_SRV
      2  * @{
      3  * @file
      4  *
      5  * Connection server.
      6  *
      7  * Handles incoming socket connections from clients using the MobiCore driver.
      8  *
      9  * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. The name of the author may not be used to endorse or promote
     20  *    products derived from this software without specific prior
     21  *    written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     24  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     27  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     29  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  */
     35 #include "public/Server.h"
     36 #include <unistd.h>
     37 #include <string.h>
     38 #include <errno.h>
     39 
     40 //#define LOG_VERBOSE
     41 #include "log.h"
     42 
     43 //------------------------------------------------------------------------------
     44 Server::Server(
     45     ConnectionHandler *connectionHandler,
     46     const char *localAddr
     47 ) : socketAddr(localAddr)
     48 {
     49     this->connectionHandler = connectionHandler;
     50 }
     51 
     52 
     53 //------------------------------------------------------------------------------
     54 void Server::run(
     55     void
     56 )
     57 {
     58     do {
     59         LOG_I("Server: start listening on socket %s", socketAddr.c_str());
     60 
     61         // Open a socket (a UNIX domain stream socket)
     62         serverSock = socket(AF_UNIX, SOCK_STREAM, 0);
     63         if (serverSock < 0) {
     64             LOG_ERRNO("Can't open stream socket, because socket");
     65             break;
     66         }
     67 
     68         // Fill in address structure and bind to socket
     69         struct sockaddr_un  serverAddr;
     70         serverAddr.sun_family = AF_UNIX;
     71         strncpy(serverAddr.sun_path, socketAddr.c_str(), sizeof(serverAddr.sun_path) - 1);
     72 
     73         uint32_t len = strlen(serverAddr.sun_path) + sizeof(serverAddr.sun_family);
     74         // Make the socket in the Abstract Domain(no path but everyone can connect)
     75         serverAddr.sun_path[0] = 0;
     76         if (bind(serverSock, (struct sockaddr *) &serverAddr, len) < 0) {
     77             LOG_ERRNO("Binding to server socket failed, because bind");
     78         }
     79 
     80         // Start listening on the socket
     81         if (listen(serverSock, LISTEN_QUEUE_LEN) < 0) {
     82             LOG_ERRNO("listen");
     83             break;
     84         }
     85 
     86         LOG_I("\n********* successfully initialized Daemon *********\n");
     87 
     88         for (;;) {
     89             fd_set fdReadSockets;
     90 
     91             // Clear FD for select()
     92             FD_ZERO(&fdReadSockets);
     93 
     94             // Select server socket descriptor
     95             FD_SET(serverSock, &fdReadSockets);
     96             int maxSocketDescriptor = serverSock;
     97 
     98             // Select socket descriptor of all connections
     99             for (connectionIterator_t iterator = peerConnections.begin();
    100                     iterator != peerConnections.end();
    101                     ++iterator) {
    102                 Connection *connection = (*iterator);
    103                 int peerSocket = connection->socketDescriptor;
    104                 FD_SET(peerSocket, &fdReadSockets);
    105                 if (peerSocket > maxSocketDescriptor) {
    106                     maxSocketDescriptor = peerSocket;
    107                 }
    108             }
    109 
    110             // Wait for activities, select() returns the number of sockets
    111             // which require processing
    112             LOG_V(" Server: waiting on sockets");
    113             int numSockets = select(
    114                                  maxSocketDescriptor + 1,
    115                                  &fdReadSockets,
    116                                  NULL, NULL, NULL);
    117 
    118             // Check if select failed
    119             if (numSockets < 0) {
    120                 LOG_ERRNO("select");
    121                 break;
    122             }
    123 
    124             // actually, this should not happen.
    125             if (0 == numSockets) {
    126                 LOG_W(" Server: select() returned 0, spurious event?.");
    127                 continue;
    128             }
    129 
    130             LOG_V(" Server: events on %d socket(s).", numSockets);
    131 
    132             // Check if a new client connected to the server socket
    133             if (FD_ISSET(serverSock, &fdReadSockets)) {
    134                 do {
    135                     LOG_V(" Server: new connection attempt.");
    136                     numSockets--;
    137 
    138                     struct sockaddr_un clientAddr;
    139                     socklen_t clientSockLen = sizeof(clientAddr);
    140                     int clientSock = accept(
    141                                          serverSock,
    142                                          (struct sockaddr *) &clientAddr,
    143                                          &clientSockLen);
    144 
    145                     if (clientSock <= 0) {
    146                         LOG_ERRNO("accept");
    147                         break;
    148                     }
    149 
    150                     Connection *connection = new Connection(clientSock, &clientAddr);
    151                     peerConnections.push_back(connection);
    152                     LOG_I(" Server: new socket connection established and start listening.");
    153                 } while (false);
    154 
    155                 // we can ignore any errors from accepting a new connection.
    156                 // If this fail, the client has to deal with it, we are done
    157                 // and nothing has changed.
    158             }
    159 
    160             // Handle traffic on existing client connections
    161             connectionIterator_t iterator = peerConnections.begin();
    162             while ( (iterator != peerConnections.end())
    163                     && (numSockets > 0) ) {
    164                 Connection *connection = (*iterator);
    165                 int peerSocket = connection->socketDescriptor;
    166 
    167                 if (!FD_ISSET(peerSocket, &fdReadSockets)) {
    168                     ++iterator;
    169                     continue;
    170                 }
    171 
    172                 numSockets--;
    173 
    174                 // the connection will be terminated if command processing
    175                 // fails
    176                 if (!connectionHandler->handleConnection(connection)) {
    177                     LOG_I(" Server: dropping connection.");
    178 
    179                     //Inform the driver
    180                     connectionHandler->dropConnection(connection);
    181 
    182                     // Remove connection from list
    183                     delete connection;
    184                     iterator = peerConnections.erase(iterator);
    185                     continue;
    186                 }
    187 
    188                 ++iterator;
    189             }
    190         }
    191 
    192     } while (false);
    193 
    194     LOG_ERRNO("Exiting Server, because");
    195 }
    196 
    197 
    198 //------------------------------------------------------------------------------
    199 void Server::detachConnection(
    200     Connection *connection
    201 )
    202 {
    203     LOG_V(" Stopping to listen on notification socket.");
    204 
    205     for (connectionIterator_t iterator = peerConnections.begin();
    206             iterator != peerConnections.end();
    207             ++iterator) {
    208         Connection *tmpConnection = (*iterator);
    209         if (tmpConnection == connection) {
    210             peerConnections.erase(iterator);
    211             LOG_I(" Stopped listening on notification socket.");
    212             break;
    213         }
    214     }
    215 }
    216 
    217 
    218 //------------------------------------------------------------------------------
    219 Server::~Server(
    220     void
    221 )
    222 {
    223     // Shut down the server socket
    224     close(serverSock);
    225 
    226     // Destroy all client connections
    227     connectionIterator_t iterator = peerConnections.begin();
    228     while (iterator != peerConnections.end()) {
    229         Connection *tmpConnection = (*iterator);
    230         delete tmpConnection;
    231         iterator = peerConnections.erase(iterator);
    232     }
    233 }
    234 
    235 /** @} */
    236