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(); 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); 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 */ 72 TSocket(const std::string& path); 73 74 /** 75 * Destroyes the socket object, closing it if necessary. 76 */ 77 virtual ~TSocket(); 78 79 /** 80 * Whether the socket is alive. 81 * 82 * @return Is the socket alive? 83 */ 84 virtual bool isOpen(); 85 86 /** 87 * Checks whether there is more data available in the socket to read. 88 * 89 * This call blocks until at least one byte is available or the socket is closed. 90 */ 91 virtual bool peek(); 92 93 /** 94 * Creates and opens the UNIX socket. 95 * 96 * @throws TTransportException If the socket could not connect 97 */ 98 virtual void open(); 99 100 /** 101 * Shuts down communications on the socket. 102 */ 103 virtual void close(); 104 105 /** 106 * Determines whether there is pending data to read or not. 107 * 108 * This call does not block. 109 * \throws TTransportException of types: 110 * NOT_OPEN means the socket has been closed 111 * UNKNOWN means something unexpected happened 112 * \returns true if there is pending data to read, false otherwise 113 */ 114 virtual bool hasPendingDataToRead(); 115 116 /** 117 * Reads from the underlying socket. 118 * \returns the number of bytes read or 0 indicates EOF 119 * \throws TTransportException of types: 120 * INTERRUPTED means the socket was interrupted 121 * out of a blocking call 122 * NOT_OPEN means the socket has been closed 123 * TIMED_OUT means the receive timeout expired 124 * UNKNOWN means something unexpected happened 125 */ 126 virtual uint32_t read(uint8_t* buf, uint32_t len); 127 128 /** 129 * Writes to the underlying socket. Loops until done or fail. 130 */ 131 virtual void write(const uint8_t* buf, uint32_t len); 132 133 /** 134 * Writes to the underlying socket. Does single send() and returns result. 135 */ 136 virtual uint32_t write_partial(const uint8_t* buf, uint32_t len); 137 138 /** 139 * Get the host that the socket is connected to 140 * 141 * @return string host identifier 142 */ 143 std::string getHost(); 144 145 /** 146 * Get the port that the socket is connected to 147 * 148 * @return int port number 149 */ 150 int getPort(); 151 152 /** 153 * Set the host that socket will connect to 154 * 155 * @param host host identifier 156 */ 157 void setHost(std::string host); 158 159 /** 160 * Set the port that socket will connect to 161 * 162 * @param port port number 163 */ 164 void setPort(int port); 165 166 /** 167 * Controls whether the linger option is set on the socket. 168 * 169 * @param on Whether SO_LINGER is on 170 * @param linger If linger is active, the number of seconds to linger for 171 */ 172 void setLinger(bool on, int linger); 173 174 /** 175 * Whether to enable/disable Nagle's algorithm. 176 * 177 * @param noDelay Whether or not to disable the algorithm. 178 * @return 179 */ 180 void setNoDelay(bool noDelay); 181 182 /** 183 * Set the connect timeout 184 */ 185 void setConnTimeout(int ms); 186 187 /** 188 * Set the receive timeout 189 */ 190 void setRecvTimeout(int ms); 191 192 /** 193 * Set the send timeout 194 */ 195 void setSendTimeout(int ms); 196 197 /** 198 * Set the max number of recv retries in case of an THRIFT_EAGAIN 199 * error 200 */ 201 void setMaxRecvRetries(int maxRecvRetries); 202 203 /** 204 * Set SO_KEEPALIVE 205 */ 206 void setKeepAlive(bool keepAlive); 207 208 /** 209 * Get socket information formatted as a string <Host: x Port: x> 210 */ 211 std::string getSocketInfo(); 212 213 /** 214 * Returns the DNS name of the host to which the socket is connected 215 */ 216 std::string getPeerHost(); 217 218 /** 219 * Returns the address of the host to which the socket is connected 220 */ 221 std::string getPeerAddress(); 222 223 /** 224 * Returns the port of the host to which the socket is connected 225 **/ 226 int getPeerPort(); 227 228 /** 229 * Returns the underlying socket file descriptor. 230 */ getSocketFD()231 THRIFT_SOCKET getSocketFD() { return socket_; } 232 233 /** 234 * (Re-)initialize a TSocket for the supplied descriptor. This is only 235 * intended for use by TNonblockingServer -- other use may result in 236 * unfortunate surprises. 237 * 238 * @param fd the descriptor for an already-connected socket 239 */ 240 void setSocketFD(THRIFT_SOCKET fd); 241 242 /* 243 * Returns a cached copy of the peer address. 244 */ 245 sockaddr* getCachedAddress(socklen_t* len) const; 246 247 /** 248 * Sets whether to use a low minimum TCP retransmission timeout. 249 */ 250 static void setUseLowMinRto(bool useLowMinRto); 251 252 /** 253 * Gets whether to use a low minimum TCP retransmission timeout. 254 */ 255 static bool getUseLowMinRto(); 256 257 /** 258 * Get the origin the socket is connected to 259 * 260 * @return string peer host identifier and port 261 */ 262 virtual const std::string getOrigin(); 263 264 /** 265 * Constructor to create socket from file descriptor. 266 */ 267 TSocket(THRIFT_SOCKET socket); 268 269 /** 270 * Constructor to create socket from file descriptor that 271 * can be interrupted safely. 272 */ 273 TSocket(THRIFT_SOCKET socket, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener); 274 275 /** 276 * Set a cache of the peer address (used when trivially available: e.g. 277 * accept() or connect()). Only caches IPV4 and IPV6; unset for others. 278 */ 279 void setCachedAddress(const sockaddr* addr, socklen_t len); 280 281 protected: 282 /** connect, called by open */ 283 void openConnection(struct addrinfo* res); 284 285 /** Host to connect to */ 286 std::string host_; 287 288 /** Port number to connect on */ 289 int port_; 290 291 /** UNIX domain socket path */ 292 std::string path_; 293 294 /** Underlying socket handle */ 295 THRIFT_SOCKET socket_; 296 297 /** Peer hostname */ 298 std::string peerHost_; 299 300 /** Peer address */ 301 std::string peerAddress_; 302 303 /** Peer port */ 304 int peerPort_; 305 306 /** 307 * A shared socket pointer that will interrupt a blocking read if data 308 * becomes available on it 309 */ 310 stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener_; 311 312 /** Connect timeout in ms */ 313 int connTimeout_; 314 315 /** Send timeout in ms */ 316 int sendTimeout_; 317 318 /** Recv timeout in ms */ 319 int recvTimeout_; 320 321 /** Keep alive on */ 322 bool keepAlive_; 323 324 /** Linger on */ 325 bool lingerOn_; 326 327 /** Linger val */ 328 int lingerVal_; 329 330 /** Nodelay */ 331 bool noDelay_; 332 333 /** Recv EGAIN retries */ 334 int maxRecvRetries_; 335 336 /** Cached peer address */ 337 union { 338 sockaddr_in ipv4; 339 sockaddr_in6 ipv6; 340 } cachedPeerAddr_; 341 342 /** Whether to use low minimum TCP retransmission timeout */ 343 static bool useLowMinRto_; 344 345 private: 346 void unix_open(); 347 void local_open(); 348 }; 349 } 350 } 351 } // apache::thrift::transport 352 353 #endif // #ifndef _THRIFT_TRANSPORT_TSOCKET_H_ 354