Fixed R5 compatibility "layer" in libnetwork:
* instead of always converting from the expected r5_sockaddr_in to haiku's own, we now explicitly check whether or not the given sockaddr is an r5_sockaddr_in or not, naturally doing the conversion only if it is. This is necessary since even R5 applications may not always pass in r5_sockaddr_in structs (as for instance gethostbyname() will return a native [haiku-]sockaddr_in) * cleaned up the confusion between the name r5addr and it's actual meaning (holding a haiku sockaddr_in) - renaming it to haikuAddr instead * undid the part of Ingo's r25489 described as: "Extended R5 compatibility check to also consider calls from libbnetapi" - as I fail to see why this would be desirable and in fact it stops at least Beam from working. Ingo: if you can remember, please enlighten me what was the reason behind this change. This finally makes Beam "work" (well: connect to servers and download mails ;-) Vision, NetworkTime and NetPositive are still working, too, so hopefully there are no regressions. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26303 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+51
-31
@@ -22,6 +22,7 @@
|
|||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
static inline bool
|
static inline bool
|
||||||
check_r5_compatibility()
|
check_r5_compatibility()
|
||||||
{
|
{
|
||||||
@@ -39,9 +40,7 @@ check_r5_compatibility()
|
|||||||
|
|
||||||
stack_frame* frame = (stack_frame*)get_stack_frame();
|
stack_frame* frame = (stack_frame*)get_stack_frame();
|
||||||
if (frame->return_address >= __gNetworkStart
|
if (frame->return_address >= __gNetworkStart
|
||||||
&& frame->return_address < __gNetworkEnd
|
&& frame->return_address < __gNetworkEnd) {
|
||||||
|| frame->return_address >= __gNetAPIStart
|
|
||||||
&& frame->return_address < __gNetAPIEnd) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +49,27 @@ check_r5_compatibility()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_r5_sockaddr(const struct sockaddr *_addr)
|
||||||
|
{
|
||||||
|
/* r5_sockaddr_in structs do not contain sin_len, but have a larger
|
||||||
|
* sin_family instead (two bytes), so in a r5_sockaddr_in, the first two
|
||||||
|
* bytes will always be equal to R5_AF_INET, while for haiku's own
|
||||||
|
* sockaddr_in, that will never be the case, since the first byte contains
|
||||||
|
* the length which should never be zero.
|
||||||
|
* The only other case where this check could fail is when the address does
|
||||||
|
* not belong to the internet family at all. But even in that case we would
|
||||||
|
* not want to try to convert the addresses, as the conversion itself
|
||||||
|
* blindly casts the address to sockaddr_in, which would yield unpredictable
|
||||||
|
* results for other address families.
|
||||||
|
*/
|
||||||
|
const r5_sockaddr_in *addr = (r5_sockaddr_in *)_addr;
|
||||||
|
if (addr == NULL || addr->sin_family != R5_AF_INET)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
convert_from_r5_sockaddr(struct sockaddr *_to, const struct sockaddr *_from)
|
convert_from_r5_sockaddr(struct sockaddr *_to, const struct sockaddr *_from)
|
||||||
{
|
{
|
||||||
@@ -174,11 +194,11 @@ socket(int family, int type, int protocol)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
bind(int socket, const struct sockaddr *address, socklen_t addressLength)
|
bind(int socket, const struct sockaddr *address, socklen_t addressLength)
|
||||||
{
|
{
|
||||||
struct sockaddr r5addr;
|
struct sockaddr haikuAddr;
|
||||||
|
|
||||||
if (check_r5_compatibility()) {
|
if (check_r5_compatibility() && is_r5_sockaddr(address)) {
|
||||||
convert_from_r5_sockaddr(&r5addr, address);
|
convert_from_r5_sockaddr(&haikuAddr, address);
|
||||||
address = &r5addr;
|
address = &haikuAddr;
|
||||||
addressLength = sizeof(struct sockaddr_in);
|
addressLength = sizeof(struct sockaddr_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,11 +216,11 @@ shutdown(int socket, int how)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
connect(int socket, const struct sockaddr *address, socklen_t addressLength)
|
connect(int socket, const struct sockaddr *address, socklen_t addressLength)
|
||||||
{
|
{
|
||||||
struct sockaddr r5addr;
|
struct sockaddr haikuAddr;
|
||||||
|
|
||||||
if (check_r5_compatibility()) {
|
if (check_r5_compatibility() && is_r5_sockaddr(address)) {
|
||||||
convert_from_r5_sockaddr(&r5addr, address);
|
convert_from_r5_sockaddr(&haikuAddr, address);
|
||||||
address = &r5addr;
|
address = &haikuAddr;
|
||||||
addressLength = sizeof(struct sockaddr_in);
|
addressLength = sizeof(struct sockaddr_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,14 +239,14 @@ extern "C" int
|
|||||||
accept(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
accept(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
||||||
{
|
{
|
||||||
bool r5compatible = check_r5_compatibility();
|
bool r5compatible = check_r5_compatibility();
|
||||||
struct sockaddr r5addr;
|
struct sockaddr haikuAddr;
|
||||||
|
|
||||||
sockaddr* address;
|
sockaddr* address;
|
||||||
socklen_t addressLength;
|
socklen_t addressLength;
|
||||||
|
|
||||||
if (r5compatible && _address != NULL) {
|
if (r5compatible && _address != NULL) {
|
||||||
address = &r5addr;
|
address = &haikuAddr;
|
||||||
addressLength = sizeof(r5addr);
|
addressLength = sizeof(haikuAddr);
|
||||||
} else {
|
} else {
|
||||||
address = _address;
|
address = _address;
|
||||||
addressLength = _addressLength ? *_addressLength : 0;
|
addressLength = _addressLength ? *_addressLength : 0;
|
||||||
@@ -239,7 +259,7 @@ accept(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (r5compatible && _address != NULL) {
|
if (r5compatible && _address != NULL) {
|
||||||
convert_to_r5_sockaddr(_address, &r5addr);
|
convert_to_r5_sockaddr(_address, &haikuAddr);
|
||||||
if (_addressLength != NULL)
|
if (_addressLength != NULL)
|
||||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
} else if (_addressLength != NULL)
|
} else if (_addressLength != NULL)
|
||||||
@@ -261,14 +281,14 @@ recvfrom(int socket, void *data, size_t length, int flags,
|
|||||||
struct sockaddr *_address, socklen_t *_addressLength)
|
struct sockaddr *_address, socklen_t *_addressLength)
|
||||||
{
|
{
|
||||||
bool r5compatible = check_r5_compatibility();
|
bool r5compatible = check_r5_compatibility();
|
||||||
struct sockaddr r5addr;
|
struct sockaddr haikuAddr;
|
||||||
|
|
||||||
sockaddr* address;
|
sockaddr* address;
|
||||||
socklen_t addressLength;
|
socklen_t addressLength;
|
||||||
|
|
||||||
if (r5compatible && _address != NULL) {
|
if (r5compatible && _address != NULL) {
|
||||||
address = &r5addr;
|
address = &haikuAddr;
|
||||||
addressLength = sizeof(r5addr);
|
addressLength = sizeof(haikuAddr);
|
||||||
} else {
|
} else {
|
||||||
address = _address;
|
address = _address;
|
||||||
addressLength = _addressLength ? *_addressLength : 0;
|
addressLength = _addressLength ? *_addressLength : 0;
|
||||||
@@ -282,7 +302,7 @@ recvfrom(int socket, void *data, size_t length, int flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (r5compatible) {
|
if (r5compatible) {
|
||||||
convert_to_r5_sockaddr(_address, &r5addr);
|
convert_to_r5_sockaddr(_address, &haikuAddr);
|
||||||
if (_addressLength != NULL)
|
if (_addressLength != NULL)
|
||||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
} else if (_addressLength != NULL)
|
} else if (_addressLength != NULL)
|
||||||
@@ -310,11 +330,11 @@ extern "C" ssize_t
|
|||||||
sendto(int socket, const void *data, size_t length, int flags,
|
sendto(int socket, const void *data, size_t length, int flags,
|
||||||
const struct sockaddr *address, socklen_t addressLength)
|
const struct sockaddr *address, socklen_t addressLength)
|
||||||
{
|
{
|
||||||
struct sockaddr r5addr;
|
struct sockaddr haikuAddr;
|
||||||
|
|
||||||
if (check_r5_compatibility()) {
|
if (check_r5_compatibility() && is_r5_sockaddr(address)) {
|
||||||
convert_from_r5_sockaddr(&r5addr, address);
|
convert_from_r5_sockaddr(&haikuAddr, address);
|
||||||
address = &r5addr;
|
address = &haikuAddr;
|
||||||
addressLength = sizeof(struct sockaddr_in);
|
addressLength = sizeof(struct sockaddr_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,14 +384,14 @@ extern "C" int
|
|||||||
getpeername(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
getpeername(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
||||||
{
|
{
|
||||||
bool r5compatible = check_r5_compatibility();
|
bool r5compatible = check_r5_compatibility();
|
||||||
struct sockaddr r5addr;
|
struct sockaddr haikuAddr;
|
||||||
|
|
||||||
sockaddr* address;
|
sockaddr* address;
|
||||||
socklen_t addressLength;
|
socklen_t addressLength;
|
||||||
|
|
||||||
if (r5compatible && _address != NULL) {
|
if (r5compatible && _address != NULL) {
|
||||||
address = &r5addr;
|
address = &haikuAddr;
|
||||||
addressLength = sizeof(r5addr);
|
addressLength = sizeof(haikuAddr);
|
||||||
} else {
|
} else {
|
||||||
address = _address;
|
address = _address;
|
||||||
addressLength = _addressLength ? *_addressLength : 0;
|
addressLength = _addressLength ? *_addressLength : 0;
|
||||||
@@ -384,7 +404,7 @@ getpeername(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (r5compatible) {
|
if (r5compatible) {
|
||||||
convert_to_r5_sockaddr(_address, &r5addr);
|
convert_to_r5_sockaddr(_address, &haikuAddr);
|
||||||
if (_addressLength != NULL)
|
if (_addressLength != NULL)
|
||||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
} else if (_addressLength != NULL)
|
} else if (_addressLength != NULL)
|
||||||
@@ -398,14 +418,14 @@ extern "C" int
|
|||||||
getsockname(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
getsockname(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
||||||
{
|
{
|
||||||
bool r5compatible = check_r5_compatibility();
|
bool r5compatible = check_r5_compatibility();
|
||||||
struct sockaddr r5addr;
|
struct sockaddr haikuAddr;
|
||||||
|
|
||||||
sockaddr* address;
|
sockaddr* address;
|
||||||
socklen_t addressLength;
|
socklen_t addressLength;
|
||||||
|
|
||||||
if (r5compatible && _address != NULL) {
|
if (r5compatible && _address != NULL) {
|
||||||
address = &r5addr;
|
address = &haikuAddr;
|
||||||
addressLength = sizeof(r5addr);
|
addressLength = sizeof(haikuAddr);
|
||||||
} else {
|
} else {
|
||||||
address = _address;
|
address = _address;
|
||||||
addressLength = _addressLength ? *_addressLength : 0;
|
addressLength = _addressLength ? *_addressLength : 0;
|
||||||
@@ -418,7 +438,7 @@ getsockname(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (r5compatible) {
|
if (r5compatible) {
|
||||||
convert_to_r5_sockaddr(_address, &r5addr);
|
convert_to_r5_sockaddr(_address, &haikuAddr);
|
||||||
if (_addressLength != NULL)
|
if (_addressLength != NULL)
|
||||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
} else if (_addressLength != NULL)
|
} else if (_addressLength != NULL)
|
||||||
|
|||||||
Reference in New Issue
Block a user