1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef LIB_ZXS_ZXS_H_
6 #define LIB_ZXS_ZXS_H_
7 
8 #include <fuchsia/net/c/fidl.h>
9 #include <stdint.h>
10 #include <unistd.h>
11 #include <zircon/compiler.h>
12 #include <zircon/types.h>
13 
14 __BEGIN_CDECLS
15 
16 // Flags that describe how the |zxs| library will interact with the kernel
17 // socket object.
18 typedef uint32_t zxs_flags_t;
19 
20 // If set, operations wait for the remote party to provide the necessary data or
21 // objects to complete the operation.
22 #define ZXS_FLAG_BLOCKING ((zxs_flags_t)1u << 0)
23 
24 // If set, the socket is used to transport data in atomic chunks.
25 #define ZXS_FLAG_DATAGRAM ((zxs_flags_t)1u << 1)
26 
27 // A socket.
28 typedef struct zxs_socket {
29     // The underlying socket kernel object.
30     zx_handle_t socket;
31 
32     // Flags that describe how the |zxs| library will interact with the kernel
33     // socket object.
34     zxs_flags_t flags;
35 } zxs_socket_t;
36 
37 // An option for a |zxs_socket_t|.
38 typedef struct zxs_option {
39     // See POSIX documentation for the available levels.
40     //
41     // For example, |man 7 socket|.
42     //
43     // TODO: Document the levels we support.
44     int32_t level;
45 
46     // See POSIX documentation for the available option names.
47     //
48     // For example, |man 7 socket|.
49     //
50     // TODO: Document the names we support.
51     int32_t name;
52 
53     // A pointer to the value of the option.
54     const void* value;
55 
56     // The number of bytes pointed to by |value|.
57     size_t length;
58 } zxs_option_t;
59 
60 // Create a |zxs_socket_t|.
61 //
62 // Given a channel |socket_provider| that implements the
63 // |fuchsia.net.LegacySocketProvider| interface, create a |zxs_socket_t| with
64 // the given characteristics.
65 //
66 // This function does not take ownership of |socket_provider|.
67 zx_status_t zxs_socket(zx_handle_t socket_provider,
68                        fuchsia_net_SocketDomain domain,
69                        fuchsia_net_SocketType type,
70                        fuchsia_net_SocketProtocol protocol,
71                        const zxs_option_t* options,
72                        size_t options_count,
73                        zxs_socket_t* out_socket);
74 
75 // Closes a |zxs_socket_t|.
76 //
77 // Gracefully closes the given socket. Closes the underlying |zx_handle_t| as
78 // well, even if the socket provider returns an error.
79 //
80 // Returns the |zx_status_t| from the socket provider (rather than from the
81 // kernel when closing the underlying |zx_handle_t|).
82 zx_status_t zxs_close(const zxs_socket_t* socket);
83 
84 // Connect the given |socket| to the given |addr|.
85 //
86 // If |socket| is a datagram socket, then |addr| is the address to which
87 // datagrams are sent by default and the only address from which datagrams are
88 // received.
89 //
90 // If |socket| is a stream socket, then this function attempts to establish a
91 // connection to |addr|.
92 zx_status_t zxs_connect(const zxs_socket_t* socket, const struct sockaddr* addr,
93                         size_t addr_length);
94 
95 // Assign a name to |socket|.
96 //
97 // Typically, stream sockets will require a local name to be assigned before
98 // they can receive connections.
99 zx_status_t zxs_bind(const zxs_socket_t* socket, const struct sockaddr* addr,
100                      size_t addr_length);
101 
102 // Mark |socket| as ready to accept connections.
103 //
104 // The |backlog| parameter is a hint for the depth of the queue of unaccepted
105 // connections. A |backlog| of zero indicates that no hint is provided.
106 zx_status_t zxs_listen(const zxs_socket_t* socket, uint32_t backlog);
107 
108 // Extract a |zxs_socket_t| from the queue of unaccepted sockets.
109 //
110 // The |socket| must first have been marked as ready to accept connections using
111 // |zxs_listen|.
112 //
113 // The |addr| buffer is filled with the address of peer socket.
114 zx_status_t zxs_accept(const zxs_socket_t* socket, struct sockaddr* addr,
115                        size_t addr_capacity, size_t* out_addr_actual,
116                        zxs_socket_t* out_socket);
117 
118 // Get the current address to which |socket| is bound.
119 //
120 // See |zxs_bind|.
121 zx_status_t zxs_getsockname(const zxs_socket_t* socket, struct sockaddr* addr,
122                             size_t capacity, size_t* out_actual);
123 
124 // Get the address of the peer for |socket|.
125 zx_status_t zxs_getpeername(const zxs_socket_t* socket, struct sockaddr* addr,
126                             size_t capacity, size_t* out_actual);
127 
128 // Get the socket option with the given |level| and |name|.
129 zx_status_t zxs_getsockopt(const zxs_socket_t* socket, int32_t level,
130                            int32_t name, void* buffer, size_t capacity,
131                            size_t* out_actual);
132 
133 // Set the given |options| on |socket|.
134 //
135 // The |count| parameter is the number of |zxs_option_t| records pointed to by
136 // |options|.
137 zx_status_t zxs_setsockopts(const zxs_socket_t* socket,
138                             const zxs_option_t* options,
139                             size_t count);
140 
141 // Send the data in the given |buffer| over |socket|.
142 zx_status_t zxs_send(const zxs_socket_t* socket, const void* buffer,
143                      size_t capacity, size_t* out_actual);
144 
145 // Receive data from |socket| into the given |buffer|.
146 zx_status_t zxs_recv(const zxs_socket_t* socket, void* buffer,
147                      size_t capacity, size_t* out_actual);
148 
149 // Send the data in the given |buffer| to |addr| over |socket|.
150 zx_status_t zxs_sendto(const zxs_socket_t* socket, const struct sockaddr* addr,
151                        size_t addr_length, const void* buffer, size_t capacity,
152                        size_t* out_actual);
153 
154 // Receive data from |socket| into the given |buffer|.
155 //
156 // The |addr| buffer is filled with the address from which the data was
157 // received.
158 zx_status_t zxs_recvfrom(const zxs_socket_t* socket, struct sockaddr* addr,
159                         size_t addr_capacity, size_t* out_addr_actual,
160                         void* buffer, size_t capacity, size_t* out_actual);
161 
162 // Send the data described by |msg| over the given |socket|.
163 //
164 // The |out_actual| parameter is the amount of data sent by this call, gathered
165 // from the |iovec| records referenced by |msg|.
166 zx_status_t zxs_sendmsg(const zxs_socket_t* socket, const struct msghdr* msg,
167                         size_t* out_actual);
168 
169 // Receive data from |socket| into the buffers described by |msg|.
170 //
171 // The |out_actual| parameter is the amount of data received by this call,
172 // scattered to the |iovec| records referenced by |msg|.
173 zx_status_t zxs_recvmsg(const zxs_socket_t* socket, struct msghdr* msg,
174                         size_t* out_actual);
175 
176 // Send an IO control message to the socket provider.
177 //
178 // The amount of data written to |out_buffer| is returned through |out_actual|.
179 zx_status_t zxs_ioctl(const zxs_socket_t* socket, uint32_t op,
180                       const void* in_buffer, size_t in_capacity,
181                       void* out_buffer, size_t out_capacity,
182                       size_t* out_actual);
183 
184 __END_CDECLS
185 
186 #endif // LIB_ZXS_ZXS_H_
187