diff options
Diffstat (limited to 'src/Net/ClientConnection.cpp')
-rw-r--r-- | src/Net/ClientConnection.cpp | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/src/Net/ClientConnection.cpp b/src/Net/ClientConnection.cpp index 7fdfd68..a3447a0 100644 --- a/src/Net/ClientConnection.cpp +++ b/src/Net/ClientConnection.cpp @@ -31,69 +31,73 @@ void ClientConnection::connectionHeaderReceiveHandler(const void *data, unsigned if(length != sizeof(ConnectionHeader)) // Error... disconnect return; - + const ConnectionHeader *header = reinterpret_cast<const ConnectionHeader*>(data); - + if(header->m != 'M' || header->a != 'A' || header->d != 'D') // Error... disconnect return; - + if(header->protVerMin != 1) // Unsupported protocol... disconnect return; - + enterReceiveLoop(); } void ClientConnection::connectionHeader() { ConnectionHeader header = {'M', 'A', 'D', daemon ? 'D' : 'C', 0, 1, 1, 1}; - + rawSend(reinterpret_cast<unsigned char*>(&header), sizeof(header)); rawReceive(sizeof(ConnectionHeader), sigc::mem_fun(this, &ClientConnection::connectionHeaderReceiveHandler)); } void ClientConnection::connect(const IPAddress &address, bool daemon0) throw(ConnectionException) { daemon = daemon0; - + if(isConnected()) disconnect(); - + sock = socket(PF_INET, SOCK_STREAM, 0); if(sock < 0) throw ConnectionException("socket()", std::strerror(errno)); - + peer = new IPAddress(address); - + if(::connect(sock, peer->getSockAddr(), peer->getSockAddrLength()) < 0) { close(sock); delete peer; peer = 0; throw ConnectionException("connect()", std::strerror(errno)); } - + // 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); - + + // Don't linger + struct linger linger = {1, 0}; + setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); + gnutls_init(&session, GNUTLS_CLIENT); - + gnutls_set_default_priority(session); - + const int kx_list[] = {GNUTLS_KX_ANON_DH, 0}; gnutls_kx_set_priority(session, kx_list); - + gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); - + gnutls_transport_set_lowat(session, 0); gnutls_transport_set_ptr(session, reinterpret_cast<gnutls_transport_ptr_t>(sock)); - + handshake(); } |