summaryrefslogtreecommitdiffstats
path: root/src/Net/Connection.cpp
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2008-06-28 15:20:04 +0200
committerMatthias Schiffer <matthias@gamezock.de>2008-06-28 15:20:04 +0200
commitee5c5c9f65556b542ab81942e5a024ba84173762 (patch)
tree0777270d017dbe986a310e1b33b9b9ebac185634 /src/Net/Connection.cpp
parentc0bd49f419b0850085d651a4ceeca45cf9d09832 (diff)
downloadmad-ee5c5c9f65556b542ab81942e5a024ba84173762.tar
mad-ee5c5c9f65556b542ab81942e5a024ba84173762.zip
Einige Bugs in der Trennung beseitigt.
Diffstat (limited to 'src/Net/Connection.cpp')
-rw-r--r--src/Net/Connection.cpp96
1 files changed, 46 insertions, 50 deletions
diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp
index 8af02c6..5d221fb 100644
--- a/src/Net/Connection.cpp
+++ b/src/Net/Connection.cpp
@@ -22,25 +22,23 @@
#include <cstring>
#include <sys/socket.h>
-#include <iostream>
-
namespace Mad {
namespace Net {
void Connection::doHandshake() {
if(state != HANDSHAKE)
return;
-
+
int ret = gnutls_handshake(session);
if(ret < 0) {
if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
return;
-
+
// TODO: Error
doDisconnect();
return;
}
-
+
state = CONNECTION_HEADER;
connectionHeader();
}
@@ -48,37 +46,35 @@ void Connection::doHandshake() {
void Connection::doBye() {
if(state != BYE)
return;
-
- int ret = gnutls_bye(session, GNUTLS_SHUT_WR);
+
+ int ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
if(ret < 0) {
if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
return;
-
+
// TODO: Error
doDisconnect();
return;
}
-
- std::cout << "Bye!" << std::endl;
-
+
doDisconnect();
}
void Connection::packetHeaderReceiveHandler(const void *data, unsigned long length) {
if(state != PACKET_HEADER)
return;
-
+
if(length != sizeof(Packet::Data)) {
// TODO: Error
doDisconnect();
return;
}
-
+
header = *reinterpret_cast<const Packet::Data*>(data);
-
+
if(header.length == 0) {
signal(this, Packet(static_cast<Packet::Type>(header.type), header.requestId));
-
+
enterReceiveLoop();
}
else {
@@ -90,45 +86,45 @@ void Connection::packetHeaderReceiveHandler(const void *data, unsigned long leng
void Connection::packetDataReceiveHandler(const void *data, unsigned long length) {
if(state != PACKET_DATA)
return;
-
+
if(length != header.length) {
// TODO: Error
doDisconnect();
return;
}
-
+
signal(this, Packet(static_cast<Packet::Type>(header.type), header.requestId, data, length));
-
+
enterReceiveLoop();
}
void Connection::doReceive() {
if(!isConnected())
return;
-
+
if(receiveComplete())
return;
-
+
ssize_t ret = gnutls_record_recv(session, transR.data+transR.transmitted, transR.length-transR.transmitted);
-
+
if(ret < 0) {
if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
return;
-
+
// TODO: Error
doDisconnect();
return;
}
-
+
transR.transmitted += ret;
-
+
if(receiveComplete()) {
// Save data pointer, as transR.notify might start a new reception
unsigned char *data = transR.data;
transR.data = 0;
-
+
transR.notify(data, transR.length);
-
+
delete [] data;
}
}
@@ -138,37 +134,37 @@ bool Connection::rawReceive(unsigned long length,
{
if(!isConnected())
return false;
-
+
if(!receiveComplete())
return false;
-
+
transR.data = new unsigned char[length];
transR.length = length;
transR.transmitted = 0;
transR.notify = notify;
-
+
return true;
}
void Connection::doSend() {
if(!isConnected())
return;
-
+
while(!sendQueueEmpty()) {
- ssize_t ret = gnutls_record_send(session, transS.front().data+transS.front().transmitted,
+ ssize_t ret = gnutls_record_send(session, transS.front().data+transS.front().transmitted,
transS.front().length-transS.front().transmitted);
-
+
if(ret < 0) {
if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
return;
-
+
// TODO: Error
doDisconnect();
return;
}
-
+
transS.front().transmitted += ret;
-
+
if(transS.front().transmitted == transS.front().length) {
delete [] transS.front().data;
transS.pop();
@@ -179,11 +175,11 @@ void Connection::doSend() {
bool Connection::rawSend(const unsigned char *data, unsigned long length) {
if(!isConnected())
return false;
-
+
Transmission trans = {length, 0, new unsigned char[length], sigc::slot<void,const void*,unsigned long>()};
std::memcpy(trans.data, data, length);
transS.push(trans);
-
+
return true;
}
@@ -192,49 +188,49 @@ void Connection::sendReceive(short events) {
doDisconnect();
return;
}
-
+
if(state == HANDSHAKE) {
doHandshake();
return;
}
-
+
if(state == BYE) {
doBye();
return;
}
-
+
if(events & POLLIN)
doReceive();
-
+
if(events & POLLOUT)
doSend();
-
- if(state == DISCONNECT && sendQueueEmpty())
+
+ if(state == DISCONNECT && sendQueueEmpty())
bye();
}
void Connection::doDisconnect() {
if(!isConnected())
return;
-
+
shutdown(sock, SHUT_RDWR);
close(sock);
-
+
gnutls_deinit(session);
-
+
if(peer)
delete peer;
peer = 0;
-
+
state = DISCONNECTED;
}
struct pollfd Connection::getPollfd() const {
struct pollfd fd = {sock, (receiveComplete() ? 0 : POLLIN) | (sendQueueEmpty() ? 0 : POLLOUT), 0};
-
- if(state == HANDSHAKE)
+
+ if(state == HANDSHAKE || state == BYE)
fd.events = ((gnutls_record_get_direction(session) == 0) ? POLLIN : POLLOUT);
-
+
return fd;
}