blob: 2078d14509923dba0788803f4441292c7374ea54 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <magenta/compiler.h>
#include <magenta/types.h>
#include <mxio/limits.h>
#include <assert.h>
#include <limits.h>
#include <stdint.h>
__BEGIN_CDECLS
// clang-format off
#define MXRIO_HDR_SZ (__builtin_offsetof(mxrio_msg_t, data))
#define MXRIO_ONE_HANDLE 0x00000100
#define MXRIO_STATUS 0x00000000
#define MXRIO_CLOSE 0x00000001
#define MXRIO_CLONE (0x00000002 | MXRIO_ONE_HANDLE)
#define MXRIO_OPEN (0x00000003 | MXRIO_ONE_HANDLE)
#define MXRIO_MISC 0x00000004
#define MXRIO_READ 0x00000005
#define MXRIO_WRITE 0x00000006
#define MXRIO_SEEK 0x00000007
#define MXRIO_STAT 0x00000008
#define MXRIO_READDIR 0x00000009
#define MXRIO_IOCTL 0x0000000a
#define MXRIO_IOCTL_1H (0x0000000a | MXRIO_ONE_HANDLE)
#define MXRIO_UNLINK 0x0000000b
#define MXRIO_READ_AT 0x0000000c
#define MXRIO_WRITE_AT 0x0000000d
#define MXRIO_TRUNCATE 0x0000000e
#define MXRIO_RENAME (0x0000000f | MXRIO_ONE_HANDLE)
#define MXRIO_CONNECT 0x00000010
#define MXRIO_BIND 0x00000011
#define MXRIO_LISTEN 0x00000012
#define MXRIO_GETSOCKNAME 0x00000013
#define MXRIO_GETPEERNAME 0x00000014
#define MXRIO_GETSOCKOPT 0x00000015
#define MXRIO_SETSOCKOPT 0x00000016
#define MXRIO_GETADDRINFO 0x00000017
#define MXRIO_SETATTR 0x00000018
#define MXRIO_SYNC 0x00000019
#define MXRIO_LINK (0x0000001a | MXRIO_ONE_HANDLE)
#define MXRIO_MMAP 0x0000001b
#define MXRIO_FCNTL 0x0000001c
#define MXRIO_NUM_OPS 29
#define MXRIO_OP(n) ((n) & 0x3FF) // opcode
#define MXRIO_HC(n) (((n) >> 8) & 3) // handle count
#define MXRIO_OPNAME(n) ((n) & 0xFF) // opcode, "name" part only
#define MXRIO_OPNAMES { \
"status", "close", "clone", "open", \
"misc", "read", "write", "seek", \
"stat", "readdir", "ioctl", "unlink", \
"read_at", "write_at", "truncate", "rename", \
"connect", "bind", "listen", "getsockname", \
"getpeername", "getsockopt", "setsockopt", "getaddrinfo", \
"setattr", "sync", "link", "mmap", "fcntl" }
// dispatcher callback return code that there were no messages to read
#define ERR_DISPATCHER_NO_WORK MX_ERR_SHOULD_WAIT
// indicates message handed off to another server
// used by rio remote handler for deferred reply pipe completion
#define ERR_DISPATCHER_INDIRECT MX_ERR_NEXT
// indicates that this was a close message and that no further
// callbacks should be made to the dispatcher
#define ERR_DISPATCHER_DONE MX_ERR_STOP
const char* mxio_opname(uint32_t op);
typedef struct mxrio_msg mxrio_msg_t;
typedef mx_status_t (*mxrio_cb_t)(mxrio_msg_t* msg, void* cookie);
// callback to process a mxrio_msg
// - on entry datalen indicates how much valid data is in msg.data[]
// - return value of ERR_DISPATCHER_INDIRECT indicates that the
// reply is being handled by the callback (forwarded to another
// server, sent later, etc, and no reply message should be sent.
// - otherwise, the return value is treated as the status to send
// in the rpc response, and msg.len indicates how much valid data
// to send. On error return msg.len will be set to 0.
// a mxio_dispatcher_handler suitable for use with a mxio_dispatcher
mx_status_t mxrio_handler(mx_handle_t h, void* cb, void* cookie);
// the underlying handling for regular rpc or for a synthetic close,
// called by mxrio_handler. handle_rpc() processes a single message
// from the provideded channel, returning a negative error value on
// error or 1 on clean shutdown (indicating no further callbacks
// should be made). handle_close() processes a "synthetic" close
// event (eg, channel was remotely closed), and neither function
// should be callaed again after handle_close().
mx_status_t mxrio_handle_rpc(mx_handle_t h, mxrio_msg_t* msg, mxrio_cb_t cb, void* cookie);
mx_status_t mxrio_handle_close(mxrio_cb_t cb, void* cookie);
// OPEN and CLOSE messages, can be forwarded to another remoteio server,
// without any need to wait for a reply. The reply channel from the initial
// request is passed along to the new server.
// If the write to the server fails, an error reply is sent to the reply channel.
void mxrio_txn_handoff(mx_handle_t server, mx_handle_t reply, mxrio_msg_t* msg);
// OPEN and CLONE ops do not return a reply
// Instead they receive a channel handle that they write their status
// and (if successful) type, extra data, and handles to.
#define MXRIO_OBJECT_EXTRA 32
#define MXRIO_OBJECT_MINSIZE (2 * sizeof(uint32_t))
#define MXRIO_OBJECT_MAXSIZE (MXRIO_OBJECT_MINSIZE + MXRIO_OBJECT_EXTRA)
typedef struct {
// Required Header
mx_status_t status;
uint32_t type;
// Optional Extra Data
uint8_t extra[MXRIO_OBJECT_EXTRA];
// OOB Data
uint32_t esize;
uint32_t hcount;
mx_handle_t handle[MXIO_MAX_HANDLES];
} mxrio_object_t;
struct mxrio_msg {
mx_txid_t txid; // transaction id
uint32_t op; // opcode
uint32_t datalen; // size of data[]
int32_t arg; // tx: argument, rx: return value
union {
int64_t off; // tx/rx: offset where needed
uint32_t mode; // tx: Open
uint32_t protocol; // rx: Open
uint32_t op; // tx: Ioctl
} arg2;
int32_t reserved;
uint32_t hcount; // number of valid handles
mx_handle_t handle[4]; // up to 3 handles + reply channel handle
uint8_t data[MXIO_CHUNK_SIZE]; // payload
};
#define MXIO_MMAP_FLAG_READ (1u << 0)
#define MXIO_MMAP_FLAG_WRITE (1u << 1)
#define MXIO_MMAP_FLAG_EXEC (1u << 2)
#define MXIO_MMAP_FLAG_PRIVATE (1u << 16)
static_assert(MXIO_MMAP_FLAG_READ == MX_VM_FLAG_PERM_READ, "Vmar / Mmap flags should be aligned");
static_assert(MXIO_MMAP_FLAG_WRITE == MX_VM_FLAG_PERM_WRITE, "Vmar / Mmap flags should be aligned");
static_assert(MXIO_MMAP_FLAG_EXEC == MX_VM_FLAG_PERM_EXECUTE, "Vmar / Mmap flags should be aligned");
typedef struct mxrio_mmap_data {
size_t offset;
uint64_t length;
int32_t flags;
} mxrio_mmap_data_t;
static_assert(MXIO_CHUNK_SIZE >= PATH_MAX, "MXIO_CHUNK_SIZE must be large enough to contain paths");
#define READDIR_CMD_NONE 0
#define READDIR_CMD_RESET 1
// - msg.datalen is the size of data sent or received and must be <= MXIO_CHUNK_SIZE
// - msg.arg is the return code on replies
// request--------------------------------------- response------------------------------
// op arg arg2 data arg2 data handle[]
// ----------- ---------- ------- -------------- ----------- --------------------------
// CLOSE 0 0 - 0 - -
// CLONE 0 0 - objtype - handle(s)
// OPEN flags mode <name> objtype - handle(s)
// READ maxread 0 - newoffset <bytes> -
// READ_AT maxread offset - 0 <bytes> -
// WRITE 0 0 <bytes> newoffset - -
// WRITE_AT 0 offset <bytes> 0 - -
// SEEK whence offset - offset - -
// STAT maxreply 0 - 0 <vnattr_t> -
// READDIR maxreply cmd - 0 <vndirent_t[]> -
// IOCTL out_len opcode <in_bytes> 0 <out_bytes> -
// UNLINK 0 0 <name> 0 - -
// TRUNCATE 0 offset - 0 - -
// RENAME 0 0 <name1>0<name2>0 0 - -
// CONNECT 0 0 <sockaddr> 0 - -
// BIND 0 0 <sockaddr> 0 - -
// LISTEN 0 0 <backlog> 0 - -
// GETSOCKNAME maxreply 0 - 0 <sockaddr> -
// GETPEERNAME maxreply 0 - 0 <sockaddr> -
// GETSOCKOPT maxreply 0 <sockopt> 0 <sockopt> -
// SETSOCKOPT 0 0 <sockopt> 0 <sockopt> -
// GETADDRINFO maxreply 0 <getaddrinfo> 0 <getaddrinfo> -
// SETATTR 0 0 <vnattr> 0 - -
// SYNC 0 0 0 0 - -
// LINK 0 0 <name1>0<name2>0 0 - -
// MMAP maxreply 0 mmap_data_msg 0 mmap_data_msg vmohandle
// FCNTL cmd flags 0 flags - -
//
// proposed:
//
// LSTAT maxreply 0 - 0 <vnattr_t> -
// MKDIR 0 0 <name> 0 - -
// SYMLINK namelen 0 <name><path> 0 - -
// READLINK maxreply 0 - 0 <path> -
// FLUSH 0 0 - 0 - -
//
// on response arg32 is always mx_status, and may be positive for read/write calls
__END_CDECLS