Warning, file /sdk/dferry/transport/iserver.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 Copyright (C) 2014 Andreas Hartmetz <ahartmetz@gmail.com> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LGPL. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 0019 Alternatively, this file is available under the Mozilla Public License 0020 Version 1.1. You may obtain a copy of the License at 0021 http://www.mozilla.org/MPL/ 0022 */ 0023 0024 #include "iserver.h" 0025 0026 #include "connectaddress.h" 0027 #include "eventdispatcher_p.h" 0028 #include "itransport.h" 0029 #include "ipserver.h" 0030 #ifdef __unix__ 0031 #include "localserver.h" 0032 #endif 0033 0034 #include <string> 0035 #include <iostream> 0036 0037 #ifdef __unix__ 0038 #include <random> 0039 #include "stringtools.h" 0040 0041 static std::string randomDbusSocketName() 0042 { 0043 std::random_device rd; 0044 std::mt19937 mt(rd()); 0045 char randomData[16]; 0046 // OK dead code elimination, show us what you can! 0047 if (sizeof(size_t) >= 8) { 0048 std::uniform_int_distribution<uint64> dist; 0049 for (size_t i = 0; i < (sizeof(randomData) / sizeof(uint64)); i++) { 0050 reinterpret_cast<uint64 *>(randomData)[i] = dist(mt); 0051 } 0052 } else { 0053 std::uniform_int_distribution<uint32> dist; 0054 for (size_t i = 0; i < (sizeof(randomData) / sizeof(uint32)); i++) { 0055 reinterpret_cast<uint32 *>(randomData)[i] = dist(mt); 0056 } 0057 } 0058 // Good that std::string knows nothing about valid utf-8 encoding! 0059 const std::string pseudoString(randomData, sizeof(randomData)); 0060 return std::string("/dbus-") + hexEncode(pseudoString); 0061 } 0062 0063 static std::string xdgRuntimeDir() 0064 { 0065 return std::string(getenv("XDG_RUNTIME_DIR")); 0066 } 0067 #endif 0068 0069 IServer::IServer() 0070 : m_newConnectionListener(nullptr) 0071 { 0072 setIoInterest(uint32(IO::RW::Read)); 0073 } 0074 0075 IServer::~IServer() 0076 { 0077 for (ITransport *c : m_incomingConnections) { 0078 delete c; 0079 } 0080 } 0081 0082 //static 0083 IServer *IServer::create(const ConnectAddress &listenAddr, ConnectAddress *concreteAddr) 0084 { 0085 if (listenAddr.role() != ConnectAddress::Role::PeerServer) { 0086 return nullptr; 0087 } 0088 0089 #ifdef __unix__ 0090 bool isLocalSocket = true; 0091 bool isAbstract = false; 0092 std::string unixSocketPath; 0093 #endif 0094 0095 switch (listenAddr.type()) { 0096 #ifdef __unix__ 0097 case ConnectAddress::Type::UnixPath: 0098 unixSocketPath = listenAddr.path(); 0099 break; 0100 case ConnectAddress::Type::UnixDir: 0101 unixSocketPath = listenAddr.path() + randomDbusSocketName(); 0102 break; 0103 case ConnectAddress::Type::RuntimeDir: 0104 unixSocketPath = xdgRuntimeDir() + randomDbusSocketName(); 0105 break; 0106 case ConnectAddress::Type::TmpDir: 0107 unixSocketPath = listenAddr.path() + randomDbusSocketName(); 0108 #ifdef __linux__ 0109 isAbstract = true; 0110 #endif 0111 break; 0112 #ifdef __linux__ 0113 case ConnectAddress::Type::AbstractUnixPath: 0114 unixSocketPath = listenAddr.path(); 0115 isAbstract = true; 0116 break; 0117 #endif 0118 #endif 0119 case ConnectAddress::Type::Tcp: 0120 case ConnectAddress::Type::Tcp4: 0121 case ConnectAddress::Type::Tcp6: 0122 #ifdef __unix__ 0123 isLocalSocket = false; 0124 #endif 0125 break; 0126 default: 0127 return nullptr; 0128 } 0129 0130 *concreteAddr = listenAddr; 0131 0132 #ifdef __unix__ 0133 if (isLocalSocket) { 0134 concreteAddr->setType(isAbstract ? ConnectAddress::Type::AbstractUnixPath 0135 : ConnectAddress::Type::UnixPath); 0136 concreteAddr->setPath(unixSocketPath); 0137 if (isAbstract) { 0138 unixSocketPath.insert(0, 1, '\0'); 0139 } 0140 return new LocalServer(unixSocketPath); 0141 } else 0142 #endif 0143 return new IpServer(listenAddr); 0144 } 0145 0146 ITransport *IServer::takeNextClient() 0147 { 0148 if (m_incomingConnections.empty()) { 0149 return nullptr; 0150 } 0151 ITransport *ret = m_incomingConnections.front(); 0152 m_incomingConnections.pop_front(); 0153 return ret; 0154 } 0155 0156 void IServer::setNewConnectionListener(ICompletionListener *listener) 0157 { 0158 m_newConnectionListener = listener; 0159 } 0160 0161 void IServer::close() 0162 { 0163 if (!isListening()) { 0164 return; 0165 } 0166 if (ioEventSource()) { 0167 ioEventSource()->removeIoListener(this); 0168 } 0169 platformClose(); 0170 }