summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2009-04-03 00:33:00 +0000
committerrubidium <rubidium@openttd.org>2009-04-03 00:33:00 +0000
commitba5aafb9bba4887b502dba32e56747fe10af604e (patch)
treeaed246d3f133b865c118d25907878c21f972bbf4
parentc7b6469dabe5018775d075bee0a5293175024b42 (diff)
downloadopenttd-ba5aafb9bba4887b502dba32e56747fe10af604e.tar.xz
(svn r15921) -Fix: some OSes don't like sizeof(sockaddr_storage) but want sizeof(sockaddr) or whatever is 'valid' for the given protocol
-rw-r--r--src/network/core/address.cpp17
-rw-r--r--src/network/core/address.h29
-rw-r--r--src/network/core/udp.cpp4
-rw-r--r--src/network/network.cpp11
4 files changed, 36 insertions, 25 deletions
diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp
index 28ab98887..c1313fe74 100644
--- a/src/network/core/address.cpp
+++ b/src/network/core/address.cpp
@@ -15,8 +15,10 @@
const char *NetworkAddress::GetHostname()
{
if (this->hostname == NULL) {
+ assert(this->address_length != 0);
+
char buf[NETWORK_HOSTNAME_LENGTH] = { '\0' };
- getnameinfo((struct sockaddr *)&this->address, sizeof(this->address), buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
+ getnameinfo((struct sockaddr *)&this->address, this->address_length, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
this->hostname = strdup(buf);
}
return this->hostname;
@@ -56,9 +58,9 @@ const char *NetworkAddress::GetAddressAsString()
const sockaddr_storage *NetworkAddress::GetAddress()
{
- if (!this->resolved) {
+ if (!this->IsResolved()) {
((struct sockaddr_in *)&this->address)->sin_addr.s_addr = NetworkResolveHost(this->hostname);
- this->resolved = true;
+ this->address_length = sizeof(sockaddr);
}
return &this->address;
}
@@ -90,11 +92,18 @@ SOCKET NetworkAddress::Connect()
if (!SetNoDelay(sock)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
- if (connect(sock, runp->ai_addr, runp->ai_addrlen) != 0) continue;
+ if (connect(sock, runp->ai_addr, runp->ai_addrlen) != 0) {
+ closesocket(sock);
+ sock = INVALID_SOCKET;
+ continue;
+ }
/* Connection succeeded */
if (!SetNonBlocking(sock)) DEBUG(net, 0, "Setting non-blocking mode failed");
+ this->address_length = runp->ai_addrlen;
+ assert(sizeof(this->address) >= runp->ai_addrlen);
+ memcpy(&this->address, runp->ai_addr, runp->ai_addrlen);
break;
}
freeaddrinfo (ai);
diff --git a/src/network/core/address.h b/src/network/core/address.h
index 598cd305e..3e8ca0343 100644
--- a/src/network/core/address.h
+++ b/src/network/core/address.h
@@ -16,8 +16,8 @@
*/
class NetworkAddress {
private:
- bool resolved; ///< Has the IP address been resolved
char *hostname; ///< The hostname, NULL if there isn't one
+ size_t address_length; ///< The length of the resolved address
sockaddr_storage address; ///< The resolved address
public:
@@ -27,8 +27,8 @@ public:
* @param port the port
*/
NetworkAddress(in_addr_t ip, uint16 port) :
- resolved(true),
- hostname(NULL)
+ hostname(NULL),
+ address_length(sizeof(sockaddr))
{
memset(&this->address, 0, sizeof(this->address));
this->address.ss_family = AF_INET;
@@ -40,9 +40,9 @@ public:
* Create a network address based on a resolved IP and port
* @param address the IP address with port
*/
- NetworkAddress(struct sockaddr_storage &address) :
- resolved(true),
+ NetworkAddress(struct sockaddr_storage &address, size_t address_length) :
hostname(NULL),
+ address_length(address_length),
address(address)
{
}
@@ -53,8 +53,8 @@ public:
* @param port the port
*/
NetworkAddress(const char *hostname = NULL, uint16 port = 0) :
- resolved(false),
- hostname(hostname == NULL ? NULL : strdup(hostname))
+ hostname(hostname == NULL ? NULL : strdup(hostname)),
+ address_length(0)
{
memset(&this->address, 0, sizeof(this->address));
this->address.ss_family = AF_INET;
@@ -66,8 +66,8 @@ public:
* @param address the address to clone
*/
NetworkAddress(const NetworkAddress &address) :
- resolved(address.resolved),
hostname(address.hostname == NULL ? NULL : strdup(address.hostname)),
+ address_length(address.address_length),
address(address.address)
{
}
@@ -98,6 +98,17 @@ public:
const sockaddr_storage *GetAddress();
/**
+ * Get the (valid) length of the address.
+ * @return the length
+ */
+ size_t GetAddressLength()
+ {
+ /* Resolve it if we didn't do it already */
+ if (!this->IsResolved()) this->GetAddress();
+ return this->address_length;
+ }
+
+ /**
* Get the port
* @return the port
*/
@@ -115,7 +126,7 @@ public:
*/
bool IsResolved() const
{
- return this->resolved;
+ return this->address_length != 0;
}
/**
diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp
index 110cec2f2..4818767d9 100644
--- a/src/network/core/udp.cpp
+++ b/src/network/core/udp.cpp
@@ -89,7 +89,7 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv)
p->PrepareToSend();
/* Send the buffer */
- res = sendto(this->sock, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv->GetAddress(), sizeof(*recv->GetAddress()));
+ res = sendto(this->sock, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv->GetAddress(), recv->GetAddressLength());
/* Check for any errors, but ignore it otherwise */
if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
@@ -119,7 +119,7 @@ void NetworkUDPSocketHandler::ReceivePackets()
/* We got some bytes for the base header of the packet. */
if (nbytes > 2) {
- NetworkAddress address(client_addr);
+ NetworkAddress address(client_addr, client_len);
p.PrepareToRead();
/* If the size does not match the packet must be corrupted.
diff --git a/src/network/network.cpp b/src/network/network.cpp
index ebd10980d..74e0dadc1 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -1090,24 +1090,15 @@ static void NetworkGenerateUniqueId()
void NetworkStartDebugLog(NetworkAddress address)
{
extern SOCKET _debug_socket; // Comes from debug.c
- SOCKET s;
DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", address.GetHostname(), address.GetPort());
- s = socket(AF_INET, SOCK_STREAM, 0);
+ SOCKET s = address.Connect();
if (s == INVALID_SOCKET) {
DEBUG(net, 0, "Failed to open socket for redirection DEBUG()");
return;
}
- if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
-
- if (connect(s, (struct sockaddr *)address.GetAddress(), sizeof(*address.GetAddress())) != 0) {
- DEBUG(net, 0, "Failed to redirection DEBUG() to %s", address.GetAddressAsString());
- return;
- }
-
- if (!SetNonBlocking(s)) DEBUG(net, 0, "Setting non-blocking mode failed");
_debug_socket = s;
DEBUG(net, 0, "DEBUG() is now redirected");