diff options
Diffstat (limited to 'src/Net/ServerConnection.cpp')
-rw-r--r-- | src/Net/ServerConnection.cpp | 58 |
1 files changed, 14 insertions, 44 deletions
diff --git a/src/Net/ServerConnection.cpp b/src/Net/ServerConnection.cpp index dd25af1..4ad6215 100644 --- a/src/Net/ServerConnection.cpp +++ b/src/Net/ServerConnection.cpp @@ -22,7 +22,7 @@ #include <cstring> #include <cerrno> #include <sys/socket.h> -#include <sys/select.h> +#include <fcntl.h> namespace Mad { namespace Net { @@ -54,14 +54,13 @@ void ServerConnection::connectionHeaderReceiveHandler(const void *data, unsigned rawSend(reinterpret_cast<unsigned char*>(&header2), sizeof(header2)); - connecting = false; enterReceiveLoop(); } void ServerConnection::listen(const IPAddress &address) throw(ConnectionException) { const int kx_list[] = {GNUTLS_KX_ANON_DH, 0}; - if(connected) + if(isConnected()) disconnect(); int listen_sock = socket(PF_INET, SOCK_STREAM, 0); @@ -97,10 +96,18 @@ void ServerConnection::listen(const IPAddress &address) throw(ConnectionExceptio close(listen_sock); - *peer = IPAddress(address); + // Set non-blocking flag + int flags = fcntl(sock, F_GETFL, 0); + + if(flags < 0) { + close(sock); + + throw ConnectionException("fcntl()", std::strerror(errno)); + } + + fcntl(sock, F_SETFL, flags | O_NONBLOCK); - connected = true; - connecting = true; + *peer = IPAddress(address); gnutls_init(&session, GNUTLS_SERVER); @@ -110,45 +117,8 @@ void ServerConnection::listen(const IPAddress &address) throw(ConnectionExceptio gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_ptr(session, reinterpret_cast<gnutls_transport_ptr_t>(sock)); - - int ret = gnutls_handshake(session); - if(ret < 0) { - disconnect(); - - throw ConnectionException("gnutls_handshake()", gnutls_strerror(ret)); - } - - rawReceive(sizeof(ConnectionHeader), sigc::mem_fun(this, &ServerConnection::connectionHeaderReceiveHandler)); -} - -void ServerConnection::disconnect() { - if(!connected) - return; - - gnutls_bye(session, GNUTLS_SHUT_RDWR); - - shutdown(sock, SHUT_RDWR); - close(sock); - - gnutls_deinit(session); - - delete peer; - - connected = false; - connecting = false; -} - -bool ServerConnection::dataPending() const { - if(!connected) - return false; - - fd_set fds; - FD_ZERO(&fds); - FD_SET(sock, &fds); - - struct timeval timeout = {0, 0}; - return (select(sock + 1, &fds, NULL, NULL, &timeout) == 1); + handshake(); } } |