1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 #ifndef _THRIFT_TRANSPORT_TSOCKET_H_ 21 #define _THRIFT_TRANSPORT_TSOCKET_H_ 1 22 23 #include <string> 24 25 #include <thrift/transport/TTransport.h> 26 #include <thrift/transport/TVirtualTransport.h> 27 #include <thrift/transport/TServerSocket.h> 28 #include <thrift/transport/PlatformSocket.h> 29 30 #ifdef HAVE_ARPA_INET_H 31 #include <arpa/inet.h> 32 #endif 33 #ifdef HAVE_SYS_TIME_H 34 #include <sys/time.h> 35 #endif 36 #ifdef HAVE_NETDB_H 37 #include <netdb.h> 38 #endif 39 40 namespace apache { 41 namespace thrift { 42 namespace transport { 43 44 /** 45 * TCP Socket implementation of the TTransport interface. 46 * 47 */ 48 class TSocket : public TVirtualTransport<TSocket> { 49 public: 50 /** 51 * Constructs a new socket. Note that this does NOT actually connect the 52 * socket. 53 * 54 */ 55 TSocket(std::shared_ptr<TConfiguration> config = nullptr); 56 57 /** 58 * Constructs a new socket. Note that this does NOT actually connect the 59 * socket. 60 * 61 * @param host An IP address or hostname to connect to 62 * @param port The port to connect on 63 */ 64 TSocket(const std::string& host, int port, std::shared_ptr<TConfiguration> config = nullptr); 65 66 /** 67 * Constructs a new Unix domain socket. 68 * Note that this does NOT actually connect the socket. 69 * 70 * @param path The Unix domain socket e.g. "/tmp/ThriftTest.binary.thrift" 71 * or a zero-prefixed string to create an abstract domain socket on Linux. 72 */ 73 TSocket(const std::string& path, std::shared_ptr<TConfiguration> config = nullptr); 74 75 /** 76 * Destroyes the socket object, closing it if necessary. 77 */ 78 ~TSocket() override; 79 80 /** 81 * Whether the socket is alive. 82 * 83 * @return Is the socket alive? 84 */ 85 bool isOpen() const override; 86 87 /** 88 * Checks whether there is more data available in the socket to read. 89 * 90 * This call blocks until at least one byte is available or the socket is closed. 91 */ 92 bool peek() override; 93 94 /** 95 * Creates and opens the UNIX socket. 96 * 97 * @throws TTransportException If the socket could not connect 98 */ 99 void open() override; 100 101 /** 102 * Shuts down communications on the socket. 103 */ 104 void close() override; 105 106 /** 107 * Determines whether there is pending data to read or not. 108 * 109 * This call does not block. 110 * \throws TTransportException of types: 111 * NOT_OPEN means the socket has been closed 112 * UNKNOWN means something unexpected happened 113 * \returns true if there is pending data to read, false otherwise 114 */ 115 virtual bool hasPendingDataToRead(); 116 117 /** 118 * Reads from the underlying socket. 119 * \returns the number of bytes read or 0 indicates EOF 120 * \throws TTransportException of types: 121 * INTERRUPTED means the socket was interrupted 122 * out of a blocking call 123 * NOT_OPEN means the socket has been closed 124 * TIMED_OUT means the receive timeout expired 125 * UNKNOWN means something unexpected happened 126 */ 127 virtual uint32_t read(uint8_t* buf, uint32_t len); 128 129 /** 130 * Writes to the underlying socket. Loops until done or fail. 131 */ 132 virtual void write(const uint8_t* buf, uint32_t len); 133 134 /** 135 * Writes to the underlying socket. Does single send() and returns result. 136 */ 137 virtual uint32_t write_partial(const uint8_t* buf, uint32_t len); 138 139 /** 140 * Get the host that the socket is connected to 141 * 142 * @return string host identifier 143 */ 144 std::string getHost(); 145 146 /** 147 * Get the port that the socket is connected to 148 * 149 * @return int port number 150 */ 151 int getPort(); 152 153 /** 154 * Get the Unix domain socket path that the socket is connected to 155 * 156 * @return std::string path 157 */ 158 std::string getPath(); 159 160 /** 161 * Set the host that socket will connect to 162 * 163 * @param host host identifier 164 */ 165 void setHost(std::string host); 166 167 /** 168 * Set the port that socket will connect to 169 * 170 * @param port port number 171 */ 172 void setPort(int port); 173 174 /** 175 * Set the Unix domain socket path for the socket 176 * 177 * @param path std::string path 178 */ 179 void setPath(std::string path); 180 181 /** 182 * Controls whether the linger option is set on the socket. 183 * 184 * @param on Whether SO_LINGER is on 185 * @param linger If linger is active, the number of seconds to linger for 186 */ 187 void setLinger(bool on, int linger); 188 189 /** 190 * Whether to enable/disable Nagle's algorithm. 191 * 192 * @param noDelay Whether or not to disable the algorithm. 193 * @return 194 */ 195 void setNoDelay(bool noDelay); 196 197 /** 198 * Set the connect timeout 199 */ 200 void setConnTimeout(int ms); 201 202 /** 203 * Set the receive timeout 204 */ 205 void setRecvTimeout(int ms); 206 207 /** 208 * Set the send timeout 209 */ 210 void setSendTimeout(int ms); 211 212 /** 213 * Set the max number of recv retries in case of an THRIFT_EAGAIN 214 * error 215 */ 216 void setMaxRecvRetries(int maxRecvRetries); 217 218 /** 219 * Set SO_KEEPALIVE 220 */ 221 void setKeepAlive(bool keepAlive); 222 223 /** 224 * Get socket information formatted as a string <Host: x Port: x> 225 */ 226 std::string getSocketInfo() const; 227 228 /** 229 * Returns the DNS name of the host to which the socket is connected 230 */ 231 std::string getPeerHost() const; 232 233 /** 234 * Returns the address of the host to which the socket is connected 235 */ 236 std::string getPeerAddress() const; 237 238 /** 239 * Returns the port of the host to which the socket is connected 240 **/ 241 int getPeerPort() const; 242 243 /** 244 * Returns the underlying socket file descriptor. 245 */ getSocketFD()246 THRIFT_SOCKET getSocketFD() { return socket_; } 247 248 /** 249 * (Re-)initialize a TSocket for the supplied descriptor. This is only 250 * intended for use by TNonblockingServer -- other use may result in 251 * unfortunate surprises. 252 * 253 * @param fd the descriptor for an already-connected socket 254 */ 255 void setSocketFD(THRIFT_SOCKET fd); 256 257 /* 258 * Returns a cached copy of the peer address. 259 */ 260 sockaddr* getCachedAddress(socklen_t* len) const; 261 262 /** 263 * Sets whether to use a low minimum TCP retransmission timeout. 264 */ 265 static void setUseLowMinRto(bool useLowMinRto); 266 267 /** 268 * Gets whether to use a low minimum TCP retransmission timeout. 269 */ 270 static bool getUseLowMinRto(); 271 272 /** 273 * Get the origin the socket is connected to 274 * 275 * @return string peer host identifier and port 276 */ 277 const std::string getOrigin() const override; 278 279 /** 280 * Constructor to create socket from file descriptor. 281 */ 282 TSocket(THRIFT_SOCKET socket, std::shared_ptr<TConfiguration> config = nullptr); 283 284 /** 285 * Constructor to create socket from file descriptor that 286 * can be interrupted safely. 287 */ 288 TSocket(THRIFT_SOCKET socket, std::shared_ptr<THRIFT_SOCKET> interruptListener, 289 std::shared_ptr<TConfiguration> config = nullptr); 290 291 /** 292 * Set a cache of the peer address (used when trivially available: e.g. 293 * accept() or connect()). Only caches IPV4 and IPV6; unset for others. 294 */ 295 void setCachedAddress(const sockaddr* addr, socklen_t len); 296 297 protected: 298 /** connect, called by open */ 299 void openConnection(struct addrinfo* res); 300 301 /** Host to connect to */ 302 std::string host_; 303 304 /** Port number to connect on */ 305 int port_; 306 307 /** UNIX domain socket path */ 308 std::string path_; 309 310 /** Underlying socket handle */ 311 THRIFT_SOCKET socket_; 312 313 /** Peer hostname */ 314 mutable std::string peerHost_; 315 316 /** Peer address */ 317 mutable std::string peerAddress_; 318 319 /** Peer port */ 320 mutable int peerPort_; 321 322 /** 323 * A shared socket pointer that will interrupt a blocking read if data 324 * becomes available on it 325 */ 326 std::shared_ptr<THRIFT_SOCKET> interruptListener_; 327 328 /** Connect timeout in ms */ 329 int connTimeout_; 330 331 /** Send timeout in ms */ 332 int sendTimeout_; 333 334 /** Recv timeout in ms */ 335 int recvTimeout_; 336 337 /** Keep alive on */ 338 bool keepAlive_; 339 340 /** Linger on */ 341 bool lingerOn_; 342 343 /** Linger val */ 344 int lingerVal_; 345 346 /** Nodelay */ 347 bool noDelay_; 348 349 /** Recv EGAIN retries */ 350 int maxRecvRetries_; 351 352 /** Cached peer address */ 353 union { 354 sockaddr_in ipv4; 355 sockaddr_in6 ipv6; 356 } cachedPeerAddr_; 357 358 /** Whether to use low minimum TCP retransmission timeout */ 359 static bool useLowMinRto_; 360 361 private: 362 void unix_open(); 363 void local_open(); 364 }; 365 } 366 } 367 } // apache::thrift::transport 368 369 #endif // #ifndef _THRIFT_TRANSPORT_TSOCKET_H_ 370