diff options
Diffstat (limited to 'client/red_peer.h')
-rw-r--r-- | client/red_peer.h | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/client/red_peer.h b/client/red_peer.h new file mode 100644 index 00000000..f1db1814 --- /dev/null +++ b/client/red_peer.h @@ -0,0 +1,182 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + 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. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _H_REDPEER +#define _H_REDPEER + +#ifdef _WIN32 +#include <winsock.h> +#else +typedef int SOCKET; +#endif + +#include <openssl/ssl.h> +#include <openssl/err.h> + +#include "common.h" +#include "red.h" +#include "events_loop.h" +#include "threads.h" + +class RedPeer: protected EventsLoop::Socket { +public: + RedPeer(); + virtual ~RedPeer(); + + class InMessage; + class CompundInMessage; + class OutMessage; + class DisconnectedException {}; + + class ConnectionOptions { + public: + + enum Type { + CON_OP_INVALID, + CON_OP_SECURE, + CON_OP_UNSECURE, + CON_OP_BOTH, + }; + + ConnectionOptions(Type in_type, int in_port, int in_sport) + : type (in_type) + , unsecure_port (in_port) + , secure_port (in_sport) + { + } + + virtual ~ConnectionOptions() {} + + bool allow_secure() const + { + return (type == CON_OP_BOTH || type == CON_OP_SECURE) && secure_port != -1; + } + + bool allow_unsecure() const + { + return (type == CON_OP_BOTH || type == CON_OP_UNSECURE) && unsecure_port != -1; + } + + public: + Type type; + int unsecure_port; + int secure_port; + }; + + void connect_unsecure(uint32_t ip, int port); + void connect_unsecure(const char* host, int port); + + void connect_secure(const ConnectionOptions& options, uint32_t ip); + void connect_secure(const ConnectionOptions& options, const char* host); + + void disconnect(); + void swap(RedPeer* other); + void close(); + void enable() { _shut = false;} + + virtual CompundInMessage* recive(); + uint32_t send(OutMessage& message); + + uint32_t recive(uint8_t* buf, uint32_t size); + uint32_t send(uint8_t* buf, uint32_t size); + + static uint32_t host_by_name(const char *host); + +protected: + virtual void on_event() {} + virtual int get_socket() { return _peer;} + +private: + void shutdown(); + void cleanup(); + +private: + SOCKET _peer; + Mutex _lock; + bool _shut; + uint64_t _serial; + + SSL_CTX *_ctx; + SSL *_ssl; +}; + +class RedPeer::InMessage { +public: + InMessage(uint16_t type, uint32_t size, uint8_t* data) + : _type (type) + , _size (size) + , _data (data) + { + } + + virtual ~InMessage() {} + + uint16_t type() { return _type;} + uint8_t* data() { return _data;} + virtual uint32_t size() { return _size;} + +protected: + uint16_t _type; + uint32_t _size; + uint8_t* _data; +}; + +class RedPeer::CompundInMessage: public RedPeer::InMessage { +public: + CompundInMessage(uint64_t _serial, uint16_t type, uint32_t size, uint32_t sub_list) + : InMessage(type, size, new uint8_t[size]) + , _serial (_serial) + , _sub_list (sub_list) + { + } + + virtual ~CompundInMessage() { delete[] _data;} + + uint64_t serial() { return _serial;} + uint32_t sub_list() { return _sub_list;} + + virtual uint32_t size() { return _sub_list ? _sub_list : _size;} + uint32_t compund_size() {return _size;} + +private: + uint64_t _serial; + uint32_t _sub_list; +}; + +class RedPeer::OutMessage { +public: + OutMessage(uint32_t type, uint32_t size); + virtual ~OutMessage(); + + RedDataHeader& header() { return *(RedDataHeader *)_data;} + uint8_t* data() { return _data + sizeof(RedDataHeader);} + void resize(uint32_t size); + +private: + uint32_t message_size() { return header().size + sizeof(RedDataHeader);} + uint8_t* base() { return _data;} + +private: + uint8_t* _data; + uint32_t _size; + + friend class RedPeer; + friend class RedChannel; +}; + +#endif + |