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).
|
result of \a from & \a mask).
|
||||||
\return B_OK if the address could be copied
|
\return B_OK if the address could be copied
|
||||||
\return B_NO_MEMORY if the new address could not be allocated
|
\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
|
\return B_MISMATCHED_VALUES if \a address does not match family AF_INET
|
||||||
*/
|
*/
|
||||||
static status_t
|
static status_t
|
||||||
@@ -47,6 +49,8 @@ ipv4_copy_address(const sockaddr *from, sockaddr **to,
|
|||||||
} else {
|
} else {
|
||||||
if (from == NULL)
|
if (from == NULL)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
if (from->sa_len == 0 || (mask != NULL && mask->sa_len == 0))
|
||||||
|
return B_BAD_VALUE;
|
||||||
if (from->sa_family != AF_INET)
|
if (from->sa_family != AF_INET)
|
||||||
return B_MISMATCHED_VALUES;
|
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
|
Routing utility function: applies \a mask to given \a address and puts
|
||||||
the resulting address into \a result.
|
the resulting address into \a result.
|
||||||
\return B_OK if the mask has been applied
|
\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
|
static status_t
|
||||||
ipv4_mask_address(const sockaddr *address, const sockaddr *mask, sockaddr *result)
|
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;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
memcpy(result, address, sizeof(sockaddr_in));
|
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
|
Compares the IP-addresses and ports of the two given address structures
|
||||||
\a a and \a b.
|
\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
|
static bool
|
||||||
ipv4_equal_addresses_and_ports(const sockaddr *a, const sockaddr *b)
|
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
|
static uint16
|
||||||
ipv4_get_port(const sockaddr *address)
|
ipv4_get_port(const sockaddr *address)
|
||||||
{
|
{
|
||||||
if (address == NULL)
|
if (address == NULL || address->sa_len == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return ((sockaddr_in *)address)->sin_port;
|
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.
|
Sets the port of the given \a address to \a port.
|
||||||
\return B_OK if the port has been set
|
\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
|
static status_t
|
||||||
ipv4_set_port(sockaddr *address, uint16 port)
|
ipv4_set_port(sockaddr *address, uint16 port)
|
||||||
{
|
{
|
||||||
if (address == NULL)
|
if (address == NULL || address->sa_len == 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
((sockaddr_in *)address)->sin_port = port;
|
((sockaddr_in *)address)->sin_port = port;
|
||||||
@@ -327,13 +334,14 @@ ipv4_set_port(sockaddr *address, uint16 port)
|
|||||||
/*!
|
/*!
|
||||||
Sets \a address to \a from.
|
Sets \a address to \a from.
|
||||||
\return B_OK if \a from has been copied into \a address
|
\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
|
\return B_MISMATCHED_VALUES if from is not of family AF_INET
|
||||||
*/
|
*/
|
||||||
static status_t
|
static status_t
|
||||||
ipv4_set_to(sockaddr *address, const sockaddr *from)
|
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;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (from->sa_family != AF_INET)
|
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
|
static status_t
|
||||||
ipv4_update_to(sockaddr *_address, const sockaddr *_from)
|
ipv4_update_to(sockaddr *_address, const sockaddr *_from)
|
||||||
{
|
{
|
||||||
sockaddr_in *address = (sockaddr_in *)_address;
|
sockaddr_in *address = (sockaddr_in *)_address;
|
||||||
const sockaddr_in *from = (const sockaddr_in *)_from;
|
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;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (from->sin_family != AF_INET)
|
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 *our = (const sockaddr_in *)ourAddress;
|
||||||
const sockaddr_in *peer = (const sockaddr_in *)peerAddress;
|
const sockaddr_in *peer = (const sockaddr_in *)peerAddress;
|
||||||
|
|
||||||
return ((our ? our->sin_port : 0) | ((peer ? peer->sin_port : 0) << 16))
|
bool haveOur = our && our->sin_len != 0;
|
||||||
^ (our ? our->sin_addr.s_addr : 0) ^ (peer ? peer->sin_addr.s_addr : 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.
|
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_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
|
static status_t
|
||||||
ipv4_checksum_address(struct Checksum *checksum, const sockaddr *address)
|
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;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
(*checksum) << (uint32)((sockaddr_in *)address)->sin_addr.s_addr;
|
(*checksum) << (uint32)((sockaddr_in *)address)->sin_addr.s_addr;
|
||||||
|
|||||||
Reference in New Issue
Block a user