// OpenVPN -- An application to securely tunnel IP networks
// over a single port, with support for SSL/TLS-based
// session authentication and key exchange,
// packet encryption, packet authentication, and
// packet compression.
//
// Copyright (C) 2012-2015 OpenVPN Technologies, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License Version 3
// as published by the Free Software Foundation.
//
// 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 in the COPYING file.
// If not, see .
// These classes define function objects to be used as asynchronous callbacks
// for Asio methods. Think of these as optimized special cases of function
// objects that could be more generally (but perhaps less optimally) defined
// with lambdas.
#ifndef OPENVPN_COMMON_ASIODISPATCH_H
#define OPENVPN_COMMON_ASIODISPATCH_H
#include
#include
#include
namespace openvpn {
// Dispatcher for asio async_write
template
class AsioDispatchWrite
{
public:
AsioDispatchWrite(Handler handle_write, C* obj)
: handle_write_(handle_write), obj_(obj) {}
void operator()(const asio::error_code& error, const size_t bytes_sent)
{
(obj_.get()->*handle_write_)(error, bytes_sent);
}
private:
Handler handle_write_;
RCPtr obj_;
};
template
AsioDispatchWrite asio_dispatch_write(Handler handle_write, C* obj)
{
return AsioDispatchWrite(handle_write, obj);
}
// Dispatcher for asio async_read with argument
template
class AsioDispatchRead
{
public:
AsioDispatchRead(Handler handle_read, C* obj, Data data)
: handle_read_(handle_read), obj_(obj), data_(data) {}
void operator()(const asio::error_code& error, const size_t bytes_recvd)
{
(obj_.get()->*handle_read_)(data_, error, bytes_recvd);
}
private:
Handler handle_read_;
RCPtr obj_;
Data data_;
};
template
AsioDispatchRead asio_dispatch_read(Handler handle_read, C* obj, Data data)
{
return AsioDispatchRead(handle_read, obj, data);
}
// Dispatcher for asio async_read without argument
template
class AsioDispatchReadNoArg
{
public:
AsioDispatchReadNoArg(Handler handle_read, C* obj)
: handle_read_(handle_read), obj_(obj) {}
void operator()(const asio::error_code& error, const size_t bytes_recvd)
{
(obj_.get()->*handle_read_)(error, bytes_recvd);
}
private:
Handler handle_read_;
RCPtr obj_;
};
template
AsioDispatchReadNoArg asio_dispatch_read_noarg(Handler handle_read, C* obj)
{
return AsioDispatchReadNoArg(handle_read, obj);
}
// Dispatcher for asio async_wait with argument
template
class AsioDispatchTimerArg
{
public:
AsioDispatchTimerArg(Handler handler, C* obj, Data data)
: handler_(handler), obj_(obj), data_(data) {}
void operator()(const asio::error_code& error)
{
(obj_.get()->*handler_)(data_, error);
}
private:
Handler handler_;
RCPtr obj_;
Data data_;
};
template
AsioDispatchTimerArg asio_dispatch_timer_arg(Handler handler, C* obj, Data data)
{
return AsioDispatchTimerArg(handler, obj, data);
}
// Dispatcher for asio async_wait without argument
template
class AsioDispatchTimer
{
public:
AsioDispatchTimer(Handler handler, C* obj)
: handler_(handler), obj_(obj) {}
void operator()(const asio::error_code& error)
{
(obj_.get()->*handler_)(error);
}
private:
Handler handler_;
RCPtr obj_;
};
template
AsioDispatchTimer asio_dispatch_timer(Handler handler, C* obj)
{
return AsioDispatchTimer(handler, obj);
}
// Dispatcher for asio async_connect with argument
template
class AsioDispatchConnectArg
{
public:
AsioDispatchConnectArg(Handler handler, C* obj, Data data)
: handler_(handler), obj_(obj), data_(data) {}
void operator()(const asio::error_code& error)
{
(obj_.get()->*handler_)(data_, error);
}
private:
Handler handler_;
RCPtr obj_;
Data data_;
};
template
AsioDispatchConnectArg asio_dispatch_connect_arg(Handler handler, C* obj, Data data)
{
return AsioDispatchConnectArg(handler, obj, data);
}
// Dispatcher for asio async_connect without argument
template
class AsioDispatchConnect
{
public:
AsioDispatchConnect(Handler handler, C* obj)
: handler_(handler), obj_(obj) {}
void operator()(const asio::error_code& error)
{
(obj_.get()->*handler_)(error);
}
private:
Handler handler_;
RCPtr obj_;
};
template
AsioDispatchConnect asio_dispatch_connect(Handler handler, C* obj)
{
return AsioDispatchConnect(handler, obj);
}
// Dispatcher for asio async_connect (ComposedConnectHandler) without argument
template
class AsioDispatchComposedConnect
{
public:
AsioDispatchComposedConnect(Handler handler, C* obj)
: handler_(handler), obj_(obj) {}
void operator()(const asio::error_code& error, asio::ip::tcp::resolver::iterator endpoint_iterator)
{
(obj_.get()->*handler_)(error, endpoint_iterator);
}
private:
Handler handler_;
RCPtr obj_;
};
template
AsioDispatchComposedConnect asio_dispatch_composed_connect(Handler handler, C* obj)
{
return AsioDispatchComposedConnect(handler, obj);
}
// Dispatcher for asio async_accept with argument
template
class AsioDispatchAcceptArg
{
public:
AsioDispatchAcceptArg(Handler handler, C* obj, Data data)
: handler_(handler), obj_(obj), data_(data) {}
void operator()(const asio::error_code& error)
{
(obj_.get()->*handler_)(data_, error);
}
private:
Handler handler_;
RCPtr obj_;
Data data_;
};
template
AsioDispatchAcceptArg asio_dispatch_accept_arg(Handler handler, C* obj, Data data)
{
return AsioDispatchAcceptArg(handler, obj, data);
}
// Dispatcher for asio post with argument
template
class AsioDispatchPostArg
{
public:
AsioDispatchPostArg(Handler handler, C* obj, Data data)
: handler_(handler), obj_(obj), data_(data) {}
void operator()()
{
(obj_.get()->*handler_)(data_);
}
private:
Handler handler_;
RCPtr obj_;
Data data_;
};
template
AsioDispatchPostArg asio_dispatch_post_arg(Handler handler, C* obj, Data data)
{
return AsioDispatchPostArg(handler, obj, data);
}
// Dispatcher for asio post without argument
template
class AsioDispatchPost
{
public:
AsioDispatchPost(Handler handler, C* obj)
: handler_(handler), obj_(obj) {}
void operator()()
{
(obj_.get()->*handler_)();
}
private:
Handler handler_;
RCPtr obj_;
};
template
AsioDispatchPost asio_dispatch_post(Handler handler, C* obj)
{
return AsioDispatchPost(handler, obj);
}
// Dispatcher for asynchronous resolver without argument
template
class AsioDispatchResolve
{
public:
AsioDispatchResolve(Handler handler, C* obj)
: handler_(handler), obj_(obj) {}
void operator()(const asio::error_code& error, EndpointIterator iter)
{
(obj_.get()->*handler_)(error, iter);
}
private:
Handler handler_;
RCPtr obj_;
};
// Dispatcher for asynchronous resolver with argument
template
class AsioDispatchResolveArg
{
public:
AsioDispatchResolveArg(Handler handler, C* obj, Data data)
: handler_(handler), obj_(obj), data_(data) {}
void operator()(const asio::error_code& error, EndpointIterator iter)
{
(obj_.get()->*handler_)(error, iter, data_);
}
private:
Handler handler_;
RCPtr obj_;
Data data_;
};
// Dispatcher for asio signal
template
class AsioDispatchSignal
{
public:
AsioDispatchSignal(Handler handler, C* obj)
: handler_(handler), obj_(obj) {}
void operator()(const asio::error_code& error, int signal_number)
{
(obj_.get()->*handler_)(error, signal_number);
}
private:
Handler handler_;
RCPtr obj_;
};
template
AsioDispatchSignal asio_dispatch_signal(Handler handler, C* obj)
{
return AsioDispatchSignal(handler, obj);
}
// General purpose dispatcher with data
template
class SimpleDispatch
{
public:
SimpleDispatch(Handler handler, C* obj)
: handler_(handler), obj_(obj) {}
void operator()(Data data)
{
(obj_->*handler_)(data);
}
private:
Handler handler_;
C* obj_;
};
} // namespace openvpn
#endif // OPENVPN_COMMON_ASIODISPATCH_H