fixed the way accept() works in regards to the cookie pointer. It is no longer visible to userspace, we pass the fd instead. Also renamed kernel's shutdown() to system_shutdown as it collides with Posix's shutdown().
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21223 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
be2f6ac347
commit
77bf99deb0
@ -86,6 +86,8 @@ extern void fd_set_close_on_exec(struct io_context *context, int fd, bool closeF
|
|||||||
|
|
||||||
static struct io_context *get_current_io_context(bool kernel);
|
static struct io_context *get_current_io_context(bool kernel);
|
||||||
|
|
||||||
|
extern status_t user_fd_kernel_ioctl(int fd, ulong op, void *buffer, size_t length);
|
||||||
|
|
||||||
/* The prototypes of the (sys|user)_ functions are currently defined in vfs.h */
|
/* The prototypes of the (sys|user)_ functions are currently defined in vfs.h */
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ extern bool kernel_startup;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
status_t shutdown(bool reboot);
|
status_t system_shutdown(bool reboot);
|
||||||
status_t _user_shutdown(bool reboot);
|
status_t _user_shutdown(bool reboot);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -23,7 +23,7 @@ enum {
|
|||||||
|
|
||||||
// ops not acting on an existing socket
|
// ops not acting on an existing socket
|
||||||
NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args *
|
NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args *
|
||||||
NET_STACK_GET_COOKIE, // void **
|
NET_STACK_GET_COOKIE, // void **
|
||||||
NET_STACK_CONTROL_NET_MODULE, // control_net_module_args *
|
NET_STACK_CONTROL_NET_MODULE, // control_net_module_args *
|
||||||
NET_STACK_GET_NEXT_STAT, // get_next_stat_args *
|
NET_STACK_GET_NEXT_STAT, // get_next_stat_args *
|
||||||
|
|
||||||
@ -72,13 +72,13 @@ struct socket_args { // used by NET_STACK_SOCKET
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct socketpair_args { // used by NET_STACK_SOCKETPAIR
|
struct socketpair_args { // used by NET_STACK_SOCKETPAIR
|
||||||
void *cookie;
|
int second_socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct accept_args { // used by NET_STACK_ACCEPT
|
struct accept_args { // used by NET_STACK_ACCEPT
|
||||||
void *cookie;
|
int accept_socket;
|
||||||
struct sockaddr *address;
|
struct sockaddr *address;
|
||||||
socklen_t address_length;
|
socklen_t address_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct get_next_stat_args { // used by NET_STACK_GET_NEXT_STAT
|
struct get_next_stat_args { // used by NET_STACK_GET_NEXT_STAT
|
||||||
|
@ -11,6 +11,7 @@ if ( $(TARGET_PLATFORM) != haiku ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UsePrivateHeaders kernel net ;
|
UsePrivateHeaders kernel net ;
|
||||||
|
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
|
||||||
|
|
||||||
# a) Userland stack version:
|
# a) Userland stack version:
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
|
|
||||||
|
#include <kernel.h> // IS_KERNEL_ADDRESS
|
||||||
|
#include <fs/fd.h> // user_fd_kernel_ioctl
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -194,6 +197,17 @@ opcode_name(int op)
|
|||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
resolve_cookie(int kernel, int socket, net_stack_cookie **cookie)
|
||||||
|
{
|
||||||
|
if (kernel)
|
||||||
|
return ioctl(socket, NET_STACK_GET_COOKIE, cookie, sizeof(*cookie));
|
||||||
|
else
|
||||||
|
return user_fd_kernel_ioctl(socket, NET_STACK_GET_COOKIE, cookie,
|
||||||
|
sizeof(*cookie));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - device
|
// #pragma mark - device
|
||||||
|
|
||||||
|
|
||||||
@ -297,10 +311,10 @@ net_stack_control(void *_cookie, uint32 op, void *data, size_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case NET_STACK_GET_COOKIE:
|
case NET_STACK_GET_COOKIE:
|
||||||
// This is needed by accept() call, allowing libnet.so accept() to pass back
|
if (!IS_KERNEL_ADDRESS(data))
|
||||||
// in NET_STACK_ACCEPT opcode the cookie (aka the net_stack_cookie!)
|
return B_BAD_ADDRESS;
|
||||||
// of the file descriptor to use for the new accepted socket
|
*((net_stack_cookie **)data) = cookie;
|
||||||
return user_memcpy(data, &cookie, sizeof(void *));
|
return B_OK;
|
||||||
|
|
||||||
case NET_STACK_GET_NEXT_STAT:
|
case NET_STACK_GET_NEXT_STAT:
|
||||||
{
|
{
|
||||||
@ -349,18 +363,22 @@ net_stack_control(void *_cookie, uint32 op, void *data, size_t length)
|
|||||||
|
|
||||||
case NET_STACK_ACCEPT:
|
case NET_STACK_ACCEPT:
|
||||||
{
|
{
|
||||||
|
int kernel = IS_KERNEL_ADDRESS(data);
|
||||||
sockaddr_storage address;
|
sockaddr_storage address;
|
||||||
accept_args args;
|
accept_args args;
|
||||||
|
|
||||||
status = check_args_and_address(args, address, data, length, false);
|
status = check_args_and_address(args, address, data, length, false);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// args.cookie is the net_stack_cookie of the already opened socket
|
net_stack_cookie *accept_cookie;
|
||||||
// TODO: find a safer way to do this!
|
status = resolve_cookie(kernel, args.accept_socket,
|
||||||
|
&accept_cookie);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
net_stack_cookie *acceptCookie = (net_stack_cookie *)args.cookie;
|
|
||||||
status = sSocket->accept(cookie->socket, args.address,
|
status = sSocket->accept(cookie->socket, args.address,
|
||||||
&args.address_length, &acceptCookie->socket);
|
&args.address_length, &accept_cookie->socket);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
@ -84,18 +84,8 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
|||||||
if (acceptSocket < 0)
|
if (acceptSocket < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// The network stack driver will need to know to which net_stack_cookie to
|
|
||||||
// *bind* with the new accepted socket. It can't itself find out, so we need
|
|
||||||
// to pass it the cookie used internally.
|
|
||||||
// TODO: change this to a safer approach using IDs!
|
|
||||||
void *cookie;
|
|
||||||
if (ioctl(acceptSocket, NET_STACK_GET_COOKIE, &cookie) < 0) {
|
|
||||||
close(acceptSocket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
accept_args args;
|
accept_args args;
|
||||||
args.cookie = cookie;
|
args.accept_socket = acceptSocket;
|
||||||
args.address = address;
|
args.address = address;
|
||||||
args.address_length = _addressLength ? *_addressLength : 0;
|
args.address_length = _addressLength ? *_addressLength : 0;
|
||||||
|
|
||||||
@ -315,14 +305,8 @@ socketpair(int family, int type, int protocol, int socketVector[2])
|
|||||||
if (socketVector[1] < 0)
|
if (socketVector[1] < 0)
|
||||||
goto err1;
|
goto err1;
|
||||||
|
|
||||||
// TODO: find a better way to do this!
|
|
||||||
void *cookie;
|
|
||||||
if (ioctl(socketVector[1], NET_STACK_GET_COOKIE, &cookie) < 0)
|
|
||||||
goto err2;
|
|
||||||
|
|
||||||
socketpair_args args;
|
socketpair_args args;
|
||||||
args.cookie = cookie;
|
args.second_socket = socketVector[1];
|
||||||
// this way driver can use the right fd/cookie!
|
|
||||||
|
|
||||||
if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0)
|
if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0)
|
||||||
goto err2;
|
goto err2;
|
||||||
@ -330,7 +314,7 @@ socketpair(int family, int type, int protocol, int socketVector[2])
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err2:
|
err2:
|
||||||
close(socketVector[1]);
|
close(socketVector[1]);
|
||||||
err1:
|
err1:
|
||||||
close(socketVector[0]);
|
close(socketVector[0]);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -249,21 +249,11 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
|||||||
if (acceptSocket < 0)
|
if (acceptSocket < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// The network stack driver will need to know to which net_stack_cookie to
|
|
||||||
// *bind* with the new accepted socket. It can't itself find out, so we need
|
|
||||||
// to pass it the cookie used internally.
|
|
||||||
// TODO: change this to a safer approach using IDs!
|
|
||||||
void *cookie;
|
|
||||||
if (ioctl(acceptSocket, NET_STACK_GET_COOKIE, &cookie) < 0) {
|
|
||||||
close(acceptSocket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool r5compatible = check_r5_compatibility();
|
bool r5compatible = check_r5_compatibility();
|
||||||
struct sockaddr r5addr;
|
struct sockaddr r5addr;
|
||||||
accept_args args;
|
accept_args args;
|
||||||
|
|
||||||
args.cookie = cookie;
|
args.accept_socket = acceptSocket;
|
||||||
|
|
||||||
if (r5compatible && address != NULL) {
|
if (r5compatible && address != NULL) {
|
||||||
args.address = &r5addr;
|
args.address = &r5addr;
|
||||||
@ -549,14 +539,8 @@ socketpair(int family, int type, int protocol, int socketVector[2])
|
|||||||
if (socketVector[1] < 0)
|
if (socketVector[1] < 0)
|
||||||
goto err1;
|
goto err1;
|
||||||
|
|
||||||
// TODO: find a better way to do this!
|
|
||||||
void *cookie;
|
|
||||||
if (ioctl(socketVector[1], NET_STACK_GET_COOKIE, &cookie) < 0)
|
|
||||||
goto err2;
|
|
||||||
|
|
||||||
socketpair_args args;
|
socketpair_args args;
|
||||||
args.cookie = cookie;
|
args.second_socket = socketVector[1];
|
||||||
// this way driver can use the right fd/cookie!
|
|
||||||
|
|
||||||
if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0)
|
if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0)
|
||||||
goto err2;
|
goto err2;
|
||||||
@ -564,7 +548,7 @@ socketpair(int family, int type, int protocol, int socketVector[2])
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err2:
|
err2:
|
||||||
close(socketVector[1]);
|
close(socketVector[1]);
|
||||||
err1:
|
err1:
|
||||||
close(socketVector[0]);
|
close(socketVector[0]);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -956,15 +956,15 @@ _kern_seek(int fd, off_t pos, int seekType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static status_t
|
||||||
_kern_ioctl(int fd, ulong op, void *buffer, size_t length)
|
_fd_ioctl(bool kernel_fd, int fd, ulong op, void *buffer, size_t length)
|
||||||
{
|
{
|
||||||
struct file_descriptor *descriptor;
|
struct file_descriptor *descriptor;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
TRACE(("sys_ioctl: fd %d\n", fd));
|
TRACE(("sys_ioctl: fd %d\n", fd));
|
||||||
|
|
||||||
descriptor = get_fd(get_current_io_context(true), fd);
|
descriptor = get_fd(get_current_io_context(kernel_fd), fd);
|
||||||
if (descriptor == NULL)
|
if (descriptor == NULL)
|
||||||
return B_FILE_ERROR;
|
return B_FILE_ERROR;
|
||||||
|
|
||||||
@ -978,6 +978,20 @@ _kern_ioctl(int fd, ulong op, void *buffer, size_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
_kern_ioctl(int fd, ulong op, void *buffer, size_t length)
|
||||||
|
{
|
||||||
|
return _fd_ioctl(true, fd, op, buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
user_fd_kernel_ioctl(int fd, ulong op, void *buffer, size_t length)
|
||||||
|
{
|
||||||
|
return _fd_ioctl(false, fd, op, buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
_kern_read_dir(int fd, struct dirent *buffer, size_t bufferSize, uint32 maxCount)
|
_kern_read_dir(int fd, struct dirent *buffer, size_t bufferSize, uint32 maxCount)
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
shutdown(bool reboot)
|
system_shutdown(bool reboot)
|
||||||
{
|
{
|
||||||
// ToDo: shutdown all system services!
|
// ToDo: shutdown all system services!
|
||||||
|
|
||||||
@ -27,6 +27,6 @@ _user_shutdown(bool reboot)
|
|||||||
{
|
{
|
||||||
if (geteuid() != 0)
|
if (geteuid() != 0)
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
return shutdown(reboot);
|
return system_shutdown(reboot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user