lxip: correct msghdr initialization

This commit is contained in:
Christian Helmuth 2017-05-29 13:06:16 +02:00
parent 6d941ede1c
commit a431657851
3 changed files with 90 additions and 99 deletions

View File

@ -0,0 +1,42 @@
/*
* \brief Complete initialization of msghdr
* \author Christian Helmuth
* \date 2017-05-29
*/
/*
* Copyright (C) 202017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _MSGHDR_H_
#define _MSGHDR_H_
#include <lx_emul/extern_c_begin.h>
#include <linux/socket.h>
#include <lx_emul/extern_c_end.h>
static inline msghdr create_msghdr(void *name, int namelen, size_t datalen,
struct iovec *iov)
{
msghdr msg;
msg.msg_name = name;
msg.msg_namelen = namelen;
msg.msg_iter.type = 0;
msg.msg_iter.iov_offset = 0;
msg.msg_iter.count = datalen;
msg.msg_iter.iov = iov;
msg.msg_iter.nr_segs = 1;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_flags = 0;
msg.msg_iocb = nullptr;
return msg;
}
#endif /* _MSGHDR_H_ */

View File

@ -30,19 +30,20 @@ static const bool verbose = false;
namespace Linux {
#include <lx_emul.h>
#include <lx_emul.h>
#include <msghdr.h>
#include <lx_emul/extern_c_begin.h>
#include <linux/socket.h>
#include <uapi/linux/in.h>
extern int sock_setsockopt(struct socket *sock, int level,
int op, char __user *optval,
unsigned int optlen);
extern int sock_getsockopt(struct socket *sock, int level,
int op, char __user *optval,
int __user *optlen);
struct socket *sock_alloc(void);
#include <lx_emul/extern_c_end.h>
#include <lx_emul/extern_c_begin.h>
#include <linux/socket.h>
#include <uapi/linux/in.h>
extern int sock_setsockopt(struct socket *sock, int level,
int op, char __user *optval,
unsigned int optlen);
extern int sock_getsockopt(struct socket *sock, int level,
int op, char __user *optval,
int __user *optlen);
struct socket *sock_alloc(void);
#include <lx_emul/extern_c_end.h>
}
namespace Net
@ -299,20 +300,11 @@ class Net::Socketcall : public Lxip::Socketcall,
void _do_recv()
{
using namespace Linux;
struct msghdr msg;
struct iovec iov;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_iter.iov = &iov;
msg.msg_iter.nr_segs = 1;
msg.msg_iter.count = _call.msg.len;
iovec iov { _call.msg.buf, _call.msg.len };
iov.iov_len = _call.msg.len;
iov.iov_base = _call.msg.buf;
msg.msg_name = _call.addr_len ? &_call.addr : 0;
msg.msg_namelen = _call.addr_len;
msg.msg_flags = 0;
msghdr msg = create_msghdr(_call.addr_len ? &_call.addr : nullptr,
_call.addr_len, _call.msg.len, &iov);
if (_call.handle.non_block)
msg.msg_flags |= MSG_DONTWAIT;
@ -331,25 +323,17 @@ class Net::Socketcall : public Lxip::Socketcall,
void _do_send()
{
using namespace Linux;
struct msghdr msg;
struct iovec iov;
_result.len = socket_check_state(call_socket());
if (_result.len < 0)
return;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_iter.iov = &iov;
msg.msg_iter.nr_segs = 1;
msg.msg_iter.count = _call.msg.len;
iovec iov { _call.msg.buf, _call.msg.len };
iov.iov_len = _call.msg.len;
iov.iov_base = _call.msg.buf;
msg.msg_name = _call.addr_len ? &_call.addr : 0;
msg.msg_namelen = _call.addr_len;
msg.msg_flags = _call.msg.flags;
msghdr msg = create_msghdr(_call.addr_len ? &_call.addr : nullptr,
_call.addr_len, _call.msg.len, &iov);
msg.msg_flags = _call.msg.flags;
if (_call.handle.non_block)
msg.msg_flags |= MSG_DONTWAIT;

View File

@ -34,26 +34,27 @@
namespace Linux {
#include <lx_emul.h>
#include <lx_emul.h>
#include <msghdr.h>
#include <lx_emul/extern_c_begin.h>
#include <linux/socket.h>
#include <uapi/linux/in.h>
#include <uapi/linux/if.h>
extern int sock_setsockopt(socket *sock, int level,
int op, char __user *optval,
unsigned int optlen);
extern int sock_getsockopt(socket *sock, int level,
int op, char __user *optval,
int __user *optlen);
socket *sock_alloc(void);
#include <lx_emul/extern_c_end.h>
#include <lx_emul/extern_c_begin.h>
#include <linux/socket.h>
#include <uapi/linux/in.h>
#include <uapi/linux/if.h>
extern int sock_setsockopt(socket *sock, int level,
int op, char __user *optval,
unsigned int optlen);
extern int sock_getsockopt(socket *sock, int level,
int op, char __user *optval,
int __user *optlen);
socket *sock_alloc(void);
#include <lx_emul/extern_c_end.h>
enum {
POLLIN_SET = (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR),
POLLOUT_SET = (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR),
POLLEX_SET = (POLLPRI)
};
enum {
POLLIN_SET = (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR),
POLLOUT_SET = (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR),
POLLEX_SET = (POLLPRI)
};
}
@ -347,22 +348,10 @@ class Vfs::Lxip_data_file : public Vfs::Lxip_file
{
using namespace Linux;
msghdr msg;
iovec iov;
iovec iov { const_cast<char *>(src), len };
msg.msg_name = &_parent.remote_addr();
msg.msg_namelen = sizeof(sockaddr_in);
msg.msg_iter.iov_offset = 0;
msg.msg_iter.count = len;
msg.msg_iter.iov = &iov;
msg.msg_iter.nr_segs = 1;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_flags = 0;
msg.msg_iocb = nullptr;
iov.iov_base = const_cast<char *>(src);
iov.iov_len = len;
msghdr msg = create_msghdr(&_parent.remote_addr(),
sizeof(sockaddr_in), len, &iov);
return _sock.ops->sendmsg(&_sock, &msg, len);
}
@ -372,22 +361,9 @@ class Vfs::Lxip_data_file : public Vfs::Lxip_file
{
using namespace Linux;
msghdr msg;
iovec iov;
iovec iov { dst, len };
msg.msg_name = nullptr;
msg.msg_namelen = 0;
msg.msg_iter.iov_offset = 0;
msg.msg_iter.count = len;
msg.msg_iter.iov = &iov;
msg.msg_iter.nr_segs = 1;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_flags = 0;
msg.msg_iocb = nullptr;
iov.iov_base = dst;
iov.iov_len = len;
msghdr msg = create_msghdr(nullptr, 0, len, &iov);
Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, len, MSG_DONTWAIT);
if (ret == -EAGAIN)
@ -682,23 +658,12 @@ class Vfs::Lxip_remote_file : public Vfs::Lxip_file
case Lxip::Protocol_dir::TYPE_DGRAM:
{
/* peek the sender address of the next packet */
msghdr msg;
iovec iov;
msg.msg_name = addr;
msg.msg_namelen = sizeof(addr_storage);
msg.msg_iter.type = 0;
msg.msg_iter.iov_offset = 0;
msg.msg_iter.count = sizeof(_content_buffer);
msg.msg_iter.iov = &iov;
msg.msg_iter.nr_segs = 1;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_iocb = nullptr;
/* buffer not used */
iov.iov_base = _content_buffer;
iov.iov_len = sizeof(_content_buffer);
iovec iov { _content_buffer, sizeof(_content_buffer) };
msghdr msg = create_msghdr(addr, sizeof(addr_storage),
sizeof(_content_buffer), &iov);
int const res = _sock.ops->recvmsg(&_sock, &msg, 0, MSG_DONTWAIT|MSG_PEEK);
if (res == -EAGAIN) throw Would_block();