fixing #3712:
* Since r30000, a net_socket is not zeroed anymore, which in turn leaves its two addresses (local and peer) in an uninitialized, but correct state - marking their state with ss_len == 0. However, this state was not properly detected in some ipv4-address functions, especially not the one that creates a hash value from those two addresses. This basically caused UDP to stop working, as here the peer address (as opposed to TCP) is usually not explicitly initialized. Adjusting the ipv4-address functions accordingly fixes the problem, such that DHCP (and the rest of UDP) should now work again. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30175 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
result of \a from & \a mask).
|
||||
\return B_OK if the address could be copied
|
||||
\return B_NO_MEMORY if the new address could not be allocated
|
||||
\return B_BAD_VALUE if any of \a from or \a mask refers to an uninitialized
|
||||
address
|
||||
\return B_MISMATCHED_VALUES if \a address does not match family AF_INET
|
||||
*/
|
||||
static status_t
|
||||
@@ -47,6 +49,8 @@ ipv4_copy_address(const sockaddr *from, sockaddr **to,
|
||||
} else {
|
||||
if (from == NULL)
|
||||
return B_OK;
|
||||
if (from->sa_len == 0 || (mask != NULL && mask->sa_len == 0))
|
||||
return B_BAD_VALUE;
|
||||
if (from->sa_family != AF_INET)
|
||||
return B_MISMATCHED_VALUES;
|
||||
|
||||
@@ -69,12 +73,14 @@ ipv4_copy_address(const sockaddr *from, sockaddr **to,
|
||||
Routing utility function: applies \a mask to given \a address and puts
|
||||
the resulting address into \a result.
|
||||
\return B_OK if the mask has been applied
|
||||
\return B_BAD_VALUE if \a address or \a mask is NULL
|
||||
\return B_BAD_VALUE if \a address is NULL or if any of \a address or \a mask
|
||||
refers to an uninitialized address
|
||||
*/
|
||||
static status_t
|
||||
ipv4_mask_address(const sockaddr *address, const sockaddr *mask, sockaddr *result)
|
||||
{
|
||||
if (address == NULL || result == NULL)
|
||||
if (address == NULL || address->sa_len == 0 || result == NULL
|
||||
|| (mask != NULL && mask->sa_len == 0))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
memcpy(result, address, sizeof(sockaddr_in));
|
||||
@@ -138,7 +144,8 @@ ipv4_equal_ports(const sockaddr *a, const sockaddr *b)
|
||||
/*!
|
||||
Compares the IP-addresses and ports of the two given address structures
|
||||
\a a and \a b.
|
||||
\return true if IP-addresses and ports of \a a and \a b are equal, false if not
|
||||
\return true if IP-addresses and ports of \a a and \a b are equal, false if
|
||||
not
|
||||
*/
|
||||
static bool
|
||||
ipv4_equal_addresses_and_ports(const sockaddr *a, const sockaddr *b)
|
||||
@@ -301,7 +308,7 @@ ipv4_print_address(const sockaddr *_address, char **_buffer, bool printPort)
|
||||
static uint16
|
||||
ipv4_get_port(const sockaddr *address)
|
||||
{
|
||||
if (address == NULL)
|
||||
if (address == NULL || address->sa_len == 0)
|
||||
return 0;
|
||||
|
||||
return ((sockaddr_in *)address)->sin_port;
|
||||
@@ -311,12 +318,12 @@ ipv4_get_port(const sockaddr *address)
|
||||
/*!
|
||||
Sets the port of the given \a address to \a port.
|
||||
\return B_OK if the port has been set
|
||||
\return B_BAD_VALUE if \a address is NULL
|
||||
\return B_BAD_VALUE if \a address is NULL or has not been initialized
|
||||
*/
|
||||
static status_t
|
||||
ipv4_set_port(sockaddr *address, uint16 port)
|
||||
{
|
||||
if (address == NULL)
|
||||
if (address == NULL || address->sa_len == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
((sockaddr_in *)address)->sin_port = port;
|
||||
@@ -327,13 +334,14 @@ ipv4_set_port(sockaddr *address, uint16 port)
|
||||
/*!
|
||||
Sets \a address to \a from.
|
||||
\return B_OK if \a from has been copied into \a address
|
||||
\return B_BAD_VALUE if either \a address or \a from is NULL
|
||||
\return B_BAD_VALUE if either \a address or \a from is NULL or if the
|
||||
address given in from has not been initialized
|
||||
\return B_MISMATCHED_VALUES if from is not of family AF_INET
|
||||
*/
|
||||
static status_t
|
||||
ipv4_set_to(sockaddr *address, const sockaddr *from)
|
||||
{
|
||||
if (address == NULL || from == NULL)
|
||||
if (address == NULL || from == NULL || from->sa_len == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (from->sa_family != AF_INET)
|
||||
@@ -345,13 +353,20 @@ ipv4_set_to(sockaddr *address, const sockaddr *from)
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Updates missing parts in \a address with the values in \a from.
|
||||
\return B_OK if \a address has been updated from \a from
|
||||
\return B_BAD_VALUE if either \a address or \a from is NULL or if the
|
||||
address given in from has not been initialized
|
||||
\return B_MISMATCHED_VALUES if from is not of family AF_INET
|
||||
*/
|
||||
static status_t
|
||||
ipv4_update_to(sockaddr *_address, const sockaddr *_from)
|
||||
{
|
||||
sockaddr_in *address = (sockaddr_in *)_address;
|
||||
const sockaddr_in *from = (const sockaddr_in *)_from;
|
||||
|
||||
if (address == NULL || from == NULL)
|
||||
if (address == NULL || from == NULL || from->sin_len == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (from->sin_family != AF_INET)
|
||||
@@ -448,20 +463,27 @@ ipv4_hash_address_pair(const sockaddr *ourAddress, const sockaddr *peerAddress)
|
||||
const sockaddr_in *our = (const sockaddr_in *)ourAddress;
|
||||
const sockaddr_in *peer = (const sockaddr_in *)peerAddress;
|
||||
|
||||
return ((our ? our->sin_port : 0) | ((peer ? peer->sin_port : 0) << 16))
|
||||
^ (our ? our->sin_addr.s_addr : 0) ^ (peer ? peer->sin_addr.s_addr : 0);
|
||||
bool haveOur = our && our->sin_len != 0;
|
||||
bool havePeer = peer && peer->sin_len != 0;
|
||||
|
||||
return
|
||||
((haveOur ? our->sin_port : 0)
|
||||
| ((havePeer ? peer->sin_port : 0) << 16))
|
||||
^ (haveOur ? our->sin_addr.s_addr : 0)
|
||||
^ (havePeer ? peer->sin_addr.s_addr : 0);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Adds the given \a address to the IP-checksum \a checksum.
|
||||
\return B_OK if \a address has been added to the checksum
|
||||
\return B_BAD_VALUE if either \a address or \a checksum is NULL
|
||||
\return B_BAD_VALUE if either \a address or \a checksum is NULL or if
|
||||
the given address is not initialized
|
||||
*/
|
||||
static status_t
|
||||
ipv4_checksum_address(struct Checksum *checksum, const sockaddr *address)
|
||||
{
|
||||
if (checksum == NULL || address == NULL)
|
||||
if (checksum == NULL || address == NULL || address->sa_len == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
(*checksum) << (uint32)((sockaddr_in *)address)->sin_addr.s_addr;
|
||||
|
||||
Reference in New Issue
Block a user