summaryrefslogtreecommitdiffstats
path: root/src/Net/ClientConnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Net/ClientConnection.cpp')
-rw-r--r--src/Net/ClientConnection.cpp42
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();
}