Imported Upstream version 1.5.1
This commit is contained in:
52
cpp/include/rpc/abstract_socket_channel.h
Normal file
52
cpp/include/rpc/abstract_socket_channel.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_ABSTRACT_SOCKET_CHANNEL_H_
|
||||
#define CPP_INCLUDE_RPC_ABSTRACT_SOCKET_CHANNEL_H_
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
typedef boost::function2<void, const boost::system::error_code&,
|
||||
std::size_t> ReadWriteHandler;
|
||||
|
||||
typedef boost::function1<void, const boost::system::error_code&>
|
||||
ConnectHandler;
|
||||
|
||||
class AbstractSocketChannel {
|
||||
public:
|
||||
virtual ~AbstractSocketChannel() {}
|
||||
|
||||
virtual void async_connect(
|
||||
const boost::asio::ip::tcp::endpoint& peer_endpoint,
|
||||
ConnectHandler handler) = 0;
|
||||
|
||||
virtual void async_read(
|
||||
const std::vector<boost::asio::mutable_buffer>& buffers,
|
||||
ReadWriteHandler handler) = 0;
|
||||
|
||||
virtual void async_read(
|
||||
const boost::asio::mutable_buffers_1& buffer,
|
||||
ReadWriteHandler handler) = 0;
|
||||
|
||||
virtual void async_write(
|
||||
const std::vector<boost::asio::const_buffer> & buffers,
|
||||
ReadWriteHandler handler) = 0;
|
||||
|
||||
virtual void close() = 0;
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_ABSTRACT_SOCKET_CHANNEL_H_
|
||||
65
cpp/include/rpc/callback_interface.h
Normal file
65
cpp/include/rpc/callback_interface.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_CALLBACK_INTERFACE_H_
|
||||
#define CPP_INCLUDE_RPC_CALLBACK_INTERFACE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pbrpc/RPC.pb.h"
|
||||
#include "rpc/client_request.h"
|
||||
#include "rpc/client_request_callback_interface.h"
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
template <class ReturnMessageType>
|
||||
class CallbackInterface : public ClientRequestCallbackInterface {
|
||||
public:
|
||||
virtual ~CallbackInterface();
|
||||
|
||||
/** To be implemented callback function which will be called by
|
||||
* RequestCompleted() as the response was received.
|
||||
*
|
||||
* @param response_message Pointer to the response message.
|
||||
* @param data Response data or NULL.
|
||||
* @param data_length Length of response data.
|
||||
* @param error Error message or NULL if no error occurred.
|
||||
*
|
||||
* @remark Ownership of response_message, data and error is transferred to
|
||||
* the caller.
|
||||
*/
|
||||
virtual void CallFinished(ReturnMessageType* response_message,
|
||||
char* data,
|
||||
uint32_t data_length,
|
||||
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error,
|
||||
void* context) = 0;
|
||||
|
||||
/** Executes CallFinished(), internal use only. */
|
||||
virtual void RequestCompleted(ClientRequest* request);
|
||||
};
|
||||
|
||||
template <class ReturnMessageType>
|
||||
CallbackInterface<ReturnMessageType>::~CallbackInterface() {}
|
||||
|
||||
template <class ReturnMessageType>
|
||||
void CallbackInterface<ReturnMessageType>::RequestCompleted(
|
||||
ClientRequest* request) {
|
||||
assert(request->resp_message() != NULL || request->error() != NULL);
|
||||
CallFinished(dynamic_cast<ReturnMessageType*>(request->resp_message()),
|
||||
request->resp_data(),
|
||||
request->resp_data_len(),
|
||||
request->error(),
|
||||
request->context());
|
||||
|
||||
delete request;
|
||||
}
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_CALLBACK_INTERFACE_H_
|
||||
160
cpp/include/rpc/client.h
Normal file
160
cpp/include/rpc/client.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
* 2012 by Michael Berlin, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_CLIENT_H_
|
||||
#define CPP_INCLUDE_RPC_CLIENT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <gtest/gtest_prod.h>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
|
||||
#include "rpc/client_connection.h"
|
||||
#include "rpc/client_request.h"
|
||||
#include "rpc/ssl_options.h"
|
||||
|
||||
#ifdef HAS_OPENSSL
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#endif // HAS_OPENSSL
|
||||
|
||||
#if (BOOST_VERSION / 100000 > 1) || (BOOST_VERSION / 100 % 1000 > 35)
|
||||
#include <boost/unordered_map.hpp>
|
||||
#else
|
||||
#include <map>
|
||||
#endif
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
// Boost introduced unordered_map in version 1.36 but we need to support
|
||||
// older versions for Debian 5.
|
||||
// TODO(bjko): Remove this typedef when support for Debian 5 is dropped.
|
||||
#if (BOOST_VERSION / 100000 > 1) || (BOOST_VERSION / 100 % 1000 > 35)
|
||||
typedef boost::unordered_map<std::string, ClientConnection*> connection_map;
|
||||
#else
|
||||
typedef std::map<std::string, ClientConnection*> connection_map;
|
||||
#endif
|
||||
|
||||
class Client {
|
||||
public:
|
||||
Client(int32_t connect_timeout_s,
|
||||
int32_t request_timeout_s,
|
||||
int32_t max_con_linger,
|
||||
const SSLOptions* options);
|
||||
|
||||
virtual ~Client();
|
||||
|
||||
void run();
|
||||
|
||||
void shutdown();
|
||||
|
||||
void sendRequest(const std::string& address,
|
||||
int32_t interface_id,
|
||||
int32_t proc_id,
|
||||
const xtreemfs::pbrpc::UserCredentials& userCreds,
|
||||
const xtreemfs::pbrpc::Auth& auth,
|
||||
const google::protobuf::Message* message,
|
||||
const char* data,
|
||||
int data_length,
|
||||
google::protobuf::Message* response_message,
|
||||
void* context,
|
||||
ClientRequestCallbackInterface *callback);
|
||||
|
||||
private:
|
||||
/** Helper function which aborts a ClientRequest with "error".
|
||||
*
|
||||
* @remarks Ownership of "request" is not transferred.
|
||||
*/
|
||||
void AbortClientRequest(ClientRequest* request, const std::string& error);
|
||||
|
||||
void handleTimeout(const boost::system::error_code& error);
|
||||
|
||||
void sendInternalRequest();
|
||||
|
||||
void ShutdownHandler();
|
||||
|
||||
FILE* create_and_open_temporary_ssl_file(std::string* filename_template,
|
||||
const char* mode);
|
||||
|
||||
#ifdef HAS_OPENSSL
|
||||
boost::asio::ssl::context_base::method string_to_ssl_method(
|
||||
std::string method_string,
|
||||
boost::asio::ssl::context_base::method default_method);
|
||||
#endif // HAS_OPENSSL
|
||||
|
||||
boost::asio::io_service service_;
|
||||
|
||||
connection_map connections_;
|
||||
/** Contains all pending requests which are uniquely identified by their
|
||||
* call id.
|
||||
*
|
||||
* Requests to this table are added when sending them and removed by the
|
||||
* handleTimeout() function and the callback processing.
|
||||
*
|
||||
* @remark All accesses to this object have to be executed in the context of
|
||||
* service_ and therefore do not require further synchronization.
|
||||
*/
|
||||
request_map request_table_;
|
||||
/** Guards access to requests_ and stopped_. */
|
||||
boost::mutex requests_mutex_;
|
||||
/** Global queue where all requests queue up before the required
|
||||
* ClientConnection is available.
|
||||
*
|
||||
* Once a ClientRequest was removed from this queue, it will be added to the
|
||||
* requests_table_ and the queue ClientConnection::requests_.
|
||||
*/
|
||||
std::queue<ClientRequest*> requests_;
|
||||
/** True when the RPC client was stopped and no new requests are accepted. */
|
||||
bool stopped_;
|
||||
/** True when the RPC client was stopped, only accessed in the context of
|
||||
* io_service::run. */
|
||||
bool stopped_ioservice_only_;
|
||||
uint32_t callid_counter_;
|
||||
boost::asio::deadline_timer rq_timeout_timer_;
|
||||
int32_t rq_timeout_s_;
|
||||
int32_t connect_timeout_s_;
|
||||
int32_t max_con_linger_;
|
||||
|
||||
#ifdef HAS_OPENSSL
|
||||
std::string get_pem_password_callback() const;
|
||||
std::string get_pkcs12_password_callback() const;
|
||||
|
||||
// For previous Boost versions the callback is not a member function (see below).
|
||||
#if (BOOST_VERSION > 104601)
|
||||
bool verify_certificate_callback(bool preverfied,
|
||||
boost::asio::ssl::verify_context& context) const;
|
||||
#endif
|
||||
|
||||
bool use_gridssl_;
|
||||
const SSLOptions* ssl_options;
|
||||
char* pemFileName;
|
||||
char* certFileName;
|
||||
char* trustedCAsFileName;
|
||||
boost::asio::ssl::context* ssl_context_;
|
||||
#endif // HAS_OPENSSL
|
||||
|
||||
FRIEND_TEST(ClientTestFastLingerTimeout, LingerTests);
|
||||
FRIEND_TEST(ClientTestFastLingerTimeoutConnectTimeout, LingerTests);
|
||||
};
|
||||
|
||||
// For newer Boost versions the callback is a member function (see above).
|
||||
#if (BOOST_VERSION < 104700)
|
||||
int verify_certificate_callback(int preverify_ok, X509_STORE_CTX *ctx);
|
||||
#endif // BOOST_VERSION < 104700
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_CLIENT_H_
|
||||
161
cpp/include/rpc/client_connection.h
Normal file
161
cpp/include/rpc/client_connection.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
* 2012 by Michael Berlin, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_CLIENT_CONNECTION_H_
|
||||
#define CPP_INCLUDE_RPC_CLIENT_CONNECTION_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
|
||||
#include "pbrpc/RPC.pb.h"
|
||||
#include "rpc/abstract_socket_channel.h"
|
||||
#include "rpc/client_request.h"
|
||||
#include "rpc/record_marker.h"
|
||||
#include "rpc/ssl_options.h"
|
||||
|
||||
#if (BOOST_VERSION / 100000 > 1) || (BOOST_VERSION / 100 % 1000 > 35)
|
||||
#include <boost/unordered_map.hpp>
|
||||
#else
|
||||
#include <map>
|
||||
#endif
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
// Boost introduced unordered_map in version 1.36 but we need to support
|
||||
// older versions for Debian 5.
|
||||
// TODO(bjko): Remove this typedef when support for Debian 5 is dropped.
|
||||
#if (BOOST_VERSION / 100000 > 1) || (BOOST_VERSION / 100 % 1000 > 35)
|
||||
typedef boost::unordered_map<int32_t, ClientRequest*> request_map;
|
||||
#else
|
||||
typedef std::map<int32_t, ClientRequest*> request_map;
|
||||
#endif
|
||||
|
||||
/** Created by xtreemfs::rpc::Client for every connection.
|
||||
*
|
||||
* This class contains the per-connection data.
|
||||
*
|
||||
* @remarks Special care has to be taken regarding the boost::asio callback
|
||||
* functions. In particular, every callback must not access members
|
||||
* when the error_code equals asio::error::operation_aborted.
|
||||
* Additionally, no further actions must be taken when
|
||||
* connection_state_ is set to CLOSED.
|
||||
*/
|
||||
class ClientConnection {
|
||||
public:
|
||||
struct PendingRequest {
|
||||
PendingRequest(uint32_t call_id, ClientRequest* rq)
|
||||
: call_id(call_id), rq(rq) {}
|
||||
|
||||
uint32_t call_id;
|
||||
ClientRequest* rq;
|
||||
};
|
||||
|
||||
ClientConnection(const std::string& server_name,
|
||||
const std::string& port,
|
||||
boost::asio::io_service& service,
|
||||
request_map *request_table,
|
||||
int32_t connect_timeout_s,
|
||||
int32_t max_reconnect_interval_s
|
||||
#ifdef HAS_OPENSSL
|
||||
,bool use_gridssl,
|
||||
boost::asio::ssl::context* ssl_context
|
||||
#endif // HAS_OPENSSL
|
||||
);
|
||||
|
||||
virtual ~ClientConnection();
|
||||
|
||||
void DoProcess();
|
||||
void AddRequest(ClientRequest *request);
|
||||
void Close(const std::string& error);
|
||||
void SendError(xtreemfs::pbrpc::POSIXErrno posix_errno,
|
||||
const std::string& error_message);
|
||||
void Reset();
|
||||
|
||||
boost::posix_time::ptime last_used() const {
|
||||
return last_used_;
|
||||
}
|
||||
|
||||
std::string GetServerAddress() const {
|
||||
return server_name_ + ":" + server_port_;
|
||||
}
|
||||
|
||||
private:
|
||||
enum State {
|
||||
CONNECTING,
|
||||
IDLE,
|
||||
ACTIVE,
|
||||
CLOSED,
|
||||
WAIT_FOR_RECONNECT
|
||||
};
|
||||
|
||||
RecordMarker *receive_marker_;
|
||||
char *receive_hdr_, *receive_msg_, *receive_data_;
|
||||
|
||||
char *receive_marker_buffer_;
|
||||
|
||||
State connection_state_;
|
||||
/** Queue of requests which have not been sent out yet. */
|
||||
std::queue<PendingRequest> requests_;
|
||||
ClientRequest* current_request_;
|
||||
|
||||
const std::string server_name_;
|
||||
const std::string server_port_;
|
||||
boost::asio::io_service &service_;
|
||||
boost::asio::ip::tcp::resolver resolver_;
|
||||
AbstractSocketChannel* socket_;
|
||||
|
||||
boost::asio::ip::tcp::endpoint* endpoint_;
|
||||
/** Points to the Client's request_table_. */
|
||||
request_map* request_table_;
|
||||
boost::asio::deadline_timer timer_;
|
||||
const int32_t connect_timeout_s_;
|
||||
const int32_t max_reconnect_interval_s_;
|
||||
boost::posix_time::ptime next_reconnect_at_;
|
||||
boost::posix_time::ptime last_connect_was_at_;
|
||||
int32_t reconnect_interval_s_;
|
||||
boost::posix_time::ptime last_used_;
|
||||
|
||||
#ifdef HAS_OPENSSL
|
||||
bool use_gridssl_;
|
||||
boost::asio::ssl::context* ssl_context_;
|
||||
#endif // HAS_OPENSSL
|
||||
|
||||
/** Deletes "socket".
|
||||
*
|
||||
* @remark Ownership of "socket" is transferred.
|
||||
*/
|
||||
void static DelayedSocketDeletionHandler(AbstractSocketChannel* socket);
|
||||
|
||||
void Connect();
|
||||
void SendRequest();
|
||||
void ReceiveRequest();
|
||||
void PostResolve(const boost::system::error_code& err,
|
||||
boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
|
||||
void PostConnect(const boost::system::error_code& err,
|
||||
boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
|
||||
void OnConnectTimeout(const boost::system::error_code& err);
|
||||
void PostReadMessage(const boost::system::error_code& err);
|
||||
void PostReadRecordMarker(const boost::system::error_code& err);
|
||||
void PostWrite(const boost::system::error_code& err,
|
||||
std::size_t bytes_written);
|
||||
void DeleteInternalBuffers();
|
||||
void CreateChannel();
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_CLIENT_CONNECTION_H_
|
||||
|
||||
211
cpp/include/rpc/client_request.h
Normal file
211
cpp/include/rpc/client_request.h
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
* 2012 by Michael Berlin, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_CLIENT_REQUEST_H_
|
||||
#define CPP_INCLUDE_RPC_CLIENT_REQUEST_H_
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include "include/Common.pb.h"
|
||||
#include "pbrpc/RPC.pb.h"
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
class ClientConnection;
|
||||
class ClientRequest;
|
||||
class ClientRequestCallbackInterface;
|
||||
class RecordMarker;
|
||||
|
||||
class ClientRequest {
|
||||
public:
|
||||
static const int ERR_NOERR = 0;
|
||||
|
||||
ClientRequest(const std::string& address,
|
||||
const uint32_t call_id,
|
||||
const uint32_t interface_id,
|
||||
const uint32_t proc_id,
|
||||
const xtreemfs::pbrpc::UserCredentials& userCreds,
|
||||
const xtreemfs::pbrpc::Auth& auth,
|
||||
const google::protobuf::Message* request_message,
|
||||
const char* request_data,
|
||||
const int data_length,
|
||||
google::protobuf::Message* response_message,
|
||||
void *context,
|
||||
ClientRequestCallbackInterface* callback);
|
||||
|
||||
virtual ~ClientRequest();
|
||||
|
||||
void ExecuteCallback();
|
||||
|
||||
void RequestSent();
|
||||
|
||||
/** Used by Client::handleTimeout() to find the respective ClientConnection.
|
||||
*
|
||||
* @remarks This object does not have the ownership of "client_connection_",
|
||||
* so it does not get transferred.
|
||||
*/
|
||||
ClientConnection* client_connection() {
|
||||
return client_connection_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @remarks Ownership is not transferred. Instead, it's assumed that this
|
||||
* ClientRequests exists as long as "client_connection".
|
||||
*/
|
||||
void set_client_connection(ClientConnection* client_connection) {
|
||||
client_connection_ = client_connection;
|
||||
}
|
||||
|
||||
void set_rq_data(const char* rq_data) {
|
||||
this->rq_data_ = rq_data;
|
||||
}
|
||||
|
||||
const char* rq_data() const {
|
||||
return rq_data_;
|
||||
}
|
||||
|
||||
void set_rq_hdr_msg(char* rq_hdr_msg) {
|
||||
this->rq_hdr_msg_ = rq_hdr_msg;
|
||||
}
|
||||
|
||||
char* rq_hdr_msg() const {
|
||||
return rq_hdr_msg_;
|
||||
}
|
||||
|
||||
void set_request_marker(RecordMarker* request_marker) {
|
||||
this->request_marker_ = request_marker;
|
||||
}
|
||||
|
||||
RecordMarker* request_marker() const {
|
||||
return request_marker_;
|
||||
}
|
||||
|
||||
void set_resp_data(char* resp_data) {
|
||||
this->resp_data_ = resp_data;
|
||||
}
|
||||
|
||||
char* resp_data() const {
|
||||
return resp_data_;
|
||||
}
|
||||
|
||||
void clear_resp_data() {
|
||||
delete[] resp_data_;
|
||||
resp_data_ = NULL;
|
||||
resp_data_len_ = 0;
|
||||
}
|
||||
|
||||
void set_resp_header(xtreemfs::pbrpc::RPCHeader* resp_header) {
|
||||
this->resp_header_ = resp_header;
|
||||
}
|
||||
|
||||
xtreemfs::pbrpc::RPCHeader* resp_header() const {
|
||||
return resp_header_;
|
||||
}
|
||||
|
||||
void set_address(std::string address) {
|
||||
this->address_ = address_;
|
||||
}
|
||||
|
||||
std::string address() const {
|
||||
return address_;
|
||||
}
|
||||
|
||||
uint32_t call_id() const {
|
||||
return call_id_;
|
||||
}
|
||||
|
||||
uint32_t interface_id() const {
|
||||
return interface_id_;
|
||||
}
|
||||
|
||||
uint32_t proc_id() const {
|
||||
return proc_id_;
|
||||
}
|
||||
|
||||
boost::posix_time::ptime time_sent() const {
|
||||
return time_sent_;
|
||||
}
|
||||
|
||||
google::protobuf::Message* resp_message() const {
|
||||
return resp_message_;
|
||||
}
|
||||
|
||||
void clear_resp_message() {
|
||||
delete resp_message_;
|
||||
resp_message_ = NULL;
|
||||
}
|
||||
|
||||
void set_error(xtreemfs::pbrpc::RPCHeader::ErrorResponse* error) {
|
||||
if (!error_) {
|
||||
// Process first error only.
|
||||
this->error_ = error;
|
||||
} else {
|
||||
delete error;
|
||||
}
|
||||
}
|
||||
|
||||
void clear_error() {
|
||||
delete error_;
|
||||
error_ = NULL;
|
||||
}
|
||||
|
||||
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error() const {
|
||||
return error_;
|
||||
}
|
||||
|
||||
void* context() const {
|
||||
return context_;
|
||||
}
|
||||
|
||||
void set_resp_data_len(uint32_t resp_data_len_) {
|
||||
this->resp_data_len_ = resp_data_len_;
|
||||
}
|
||||
|
||||
uint32_t resp_data_len() const {
|
||||
return resp_data_len_;
|
||||
}
|
||||
|
||||
private:
|
||||
/** Pointer to the ClientConnection which is responsible for this object. */
|
||||
ClientConnection* client_connection_;
|
||||
|
||||
/** ID of the request to match received responses to sent requests. */
|
||||
const uint32_t call_id_;
|
||||
/** Type of interface (service) which will be contacted. */
|
||||
const uint32_t interface_id_;
|
||||
/** Number of the operation which will be executed. */
|
||||
const uint32_t proc_id_;
|
||||
void *context_;
|
||||
ClientRequestCallbackInterface *callback_;
|
||||
std::string address_;
|
||||
boost::posix_time::ptime time_sent_;
|
||||
bool callback_executed_;
|
||||
|
||||
/** Internal buffers (will be deleted with the object). */
|
||||
RecordMarker *request_marker_;
|
||||
char *rq_hdr_msg_;
|
||||
|
||||
/** Buffers which are passed to the callback. */
|
||||
xtreemfs::pbrpc::RPCHeader::ErrorResponse *error_;
|
||||
const char *rq_data_;
|
||||
xtreemfs::pbrpc::RPCHeader *resp_header_;
|
||||
google::protobuf::Message *resp_message_;
|
||||
char *resp_data_;
|
||||
uint32_t resp_data_len_;
|
||||
|
||||
void deleteInternalBuffers();
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_CLIENT_REQUEST_H_
|
||||
|
||||
25
cpp/include/rpc/client_request_callback_interface.h
Normal file
25
cpp/include/rpc/client_request_callback_interface.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_CLIENT_REQUEST_CALLBACK_INTERFACE_H_
|
||||
#define CPP_INCLUDE_RPC_CLIENT_REQUEST_CALLBACK_INTERFACE_H_
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
class ClientRequest;
|
||||
|
||||
class ClientRequestCallbackInterface {
|
||||
public:
|
||||
virtual ~ClientRequestCallbackInterface() {}
|
||||
virtual void RequestCompleted(ClientRequest* request) = 0;
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_CLIENT_REQUEST_CALLBACK_INTERFACE_H_
|
||||
105
cpp/include/rpc/grid_ssl_socket_channel.h
Normal file
105
cpp/include/rpc/grid_ssl_socket_channel.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_GRID_SSL_SOCKET_CHANNEL_H_
|
||||
#define CPP_INCLUDE_RPC_GRID_SSL_SOCKET_CHANNEL_H_
|
||||
|
||||
#ifdef HAS_OPENSSL
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "pbrpc/RPC.pb.h"
|
||||
#include "rpc/abstract_socket_channel.h"
|
||||
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
class GridSSLSocketChannel : public AbstractSocketChannel {
|
||||
public:
|
||||
|
||||
GridSSLSocketChannel(boost::asio::io_service& service,
|
||||
boost::asio::ssl::context& context)
|
||||
: ssl_stream_(service, context) {
|
||||
}
|
||||
|
||||
virtual ~GridSSLSocketChannel() {
|
||||
}
|
||||
|
||||
virtual void async_connect(
|
||||
const boost::asio::ip::tcp::endpoint& peer_endpoint,
|
||||
ConnectHandler handler) {
|
||||
connect_handler_ = handler;
|
||||
ssl_stream_.lowest_layer().async_connect(
|
||||
peer_endpoint,
|
||||
boost::bind(&GridSSLSocketChannel::internal_do_handshake,
|
||||
this,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void internal_do_handshake(const boost::system::error_code& error) {
|
||||
if (error) {
|
||||
connect_handler_(error);
|
||||
} else {
|
||||
ssl_stream_.async_handshake(
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket>::client,
|
||||
connect_handler_);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void async_read(
|
||||
const std::vector<boost::asio::mutable_buffer>& buffers,
|
||||
ReadWriteHandler handler) {
|
||||
boost::asio::async_read(ssl_stream_.next_layer(), buffers, handler);
|
||||
}
|
||||
|
||||
virtual void async_read(
|
||||
const boost::asio::mutable_buffers_1& buffer,
|
||||
ReadWriteHandler handler) {
|
||||
boost::asio::async_read(ssl_stream_.next_layer(), buffer, handler);
|
||||
}
|
||||
|
||||
virtual void async_write(
|
||||
const std::vector<boost::asio::const_buffer> & buffers,
|
||||
ReadWriteHandler handler) {
|
||||
boost::asio::async_write(ssl_stream_.next_layer(), buffers, handler);
|
||||
}
|
||||
|
||||
virtual void close() {
|
||||
boost::system::error_code ignored_error;
|
||||
|
||||
ssl_stream_.lowest_layer().shutdown(
|
||||
boost::asio::ip::tcp::socket::shutdown_both,
|
||||
ignored_error);
|
||||
ssl_stream_.lowest_layer().close(ignored_error);
|
||||
|
||||
ssl_stream_.shutdown(ignored_error);
|
||||
}
|
||||
|
||||
const char *ssl_tls_version() {
|
||||
#if (BOOST_VERSION < 104700)
|
||||
return SSL_get_version(ssl_stream_.impl()->ssl);
|
||||
#else // BOOST_VERSION < 104700
|
||||
return SSL_get_version(ssl_stream_.native_handle());
|
||||
#endif // BOOST_VERSION < 104700
|
||||
}
|
||||
|
||||
private:
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_stream_;
|
||||
ConnectHandler connect_handler_;
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // HAS_OPENSSL
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_GRID_SSL_SOCKET_CHANNEL_H_
|
||||
43
cpp/include/rpc/record_marker.h
Normal file
43
cpp/include/rpc/record_marker.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_RECORD_MARKER_H_
|
||||
#define CPP_INCLUDE_RPC_RECORD_MARKER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
class RecordMarker {
|
||||
public:
|
||||
RecordMarker(uint32_t header_len,
|
||||
uint32_t message_len,
|
||||
uint32_t data_len);
|
||||
explicit RecordMarker(const char* buffer);
|
||||
void serialize(char* buffer) const;
|
||||
|
||||
uint32_t data_len() const;
|
||||
uint32_t message_len() const;
|
||||
uint32_t header_len() const;
|
||||
|
||||
static std::size_t get_size() {
|
||||
return sizeof(uint32_t) * 3;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t header_len_;
|
||||
uint32_t message_len_;
|
||||
uint32_t data_len_;
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_RECORD_MARKER_H_
|
||||
|
||||
117
cpp/include/rpc/ssl_options.h
Normal file
117
cpp/include/rpc/ssl_options.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_SSL_OPTIONS_H_
|
||||
#define CPP_INCLUDE_RPC_SSL_OPTIONS_H_
|
||||
|
||||
#ifdef HAS_OPENSSL
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#endif // HAS_OPENSSL
|
||||
|
||||
#include <algorithm> // std::find
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
class SSLOptions {
|
||||
#ifdef HAS_OPENSSL
|
||||
public:
|
||||
SSLOptions(const std::string ssl_pem_path,
|
||||
const std::string ssl_pem_cert_path,
|
||||
const std::string ssl_pem_key_pass,
|
||||
const std::string ssl_pem_trusted_certs_path,
|
||||
const std::string ssl_pkcs12_path,
|
||||
const std::string ssl_pkcs12_pass,
|
||||
const boost::asio::ssl::context::file_format format,
|
||||
const bool use_grid_ssl,
|
||||
const bool ssl_verify_certificates,
|
||||
const std::vector<int> ssl_ignore_verify_errors,
|
||||
const std::string ssl_method_string)
|
||||
: pem_file_name_(ssl_pem_path),
|
||||
pem_file_pass_(ssl_pem_key_pass),
|
||||
pem_cert_name_(ssl_pem_cert_path),
|
||||
pem_trusted_certs_file_name_(ssl_pem_trusted_certs_path),
|
||||
pkcs12_file_name_(ssl_pkcs12_path),
|
||||
pkcs12_file_pass_(ssl_pkcs12_pass),
|
||||
cert_format_(format),
|
||||
use_grid_ssl_(use_grid_ssl),
|
||||
verify_certificates_(ssl_verify_certificates),
|
||||
ignore_verify_errors_(ssl_ignore_verify_errors),
|
||||
ssl_method_string_(ssl_method_string) {}
|
||||
|
||||
virtual ~SSLOptions() {
|
||||
}
|
||||
|
||||
std::string pem_file_name() const {
|
||||
return pem_file_name_;
|
||||
}
|
||||
|
||||
std::string pem_cert_name() const {
|
||||
return pem_cert_name_;
|
||||
}
|
||||
|
||||
std::string pem_file_password() const {
|
||||
return pem_file_pass_;
|
||||
}
|
||||
|
||||
std::string pem_trusted_certs_file_name() const {
|
||||
return pem_trusted_certs_file_name_;
|
||||
}
|
||||
|
||||
std::string pkcs12_file_name() const {
|
||||
return pkcs12_file_name_;
|
||||
}
|
||||
|
||||
std::string pkcs12_file_password() const {
|
||||
return pkcs12_file_pass_;
|
||||
}
|
||||
|
||||
boost::asio::ssl::context::file_format cert_format() const {
|
||||
return cert_format_;
|
||||
}
|
||||
|
||||
bool use_grid_ssl() const {
|
||||
return use_grid_ssl_;
|
||||
}
|
||||
|
||||
bool verify_certificates() const {
|
||||
return verify_certificates_;
|
||||
}
|
||||
|
||||
bool ignore_verify_error(int verify_error) const {
|
||||
return std::find(ignore_verify_errors_.begin(),
|
||||
ignore_verify_errors_.end(),
|
||||
verify_error) != ignore_verify_errors_.end();
|
||||
}
|
||||
|
||||
std::string ssl_method_string() const {
|
||||
return ssl_method_string_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string pem_file_name_;
|
||||
std::string pem_file_pass_;
|
||||
std::string pem_cert_name_;
|
||||
std::string pem_trusted_certs_file_name_;
|
||||
std::string pkcs12_file_name_;
|
||||
std::string pkcs12_file_pass_;
|
||||
|
||||
boost::asio::ssl::context::file_format cert_format_;
|
||||
bool use_grid_ssl_;
|
||||
bool verify_certificates_;
|
||||
std::vector<int> ignore_verify_errors_;
|
||||
std::string ssl_method_string_;
|
||||
#endif // HAS_OPENSSL
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_SSL_OPTIONS_H_
|
||||
|
||||
104
cpp/include/rpc/ssl_socket_channel.h
Normal file
104
cpp/include/rpc/ssl_socket_channel.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_SSL_SOCKET_CHANNEL_H_
|
||||
#define CPP_INCLUDE_RPC_SSL_SOCKET_CHANNEL_H_
|
||||
|
||||
#ifdef HAS_OPENSSL
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "pbrpc/RPC.pb.h"
|
||||
#include "rpc/abstract_socket_channel.h"
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
class SSLSocketChannel : public AbstractSocketChannel {
|
||||
public:
|
||||
SSLSocketChannel(boost::asio::io_service& service,
|
||||
boost::asio::ssl::context& context)
|
||||
: ssl_stream_(service, context) {
|
||||
}
|
||||
|
||||
virtual ~SSLSocketChannel() {
|
||||
}
|
||||
|
||||
virtual void async_connect(
|
||||
const boost::asio::ip::tcp::endpoint& peer_endpoint,
|
||||
ConnectHandler handler) {
|
||||
connect_handler_ = handler;
|
||||
ssl_stream_.lowest_layer().async_connect(
|
||||
peer_endpoint,
|
||||
boost::bind(&SSLSocketChannel::internal_do_handshake,
|
||||
this,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void internal_do_handshake(const boost::system::error_code& error) {
|
||||
if (error) {
|
||||
connect_handler_(error);
|
||||
} else {
|
||||
ssl_stream_.async_handshake(
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket>::client,
|
||||
connect_handler_);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void async_read(
|
||||
const std::vector<boost::asio::mutable_buffer>& buffers,
|
||||
ReadWriteHandler handler) {
|
||||
boost::asio::async_read(ssl_stream_, buffers, handler);
|
||||
}
|
||||
|
||||
virtual void async_read(
|
||||
const boost::asio::mutable_buffers_1& buffer,
|
||||
ReadWriteHandler handler) {
|
||||
boost::asio::async_read(ssl_stream_, buffer, handler);
|
||||
}
|
||||
|
||||
virtual void async_write(
|
||||
const std::vector<boost::asio::const_buffer> & buffers,
|
||||
ReadWriteHandler handler) {
|
||||
boost::asio::async_write(ssl_stream_, buffers, handler);
|
||||
}
|
||||
|
||||
virtual void close() {
|
||||
boost::system::error_code ignored_error;
|
||||
|
||||
ssl_stream_.lowest_layer().shutdown(
|
||||
boost::asio::ip::tcp::socket::shutdown_both,
|
||||
ignored_error);
|
||||
ssl_stream_.lowest_layer().close(ignored_error);
|
||||
|
||||
ssl_stream_.shutdown(ignored_error);
|
||||
}
|
||||
|
||||
const char *ssl_tls_version() {
|
||||
#if (BOOST_VERSION < 104700)
|
||||
return SSL_get_version(ssl_stream_.impl()->ssl);
|
||||
#else // BOOST_VERSION < 104700
|
||||
return SSL_get_version(ssl_stream_.native_handle());
|
||||
#endif // BOOST_VERSION < 104700
|
||||
}
|
||||
|
||||
private:
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_stream_;
|
||||
ConnectHandler connect_handler_;
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // HAS_OPENSSL
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_SSL_SOCKET_CHANNEL_H_
|
||||
|
||||
96
cpp/include/rpc/sync_callback.h
Normal file
96
cpp/include/rpc/sync_callback.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_SYNC_CALLBACK_H_
|
||||
#define CPP_INCLUDE_RPC_SYNC_CALLBACK_H_
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pbrpc/RPC.pb.h"
|
||||
#include "rpc/client_request_callback_interface.h"
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
class ClientRequest;
|
||||
|
||||
class SyncCallbackBase : public ClientRequestCallbackInterface {
|
||||
public:
|
||||
SyncCallbackBase();
|
||||
virtual ~SyncCallbackBase();
|
||||
|
||||
/**
|
||||
* Returns if the rpc has finished (response was received or error).
|
||||
* This operation does not block.
|
||||
* @return true, if the RPC has finished
|
||||
*/
|
||||
bool HasFinished();
|
||||
|
||||
/**
|
||||
* Returns true if the request has failed. Blocks until
|
||||
* response is available.
|
||||
* @return true if an error occurred
|
||||
*/
|
||||
bool HasFailed();
|
||||
|
||||
/**
|
||||
* Returns a pointer to the error or NULL if the request was successful.
|
||||
* Blocks until response is available.
|
||||
* @return pointer to ErrorResponse, caller is responsible for deleting
|
||||
* the object or calling deleteBuffers
|
||||
*/
|
||||
xtreemfs::pbrpc::RPCHeader::ErrorResponse* error();
|
||||
|
||||
/**
|
||||
* Returns a pointer to the response message. Blocks until response is
|
||||
* available.
|
||||
* @return pointer to response message, caller is responsible for
|
||||
* deleting the object or calling deleteBuffers
|
||||
*/
|
||||
::google::protobuf::Message* response();
|
||||
|
||||
/**
|
||||
* Returns the length of the response data or 0.
|
||||
* Blocks until response is available.
|
||||
* @return ength of the response data or 0
|
||||
*/
|
||||
uint32_t data_length();
|
||||
|
||||
/**
|
||||
* Returns a pointer to the response data. Blocks until response
|
||||
* is available.
|
||||
* @return pointer to response data, caller is responsible for
|
||||
* deleting[] the data or calling deleteBuffers
|
||||
*/
|
||||
char* data();
|
||||
|
||||
/**
|
||||
* Deletes the response objects (message, response, data)
|
||||
* This is not done automatically when the SyncCallback is deleted!
|
||||
*/
|
||||
void DeleteBuffers();
|
||||
|
||||
/** internal callback, ignore */
|
||||
virtual void RequestCompleted(ClientRequest* rq);
|
||||
|
||||
private:
|
||||
boost::mutex cond_lock_;
|
||||
boost::condition_variable response_avail_;
|
||||
ClientRequest* request_;
|
||||
|
||||
void WaitForResponse();
|
||||
};
|
||||
|
||||
// TODO(hupfeld): update pbrpcgen to emit dynamic types.
|
||||
template <class ReturnMessageType>
|
||||
class SyncCallback : public SyncCallbackBase {};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_SYNC_CALLBACK_H_
|
||||
72
cpp/include/rpc/tcp_socket_channel.h
Normal file
72
cpp/include/rpc/tcp_socket_channel.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2010 by Bjoern Kolbeck, Zuse Institute Berlin
|
||||
*
|
||||
* Licensed under the BSD License, see LICENSE file for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPP_INCLUDE_RPC_TCP_SOCKET_CHANNEL_H_
|
||||
#define CPP_INCLUDE_RPC_TCP_SOCKET_CHANNEL_H_
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "pbrpc/RPC.pb.h"
|
||||
#include "rpc/abstract_socket_channel.h"
|
||||
|
||||
namespace xtreemfs {
|
||||
namespace rpc {
|
||||
|
||||
class TCPSocketChannel : public AbstractSocketChannel {
|
||||
public:
|
||||
explicit TCPSocketChannel(boost::asio::io_service& service) {
|
||||
socket_ = new boost::asio::ip::tcp::socket(service);
|
||||
}
|
||||
|
||||
virtual ~TCPSocketChannel() {
|
||||
delete socket_;
|
||||
}
|
||||
|
||||
virtual void async_connect(
|
||||
const boost::asio::ip::tcp::endpoint& peer_endpoint,
|
||||
ConnectHandler handler) {
|
||||
socket_->async_connect(peer_endpoint, handler);
|
||||
}
|
||||
|
||||
virtual void async_read(
|
||||
const std::vector<boost::asio::mutable_buffer>& buffers,
|
||||
ReadWriteHandler handler) {
|
||||
boost::asio::async_read(*socket_, buffers, handler);
|
||||
}
|
||||
|
||||
virtual void async_read(
|
||||
const boost::asio::mutable_buffers_1& buffer,
|
||||
ReadWriteHandler handler) {
|
||||
boost::asio::async_read(*socket_, buffer, handler);
|
||||
}
|
||||
|
||||
virtual void async_write(
|
||||
const std::vector<boost::asio::const_buffer> & buffers,
|
||||
ReadWriteHandler handler) {
|
||||
boost::asio::async_write(*socket_, buffers, handler);
|
||||
}
|
||||
|
||||
virtual void close() {
|
||||
boost::system::error_code ignored_error;
|
||||
|
||||
socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both,
|
||||
ignored_error);
|
||||
socket_->close(ignored_error);
|
||||
}
|
||||
|
||||
protected:
|
||||
boost::asio::ip::tcp::socket *socket_;
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace xtreemfs
|
||||
|
||||
#endif // CPP_INCLUDE_RPC_TCP_SOCKET_CHANNEL_H_
|
||||
|
||||
Reference in New Issue
Block a user