* Added a link from libnet.so to libnetwork.so for R5 compatibility.
* Fixed R5 socket definitions to match their actual definitions. * libnetwork.so now detects at runtime wether or not R5 compatibility should be enabled or not. * All socket functions should now be R5 net_server compatible. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19012 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -136,6 +136,7 @@ AddFilesToHaikuImage beos system : kernel_$(TARGET_ARCH) ;
|
|||||||
AddFilesToHaikuImage beos system lib : $(BEOS_SYSTEM_LIB) ;
|
AddFilesToHaikuImage beos system lib : $(BEOS_SYSTEM_LIB) ;
|
||||||
AddSymlinkToHaikuImage beos system lib : libnetwork.so : libsocket.so ;
|
AddSymlinkToHaikuImage beos system lib : libnetwork.so : libsocket.so ;
|
||||||
AddSymlinkToHaikuImage beos system lib : libnetwork.so : libbind.so ;
|
AddSymlinkToHaikuImage beos system lib : libnetwork.so : libbind.so ;
|
||||||
|
AddSymlinkToHaikuImage beos system lib : libnetwork.so : libnet.so ;
|
||||||
|
|
||||||
# servers
|
# servers
|
||||||
AddFilesToHaikuImage beos system servers : $(BEOS_SYSTEM_SERVERS) ;
|
AddFilesToHaikuImage beos system servers : $(BEOS_SYSTEM_SERVERS) ;
|
||||||
|
|||||||
@@ -5,11 +5,39 @@
|
|||||||
#ifndef NET_R5_COMPATIBILITY_H
|
#ifndef NET_R5_COMPATIBILITY_H
|
||||||
#define NET_R5_COMPATIBILITY_H
|
#define NET_R5_COMPATIBILITY_H
|
||||||
|
|
||||||
// TODO: judging from R5 headers, this is all wrong, though (this has been taken from
|
|
||||||
// our old socket header) - we'll need to test this later on!
|
#include <SupportDefs.h>
|
||||||
// Also, more problematic is that IPPROTO_* constants also don't seem to be compatible, too
|
|
||||||
#define R5_SOCK_DGRAM 10
|
|
||||||
#define R5_SOCK_STREAM 11
|
#define R5_SOCK_DGRAM 1
|
||||||
#define R5_SOCK_RAW 12
|
#define R5_SOCK_STREAM 2
|
||||||
|
|
||||||
|
#define R5_AF_INET 1
|
||||||
|
|
||||||
|
#define R5_IPPROTO_UDP 1
|
||||||
|
#define R5_IPPROTO_TCP 2
|
||||||
|
#define R5_IPPROTO_ICMP 3
|
||||||
|
|
||||||
|
// setsockopt() defines
|
||||||
|
|
||||||
|
#define R5_SOL_SOCKET 1
|
||||||
|
|
||||||
|
#define R5_SO_DEBUG 1
|
||||||
|
#define R5_SO_REUSEADDR 2
|
||||||
|
#define R5_SO_NONBLOCK 3
|
||||||
|
#define R5_SO_REUSEPORT 4
|
||||||
|
#define R5_SO_FIONREAD 5
|
||||||
|
|
||||||
|
#define R5_MSG_OOB 0x01
|
||||||
|
|
||||||
|
|
||||||
|
struct r5_sockaddr_in {
|
||||||
|
uint16 sin_family;
|
||||||
|
uint16 sin_port;
|
||||||
|
uint32 sin_addr;
|
||||||
|
char sin_zero[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern bool __gR5Compatibility;
|
||||||
|
|
||||||
#endif // NET_R5_COMPATIBILITY_H
|
#endif // NET_R5_COMPATIBILITY_H
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
SubDir HAIKU_TOP src kits network ;
|
SubDir HAIKU_TOP src kits network ;
|
||||||
|
|
||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders libroot net ;
|
||||||
|
|
||||||
SharedLibrary libnetwork.so :
|
SharedLibrary libnetwork.so :
|
||||||
|
init.cpp
|
||||||
interfaces.cpp
|
interfaces.cpp
|
||||||
socket.cpp
|
socket.cpp
|
||||||
:
|
:
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <libroot_private.h>
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <image.h>
|
||||||
|
|
||||||
|
|
||||||
|
bool __gR5Compatibility = false;
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
initialize_before()
|
||||||
|
{
|
||||||
|
// determine if we have to run in R5 compatibility mode
|
||||||
|
|
||||||
|
// get image of executable
|
||||||
|
image_info info;
|
||||||
|
uint32 cookie = 0;
|
||||||
|
if (get_next_image_info(B_CURRENT_TEAM, (int32 *)&cookie, &info) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (get_image_symbol(info.id, "__gHaikuStartupCode", B_SYMBOL_TYPE_DATA,
|
||||||
|
NULL) == B_OK) {
|
||||||
|
// we were linked on/for Haiku
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're using the BeOS startup code, check if BONE libraries are in
|
||||||
|
// use, and if not, enable the R5 compatibility layer.
|
||||||
|
|
||||||
|
const char *name;
|
||||||
|
cookie = 0;
|
||||||
|
int enable = 0;
|
||||||
|
|
||||||
|
while (__get_next_image_dependency(info.id, &cookie, &name) == B_OK) {
|
||||||
|
if (!strcmp(name, "libbind.so")
|
||||||
|
|| !strcmp(name, "libsocket.so")
|
||||||
|
|| !strcmp(name, "libnetwork.so")
|
||||||
|
enable -= 2;
|
||||||
|
else if (!strcmp(name, "libnet.so"))
|
||||||
|
enable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable > 0) {
|
||||||
|
__gR5Compatibility = true;
|
||||||
|
debug_printf("libnetwork.so running in R5 compatibility mode.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
+204
-13
@@ -9,10 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <net_stack_driver.h>
|
#include <net_stack_driver.h>
|
||||||
|
#include <r5_compatibility.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <netinet/in.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
// TODO: this is meant for debugging purposes only, and should be disabled later
|
// TODO: this is meant for debugging purposes only, and should be disabled later
|
||||||
@@ -29,6 +33,106 @@ stack_driver_path(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_from_r5_sockaddr(struct sockaddr *_to, const struct sockaddr *_from)
|
||||||
|
{
|
||||||
|
const r5_sockaddr_in *from = (r5_sockaddr_in *)_from;
|
||||||
|
sockaddr_in *to = (sockaddr_in *)_to;
|
||||||
|
|
||||||
|
memset(to, 0, sizeof(*to));
|
||||||
|
to->sin_len = sizeof(*to);
|
||||||
|
|
||||||
|
if (from->sin_family == R5_AF_INET)
|
||||||
|
to->sin_family = AF_INET;
|
||||||
|
else
|
||||||
|
to->sin_family = from->sin_family;
|
||||||
|
|
||||||
|
to->sin_port = from->sin_port;
|
||||||
|
to->sin_addr.s_addr = from->sin_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_to_r5_sockaddr(struct sockaddr *_to, const struct sockaddr *_from)
|
||||||
|
{
|
||||||
|
const sockaddr_in *from = (sockaddr_in *)_from;
|
||||||
|
r5_sockaddr_in *to = (r5_sockaddr_in *)_to;
|
||||||
|
|
||||||
|
memset(to, 0, sizeof(*to));
|
||||||
|
if (from->sin_family == AF_INET)
|
||||||
|
to->sin_family = R5_AF_INET;
|
||||||
|
else
|
||||||
|
to->sin_family = from->sin_family;
|
||||||
|
|
||||||
|
to->sin_port = from->sin_port;
|
||||||
|
to->sin_addr = from->sin_addr.s_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_from_r5_socket(int& family, int& type, int& protocol)
|
||||||
|
{
|
||||||
|
switch (family) {
|
||||||
|
case R5_AF_INET:
|
||||||
|
family = AF_INET;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case R5_SOCK_DGRAM:
|
||||||
|
type = SOCK_DGRAM;
|
||||||
|
break;
|
||||||
|
case R5_SOCK_STREAM:
|
||||||
|
type = SOCK_STREAM;
|
||||||
|
break;
|
||||||
|
#if 0
|
||||||
|
case R5_SOCK_RAW:
|
||||||
|
type = SOCK_RAW;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (protocol) {
|
||||||
|
case R5_IPPROTO_UDP:
|
||||||
|
protocol = IPPROTO_UDP;
|
||||||
|
break;
|
||||||
|
case R5_IPPROTO_TCP:
|
||||||
|
protocol = R5_IPPROTO_TCP;
|
||||||
|
break;
|
||||||
|
case R5_IPPROTO_ICMP:
|
||||||
|
protocol = R5_IPPROTO_ICMP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_from_r5_sockopt(int& level, int& option)
|
||||||
|
{
|
||||||
|
if (level == R5_SOL_SOCKET)
|
||||||
|
level = SOL_SOCKET;
|
||||||
|
|
||||||
|
switch (option) {
|
||||||
|
case R5_SO_DEBUG:
|
||||||
|
option = SO_DEBUG;
|
||||||
|
break;
|
||||||
|
case R5_SO_REUSEADDR:
|
||||||
|
option = SO_REUSEADDR;
|
||||||
|
break;
|
||||||
|
case R5_SO_NONBLOCK:
|
||||||
|
option = SO_NONBLOCK;
|
||||||
|
break;
|
||||||
|
case R5_SO_REUSEPORT:
|
||||||
|
option = SO_REUSEPORT;
|
||||||
|
break;
|
||||||
|
case R5_SO_FIONREAD:
|
||||||
|
// there is no SO_FIONREAD
|
||||||
|
option = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -39,6 +143,9 @@ socket(int family, int type, int protocol)
|
|||||||
if (socket < 0)
|
if (socket < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (__gR5Compatibility)
|
||||||
|
convert_from_r5_socket(family, type, protocol);
|
||||||
|
|
||||||
socket_args args;
|
socket_args args;
|
||||||
args.family = family;
|
args.family = family;
|
||||||
args.type = type;
|
args.type = type;
|
||||||
@@ -56,6 +163,14 @@ 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;
|
||||||
|
|
||||||
|
if (__gR5Compatibility) {
|
||||||
|
convert_from_r5_sockaddr(&r5addr, address);
|
||||||
|
address = &r5addr;
|
||||||
|
addressLength = sizeof(struct sockaddr_in);
|
||||||
|
}
|
||||||
|
|
||||||
sockaddr_args args;
|
sockaddr_args args;
|
||||||
args.address = const_cast<struct sockaddr *>(address);
|
args.address = const_cast<struct sockaddr *>(address);
|
||||||
args.address_length = addressLength;
|
args.address_length = addressLength;
|
||||||
@@ -74,6 +189,14 @@ 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;
|
||||||
|
|
||||||
|
if (__gR5Compatibility) {
|
||||||
|
convert_from_r5_sockaddr(&r5addr, address);
|
||||||
|
address = &r5addr;
|
||||||
|
addressLength = sizeof(struct sockaddr_in);
|
||||||
|
}
|
||||||
|
|
||||||
sockaddr_args args;
|
sockaddr_args args;
|
||||||
args.address = const_cast<struct sockaddr *>(address);
|
args.address = const_cast<struct sockaddr *>(address);
|
||||||
args.address_length = addressLength;
|
args.address_length = addressLength;
|
||||||
@@ -106,17 +229,30 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sockaddr r5addr;
|
||||||
accept_args args;
|
accept_args args;
|
||||||
|
|
||||||
args.cookie = cookie;
|
args.cookie = cookie;
|
||||||
args.address = address;
|
|
||||||
args.address_length = _addressLength ? *_addressLength : 0;
|
if (__gR5Compatibility) {
|
||||||
|
args.address = &r5addr;
|
||||||
|
args.address_length = sizeof(r5addr);
|
||||||
|
} else {
|
||||||
|
args.address = address;
|
||||||
|
args.address_length = _addressLength ? *_addressLength : 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ioctl(socket, NET_STACK_ACCEPT, &args, sizeof(args)) < 0) {
|
if (ioctl(socket, NET_STACK_ACCEPT, &args, sizeof(args)) < 0) {
|
||||||
close(acceptSocket);
|
close(acceptSocket);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*_addressLength = args.address_length;
|
if (__gR5Compatibility) {
|
||||||
|
convert_to_r5_sockaddr(address, &r5addr);
|
||||||
|
if (_addressLength != NULL)
|
||||||
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
|
} else if (_addressLength != NULL)
|
||||||
|
*_addressLength = args.address_length;
|
||||||
|
|
||||||
return acceptSocket;
|
return acceptSocket;
|
||||||
}
|
}
|
||||||
@@ -140,18 +276,30 @@ 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)
|
||||||
{
|
{
|
||||||
|
struct sockaddr r5addr;
|
||||||
|
|
||||||
transfer_args args;
|
transfer_args args;
|
||||||
args.data = data;
|
args.data = data;
|
||||||
args.data_length = length;
|
args.data_length = length;
|
||||||
args.flags = flags;
|
args.flags = flags;
|
||||||
args.address = address;
|
|
||||||
args.address_length = _addressLength ? *_addressLength : 0;
|
if (__gR5Compatibility) {
|
||||||
|
args.address = &r5addr;
|
||||||
|
args.address_length = sizeof(r5addr);
|
||||||
|
} else {
|
||||||
|
args.address = address;
|
||||||
|
args.address_length = _addressLength ? *_addressLength : 0;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t bytesReceived = ioctl(socket, NET_STACK_RECVFROM, &args, sizeof(args));
|
ssize_t bytesReceived = ioctl(socket, NET_STACK_RECVFROM, &args, sizeof(args));
|
||||||
if (bytesReceived < 0)
|
if (bytesReceived < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (_addressLength)
|
if (__gR5Compatibility) {
|
||||||
|
convert_to_r5_sockaddr(address, &r5addr);
|
||||||
|
if (_addressLength != NULL)
|
||||||
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
|
} else if (_addressLength != NULL)
|
||||||
*_addressLength = args.address_length;
|
*_addressLength = args.address_length;
|
||||||
|
|
||||||
return bytesReceived;
|
return bytesReceived;
|
||||||
@@ -184,6 +332,14 @@ 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;
|
||||||
|
|
||||||
|
if (__gR5Compatibility) {
|
||||||
|
convert_from_r5_sockaddr(&r5addr, address);
|
||||||
|
address = &r5addr;
|
||||||
|
addressLength = sizeof(struct sockaddr_in);
|
||||||
|
}
|
||||||
|
|
||||||
transfer_args args;
|
transfer_args args;
|
||||||
args.data = const_cast<void *>(data);
|
args.data = const_cast<void *>(data);
|
||||||
args.data_length = length;
|
args.data_length = length;
|
||||||
@@ -206,6 +362,16 @@ 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 (option == R5_SO_FIONREAD) {
|
||||||
|
// there is no SO_FIONREAD in our stack; we're using FIONREAD instead
|
||||||
|
*_length = sizeof(int);
|
||||||
|
return ioctl(socket, FIONREAD, &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_from_r5_sockopt(level, option);
|
||||||
|
}
|
||||||
|
|
||||||
sockopt_args args;
|
sockopt_args args;
|
||||||
args.level = level;
|
args.level = level;
|
||||||
args.option = option;
|
args.option = option;
|
||||||
@@ -225,6 +391,9 @@ 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)
|
||||||
|
convert_from_r5_sockopt(level, option);
|
||||||
|
|
||||||
sockopt_args args;
|
sockopt_args args;
|
||||||
args.level = level;
|
args.level = level;
|
||||||
args.option = option;
|
args.option = option;
|
||||||
@@ -238,14 +407,25 @@ 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)
|
||||||
{
|
{
|
||||||
|
struct sockaddr r5addr;
|
||||||
|
|
||||||
sockaddr_args args;
|
sockaddr_args args;
|
||||||
args.address = address;
|
if (__gR5Compatibility) {
|
||||||
args.address_length = _addressLength ? *_addressLength : 0;
|
args.address = &r5addr;
|
||||||
|
args.address_length = sizeof(r5addr);
|
||||||
|
} else {
|
||||||
|
args.address = address;
|
||||||
|
args.address_length = _addressLength ? *_addressLength : 0;
|
||||||
|
}
|
||||||
|
|
||||||
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 (_addressLength)
|
if (__gR5Compatibility) {
|
||||||
|
convert_to_r5_sockaddr(address, &r5addr);
|
||||||
|
if (_addressLength != NULL)
|
||||||
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
|
} else if (_addressLength != NULL)
|
||||||
*_addressLength = args.address_length;
|
*_addressLength = args.address_length;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -255,14 +435,25 @@ 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)
|
||||||
{
|
{
|
||||||
|
struct sockaddr r5addr;
|
||||||
|
|
||||||
sockaddr_args args;
|
sockaddr_args args;
|
||||||
args.address = address;
|
if (__gR5Compatibility) {
|
||||||
args.address_length = _addressLength ? *_addressLength : 0;
|
args.address = &r5addr;
|
||||||
|
args.address_length = sizeof(r5addr);
|
||||||
|
} else {
|
||||||
|
args.address = address;
|
||||||
|
args.address_length = _addressLength ? *_addressLength : 0;
|
||||||
|
}
|
||||||
|
|
||||||
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 (_addressLength)
|
if (__gR5Compatibility) {
|
||||||
|
convert_to_r5_sockaddr(address, &r5addr);
|
||||||
|
if (_addressLength != NULL)
|
||||||
|
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||||
|
} else if (_addressLength != NULL)
|
||||||
*_addressLength = args.address_length;
|
*_addressLength = args.address_length;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user