diff options
Diffstat (limited to 'src/Net/Connection.h')
-rw-r--r-- | src/Net/Connection.h | 104 |
1 files changed, 77 insertions, 27 deletions
diff --git a/src/Net/Connection.h b/src/Net/Connection.h index 1c15a95..1176f92 100644 --- a/src/Net/Connection.h +++ b/src/Net/Connection.h @@ -20,6 +20,8 @@ #ifndef MAD_NET_CONNECTION_H_ #define MAD_NET_CONNECTION_H_ +#include <config.h> + #include "Packet.h" #include <queue> @@ -28,6 +30,10 @@ #include <sigc++/signal.h> #include <poll.h> +#include "glthread/lock.h" + +#include <iostream> + namespace Mad { namespace Net { @@ -36,6 +42,18 @@ class Packet; class Connection { private: + class StaticInit { + public: + StaticInit() { + gnutls_global_init(); + } + + ~StaticInit() { + gnutls_global_deinit(); + } + }; + static StaticInit staticInit; + struct Transmission { unsigned long length; unsigned long transmitted; @@ -45,16 +63,17 @@ class Connection { sigc::slot<void,const void*,unsigned long> notify; }; - enum State { - DISCONNECTED, HANDSHAKE, CONNECTION_HEADER, PACKET_HEADER, PACKET_DATA, DISCONNECT, BYE - } state; - + gl_lock_t receiveLock; Transmission transR; + + gl_lock_t sendLock; std::queue<Transmission> transS; Packet::Data header; - sigc::signal<void,const Packet&> signal; + sigc::signal<void,const Packet&> receiveSignal; + sigc::signal<void> connectedSignal; + sigc::signal<void> disconnectedSignal; void doHandshake(); @@ -68,13 +87,13 @@ class Connection { void doDisconnect(); - bool receiveComplete() const { + bool _receiveComplete() const { return (transR.length == transR.transmitted); } - void bye(); + bool _sendQueueEmpty() const {return transS.empty();} - void updateEvents() const; + void bye(); // Prevent shallow copy Connection(const Connection &o); @@ -93,6 +112,12 @@ class Connection { uint8_t protVerMax; }; + gl_rwlock_t stateLock; + + enum State { + DISCONNECTED, CONNECT, HANDSHAKE, CONNECTION_HEADER, PACKET_HEADER, PACKET_DATA, DISCONNECT, BYE + } state; + int sock; gnutls_session_t session; gnutls_certificate_credentials_t x509_cred; @@ -106,55 +131,80 @@ class Connection { bool rawReceive(unsigned long length, const sigc::slot<void,const void*,unsigned long> ¬ify); bool rawSend(const uint8_t *data, unsigned long length); - bool enterReceiveLoop(); + void enterReceiveLoop(); + + void sendReceive(short events); + + bool _isConnected() const {return (state != DISCONNECTED);} + bool _isConnecting() const { + return (state == CONNECT || state == HANDSHAKE || state == CONNECTION_HEADER); + } + + bool _isDisconnecting() const { + return (state == DISCONNECT || state == BYE); + } + + void updateEvents(); public: Connection() : state(DISCONNECTED), peer(0) { transR.length = transR.transmitted = 0; transR.data = 0; + gl_rwlock_init(stateLock); + gl_lock_init(sendLock); + gl_lock_init(receiveLock); + gnutls_certificate_allocate_credentials(&x509_cred); } virtual ~Connection(); - bool isConnected() const {return (state != DISCONNECTED);} - bool isConnecting() const { - return (state == HANDSHAKE || state == CONNECTION_HEADER); + bool isConnected() { + gl_rwlock_rdlock(stateLock); + bool ret = _isConnected(); + gl_rwlock_unlock(stateLock); + + return ret; } - bool isDisconnecting() const { - return (state == DISCONNECT || state == BYE); + bool isConnecting() { + gl_rwlock_rdlock(stateLock); + bool ret = _isConnecting(); + gl_rwlock_unlock(stateLock); + + return ret; } + /*bool isDisconnecting() { + gl_rwlock_rdlock(stateLock); + bool ret = (state == DISCONNECT || state == BYE); + gl_rwlock_unlock(stateLock); + + return ret; + }*/ + const gnutls_datum_t* getCertificate() const { + // TODO Thread-safeness return gnutls_certificate_get_ours(session); } const gnutls_datum_t* getPeerCertificate() const { + // TODO Thread-safeness unsigned int n; return gnutls_certificate_get_peers(session, &n); } + // TODO Thread-safeness const IPAddress* getPeer() const {return peer;} void disconnect(); bool send(const Packet &packet); - void sendReceive(short events); - - bool sendQueueEmpty() const {return transS.empty();} - - sigc::signal<void,const Packet&> signalReceive() const {return signal;} - - static void init() { - gnutls_global_init(); - } - - static void deinit() { - gnutls_global_deinit(); - } + sigc::signal<void,const Packet&> signalReceive() const {return receiveSignal;} + sigc::signal<void> signalConnected() const {return connectedSignal;} + sigc::signal<void> signalDisconnected() const {return disconnectedSignal;} }; } |