summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/network/core/address.cpp40
-rw-r--r--src/network/core/address.h10
-rw-r--r--src/network/core/tcp_connect.cpp21
3 files changed, 53 insertions, 18 deletions
diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp
index 888625dc1..28ab98887 100644
--- a/src/network/core/address.cpp
+++ b/src/network/core/address.cpp
@@ -10,6 +10,7 @@
#include "config.h"
#include "host.h"
#include "../../string_func.h"
+#include "../../debug.h"
const char *NetworkAddress::GetHostname()
{
@@ -62,4 +63,43 @@ const sockaddr_storage *NetworkAddress::GetAddress()
return &this->address;
}
+SOCKET NetworkAddress::Connect()
+{
+ DEBUG(net, 1, "Connecting to %s", this->GetAddressAsString());
+
+ struct addrinfo *ai;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof (hints));
+ hints.ai_flags = AI_ADDRCONFIG;
+ hints.ai_socktype = SOCK_STREAM;
+
+ /* The port needs to be a string. Six is enough to contain all characters + '\0'. */
+ char port_name[6];
+ seprintf(port_name, lastof(port_name), "%u", this->GetPort());
+
+ int e = getaddrinfo(this->GetHostname(), port_name, &hints, &ai);
+ if (e != 0) {
+ DEBUG(net, 0, "getaddrinfo failed: %s", gai_strerror(e));
+ return false;
+ }
+
+ SOCKET sock = INVALID_SOCKET;
+ for (struct addrinfo *runp = ai; runp != NULL; runp = runp->ai_next) {
+ sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
+ if (sock == INVALID_SOCKET) continue;
+
+ if (!SetNoDelay(sock)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
+
+ if (connect(sock, runp->ai_addr, runp->ai_addrlen) != 0) continue;
+
+ /* Connection succeeded */
+ if (!SetNonBlocking(sock)) DEBUG(net, 0, "Setting non-blocking mode failed");
+
+ break;
+ }
+ freeaddrinfo (ai);
+
+ return sock;
+}
+
#endif /* ENABLE_NETWORK */
diff --git a/src/network/core/address.h b/src/network/core/address.h
index 3a4b8c06e..598cd305e 100644
--- a/src/network/core/address.h
+++ b/src/network/core/address.h
@@ -128,6 +128,11 @@ public:
return this->GetPort() == address.GetPort() && strcmp(this->GetHostname(), address.GetHostname()) == 0;
}
+ /**
+ * Assign another address to ourself
+ * @param other obviously the address to assign to us
+ * @return 'this'
+ */
NetworkAddress& operator = (const NetworkAddress &other)
{
if (this != &other) { // protect against invalid self-assignment
@@ -138,6 +143,11 @@ public:
return *this;
}
+ /**
+ * Connect to the given address.
+ * @return the connected socket or INVALID_SOCKET.
+ */
+ SOCKET Connect();
};
#endif /* ENABLE_NETWORK */
diff --git a/src/network/core/tcp_connect.cpp b/src/network/core/tcp_connect.cpp
index a994fc6d2..2e292b5d0 100644
--- a/src/network/core/tcp_connect.cpp
+++ b/src/network/core/tcp_connect.cpp
@@ -31,27 +31,12 @@ TCPConnecter::TCPConnecter(const NetworkAddress &address) :
void TCPConnecter::Connect()
{
- DEBUG(net, 1, "Connecting to %s %d", address.GetHostname(), address.GetPort());
-
- this->sock = socket(AF_INET, SOCK_STREAM, 0);
+ this->sock = this->address.Connect();
if (this->sock == INVALID_SOCKET) {
this->aborted = true;
- return;
+ } else {
+ this->connected = true;
}
-
- if (!SetNoDelay(this->sock)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
-
- /* We failed to connect for which reason what so ever */
- if (connect(this->sock, (struct sockaddr*)this->address.GetAddress(), sizeof(*this->address.GetAddress())) != 0) {
- closesocket(this->sock);
- this->sock = INVALID_SOCKET;
- this->aborted = true;
- return;
- }
-
- if (!SetNonBlocking(this->sock)) DEBUG(net, 0, "Setting non-blocking mode failed");
-
- this->connected = true;
}