Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Donald Haase
Cockatrice
Commits
0719d4c6
Commit
0719d4c6
authored
Mar 04, 2012
by
Max-Wilhelm Bruker
Browse files
client-side SSL works, thread initialization needs fixing
parent
c9b66e42
Changes
5
Hide whitespace changes
Inline
Side-by-side
servatrice/src/networkserverinterface.cpp
View file @
0719d4c6
...
...
@@ -9,14 +9,17 @@
#include
"pb/event_server_complete_list.pb.h"
#include
<google/protobuf/descriptor.h>
NetworkServerInterface
::
NetworkServerInterface
(
Servatrice
*
_server
,
QSslSocket
*
_socket
)
:
QObject
(),
server
(
_server
),
socket
(
_socket
),
messageInProgress
(
false
)
void
NetworkServerInterface
::
sharedCtor
()
{
connect
(
socket
,
SIGNAL
(
readyRead
()),
this
,
SLOT
(
readClient
()));
connect
(
socket
,
SIGNAL
(
disconnected
()),
this
,
SLOT
(
deleteLater
()));
connect
(
socket
,
SIGNAL
(
error
(
QAbstractSocket
::
SocketError
)),
this
,
SLOT
(
catchSocketError
(
QAbstractSocket
::
SocketError
)));
connect
(
this
,
SIGNAL
(
outputBufferChanged
()),
this
,
SLOT
(
flushOutputBuffer
()),
Qt
::
QueuedConnection
);
}
NetworkServerInterface
::
NetworkServerInterface
(
Servatrice
*
_server
,
QSslSocket
*
_socket
)
:
QObject
(),
server
(
_server
),
socket
(
_socket
),
messageInProgress
(
false
)
{
Event_ServerCompleteList
event
;
event
.
set_server_id
(
server
->
getServerId
());
...
...
@@ -46,6 +49,29 @@ NetworkServerInterface::NetworkServerInterface(Servatrice *_server, QSslSocket *
server
->
serverMutex
.
unlock
();
}
NetworkServerInterface
::
NetworkServerInterface
(
const
QString
&
peerHostName
,
const
QString
&
peerAddress
,
int
peerPort
,
Servatrice
*
_server
,
QSslSocket
*
_socket
)
:
QObject
(),
server
(
_server
),
socket
(
_socket
),
messageInProgress
(
false
)
{
sharedCtor
();
socket
->
connectToHostEncrypted
(
peerAddress
,
peerPort
,
peerHostName
);
if
(
!
socket
->
waitForConnected
(
5000
))
{
qDebug
()
<<
"[SN] Socket error:"
<<
socket
->
errorString
();
deleteLater
();
return
;
}
if
(
!
socket
->
waitForEncrypted
(
5000
))
{
QList
<
QSslError
>
sslErrors
(
socket
->
sslErrors
());
if
(
sslErrors
.
isEmpty
())
qDebug
()
<<
"[SN] SSL handshake timeout, terminating connection"
;
else
qDebug
()
<<
"[SN] SSL errors:"
<<
sslErrors
;
deleteLater
();
return
;
}
server
->
addNetworkServerInterface
(
this
);
}
NetworkServerInterface
::~
NetworkServerInterface
()
{
logger
->
logMessage
(
"[SN] session ended"
,
this
);
...
...
@@ -56,6 +82,7 @@ NetworkServerInterface::~NetworkServerInterface()
void
NetworkServerInterface
::
flushOutputBuffer
()
{
QMutexLocker
locker
(
&
outputBufferMutex
);
qDebug
(
"FLUSH"
);
if
(
outputBuffer
.
isEmpty
())
return
;
server
->
incTxBytes
(
outputBuffer
.
size
());
...
...
@@ -96,7 +123,7 @@ void NetworkServerInterface::readClient()
void
NetworkServerInterface
::
catchSocketError
(
QAbstractSocket
::
SocketError
socketError
)
{
qDebug
()
<<
"Socket error:"
<<
socketError
;
qDebug
()
<<
"
[SN]
Socket error:"
<<
socketError
;
deleteLater
();
}
...
...
@@ -112,11 +139,14 @@ void NetworkServerInterface::transmitMessage(const ServerNetworkMessage &item)
buf
.
data
()[
1
]
=
(
unsigned
char
)
(
size
>>
16
);
buf
.
data
()[
0
]
=
(
unsigned
char
)
(
size
>>
24
);
QMutexLocker
locker
(
&
outputBufferMutex
);
outputBufferMutex
.
lock
(
);
outputBuffer
.
append
(
buf
);
outputBufferMutex
.
unlock
();
qDebug
(
"TRANSMIT"
);
emit
outputBufferChanged
();
}
void
NetworkServerInterface
::
processMessage
(
const
ServerNetworkMessage
&
item
)
{
qDebug
()
<<
QString
::
fromStdString
(
item
.
DebugString
());
}
servatrice/src/networkserverinterface.h
View file @
0719d4c6
...
...
@@ -25,8 +25,10 @@ private:
int
messageLength
;
void
processMessage
(
const
ServerNetworkMessage
&
item
);
void
sharedCtor
();
public:
NetworkServerInterface
(
Servatrice
*
_server
,
QSslSocket
*
_socket
);
NetworkServerInterface
(
const
QString
&
peerHostName
,
const
QString
&
peerAddress
,
int
peerPort
,
Servatrice
*
_server
,
QSslSocket
*
_socket
);
~
NetworkServerInterface
();
void
transmitMessage
(
const
ServerNetworkMessage
&
item
);
...
...
servatrice/src/networkserverthread.cpp
View file @
0719d4c6
...
...
@@ -4,9 +4,16 @@
#include
"servatrice.h"
#include
"main.h"
#include
<QSslSocket>
#include
<QSslError>
NetworkServerThread
::
NetworkServerThread
(
int
_socketDescriptor
,
Servatrice
*
_server
,
const
QSslCertificate
&
_cert
,
const
QSslKey
&
_privateKey
,
QObject
*
parent
)
:
QThread
(
parent
),
server
(
_server
),
socketDescriptor
(
_socketDescriptor
),
cert
(
_cert
),
privateKey
(
_privateKey
)
:
QThread
(
parent
),
server
(
_server
),
socketDescriptor
(
_socketDescriptor
),
cert
(
_cert
),
privateKey
(
_privateKey
),
connectionType
(
ServerType
)
{
connect
(
this
,
SIGNAL
(
finished
()),
this
,
SLOT
(
deleteLater
()));
}
NetworkServerThread
::
NetworkServerThread
(
const
QString
&
_hostName
,
const
QString
&
_address
,
int
_port
,
const
QSslCertificate
&
_peerCert
,
Servatrice
*
_server
,
const
QSslCertificate
&
_cert
,
const
QSslKey
&
_privateKey
,
QObject
*
parent
)
:
QThread
(
parent
),
server
(
_server
),
cert
(
_cert
),
privateKey
(
_privateKey
),
peerHostName
(
_hostName
),
peerAddress
(
_address
),
peerPort
(
_port
),
peerCert
(
_peerCert
),
connectionType
(
ClientType
)
{
connect
(
this
,
SIGNAL
(
finished
()),
this
,
SLOT
(
deleteLater
()));
}
...
...
@@ -22,10 +29,38 @@ NetworkServerThread::~NetworkServerThread()
void
NetworkServerThread
::
run
()
{
socket
=
new
QSslSocket
;
socket
->
setSocketDescriptor
(
socketDescriptor
);
socket
->
setLocalCertificate
(
cert
);
socket
->
setPrivateKey
(
privateKey
);
if
(
connectionType
==
ClientType
)
try
{
initClient
();
}
catch
(
bool
)
{
usleep
(
100000
);
initWaitCondition
.
wakeAll
();
return
;
}
else
try
{
initServer
();
}
catch
(
bool
)
{
return
;
}
interface
=
new
NetworkServerInterface
(
server
,
socket
);
connect
(
interface
,
SIGNAL
(
destroyed
()),
this
,
SLOT
(
deleteLater
()));
if
(
connectionType
==
ClientType
)
{
usleep
(
100000
);
initWaitCondition
.
wakeAll
();
}
exec
();
}
void
NetworkServerThread
::
initServer
()
{
socket
->
setSocketDescriptor
(
socketDescriptor
);
logger
->
logMessage
(
QString
(
"[SN] incoming connection: %1"
).
arg
(
socket
->
peerAddress
().
toString
()));
QList
<
ServerProperties
>
serverList
=
server
->
getServerList
();
...
...
@@ -52,9 +87,14 @@ void NetworkServerThread::run()
logger
->
logMessage
(
QString
(
"[SN] Authentication failed, terminating connection"
));
return
;
}
}
void
NetworkServerThread
::
initClient
()
{
qDebug
()
<<
"[SN] Connecting to "
<<
peerAddress
<<
":"
<<
peerPort
;
interface
=
new
NetworkServerInterface
(
server
,
socket
)
;
connect
(
interface
,
SIGNAL
(
destroyed
()),
this
,
SLOT
(
deleteLater
()
));
exec
();
QList
<
QSslError
>
expectedErrors
;
expectedErrors
.
append
(
QSslError
(
QSslError
::
SelfSignedCertificate
,
peerCert
));
socket
->
ignoreSslErrors
(
expectedErrors
);
}
servatrice/src/networkserverthread.h
View file @
0719d4c6
...
...
@@ -4,6 +4,7 @@
#include
<QThread>
#include
<QSslCertificate>
#include
<QSslKey>
#include
<QWaitCondition>
class
Servatrice
;
class
NetworkServerInterface
;
...
...
@@ -16,11 +17,20 @@ private:
NetworkServerInterface
*
interface
;
QSslCertificate
cert
;
QSslKey
privateKey
;
QString
peerHostName
,
peerAddress
;
int
peerPort
;
QSslCertificate
peerCert
;
int
socketDescriptor
;
QSslSocket
*
socket
;
enum
ConnectionType
{
ClientType
,
ServerType
}
connectionType
;
void
initClient
();
void
initServer
();
public:
NetworkServerThread
(
int
_socketDescriptor
,
Servatrice
*
_server
,
const
QSslCertificate
&
_cert
,
const
QSslKey
&
_privateKey
,
QObject
*
parent
=
0
);
NetworkServerThread
(
const
QString
&
_hostName
,
const
QString
&
_address
,
int
_port
,
const
QSslCertificate
&
peerCert
,
Servatrice
*
_server
,
const
QSslCertificate
&
_cert
,
const
QSslKey
&
_privateKey
,
QObject
*
parent
=
0
);
~
NetworkServerThread
();
QWaitCondition
initWaitCondition
;
protected:
void
run
();
};
...
...
servatrice/src/servatrice.cpp
View file @
0719d4c6
...
...
@@ -57,28 +57,8 @@ void Servatrice_NetworkServer::incomingConnection(int socketDescriptor)
Servatrice
::
Servatrice
(
QSettings
*
_settings
,
QObject
*
parent
)
:
Server
(
parent
),
dbMutex
(
QMutex
::
Recursive
),
settings
(
_settings
),
uptime
(
0
),
shutdownTimer
(
0
)
{
pingClock
=
new
QTimer
(
this
);
connect
(
pingClock
,
SIGNAL
(
timeout
()),
this
,
SIGNAL
(
pingClockTimeout
()));
pingClock
->
start
(
1000
);
serverName
=
settings
->
value
(
"server/name"
).
toString
();
serverId
=
settings
->
value
(
"server/id"
,
0
).
toInt
();
int
statusUpdateTime
=
settings
->
value
(
"server/statusupdate"
).
toInt
();
statusUpdateClock
=
new
QTimer
(
this
);
connect
(
statusUpdateClock
,
SIGNAL
(
timeout
()),
this
,
SLOT
(
statusUpdate
()));
if
(
statusUpdateTime
!=
0
)
{
qDebug
()
<<
"Starting status update clock, interval "
<<
statusUpdateTime
<<
" ms"
;
statusUpdateClock
->
start
(
statusUpdateTime
);
}
threaded
=
settings
->
value
(
"server/threaded"
,
false
).
toInt
();
gameServer
=
new
Servatrice_GameServer
(
this
,
threaded
,
this
);
const
int
gamePort
=
settings
->
value
(
"server/port"
,
4747
).
toInt
();
qDebug
()
<<
"Starting server on port"
<<
gamePort
;
if
(
gameServer
->
listen
(
QHostAddress
::
Any
,
gamePort
))
qDebug
()
<<
"Server listening."
;
else
qDebug
()
<<
"gameServer->listen(): Error."
;
const
QString
authenticationMethodStr
=
settings
->
value
(
"authentication/method"
).
toString
();
if
(
authenticationMethodStr
==
"sql"
)
...
...
@@ -98,37 +78,6 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent)
updateServerList
();
clearSessionTables
();
try
{
if
(
settings
->
value
(
"servernetwork/active"
,
0
).
toInt
())
{
qDebug
()
<<
"Connecting to server network."
;
const
QString
certFileName
=
settings
->
value
(
"servernetwork/ssl_cert"
).
toString
();
const
QString
keyFileName
=
settings
->
value
(
"servernetwork/ssl_key"
).
toString
();
qDebug
()
<<
"Loading certificate..."
;
QFile
certFile
(
certFileName
);
if
(
!
certFile
.
open
(
QIODevice
::
ReadOnly
))
throw
QString
(
"Error opening certificate file: %1"
).
arg
(
certFileName
);
QSslCertificate
cert
(
&
certFile
);
if
(
!
cert
.
isValid
())
throw
(
QString
(
"Invalid certificate."
));
qDebug
()
<<
"Loading private key..."
;
QFile
keyFile
(
keyFileName
);
if
(
!
keyFile
.
open
(
QIODevice
::
ReadOnly
))
throw
QString
(
"Error opening private key file: %1"
).
arg
(
keyFileName
);
QSslKey
key
(
&
keyFile
,
QSsl
::
Rsa
,
QSsl
::
Pem
,
QSsl
::
PrivateKey
);
if
(
key
.
isNull
())
throw
QString
(
"Invalid private key."
);
const
int
networkPort
=
settings
->
value
(
"servernetwork/port"
,
14747
).
toInt
();
qDebug
()
<<
"Starting network server on port"
<<
networkPort
;
networkServer
=
new
Servatrice_NetworkServer
(
this
,
cert
,
key
,
this
);
if
(
networkServer
->
listen
(
QHostAddress
::
Any
,
networkPort
))
qDebug
()
<<
"Network server listening."
;
else
throw
QString
(
"networkServer->listen(): Error."
);
}
}
catch
(
QString
error
)
{
qDebug
()
<<
"ERROR --"
<<
error
;
}
int
size
=
settings
->
beginReadArray
(
"rooms"
);
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
settings
->
setArrayIndex
(
i
);
...
...
@@ -164,6 +113,76 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent)
maxMessageCountPerInterval
=
settings
->
value
(
"security/max_message_count_per_interval"
).
toInt
();
maxMessageSizePerInterval
=
settings
->
value
(
"security/max_message_size_per_interval"
).
toInt
();
maxGamesPerUser
=
settings
->
value
(
"security/max_games_per_user"
).
toInt
();
try
{
if
(
settings
->
value
(
"servernetwork/active"
,
0
).
toInt
())
{
qDebug
()
<<
"Connecting to server network."
;
const
QString
certFileName
=
settings
->
value
(
"servernetwork/ssl_cert"
).
toString
();
const
QString
keyFileName
=
settings
->
value
(
"servernetwork/ssl_key"
).
toString
();
qDebug
()
<<
"Loading certificate..."
;
QFile
certFile
(
certFileName
);
if
(
!
certFile
.
open
(
QIODevice
::
ReadOnly
))
throw
QString
(
"Error opening certificate file: %1"
).
arg
(
certFileName
);
QSslCertificate
cert
(
&
certFile
);
if
(
!
cert
.
isValid
())
throw
(
QString
(
"Invalid certificate."
));
qDebug
()
<<
"Loading private key..."
;
QFile
keyFile
(
keyFileName
);
if
(
!
keyFile
.
open
(
QIODevice
::
ReadOnly
))
throw
QString
(
"Error opening private key file: %1"
).
arg
(
keyFileName
);
QSslKey
key
(
&
keyFile
,
QSsl
::
Rsa
,
QSsl
::
Pem
,
QSsl
::
PrivateKey
);
if
(
key
.
isNull
())
throw
QString
(
"Invalid private key."
);
const
int
networkPort
=
settings
->
value
(
"servernetwork/port"
,
14747
).
toInt
();
qDebug
()
<<
"Starting network server on port"
<<
networkPort
;
networkServer
=
new
Servatrice_NetworkServer
(
this
,
cert
,
key
,
this
);
if
(
networkServer
->
listen
(
QHostAddress
::
Any
,
networkPort
))
qDebug
()
<<
"Network server listening."
;
else
throw
QString
(
"networkServer->listen(): Error."
);
QMutableListIterator
<
ServerProperties
>
serverIterator
(
serverList
);
while
(
serverIterator
.
hasNext
())
{
const
ServerProperties
&
prop
=
serverIterator
.
next
();
if
(
prop
.
cert
==
cert
)
{
serverIterator
.
remove
();
continue
;
}
NetworkServerThread
*
thread
=
new
NetworkServerThread
(
prop
.
hostname
,
prop
.
address
.
toString
(),
prop
.
controlPort
,
prop
.
cert
,
this
,
cert
,
key
);
thread
->
start
();
QMutex
initMutex
;
initMutex
.
lock
();
thread
->
initWaitCondition
.
wait
(
&
initMutex
);
}
}
}
catch
(
QString
error
)
{
qDebug
()
<<
"ERROR --"
<<
error
;
}
pingClock
=
new
QTimer
(
this
);
connect
(
pingClock
,
SIGNAL
(
timeout
()),
this
,
SIGNAL
(
pingClockTimeout
()));
pingClock
->
start
(
1000
);
int
statusUpdateTime
=
settings
->
value
(
"server/statusupdate"
).
toInt
();
statusUpdateClock
=
new
QTimer
(
this
);
connect
(
statusUpdateClock
,
SIGNAL
(
timeout
()),
this
,
SLOT
(
statusUpdate
()));
if
(
statusUpdateTime
!=
0
)
{
qDebug
()
<<
"Starting status update clock, interval "
<<
statusUpdateTime
<<
" ms"
;
statusUpdateClock
->
start
(
statusUpdateTime
);
}
threaded
=
settings
->
value
(
"server/threaded"
,
false
).
toInt
();
gameServer
=
new
Servatrice_GameServer
(
this
,
threaded
,
this
);
const
int
gamePort
=
settings
->
value
(
"server/port"
,
4747
).
toInt
();
qDebug
()
<<
"Starting server on port"
<<
gamePort
;
if
(
gameServer
->
listen
(
QHostAddress
::
Any
,
gamePort
))
qDebug
()
<<
"Server listening."
;
else
qDebug
()
<<
"gameServer->listen(): Error."
;
}
Servatrice
::~
Servatrice
()
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment