The R5 compatibility is now turned off when the socket functions are used
within the library - theoretically, this mechanism could be extended to turn the compatibility layer on and off based on the images that call the functions (allowing to mix R5 and BONE network add-ons in a single executable). This change fixes R5 networking apps such as Vision, and NetworkTime (both now seem to work fine under Haiku). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19431 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -39,5 +39,7 @@ struct r5_sockaddr_in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern bool __gR5Compatibility;
|
extern bool __gR5Compatibility;
|
||||||
|
extern addr_t __gNetworkStart;
|
||||||
|
extern addr_t __gNetworkEnd;
|
||||||
|
|
||||||
#endif // NET_R5_COMPATIBILITY_H
|
#endif // NET_R5_COMPATIBILITY_H
|
||||||
|
|||||||
@@ -16,6 +16,26 @@
|
|||||||
|
|
||||||
|
|
||||||
bool __gR5Compatibility = false;
|
bool __gR5Compatibility = false;
|
||||||
|
addr_t __gNetworkStart;
|
||||||
|
addr_t __gNetworkEnd;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
find_own_image()
|
||||||
|
{
|
||||||
|
int32 cookie = 0;
|
||||||
|
image_info info;
|
||||||
|
while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
|
||||||
|
if (((uint32)info.text <= (uint32)find_own_image
|
||||||
|
&& (uint32)info.text + (uint32)info.text_size > (uint32)find_own_image)) {
|
||||||
|
// found us
|
||||||
|
__gNetworkStart = (addr_t)min_c(info.text, info.data);
|
||||||
|
__gNetworkEnd = min_c((addr_t)info.text + info.text_size,
|
||||||
|
(addr_t)info.data + info.data_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
@@ -55,6 +75,7 @@ initialize_before()
|
|||||||
|
|
||||||
if (enable > 0) {
|
if (enable > 0) {
|
||||||
__gR5Compatibility = true;
|
__gR5Compatibility = true;
|
||||||
|
find_own_image();
|
||||||
debug_printf("libnetwork.so running in R5 compatibility mode.\n");
|
debug_printf("libnetwork.so running in R5 compatibility mode.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-14
@@ -33,6 +33,30 @@ stack_driver_path(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
check_r5_compatibility()
|
||||||
|
{
|
||||||
|
if (!__gR5Compatibility)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#ifndef __INTEL__
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct stack_frame {
|
||||||
|
struct stack_frame* previous;
|
||||||
|
addr_t return_address;
|
||||||
|
};
|
||||||
|
|
||||||
|
stack_frame* frame = (stack_frame*)get_stack_frame();
|
||||||
|
if (frame->return_address >= __gNetworkStart && frame->return_address < __gNetworkEnd)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -143,7 +167,7 @@ socket(int family, int type, int protocol)
|
|||||||
if (socket < 0)
|
if (socket < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (__gR5Compatibility)
|
if (check_r5_compatibility())
|
||||||
convert_from_r5_socket(family, type, protocol);
|
convert_from_r5_socket(family, type, protocol);
|
||||||
|
|
||||||
socket_args args;
|
socket_args args;
|
||||||
@@ -165,7 +189,7 @@ bind(int socket, const struct sockaddr *address, socklen_t addressLength)
|
|||||||
{
|
{
|
||||||
struct sockaddr r5addr;
|
struct sockaddr r5addr;
|
||||||
|
|
||||||
if (__gR5Compatibility) {
|
if (check_r5_compatibility()) {
|
||||||
convert_from_r5_sockaddr(&r5addr, address);
|
convert_from_r5_sockaddr(&r5addr, address);
|
||||||
address = &r5addr;
|
address = &r5addr;
|
||||||
addressLength = sizeof(struct sockaddr_in);
|
addressLength = sizeof(struct sockaddr_in);
|
||||||
@@ -191,7 +215,7 @@ connect(int socket, const struct sockaddr *address, socklen_t addressLength)
|
|||||||
{
|
{
|
||||||
struct sockaddr r5addr;
|
struct sockaddr r5addr;
|
||||||
|
|
||||||
if (__gR5Compatibility) {
|
if (check_r5_compatibility()) {
|
||||||
convert_from_r5_sockaddr(&r5addr, address);
|
convert_from_r5_sockaddr(&r5addr, address);
|
||||||
address = &r5addr;
|
address = &r5addr;
|
||||||
addressLength = sizeof(struct sockaddr_in);
|
addressLength = sizeof(struct sockaddr_in);
|
||||||
@@ -229,12 +253,13 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool r5compatible = check_r5_compatibility();
|
||||||
struct sockaddr r5addr;
|
struct sockaddr r5addr;
|
||||||
accept_args args;
|
accept_args args;
|
||||||
|
|
||||||
args.cookie = cookie;
|
args.cookie = cookie;
|
||||||
|
|
||||||
if (__gR5Compatibility) {
|
if (r5compatible) {
|
||||||
args.address = &r5addr;
|
args.address = &r5addr;
|
||||||
args.address_length = sizeof(r5addr);
|
args.address_length = sizeof(r5addr);
|
||||||
} else {
|
} else {
|
||||||
@@ -247,7 +272,7 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__gR5Compatibility) {
|
if (r5compatible) {
|
||||||
convert_to_r5_sockaddr(address, &r5addr);
|
convert_to_r5_sockaddr(address, &r5addr);
|
||||||
if (_addressLength != NULL)
|
if (_addressLength != NULL)
|
||||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
@@ -276,6 +301,7 @@ extern "C" ssize_t
|
|||||||
recvfrom(int socket, void *data, size_t length, int flags,
|
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();
|
||||||
struct sockaddr r5addr;
|
struct sockaddr r5addr;
|
||||||
|
|
||||||
transfer_args args;
|
transfer_args args;
|
||||||
@@ -283,7 +309,7 @@ recvfrom(int socket, void *data, size_t length, int flags,
|
|||||||
args.data_length = length;
|
args.data_length = length;
|
||||||
args.flags = flags;
|
args.flags = flags;
|
||||||
|
|
||||||
if (__gR5Compatibility) {
|
if (r5compatible) {
|
||||||
args.address = &r5addr;
|
args.address = &r5addr;
|
||||||
args.address_length = sizeof(r5addr);
|
args.address_length = sizeof(r5addr);
|
||||||
} else {
|
} else {
|
||||||
@@ -295,7 +321,7 @@ recvfrom(int socket, void *data, size_t length, int flags,
|
|||||||
if (bytesReceived < 0)
|
if (bytesReceived < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (__gR5Compatibility) {
|
if (r5compatible) {
|
||||||
convert_to_r5_sockaddr(address, &r5addr);
|
convert_to_r5_sockaddr(address, &r5addr);
|
||||||
if (_addressLength != NULL)
|
if (_addressLength != NULL)
|
||||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
@@ -334,7 +360,7 @@ sendto(int socket, const void *data, size_t length, int flags,
|
|||||||
{
|
{
|
||||||
struct sockaddr r5addr;
|
struct sockaddr r5addr;
|
||||||
|
|
||||||
if (__gR5Compatibility) {
|
if (check_r5_compatibility()) {
|
||||||
convert_from_r5_sockaddr(&r5addr, address);
|
convert_from_r5_sockaddr(&r5addr, address);
|
||||||
address = &r5addr;
|
address = &r5addr;
|
||||||
addressLength = sizeof(struct sockaddr_in);
|
addressLength = sizeof(struct sockaddr_in);
|
||||||
@@ -362,7 +388,7 @@ sendmsg(int socket, const struct msghdr *message, int flags)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
getsockopt(int socket, int level, int option, void *value, size_t *_length)
|
getsockopt(int socket, int level, int option, void *value, size_t *_length)
|
||||||
{
|
{
|
||||||
if (__gR5Compatibility) {
|
if (check_r5_compatibility()) {
|
||||||
if (option == R5_SO_FIONREAD) {
|
if (option == R5_SO_FIONREAD) {
|
||||||
// there is no SO_FIONREAD in our stack; we're using FIONREAD instead
|
// there is no SO_FIONREAD in our stack; we're using FIONREAD instead
|
||||||
*_length = sizeof(int);
|
*_length = sizeof(int);
|
||||||
@@ -391,7 +417,7 @@ getsockopt(int socket, int level, int option, void *value, size_t *_length)
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
setsockopt(int socket, int level, int option, const void *value, size_t length)
|
setsockopt(int socket, int level, int option, const void *value, size_t length)
|
||||||
{
|
{
|
||||||
if (__gR5Compatibility)
|
if (check_r5_compatibility())
|
||||||
convert_from_r5_sockopt(level, option);
|
convert_from_r5_sockopt(level, option);
|
||||||
|
|
||||||
sockopt_args args;
|
sockopt_args args;
|
||||||
@@ -407,10 +433,11 @@ setsockopt(int socket, int level, int option, const void *value, size_t length)
|
|||||||
extern "C" int
|
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();
|
||||||
struct sockaddr r5addr;
|
struct sockaddr r5addr;
|
||||||
|
|
||||||
sockaddr_args args;
|
sockaddr_args args;
|
||||||
if (__gR5Compatibility) {
|
if (r5compatible) {
|
||||||
args.address = &r5addr;
|
args.address = &r5addr;
|
||||||
args.address_length = sizeof(r5addr);
|
args.address_length = sizeof(r5addr);
|
||||||
} else {
|
} else {
|
||||||
@@ -421,7 +448,7 @@ getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
|||||||
if (ioctl(socket, NET_STACK_GETPEERNAME, &args, sizeof(args)) < 0)
|
if (ioctl(socket, NET_STACK_GETPEERNAME, &args, sizeof(args)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (__gR5Compatibility) {
|
if (r5compatible) {
|
||||||
convert_to_r5_sockaddr(address, &r5addr);
|
convert_to_r5_sockaddr(address, &r5addr);
|
||||||
if (_addressLength != NULL)
|
if (_addressLength != NULL)
|
||||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
@@ -435,10 +462,11 @@ getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
|||||||
extern "C" int
|
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();
|
||||||
struct sockaddr r5addr;
|
struct sockaddr r5addr;
|
||||||
|
|
||||||
sockaddr_args args;
|
sockaddr_args args;
|
||||||
if (__gR5Compatibility) {
|
if (r5compatible) {
|
||||||
args.address = &r5addr;
|
args.address = &r5addr;
|
||||||
args.address_length = sizeof(r5addr);
|
args.address_length = sizeof(r5addr);
|
||||||
} else {
|
} else {
|
||||||
@@ -449,7 +477,7 @@ getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
|||||||
if (ioctl(socket, NET_STACK_GETSOCKNAME, &args, sizeof(args)) < 0)
|
if (ioctl(socket, NET_STACK_GETSOCKNAME, &args, sizeof(args)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (__gR5Compatibility) {
|
if (r5compatible) {
|
||||||
convert_to_r5_sockaddr(address, &r5addr);
|
convert_to_r5_sockaddr(address, &r5addr);
|
||||||
if (_addressLength != NULL)
|
if (_addressLength != NULL)
|
||||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
|
|||||||
Reference in New Issue
Block a user