/* * ZeroTier One - Global Peer to Peer Ethernet * Copyright (C) 2011-2014 ZeroTier Networks LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * -- * * ZeroTier may be used and distributed under the terms of the GPLv3, which * are available at: http://www.gnu.org/licenses/gpl-3.0.html * * If you would like to embed ZeroTier into a commercial application or * redistribute it in a modified binary form, please contact ZeroTier Networks * LLC. Start here: http://www.zerotier.com/ */ #ifndef ZT_NATIVESOCKETMANAGER_HPP #define ZT_NATIVESOCKETMANAGER_HPP #include #include #include #include #include "../node/Constants.hpp" #include "../node/SharedPtr.hpp" #include "../node/Mutex.hpp" #include "../node/SocketManager.hpp" #include "../node/Socket.hpp" #ifdef __WINDOWS__ #include #include #include #else #include #include #include #include #endif namespace ZeroTier { class NativeSocket; class NativeUdpSocket; class NativeTcpSocket; /** * Socket I/O multiplexer * * This wraps select(), epoll(), etc. and handles creation of Sockets. */ class NativeSocketManager : public SocketManager { friend class NativeUdpSocket; friend class NativeTcpSocket; public: /** * @param localUdpPort Local UDP port to bind or 0 for no UDP support * @param localTcpPort Local TCP port to listen to or 0 for no incoming TCP connect support * @param packetHandler Function to call when packets are received by a socket * @param arg Second argument to packetHandler() * @throws std::runtime_error Could not bind local port(s) or open socket(s) */ NativeSocketManager( int localUdpPort, int localTcpPort, void (*packetHandler)(const SharedPtr &,void *,const InetAddress &,Buffer &), void *arg); virtual ~NativeSocketManager(); virtual bool send(const InetAddress &to,bool tcp,bool autoConnectTcp,const void *msg,unsigned int msglen); virtual void poll(unsigned long timeout); virtual void whack(); virtual void closeTcpSockets(); private: // Called by socket implementations when a packet is received inline void handleReceivedPacket(const SharedPtr &sock,const InetAddress &from,Buffer &data) throw() { try { _packetHandler(sock,_arg,from,data); } catch ( ... ) {} // handlers shouldn't throw } // Used by TcpSocket to register/unregister for write availability notification void _startNotifyWrite(const NativeSocket *sock); void _stopNotifyWrite(const NativeSocket *sock); // Called in SocketManager destructor or in constructor cleanup before exception throwing void _closeSockets(); // Called in SocketManager to recompute _nfds for select() based implementation void _updateNfds(); #ifdef __WINDOWS__ SOCKET _whackSendPipe; SOCKET _whackReceivePipe; SOCKET _tcpV4ListenSocket; SOCKET _tcpV6ListenSocket; #else int _whackSendPipe; int _whackReceivePipe; int _tcpV4ListenSocket; int _tcpV6ListenSocket; #endif Mutex _whackSendPipe_m; SharedPtr _udpV4Socket; SharedPtr _udpV6Socket; fd_set _readfds; fd_set _writefds; volatile int _nfds; Mutex _fdSetLock; std::map< InetAddress,SharedPtr > _tcpSockets; Mutex _tcpSockets_m; Mutex _pollLock; }; } // namespace ZeroTier #endif