summaryrefslogtreecommitdiffstats
path: root/src/Net
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2008-10-10 15:04:28 +0200
committerMatthias Schiffer <matthias@gamezock.de>2008-10-10 15:04:28 +0200
commitfcab8098d6a9a385e0e5edfb26f4abf615da77ca (patch)
tree7ae3ff0d47bab59a409ccebb036e339894493b80 /src/Net
parent535a6e799ee98e745c85c655c5db3279fd25c1bc (diff)
downloadmad-fcab8098d6a9a385e0e5edfb26f4abf615da77ca.tar
mad-fcab8098d6a9a385e0e5edfb26f4abf615da77ca.zip
FdManager hinzugef?gt und Verbindungsklassen angepasst
Diffstat (limited to 'src/Net')
-rw-r--r--src/Net/ClientConnection.cpp4
-rw-r--r--src/Net/Connection.cpp29
-rw-r--r--src/Net/Connection.h6
-rw-r--r--src/Net/FdManager.cpp102
-rw-r--r--src/Net/FdManager.h58
-rw-r--r--src/Net/Listener.cpp53
-rw-r--r--src/Net/Listener.h7
-rw-r--r--src/Net/Makefile.am4
-rw-r--r--src/Net/Makefile.in7
-rw-r--r--src/Net/ServerConnection.cpp4
10 files changed, 220 insertions, 54 deletions
diff --git a/src/Net/ClientConnection.cpp b/src/Net/ClientConnection.cpp
index 5c602e1..25673fd 100644
--- a/src/Net/ClientConnection.cpp
+++ b/src/Net/ClientConnection.cpp
@@ -18,7 +18,9 @@
*/
#include "ClientConnection.h"
+#include "FdManager.h"
#include "IPAddress.h"
+
#include <cstring>
#include <cerrno>
#include <sys/socket.h>
@@ -96,6 +98,8 @@ void ClientConnection::connect(const IPAddress &address, bool daemon0) throw(Com
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)sock);
+ FdManager::getFdManager()->registerFd(sock, sigc::mem_fun(this, &Connection::sendReceive));
+
handshake();
}
diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp
index 03e9f73..72f9848 100644
--- a/src/Net/Connection.cpp
+++ b/src/Net/Connection.cpp
@@ -18,6 +18,7 @@
*/
#include "Connection.h"
+#include "FdManager.h"
#include "IPAddress.h"
#include <cstring>
#include <sys/socket.h>
@@ -67,8 +68,11 @@ void Connection::doHandshake() {
int ret = gnutls_handshake(session);
if(ret < 0) {
- if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
+ if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
+ updateEvents();
return;
+ }
+
// TODO: Error
doDisconnect();
@@ -85,8 +89,10 @@ void Connection::doBye() {
int ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
if(ret < 0) {
- if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
+ if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
+ updateEvents();
return;
+ }
// TODO: Error
doDisconnect();
@@ -172,6 +178,8 @@ void Connection::doReceive() {
delete [] data;
}
+
+ updateEvents();
}
bool Connection::rawReceive(unsigned long length,
@@ -188,6 +196,8 @@ bool Connection::rawReceive(unsigned long length,
transR.transmitted = 0;
transR.notify = notify;
+ updateEvents();
+
return true;
}
@@ -215,6 +225,8 @@ void Connection::doSend() {
transS.pop();
}
}
+
+ updateEvents();
}
bool Connection::rawSend(const uint8_t *data, unsigned long length) {
@@ -225,7 +237,8 @@ bool Connection::rawSend(const uint8_t *data, unsigned long length) {
std::memcpy(trans.data, data, length);
transS.push(trans);
- doSend();
+ updateEvents();
+ doSend(); // TODO !!!
return true;
}
@@ -276,6 +289,8 @@ void Connection::doDisconnect() {
if(!isConnected())
return;
+ FdManager::getFdManager()->unregisterFd(sock);
+
shutdown(sock, SHUT_RDWR);
close(sock);
@@ -284,13 +299,13 @@ void Connection::doDisconnect() {
state = DISCONNECTED;
}
-struct pollfd Connection::getPollfd() const {
- struct pollfd fd = {sock, (receiveComplete() ? 0 : POLLIN) | (sendQueueEmpty() ? 0 : POLLOUT), 0};
+void Connection::updateEvents() const {
+ short events = (receiveComplete() ? 0 : POLLIN) | (sendQueueEmpty() ? 0 : POLLOUT);
if(state == HANDSHAKE || state == BYE)
- fd.events = ((gnutls_record_get_direction(session) == 0) ? POLLIN : POLLOUT);
+ events = ((gnutls_record_get_direction(session) == 0) ? POLLIN : POLLOUT);
- return fd;
+ FdManager::getFdManager()->setFdEvents(sock, events);
}
}
diff --git a/src/Net/Connection.h b/src/Net/Connection.h
index 77b8cc4..0d7e6cf 100644
--- a/src/Net/Connection.h
+++ b/src/Net/Connection.h
@@ -74,6 +74,8 @@ class Connection {
void bye();
+ void updateEvents() const;
+
// Prevent shallow copy
Connection(const Connection &o);
Connection& operator=(const Connection &o);
@@ -146,11 +148,9 @@ class Connection {
void disconnect();
- struct pollfd getPollfd() const;
-
bool send(const Packet &packet);
- void sendReceive(short events = POLLIN|POLLOUT);
+ void sendReceive(short events);
bool sendQueueEmpty() const {return transS.empty();}
diff --git a/src/Net/FdManager.cpp b/src/Net/FdManager.cpp
new file mode 100644
index 0000000..aab634d
--- /dev/null
+++ b/src/Net/FdManager.cpp
@@ -0,0 +1,102 @@
+/*
+ * FdManager.cpp
+ *
+ * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * 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 3 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/>.
+ */
+
+#include "FdManager.h"
+#include <signal.h>
+
+
+namespace Mad {
+namespace Net {
+
+FdManager FdManager::fdManager;
+
+
+FdManager::FdManager() {
+ // TODO Auto-generated constructor stub
+
+}
+
+FdManager::~FdManager() {
+ // TODO Auto-generated destructor stub
+}
+
+
+bool FdManager::registerFd(int fd, const sigc::slot<void, short> &handler, short events) {
+ struct pollfd pollfd = {fd, events, 0};
+
+ pollfds.insert(std::make_pair(fd, pollfd));
+
+ return handlers.insert(std::make_pair(fd, handler)).second;
+}
+
+bool FdManager::unregisterFd(int fd) {
+ pollfds.erase(fd);
+ return handlers.erase(fd);
+}
+
+bool FdManager::setFdEvents(int fd, short events) {
+ std::map<int, struct pollfd>::iterator pollfd = pollfds.find(fd);
+
+ if(pollfd == pollfds.end())
+ return false;
+
+ if(pollfd->second.events != events) {
+ pollfd->second.events = events;
+ interrupt();
+ }
+
+ return true;
+}
+
+short FdManager::getFdEvents(int fd) const {
+ std::map<int, struct pollfd>::const_iterator pollfd = pollfds.find(fd);
+
+ if(pollfd == pollfds.end())
+ return -1;
+
+ return pollfd->second.events;
+}
+
+void FdManager::interrupt() {
+ // TODO Implement this.
+}
+
+void FdManager::run() {
+ size_t count = pollfds.size();
+ struct pollfd *fdarray = new struct pollfd[count];
+
+ std::map<int, struct pollfd>::iterator pollfd = pollfds.begin();
+
+ for(size_t n = 0; n < count; ++n) {
+ fdarray[n] = pollfd->second;
+ ++pollfd;
+ }
+
+ if(poll(fdarray, count, -1) > 0) {
+ for(size_t n = 0; n < count; ++n) {
+ if(fdarray[n].revents)
+ handlers[fdarray[n].fd](fdarray[n].revents);
+ }
+ }
+
+ delete [] fdarray;
+}
+
+}
+}
diff --git a/src/Net/FdManager.h b/src/Net/FdManager.h
new file mode 100644
index 0000000..f6a528f
--- /dev/null
+++ b/src/Net/FdManager.h
@@ -0,0 +1,58 @@
+/*
+ * FdManager.h
+ *
+ * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * 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 3 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 MAD_NET_FDMANAGER_H_
+#define MAD_NET_FDMANAGER_H_
+
+#include <map>
+#include <poll.h>
+#include <sigc++/signal.h>
+
+namespace Mad {
+namespace Net {
+
+class FdManager {
+ private:
+ static FdManager fdManager;
+
+ std::map<int, struct pollfd> pollfds;
+ std::map<int, sigc::slot<void, short> > handlers;
+
+ FdManager();
+
+ public:
+ virtual ~FdManager();
+
+ static FdManager *getFdManager() {return &fdManager;}
+
+ bool registerFd(int fd, const sigc::slot<void, short> &handler, short events = 0);
+ bool unregisterFd(int fd);
+
+ bool setFdEvents(int fd, short events);
+ short getFdEvents(int fd) const;
+
+ void interrupt();
+
+ void run();
+};
+
+}
+}
+
+#endif /* MAD_NET_FDMANAGER_H_ */
diff --git a/src/Net/Listener.cpp b/src/Net/Listener.cpp
index 9233a79..ed820d0 100644
--- a/src/Net/Listener.cpp
+++ b/src/Net/Listener.cpp
@@ -18,7 +18,9 @@
*/
#include "Listener.h"
+#include "FdManager.h"
#include "ServerConnection.h"
+
#include <cerrno>
#include <cstring>
#include <fcntl.h>
@@ -26,6 +28,19 @@
namespace Mad {
namespace Net {
+void Listener::acceptHandler(int) {
+ int sd;
+ struct sockaddr_in sa;
+ socklen_t addrlen = sizeof(sa);
+
+
+ while((sd = accept(sock, (struct sockaddr*)&sa, &addrlen)) >= 0) {
+ connections.push_back(new ServerConnection(sd, IPAddress(sa), dh_params, x905CertFile, x905KeyFile));
+
+ addrlen = sizeof(sa);
+ }
+}
+
Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0, const IPAddress &address0) throw(Common::Exception)
: x905CertFile(x905CertFile0), x905KeyFile(x905KeyFile0), address(address0) {
gnutls_dh_params_init(&dh_params);
@@ -62,6 +77,8 @@ Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyF
throw Common::Exception("listen()", Common::Exception::INTERNAL_ERRNO, errno);
}
+
+ FdManager::getFdManager()->registerFd(sock, sigc::mem_fun(this, &Listener::acceptHandler), POLLIN);
}
Listener::~Listener() {
@@ -76,43 +93,9 @@ Listener::~Listener() {
gnutls_dh_params_deinit(dh_params);
}
-std::vector<struct pollfd> Listener::getPollfds() const {
- std::vector<struct pollfd> pollfds;
-
- struct pollfd fd = {sock, POLLIN, 0};
- pollfds.push_back(fd);
-
- for(std::list<ServerConnection*>::const_iterator con = connections.begin(); con != connections.end(); ++con)
- pollfds.push_back((*con)->getPollfd());
-
- return pollfds;
-}
-
-ServerConnection* Listener::getConnection(const std::map<int,const short*> &pollfdMap) {
+ServerConnection* Listener::getConnection() {
// TODO: Logging
- int sd;
- struct sockaddr_in sa;
- socklen_t addrlen = sizeof(sa);
-
-
- while((sd = accept(sock, (struct sockaddr*)&sa, &addrlen)) >= 0) {
- connections.push_back(new ServerConnection(sd, IPAddress(sa), dh_params, x905CertFile, x905KeyFile));
-
- addrlen = sizeof(sa);
- }
-
- for(std::list<ServerConnection*>::iterator con = connections.begin(); con != connections.end(); ++con) {
- std::map<int,const short*>::const_iterator events = pollfdMap.find((*con)->getSocket());
-
- if(events != pollfdMap.end()) {
- if(*events->second)
- (*con)->sendReceive(*events->second);
- }
- else
- (*con)->sendReceive();
- }
-
for(std::list<ServerConnection*>::iterator con = connections.begin(); con != connections.end();) {
if(!(*con)->isConnected()) {
delete *con;
diff --git a/src/Net/Listener.h b/src/Net/Listener.h
index 9c4ddab..a095439 100644
--- a/src/Net/Listener.h
+++ b/src/Net/Listener.h
@@ -24,7 +24,6 @@
#include <Common/Exception.h>
#include <gnutls/gnutls.h>
-#include <poll.h>
#include <list>
#include <vector>
#include <map>
@@ -45,6 +44,8 @@ class Listener {
std::list<ServerConnection*> connections;
+ void acceptHandler(int);
+
// Prevent shallow copy
Listener(const Listener &o);
Listener& operator=(const Listener &o);
@@ -53,9 +54,7 @@ class Listener {
Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0, const IPAddress &address0 = IPAddress()) throw(Common::Exception);
virtual ~Listener();
- std::vector<struct pollfd> getPollfds() const;
-
- ServerConnection* getConnection(const std::map<int,const short*> &pollfdMap);
+ ServerConnection* getConnection();
};
}
diff --git a/src/Net/Makefile.am b/src/Net/Makefile.am
index 84ef644..907b47c 100644
--- a/src/Net/Makefile.am
+++ b/src/Net/Makefile.am
@@ -1,7 +1,7 @@
SUBDIRS = Packets
noinst_LTLIBRARIES = libnet.la
-libnet_la_SOURCES = ClientConnection.cpp ServerConnection.cpp Connection.cpp IPAddress.cpp Listener.cpp Packet.cpp
+libnet_la_SOURCES = ClientConnection.cpp ServerConnection.cpp Connection.cpp FdManager.cpp IPAddress.cpp Listener.cpp Packet.cpp
libnet_la_LIBADD = Packets/libpackets.la
-noinst_HEADERS = ClientConnection.h ServerConnection.h Connection.h IPAddress.h Listener.h Packet.h
+noinst_HEADERS = ClientConnection.h ServerConnection.h Connection.h FdManager.h IPAddress.h Listener.h Packet.h
diff --git a/src/Net/Makefile.in b/src/Net/Makefile.in
index a0eb761..6e9051f 100644
--- a/src/Net/Makefile.in
+++ b/src/Net/Makefile.in
@@ -49,7 +49,7 @@ CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libnet_la_DEPENDENCIES = Packets/libpackets.la
am_libnet_la_OBJECTS = ClientConnection.lo ServerConnection.lo \
- Connection.lo IPAddress.lo Listener.lo Packet.lo
+ Connection.lo FdManager.lo IPAddress.lo Listener.lo Packet.lo
libnet_la_OBJECTS = $(am_libnet_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -199,9 +199,9 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = Packets
noinst_LTLIBRARIES = libnet.la
-libnet_la_SOURCES = ClientConnection.cpp ServerConnection.cpp Connection.cpp IPAddress.cpp Listener.cpp Packet.cpp
+libnet_la_SOURCES = ClientConnection.cpp ServerConnection.cpp Connection.cpp FdManager.cpp IPAddress.cpp Listener.cpp Packet.cpp
libnet_la_LIBADD = Packets/libpackets.la
-noinst_HEADERS = ClientConnection.h ServerConnection.h Connection.h IPAddress.h Listener.h Packet.h
+noinst_HEADERS = ClientConnection.h ServerConnection.h Connection.h FdManager.h IPAddress.h Listener.h Packet.h
all: all-recursive
.SUFFIXES:
@@ -255,6 +255,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientConnection.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Connection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FdManager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IPAddress.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Listener.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Packet.Plo@am__quote@
diff --git a/src/Net/ServerConnection.cpp b/src/Net/ServerConnection.cpp
index fbdd69f..05cc861 100644
--- a/src/Net/ServerConnection.cpp
+++ b/src/Net/ServerConnection.cpp
@@ -18,7 +18,9 @@
*/
#include "ServerConnection.h"
+#include "FdManager.h"
#include "IPAddress.h"
+
#include <cstring>
#include <cerrno>
#include <sys/socket.h>
@@ -71,6 +73,8 @@ ServerConnection::ServerConnection(int sock0, const IPAddress &address, gnutls_d
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)sock);
+ FdManager::getFdManager()->registerFd(sock, sigc::mem_fun(this, &Connection::sendReceive));
+
handshake();
}