* This fixes the problem when a socket changes something with regards to its parent. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30000 a95241bf-73f2-0310-859d-f6bbb57e9c96
302 lines
6.3 KiB
C++
302 lines
6.3 KiB
C++
/*
|
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
#include "stack_private.h"
|
|
|
|
|
|
/* Interface module providing networking to the kernel.
|
|
*/
|
|
|
|
|
|
static status_t
|
|
stack_interface_open(int family, int type, int protocol, net_socket** _socket)
|
|
{
|
|
return gNetSocketModule.open_socket(family, type, protocol, _socket);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_close(net_socket* socket)
|
|
{
|
|
return gNetSocketModule.close(socket);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_free(net_socket* socket)
|
|
{
|
|
gNetSocketModule.free(socket);
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_bind(net_socket* socket, const struct sockaddr* address,
|
|
socklen_t addressLength)
|
|
{
|
|
return gNetSocketModule.bind(socket, address, addressLength);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_shutdown(net_socket* socket, int how)
|
|
{
|
|
return gNetSocketModule.shutdown(socket, how);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_connect(net_socket* socket, const struct sockaddr* address,
|
|
socklen_t addressLength)
|
|
{
|
|
return gNetSocketModule.connect(socket, address, addressLength);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_listen(net_socket* socket, int backlog)
|
|
{
|
|
return gNetSocketModule.listen(socket, backlog);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_accept(net_socket* socket, struct sockaddr* address,
|
|
socklen_t* _addressLength, net_socket** _acceptedSocket)
|
|
{
|
|
return gNetSocketModule.accept(socket, address, _addressLength,
|
|
_acceptedSocket);
|
|
}
|
|
|
|
|
|
static ssize_t
|
|
stack_interface_recv(net_socket* socket, void* data, size_t length, int flags)
|
|
{
|
|
return gNetSocketModule.receive(socket, NULL, data, length, flags);
|
|
}
|
|
|
|
|
|
static ssize_t
|
|
stack_interface_recvfrom(net_socket* socket, void* data, size_t length,
|
|
int flags, struct sockaddr* address, socklen_t* _addressLength)
|
|
{
|
|
msghdr message;
|
|
iovec vecs[1] = { { data, length } };
|
|
message.msg_name = address;
|
|
if (_addressLength != NULL)
|
|
message.msg_namelen = *_addressLength;
|
|
else
|
|
message.msg_namelen = 0;
|
|
message.msg_iov = vecs;
|
|
message.msg_iovlen = 1;
|
|
message.msg_control = NULL;
|
|
message.msg_controllen = 0;
|
|
message.msg_flags = 0;
|
|
|
|
ssize_t received = gNetSocketModule.receive(socket, &message, data, length,
|
|
flags);
|
|
|
|
if (received >= 0 && _addressLength != NULL)
|
|
*_addressLength = message.msg_namelen;
|
|
|
|
return received;
|
|
}
|
|
|
|
|
|
static ssize_t
|
|
stack_interface_recvmsg(net_socket* socket, struct msghdr* message, int flags)
|
|
{
|
|
void* buffer = NULL;
|
|
size_t len = 0;
|
|
if (message->msg_iovlen > 0) {
|
|
buffer = message->msg_iov[0].iov_base;
|
|
len = message->msg_iov[0].iov_len;
|
|
}
|
|
|
|
return gNetSocketModule.receive(socket, message, buffer, len, flags);
|
|
}
|
|
|
|
|
|
static ssize_t
|
|
stack_interface_send(net_socket* socket, const void* data, size_t length,
|
|
int flags)
|
|
{
|
|
return gNetSocketModule.send(socket, NULL, data, length, flags);
|
|
}
|
|
|
|
|
|
static ssize_t
|
|
stack_interface_sendto(net_socket* socket, const void* data, size_t length,
|
|
int flags, const struct sockaddr* address, socklen_t addressLength)
|
|
{
|
|
msghdr message;
|
|
iovec vecs[1] = { { (void*)data, length } };
|
|
message.msg_name = (void*)address;
|
|
message.msg_namelen = addressLength;
|
|
message.msg_iov = vecs;
|
|
message.msg_iovlen = 1;
|
|
message.msg_control = NULL;
|
|
message.msg_controllen = 0;
|
|
message.msg_flags = 0;
|
|
|
|
return gNetSocketModule.send(socket, &message, data, length, flags);
|
|
}
|
|
|
|
|
|
static ssize_t
|
|
stack_interface_sendmsg(net_socket* socket, const struct msghdr* message,
|
|
int flags)
|
|
{
|
|
void* buffer = NULL;
|
|
size_t len = 0;
|
|
if (message->msg_iovlen > 0) {
|
|
buffer = message->msg_iov[0].iov_base;
|
|
len = message->msg_iov[0].iov_len;
|
|
}
|
|
|
|
return gNetSocketModule.send(socket, (msghdr*)message, buffer, len, flags);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_getsockopt(net_socket* socket, int level, int option,
|
|
void* value, socklen_t* _length)
|
|
{
|
|
int length = *_length;
|
|
status_t error = gNetSocketModule.getsockopt(socket, level, option, value,
|
|
&length);
|
|
*_length = length;
|
|
return error;
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_setsockopt(net_socket* socket, int level, int option,
|
|
const void* value, socklen_t length)
|
|
{
|
|
return gNetSocketModule.setsockopt(socket, level, option, value, length);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_getpeername(net_socket* socket, struct sockaddr* address,
|
|
socklen_t* _addressLength)
|
|
{
|
|
return gNetSocketModule.getpeername(socket, address, _addressLength);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_getsockname(net_socket* socket, struct sockaddr* address,
|
|
socklen_t* _addressLength)
|
|
{
|
|
return gNetSocketModule.getsockname(socket, address, _addressLength);
|
|
}
|
|
|
|
|
|
static int
|
|
stack_interface_sockatmark(net_socket* socket)
|
|
{
|
|
// TODO:...
|
|
return B_UNSUPPORTED;
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_socketpair(int family, int type, int protocol,
|
|
net_socket* _sockets[2])
|
|
{
|
|
return gNetSocketModule.socketpair(family, type, protocol, _sockets);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_ioctl(net_socket* socket, uint32 op, void *buffer,
|
|
size_t length)
|
|
{
|
|
return gNetSocketModule.control(socket, op, buffer, length);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_select(net_socket* socket, uint8 event, struct selectsync *sync)
|
|
{
|
|
return gNetSocketModule.request_notification(socket, event, sync);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_deselect(net_socket* socket, uint8 event,
|
|
struct selectsync *sync)
|
|
{
|
|
return gNetSocketModule.cancel_notification(socket, event, sync);
|
|
}
|
|
|
|
|
|
status_t
|
|
stack_interface_get_next_socket_stat(int family, uint32 *cookie,
|
|
struct net_stat *stat)
|
|
{
|
|
return gNetSocketModule.get_next_stat(cookie, family, stat);
|
|
}
|
|
|
|
|
|
static status_t
|
|
stack_interface_std_ops(int32 op, ...)
|
|
{
|
|
switch (op) {
|
|
case B_MODULE_INIT:
|
|
return init_stack();
|
|
case B_MODULE_UNINIT:
|
|
return uninit_stack();
|
|
|
|
default:
|
|
return B_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
net_stack_interface_module_info gNetStackInterfaceModule = {
|
|
{
|
|
NET_STACK_INTERFACE_MODULE_NAME,
|
|
0,
|
|
stack_interface_std_ops
|
|
},
|
|
|
|
&stack_interface_open,
|
|
&stack_interface_close,
|
|
&stack_interface_free,
|
|
|
|
&stack_interface_bind,
|
|
&stack_interface_shutdown,
|
|
&stack_interface_connect,
|
|
&stack_interface_listen,
|
|
&stack_interface_accept,
|
|
|
|
&stack_interface_recv,
|
|
&stack_interface_recvfrom,
|
|
&stack_interface_recvmsg,
|
|
|
|
&stack_interface_send,
|
|
&stack_interface_sendto,
|
|
&stack_interface_sendmsg,
|
|
|
|
&stack_interface_getsockopt,
|
|
&stack_interface_setsockopt,
|
|
|
|
&stack_interface_getpeername,
|
|
&stack_interface_getsockname,
|
|
|
|
&stack_interface_sockatmark,
|
|
|
|
&stack_interface_socketpair,
|
|
|
|
&stack_interface_ioctl,
|
|
&stack_interface_select,
|
|
&stack_interface_deselect,
|
|
|
|
&stack_interface_get_next_socket_stat
|
|
};
|