1 /* 2 * Copyright 2006 Facebook 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef _THRIFT_TRANSPORT_TSERVERSOCKET_H_ 8 #define _THRIFT_TRANSPORT_TSERVERSOCKET_H_ 1 9 10 #include <functional> 11 12 #include <thrift/concurrency/Mutex.h> 13 #include <thrift/transport/PlatformSocket.h> 14 #include <thrift/transport/TServerTransport.h> 15 16 #include <sys/types.h> 17 #ifdef HAVE_SYS_SOCKET_H 18 #include <zephyr/posix/sys/socket.h> 19 #endif 20 #ifdef HAVE_NETDB_H 21 #include <zephyr/posix/netdb.h> 22 #endif 23 24 namespace apache 25 { 26 namespace thrift 27 { 28 namespace transport 29 { 30 31 class TSocket; 32 33 /** 34 * Server socket implementation of TServerTransport. Wrapper around a unix 35 * socket listen and accept calls. 36 * 37 */ 38 class TServerSocket : public TServerTransport 39 { 40 public: 41 typedef std::function<void(THRIFT_SOCKET fd)> socket_func_t; 42 43 const static int DEFAULT_BACKLOG = 1024; 44 45 /** 46 * Constructor. 47 * 48 * @param port Port number to bind to 49 */ 50 TServerSocket(int port); 51 52 /** 53 * Constructor. 54 * 55 * @param port Port number to bind to 56 * @param sendTimeout Socket send timeout 57 * @param recvTimeout Socket receive timeout 58 */ 59 TServerSocket(int port, int sendTimeout, int recvTimeout); 60 61 /** 62 * Constructor. 63 * 64 * @param address Address to bind to 65 * @param port Port number to bind to 66 */ 67 TServerSocket(const std::string &address, int port); 68 69 /** 70 * Constructor used for unix sockets. 71 * 72 * @param path Pathname for unix socket. 73 */ 74 TServerSocket(const std::string &path); 75 76 ~TServerSocket() override; 77 78 bool isOpen() const override; 79 80 void setSendTimeout(int sendTimeout); 81 void setRecvTimeout(int recvTimeout); 82 83 void setAcceptTimeout(int accTimeout); 84 void setAcceptBacklog(int accBacklog); 85 86 void setRetryLimit(int retryLimit); 87 void setRetryDelay(int retryDelay); 88 setKeepAlive(bool keepAlive)89 void setKeepAlive(bool keepAlive) 90 { 91 keepAlive_ = keepAlive; 92 } 93 94 void setTcpSendBuffer(int tcpSendBuffer); 95 void setTcpRecvBuffer(int tcpRecvBuffer); 96 97 // listenCallback gets called just before listen, and after all Thrift 98 // setsockopt calls have been made. If you have custom setsockopt 99 // things that need to happen on the listening socket, this is the place to do it. setListenCallback(const socket_func_t & listenCallback)100 void setListenCallback(const socket_func_t &listenCallback) 101 { 102 listenCallback_ = listenCallback; 103 } 104 105 // acceptCallback gets called after each accept call, on the newly created socket. 106 // It is called after all Thrift setsockopt calls have been made. If you have 107 // custom setsockopt things that need to happen on the accepted 108 // socket, this is the place to do it. setAcceptCallback(const socket_func_t & acceptCallback)109 void setAcceptCallback(const socket_func_t &acceptCallback) 110 { 111 acceptCallback_ = acceptCallback; 112 } 113 114 // When enabled (the default), new children TSockets will be constructed so 115 // they can be interrupted by TServerTransport::interruptChildren(). 116 // This is more expensive in terms of system calls (poll + recv) however 117 // ensures a connected client cannot interfere with TServer::stop(). 118 // 119 // When disabled, TSocket children do not incur an additional poll() call. 120 // Server-side reads are more efficient, however a client can interfere with 121 // the server's ability to shutdown properly by staying connected. 122 // 123 // Must be called before listen(); mode cannot be switched after that. 124 // \throws std::logic_error if listen() has been called 125 void setInterruptableChildren(bool enable); 126 getSocketFD()127 THRIFT_SOCKET getSocketFD() override 128 { 129 return serverSocket_; 130 } 131 132 int getPort() const; 133 134 std::string getPath() const; 135 136 bool isUnixDomainSocket() const; 137 138 void listen() override; 139 void interrupt() override; 140 void interruptChildren() override; 141 void close() override; 142 143 protected: 144 std::shared_ptr<TTransport> acceptImpl() override; 145 virtual std::shared_ptr<TSocket> createSocket(THRIFT_SOCKET client); 146 bool interruptableChildren_; 147 std::shared_ptr<THRIFT_SOCKET> pChildInterruptSockReader_; // if interruptableChildren_ this 148 // is shared with child TSockets 149 150 void _setup_sockopts(); 151 void _setup_tcp_sockopts(); 152 153 private: 154 void notify(THRIFT_SOCKET notifySock); 155 void _setup_unixdomain_sockopts(); 156 157 protected: 158 int port_; 159 std::string address_; 160 std::string path_; 161 THRIFT_SOCKET serverSocket_; 162 int acceptBacklog_; 163 int sendTimeout_; 164 int recvTimeout_; 165 int accTimeout_; 166 int retryLimit_; 167 int retryDelay_; 168 int tcpSendBuffer_; 169 int tcpRecvBuffer_; 170 bool keepAlive_; 171 bool listening_; 172 173 concurrency::Mutex rwMutex_; // thread-safe interrupt 174 THRIFT_SOCKET interruptSockWriter_; // is notified on interrupt() 175 THRIFT_SOCKET 176 interruptSockReader_; // is used in select/poll with serverSocket_ for interruptability 177 THRIFT_SOCKET childInterruptSockWriter_; // is notified on interruptChildren() 178 179 socket_func_t listenCallback_; 180 socket_func_t acceptCallback_; 181 }; 182 } // namespace transport 183 } // namespace thrift 184 } // namespace apache 185 186 #endif // #ifndef _THRIFT_TRANSPORT_TSERVERSOCKET_H_ 187