From d1306a1710cda4acb9a0138347cdb43943271b9c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 27 Jun 2008 19:34:09 +0200 Subject: Verbindungen geregelt trennen... hoffentlich... --- src/Net/Connection.cpp | 18 ++++++++++-------- src/Net/Connection.h | 34 +++++++++++++++++++++++++--------- src/Net/Packet.h | 11 ++++++++--- 3 files changed, 43 insertions(+), 20 deletions(-) (limited to 'src/Net') diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp index 19e7bf1..d069fc9 100644 --- a/src/Net/Connection.cpp +++ b/src/Net/Connection.cpp @@ -22,6 +22,8 @@ #include #include +#include + namespace Mad { namespace Net { @@ -49,14 +51,14 @@ void Connection::packetHeaderReceiveHandler(const void *data, unsigned long leng if(length != sizeof(Packet::Data)) { // TODO: Error - disconnect(); + doDisconnect(); return; } header = *reinterpret_cast(data); if(header.length == 0) { - signal(this, Packet(header.type, header.requestId)); + signal(this, Packet(static_cast(header.type), header.requestId)); enterReceiveLoop(); } @@ -72,11 +74,11 @@ void Connection::packetDataReceiveHandler(const void *data, unsigned long length if(length != header.length) { // TODO: Error - disconnect(); + doDisconnect(); return; } - signal(this, Packet(header.type, header.requestId, data, length)); + signal(this, Packet(static_cast(header.type), header.requestId, data, length)); enterReceiveLoop(); } @@ -95,7 +97,7 @@ void Connection::doReceive() { return; // TODO: Error - disconnect(); + doDisconnect(); return; } @@ -142,7 +144,7 @@ void Connection::doSend() { return; // TODO: Error - disconnect(); + doDisconnect(); return; } @@ -166,11 +168,11 @@ bool Connection::rawSend(const unsigned char *data, unsigned long length) { return true; } -void Connection::disconnect() { +void Connection::doDisconnect() { if(!isConnected()) return; - gnutls_bye(session, GNUTLS_SHUT_RDWR); + gnutls_bye(session, GNUTLS_SHUT_WR); shutdown(sock, SHUT_RDWR); close(sock); diff --git a/src/Net/Connection.h b/src/Net/Connection.h index adb677a..a3670b0 100644 --- a/src/Net/Connection.h +++ b/src/Net/Connection.h @@ -44,7 +44,7 @@ class Connection { }; enum State { - DISCONNECTED, HANDSHAKE, CONNECTION_HEADER, PACKET_HEADER, PACKET_DATA + DISCONNECTED, HANDSHAKE, CONNECTION_HEADER, PACKET_HEADER, PACKET_DATA, DISCONNECT, BYE } state; Transmission transR; @@ -52,7 +52,7 @@ class Connection { Packet::Data header; - sigc::signal signal; + sigc::signal signal; void doHandshake(); @@ -62,6 +62,8 @@ class Connection { void doReceive(); void doSend(); + void doDisconnect(); + bool receiveComplete() const { return (transR.length == transR.transmitted); } @@ -103,7 +105,7 @@ class Connection { bool rawSend(const unsigned char *data, unsigned long length); bool enterReceiveLoop() { - if(!isConnected()) + if(!isConnected() || isDisconnecting()) return false; state = PACKET_HEADER; @@ -119,7 +121,7 @@ class Connection { virtual ~Connection() { if(isConnected()) - disconnect(); + doDisconnect(); if(transR.data) delete [] transR.data; @@ -131,19 +133,30 @@ class Connection { } bool isConnected() const {return (state != DISCONNECTED);} - bool isConnecting() { + bool isConnecting() const { return (state == HANDSHAKE || state == CONNECTION_HEADER); } + bool isDisconnecting() const { + return (state == DISCONNECT || state == BYE); + } + const IPAddress* getPeer() {return peer;} int getSocket() const {return sock;} - void disconnect(); + void disconnect() { + if(isConnected() && !isDisconnecting()) { + state = DISCONNECT; + + if(sendQueueEmpty()) + doDisconnect(); + } + } struct pollfd getPollfd() const; bool send(const Packet &packet) { - if(!isConnected() || isConnecting()) + if(!isConnected() || isConnecting() || isDisconnecting()) return false; return rawSend(reinterpret_cast(packet.getRawData()), packet.getRawDataLength()); @@ -151,7 +164,7 @@ class Connection { void sendReceive(short events = POLLIN|POLLOUT) { if(events & POLLHUP || events & POLLERR) { - disconnect(); + doDisconnect(); return; } @@ -165,11 +178,14 @@ class Connection { if(events & POLLOUT) doSend(); + + if(state == DISCONNECT && sendQueueEmpty()) + doDisconnect(); } bool sendQueueEmpty() const {return transS.empty();} - sigc::signal signalReceive() const {return signal;} + sigc::signal signalReceive() const {return signal;} static void init() { gnutls_global_init(); diff --git a/src/Net/Packet.h b/src/Net/Packet.h index 32aba18..c2bd4d1 100644 --- a/src/Net/Packet.h +++ b/src/Net/Packet.h @@ -28,6 +28,11 @@ namespace Net { class Packet { public: + enum Type { + TYPE_UNKNOWN = 0x0000, TYPE_DEBUG = 0x0001, TYPE_PING = 0x0002, TYPE_PONG = 0x0003, + TYPE_DISCONNECT_REQ = 0x0010, TYPE_DISCONNECT_REP = 0x0011 + }; + struct Data { unsigned short type; unsigned short requestId; @@ -39,7 +44,7 @@ class Packet { Data *rawData; public: - Packet(unsigned short type, unsigned short requestId, const void *data = NULL, unsigned long length = 0) { + Packet(Type type, unsigned short requestId, const void *data = NULL, unsigned long length = 0) { rawData = (Data*)std::malloc(sizeof(Data)+length); rawData->type = type; @@ -71,8 +76,8 @@ class Packet { std::free(rawData); } - unsigned short getType() const { - return rawData->type; + Type getType() const { + return (Type)rawData->type; } unsigned short getRequestId() const { -- cgit v1.2.3