mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-16 00:12:51 +00:00
(svn r15921) -Fix: some OSes don't like sizeof(sockaddr_storage) but want sizeof(sockaddr) or whatever is 'valid' for the given protocol
This commit is contained in:
parent
c7b6469dab
commit
ba5aafb9bb
@ -15,8 +15,10 @@
|
|||||||
const char *NetworkAddress::GetHostname()
|
const char *NetworkAddress::GetHostname()
|
||||||
{
|
{
|
||||||
if (this->hostname == NULL) {
|
if (this->hostname == NULL) {
|
||||||
|
assert(this->address_length != 0);
|
||||||
|
|
||||||
char buf[NETWORK_HOSTNAME_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);
|
this->hostname = strdup(buf);
|
||||||
}
|
}
|
||||||
return this->hostname;
|
return this->hostname;
|
||||||
@ -56,9 +58,9 @@ const char *NetworkAddress::GetAddressAsString()
|
|||||||
|
|
||||||
const sockaddr_storage *NetworkAddress::GetAddress()
|
const sockaddr_storage *NetworkAddress::GetAddress()
|
||||||
{
|
{
|
||||||
if (!this->resolved) {
|
if (!this->IsResolved()) {
|
||||||
((struct sockaddr_in *)&this->address)->sin_addr.s_addr = NetworkResolveHost(this->hostname);
|
((struct sockaddr_in *)&this->address)->sin_addr.s_addr = NetworkResolveHost(this->hostname);
|
||||||
this->resolved = true;
|
this->address_length = sizeof(sockaddr);
|
||||||
}
|
}
|
||||||
return &this->address;
|
return &this->address;
|
||||||
}
|
}
|
||||||
@ -90,11 +92,18 @@ SOCKET NetworkAddress::Connect()
|
|||||||
|
|
||||||
if (!SetNoDelay(sock)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
|
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 */
|
/* Connection succeeded */
|
||||||
if (!SetNonBlocking(sock)) DEBUG(net, 0, "Setting non-blocking mode failed");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
freeaddrinfo (ai);
|
freeaddrinfo (ai);
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
class NetworkAddress {
|
class NetworkAddress {
|
||||||
private:
|
private:
|
||||||
bool resolved; ///< Has the IP address been resolved
|
|
||||||
char *hostname; ///< The hostname, NULL if there isn't one
|
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
|
sockaddr_storage address; ///< The resolved address
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -27,8 +27,8 @@ public:
|
|||||||
* @param port the port
|
* @param port the port
|
||||||
*/
|
*/
|
||||||
NetworkAddress(in_addr_t ip, uint16 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));
|
memset(&this->address, 0, sizeof(this->address));
|
||||||
this->address.ss_family = AF_INET;
|
this->address.ss_family = AF_INET;
|
||||||
@ -40,9 +40,9 @@ public:
|
|||||||
* Create a network address based on a resolved IP and port
|
* Create a network address based on a resolved IP and port
|
||||||
* @param address the IP address with port
|
* @param address the IP address with port
|
||||||
*/
|
*/
|
||||||
NetworkAddress(struct sockaddr_storage &address) :
|
NetworkAddress(struct sockaddr_storage &address, size_t address_length) :
|
||||||
resolved(true),
|
|
||||||
hostname(NULL),
|
hostname(NULL),
|
||||||
|
address_length(address_length),
|
||||||
address(address)
|
address(address)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -53,8 +53,8 @@ public:
|
|||||||
* @param port the port
|
* @param port the port
|
||||||
*/
|
*/
|
||||||
NetworkAddress(const char *hostname = NULL, uint16 port = 0) :
|
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));
|
memset(&this->address, 0, sizeof(this->address));
|
||||||
this->address.ss_family = AF_INET;
|
this->address.ss_family = AF_INET;
|
||||||
@ -66,8 +66,8 @@ public:
|
|||||||
* @param address the address to clone
|
* @param address the address to clone
|
||||||
*/
|
*/
|
||||||
NetworkAddress(const NetworkAddress &address) :
|
NetworkAddress(const NetworkAddress &address) :
|
||||||
resolved(address.resolved),
|
|
||||||
hostname(address.hostname == NULL ? NULL : strdup(address.hostname)),
|
hostname(address.hostname == NULL ? NULL : strdup(address.hostname)),
|
||||||
|
address_length(address.address_length),
|
||||||
address(address.address)
|
address(address.address)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -97,6 +97,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
const sockaddr_storage *GetAddress();
|
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
|
* Get the port
|
||||||
* @return the port
|
* @return the port
|
||||||
@ -115,7 +126,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool IsResolved() const
|
bool IsResolved() const
|
||||||
{
|
{
|
||||||
return this->resolved;
|
return this->address_length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,7 +89,7 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv)
|
|||||||
p->PrepareToSend();
|
p->PrepareToSend();
|
||||||
|
|
||||||
/* Send the buffer */
|
/* 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 */
|
/* Check for any errors, but ignore it otherwise */
|
||||||
if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
|
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. */
|
/* We got some bytes for the base header of the packet. */
|
||||||
if (nbytes > 2) {
|
if (nbytes > 2) {
|
||||||
NetworkAddress address(client_addr);
|
NetworkAddress address(client_addr, client_len);
|
||||||
p.PrepareToRead();
|
p.PrepareToRead();
|
||||||
|
|
||||||
/* If the size does not match the packet must be corrupted.
|
/* If the size does not match the packet must be corrupted.
|
||||||
|
@ -1090,24 +1090,15 @@ static void NetworkGenerateUniqueId()
|
|||||||
void NetworkStartDebugLog(NetworkAddress address)
|
void NetworkStartDebugLog(NetworkAddress address)
|
||||||
{
|
{
|
||||||
extern SOCKET _debug_socket; // Comes from debug.c
|
extern SOCKET _debug_socket; // Comes from debug.c
|
||||||
SOCKET s;
|
|
||||||
|
|
||||||
DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", address.GetHostname(), address.GetPort());
|
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) {
|
if (s == INVALID_SOCKET) {
|
||||||
DEBUG(net, 0, "Failed to open socket for redirection DEBUG()");
|
DEBUG(net, 0, "Failed to open socket for redirection DEBUG()");
|
||||||
return;
|
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_socket = s;
|
||||||
|
|
||||||
DEBUG(net, 0, "DEBUG() is now redirected");
|
DEBUG(net, 0, "DEBUG() is now redirected");
|
||||||
|
Loading…
Reference in New Issue
Block a user