summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-08-27 22:43:37 +0200
committerMatthias Schiffer <matthias@gamezock.de>2009-08-27 22:43:37 +0200
commitbf56fa726e1d6ed228fde841e6312d61122174da (patch)
tree662195b887f69615571957cbaedd5c07aee7eef6
parent96b69222fa0c22d0eaefaae291e78913b2ae13e9 (diff)
downloadmad-bf56fa726e1d6ed228fde841e6312d61122174da.tar
mad-bf56fa726e1d6ed228fde841e6312d61122174da.zip
Connection: Noch eine Race Condition gefixt
-rw-r--r--src/Net/ClientConnection.cpp2
-rw-r--r--src/Net/Connection.cpp13
-rw-r--r--src/Net/Connection.h35
-rw-r--r--src/Net/Listener.cpp4
-rw-r--r--src/Server/ConnectionManager.cpp2
-rw-r--r--src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp4
6 files changed, 47 insertions, 13 deletions
diff --git a/src/Net/ClientConnection.cpp b/src/Net/ClientConnection.cpp
index 10a03f1..3d218e7 100644
--- a/src/Net/ClientConnection.cpp
+++ b/src/Net/ClientConnection.cpp
@@ -43,7 +43,7 @@ void ClientConnection::connect(const boost::asio::ip::tcp::endpoint &address) th
}
peer = address;
- _setState(CONNECT);
+ _setState(HANDSHAKE);
socket.lowest_layer().async_connect(address, boost::bind(&ClientConnection::handleConnect, boost::dynamic_pointer_cast<ClientConnection>(thisPtr.lock()), boost::asio::placeholders::error));
}
diff --git a/src/Net/Connection.cpp b/src/Net/Connection.cpp
index fc917d4..94b5493 100644
--- a/src/Net/Connection.cpp
+++ b/src/Net/Connection.cpp
@@ -44,17 +44,20 @@ void Connection::handleHandshake(const boost::system::error_code& error) {
{
boost::lock_guard<boost::shared_mutex> lock(connectionLock);
- _setState(CONNECTED);
+ _setState(CONNECT);
receiving = false;
sending = 0;
received = 0;
- }
- connectedSignal.emit();
+ connectedSignal.emit();
- enterReceiveLoop();
+ if(dontStart)
+ return;
+ }
+
+ startReceive();
}
void Connection::handleShutdown(const boost::system::error_code& error) {
@@ -73,7 +76,7 @@ void Connection::enterReceiveLoop() {
{
boost::lock_guard<boost::shared_mutex> lock(connectionLock);
- if(!_isConnected() || _isDisconnecting())
+ if(state != CONNECTED)
return;
}
diff --git a/src/Net/Connection.h b/src/Net/Connection.h
index 51f40b0..add10b7 100644
--- a/src/Net/Connection.h
+++ b/src/Net/Connection.h
@@ -44,7 +44,7 @@ class MAD_NET_EXPORT Connection : boost::noncopyable {
friend class Listener;
enum State {
- DISCONNECTED, CONNECT, CONNECTED, DISCONNECT, SHUTDOWN
+ DISCONNECTED, HANDSHAKE, CONNECT, CONNECTED, DISCONNECT, SHUTDOWN
};
private:
@@ -69,6 +69,8 @@ class MAD_NET_EXPORT Connection : boost::noncopyable {
State state;
+ bool dontStart;
+
boost::scoped_ptr<boost::array<boost::uint8_t, 1024*1024> > receiveBuffer;
std::size_t received;
@@ -80,7 +82,7 @@ class MAD_NET_EXPORT Connection : boost::noncopyable {
bool receiving;
unsigned long sending;
-
+
void enterReceiveLoop();
void handleHeaderReceive(const boost::shared_array<boost::uint8_t> &data);
@@ -107,7 +109,7 @@ class MAD_NET_EXPORT Connection : boost::noncopyable {
bool _isConnected() const {return (state != DISCONNECTED);}
bool _isConnecting() const {
- return (state == CONNECT);
+ return (state == HANDSHAKE || state == CONNECT);
}
bool _isDisconnecting() const {
@@ -133,7 +135,9 @@ class MAD_NET_EXPORT Connection : boost::noncopyable {
}
Connection(Core::Application *application0, boost::shared_ptr<boost::asio::ssl::context> context0) :
- application(application0), state(DISCONNECTED), receiveBuffer(new boost::array<boost::uint8_t, 1024*1024>), receiveSignal(application), connectedSignal(application),
+ application(application0), state(DISCONNECTED), dontStart(false),
+ receiveBuffer(new boost::array<boost::uint8_t, 1024*1024>),
+ receiveSignal(application), connectedSignal(application),
disconnectedSignal(application), context(context0), socket(application->getIOService(), *context) {}
static boost::shared_ptr<Connection> create(Core::Application *application, boost::shared_ptr<boost::asio::ssl::context> context) {
@@ -192,6 +196,29 @@ class MAD_NET_EXPORT Connection : boost::noncopyable {
return peer;
}
+ void setStart(bool start = true) {
+ boost::lock_guard<boost::shared_mutex> lock(connectionLock);
+
+ dontStart = !start;
+ }
+
+ void unsetStart() {
+ setStart(false);
+ }
+
+ void startReceive() {
+ {
+ boost::lock_guard<boost::shared_mutex> lock(connectionLock);
+
+ if(state != CONNECT)
+ return;
+
+ _setState(CONNECTED);
+ }
+
+ enterReceiveLoop();
+ }
+
void disconnect();
bool send(const Packet &packet);
diff --git a/src/Net/Listener.cpp b/src/Net/Listener.cpp
index b3974d1..a67e608 100644
--- a/src/Net/Listener.cpp
+++ b/src/Net/Listener.cpp
@@ -29,6 +29,8 @@ namespace Net {
void Listener::accept() {
boost::shared_ptr<Connection> con(Connection::create(application, context));
+ con->unsetStart();
+
acceptor.async_accept(con->socket.lowest_layer(), boost::bind(&Listener::handleAccept, this, boost::asio::placeholders::error, con));
}
@@ -41,7 +43,7 @@ void Listener::handleAccept(const boost::system::error_code &error, boost::share
{
boost::lock_guard<boost::shared_mutex> conLock(con->connectionLock);
- con->_setState(Connection::CONNECT);
+ con->_setState(Connection::HANDSHAKE);
Core::Signals::Connection con1 = con->connectSignalConnected(boost::bind(&Listener::handleConnect, this, con));
Core::Signals::Connection con2 = con->connectSignalDisconnected(boost::bind(&Listener::handleDisconnect, this, con));
diff --git a/src/Server/ConnectionManager.cpp b/src/Server/ConnectionManager.cpp
index 27b65c2..cb7376c 100644
--- a/src/Server/ConnectionManager.cpp
+++ b/src/Server/ConnectionManager.cpp
@@ -198,6 +198,8 @@ void ConnectionManager::handleNewConnection(boost::shared_ptr<Net::Connection> c
connections.insert(connection);
application->getRequestManager()->registerConnection(connection.get());
+
+ con->startReceive();
}
void ConnectionManager::handleDisconnect(boost::weak_ptr<ServerConnection> con) {
diff --git a/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp
index 39f2672..5878362 100644
--- a/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp
+++ b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp
@@ -28,9 +28,9 @@ namespace AuthBackendChallengeResponse {
const std::string AuthBackendChallengeResponse::methodName = "Challenge-Response";
AuthBackendChallengeResponse::AuthContextChallengeResponse::AuthContextChallengeResponse(AuthBackendChallengeResponse *backend) : authenticated(false) {
- challenge.reserve(20);
+ challenge.reserve(32);
- for(int i = 0; i < 20; ++i)
+ for(int i = 0; i < 32; ++i)
challenge.push_back(backend->randomGenerator());
}