14e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park/** @addtogroup MCD_MCDIMPL_DAEMON_SRV 24e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * @{ 34e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * @file 44e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 54e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * Connection server. 64e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 74e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * Handles incoming socket connections from clients using the MobiCore driver. 84e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 94e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 --> 107b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim * 114e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * Redistribution and use in source and binary forms, with or without 124e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * modification, are permitted provided that the following conditions 134e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * are met: 144e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 1. Redistributions of source code must retain the above copyright 154e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * notice, this list of conditions and the following disclaimer. 164e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 2. Redistributions in binary form must reproduce the above copyright 174e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * notice, this list of conditions and the following disclaimer in the 184e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * documentation and/or other materials provided with the distribution. 194e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 3. The name of the author may not be used to endorse or promote 204e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * products derived from this software without specific prior 214e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * written permission. 224e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 234e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 244e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 254e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 264e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 274e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 284e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 294e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 304e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 314e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 324e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 334e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 344e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park */ 354e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "public/NetlinkServer.h" 364e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <unistd.h> 374e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <string.h> 384e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <errno.h> 394e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <linux/netlink.h> 404e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 414e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <stdlib.h> 424e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "NetlinkConnection.h" 434e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <signal.h> 444e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 457b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim#define LOG_TAG "McDaemon" 464e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "log.h" 474e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 484e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------ 494e9e8c9c0169b40318386436d762c3d73cf4c328DongJin ParkNetlinkServer::NetlinkServer( 507b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim ConnectionHandler *connectionHandler 517b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim): Server(connectionHandler, "dummy") 527b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{ 534e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park} 544e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 554e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 564e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------ 574e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid NetlinkServer::run( 587b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim) 597b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{ 607b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim do { 617b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim LOG_I("NetlinkServer: Starting to listen on netlink bus"); 627b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 637b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Open a socket 647b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim serverSock = socket(PF_NETLINK, SOCK_DGRAM, MC_DAEMON_NETLINK); 657b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (serverSock < 0) { 667b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim LOG_ERRNO("Opening socket"); 677b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim break; 687b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 697b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 707b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Fill in address structure and bind to socket 717b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim struct sockaddr_nl src_addr; 727b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim struct nlmsghdr *nlh = NULL; 737b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim struct iovec iov; 747b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim struct msghdr msg; 757b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim uint32_t len; 767b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 777b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim memset(&src_addr, 0, sizeof(src_addr)); 787b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim src_addr.nl_family = AF_NETLINK; 797b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim src_addr.nl_pid = MC_DAEMON_PID; /* daemon pid */ 807b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim src_addr.nl_groups = 0; /* not in mcast groups */ 817b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (bind(serverSock, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) { 829081ca65cb7959b6a06ba44823f84a6afa8bca2fJihyun Kim LOG_ERRNO("Binding to server socket failed, because bind"); 837b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim close(serverSock); 847b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim break; 857b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 867b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 877b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Start reading the socket 887b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim LOG_I("\n********* successfully initialized *********\n"); 897b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 907b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim for (;;) { 917b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // This buffer will be taken over by the connection it was routed to 927b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); 937b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim memset(&msg, 0, sizeof(msg)); 947b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim iov.iov_base = (void *)nlh; 957b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); 967b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim msg.msg_iov = &iov; 977b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim msg.msg_iovlen = 1; 987b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim msg.msg_name = &src_addr; 997b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim msg.msg_namelen = sizeof(src_addr); 1007b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 1017b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); 1027b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 1037b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Read the incomming message and route it to the connection based 1047b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // on the incomming PID 1057b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if ((len = recvmsg(serverSock, &msg, 0)) < 0) { 1067b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim LOG_ERRNO("recvmsg"); 1077b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim break; 1087b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 1097b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 1104e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park if (NLMSG_OK(nlh, len)) { 1117b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim handleMessage(nlh); 1127b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } else { 1137b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim break; 1147b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 1157b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 1167b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } while (false); 1177b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 1187b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim LOG_ERRNO("Exiting NetlinkServer! Because it"); 1194e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park} 1204e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 1214e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------ 1224e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid NetlinkServer::handleMessage( 1234e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park struct nlmsghdr *nlh 1247b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim) 1257b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{ 1267b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim uint32_t seq = nlh->nlmsg_seq; 1277b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim uint32_t pid = nlh->nlmsg_pid; 1287b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim //LOG_I("%s: Handling NQ message for pid %u seq %u...", __FUNCTION__, pid, seq); 1297b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim uint64_t hash = hashConnection(pid, seq); 1307b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim /* First cleanup the connection list */ 1317b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim cleanupConnections(); 1327b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 1337b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim NetlinkConnection *connection = findConnection(hash); 1347b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // This is a message from a new client 1357b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (connection == NULL) { 1367b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim //LOG_I("%s: Cound't find the connection, creating a new one", __FUNCTION__); 1377b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connection = new NetlinkConnection(this, serverSock, pid, seq); 1387b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Add the new connection 1397b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim insertConnection(hash, connection); 1407b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 1417b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 1427b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connection->handleMessage(nlh); 1437b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 1447b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Only handle connections which have not been detached 1457b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (connection->detached == false) { 1467b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (!connectionHandler->handleConnection(connection)) { 1477b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim LOG_I("%s: No command processed.", __FUNCTION__); 1487b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connection->socketDescriptor = -1; 1497b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim //Inform the driver 1507b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connectionHandler->dropConnection(connection); 1517b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 1527b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Remove connection from list 1537b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim removeConnection(hash); 1547b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connection->socketDescriptor = -1; 1557b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim delete connection; 1567b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 1577b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // If connection data is set to NULL then device close has been called 1587b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // so we must remove all connections associated with this hash 1597b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim else if (connection->connectionData == NULL && 1607b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connection->detached == false) { 1617b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim delete connection; 1627b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 1637b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 1644e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park} 1654e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 1664e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 1674e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------ 1684e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid NetlinkServer::detachConnection( 1694e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park Connection *connection 1707b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim) 1717b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{ 1727b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connection->detached = true; 1734e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park} 1744e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 1754e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 1764e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------ 1774e9e8c9c0169b40318386436d762c3d73cf4c328DongJin ParkNetlinkServer::~NetlinkServer( 1787b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim void 1797b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim) 1807b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{ 1817b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connectionMap_t::iterator i; 1827b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Shut down the server socket 1837b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim close(serverSock); 1847b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 1857b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Destroy all client connections 1867b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim for (i = peerConnections.begin(); i != peerConnections.end(); i++) { 1877b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (i->second->detached == false) { 1887b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim delete i->second; 1897b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 1907b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 1917b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim peerConnections.clear(); 1924e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park} 1934e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 1944e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 1954e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------ 1967b143edf281bed18c8ebd0733465f3af5af327ebJungtae KimNetlinkConnection *NetlinkServer::findConnection( 1974e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park uint64_t hash 1987b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim) 1997b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{ 2007b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connectionMap_t::iterator i = peerConnections.find(hash); 2017b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (i != peerConnections.end()) { 2027b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim return i->second; 2037b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 2044e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 2057b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim return NULL; 2064e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park} 2074e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 2084e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 2094e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------ 2104e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid NetlinkServer::insertConnection( 2117b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim uint64_t hash, 2124e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park NetlinkConnection *connection 2137b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim) 2147b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{ 2157b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim peerConnections[hash] = connection; 2164e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park} 2174e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 2184e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park/* This is called from multiple threads! */ 2194e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------ 2204e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid NetlinkServer::removeConnection( 2217b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim uint64_t hash 2227b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim) 2237b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{ 2247b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connectionMap_t::iterator i = peerConnections.find(hash); 2257b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (i != peerConnections.end()) { 2267b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim peerConnections.erase(i); 2277b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 2284e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park} 2294e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 2304e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------ 2314e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid NetlinkServer::cleanupConnections( 2327b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim void 2337b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim) 2347b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim{ 2357b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connectionMap_t::reverse_iterator i; 2367b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim pid_t pid; 2377b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim NetlinkConnection *connection = NULL; 2387b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Destroy all client connections 2397b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim for (i = peerConnections.rbegin(); i != peerConnections.rend(); ++i) { 2407b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connection = i->second; 2417b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Only 16 bits are for the actual PID, the rest is session magic 2427b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim pid = connection->peerPid & 0xFFFF; 2437b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim //LOG_I("%s: checking PID %u", __FUNCTION__, pid); 2447b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Check if the peer pid is still alive 2457b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (pid == 0) { 2467b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim continue; 2477b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 2487b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (kill(pid, 0)) { 2497b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim bool detached = connection->detached; 2507b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim LOG_I("%s: PID %u has died, cleaning up session 0x%X", 2517b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim __FUNCTION__, pid, connection->peerPid); 2527b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 2537b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connection->socketDescriptor = -1; 2547b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim //Inform the driver 2557b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim connectionHandler->dropConnection(connection); 2567b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 2577b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // We aren't handling this connection anymore no matter what 2587b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim removeConnection(connection->hash); 2597b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim 2607b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // Remove connection from list only if detached, the detached 2617b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim // connections are managed by the device 2627b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (detached == false) { 2637b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim delete connection; 2647b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 2657b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim if (peerConnections.size() == 0) { 2667b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim break; 2677b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 2687b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim i = peerConnections.rbegin(); 2697b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 2707b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim } 2714e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park} 2724e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park 2734e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park/** @} */ 274