summaryrefslogtreecommitdiffstats
path: root/src/Net
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2008-06-27 19:34:09 +0200
committerMatthias Schiffer <matthias@gamezock.de>2008-06-27 19:34:09 +0200
commitd1306a1710cda4acb9a0138347cdb43943271b9c (patch)
tree50544a31e47670b257be804648c6d714750cee12 /src/Net
parentb143406a05a1698df5b88b0d4298362a9c8c080b (diff)
downloadmad-d1306a1710cda4acb9a0138347cdb43943271b9c.tar
mad-d1306a1710cda4acb9a0138347cdb43943271b9c.zip
Verbindungen geregelt trennen... hoffentlich...
Diffstat (limited to 'src/Net')
-rw-r--r--src/Net/Connection.cpp18
-rw-r--r--src/Net/Connection.h34
-rw-r--r--src/Net/Packet.h11
3 files changed, 43 insertions, 20 deletions
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 <cstring>
#include <sys/socket.h>
+#include <iostream>
+
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<const Packet::Data*>(data);
if(header.length == 0) {
- signal(this, Packet(header.type, header.requestId));
+ signal(this, Packet(static_cast<Packet::Type>(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<Packet::Type>(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<void,const Connection*,const Packet&> signal;
+ sigc::signal<void,Connection*,const Packet&> 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<const unsigned char*>(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<void,const Connection*,const Packet&> signalReceive() const {return signal;}
+ sigc::signal<void,Connection*,const Packet&> 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 {