source: mainline/uspace/lib/c/generic/inet.c@ 514d561

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 514d561 was 984a9ba, checked in by Martin Decky <martin@…>, 7 years ago

do not expose the call capability handler from the async framework

Keep the call capability handler encapsulated within the async framework
and do not expose it explicitly via its API. Use the pointer to
ipc_call_t as the sole object identifying an IPC call in the code that
uses the async framework.

This plugs a major leak in the abstraction and also simplifies both the
async framework (slightly) and all IPC servers.

  • Property mode set to 100644
File size: 5.9 KB
RevLine 
[c76e926]1/*
[f1a8c23]2 * Copyright (c) 2013 Jiri Svoboda
[c76e926]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <async.h>
30#include <assert.h>
31#include <errno.h>
32#include <inet/inet.h>
33#include <ipc/inet.h>
34#include <ipc/services.h>
35#include <loc.h>
[f1a8c23]36#include <stdlib.h>
[c76e926]37
[984a9ba]38static void inet_cb_conn(ipc_call_t *icall, void *arg);
[c76e926]39
40static async_sess_t *inet_sess = NULL;
41static inet_ev_ops_t *inet_ev_ops = NULL;
42static uint8_t inet_protocol = 0;
43
[b7fd2a0]44static errno_t inet_callback_create(void)
[c76e926]45{
46 async_exch_t *exch = async_exchange_begin(inet_sess);
[a35b458]47
[c76e926]48 ipc_call_t answer;
49 aid_t req = async_send_0(exch, INET_CALLBACK_CREATE, &answer);
[a35b458]50
[f9b2cb4c]51 port_id_t port;
[b7fd2a0]52 errno_t rc = async_create_callback_port(exch, INTERFACE_INET_CB, 0, 0,
[f9b2cb4c]53 inet_cb_conn, NULL, &port);
[a35b458]54
[c76e926]55 async_exchange_end(exch);
[a35b458]56
[c76e926]57 if (rc != EOK)
58 return rc;
[a35b458]59
[b7fd2a0]60 errno_t retval;
[c76e926]61 async_wait_for(req, &retval);
[a35b458]62
[77ad86c]63 return retval;
[c76e926]64}
65
[b7fd2a0]66static errno_t inet_set_proto(uint8_t protocol)
[c76e926]67{
68 async_exch_t *exch = async_exchange_begin(inet_sess);
[b7fd2a0]69 errno_t rc = async_req_1_0(exch, INET_SET_PROTO, protocol);
[c76e926]70 async_exchange_end(exch);
[a35b458]71
[c76e926]72 return rc;
73}
74
[b7fd2a0]75errno_t inet_init(uint8_t protocol, inet_ev_ops_t *ev_ops)
[c76e926]76{
77 service_id_t inet_svc;
[b7fd2a0]78 errno_t rc;
[c76e926]79
80 assert(inet_sess == NULL);
81 assert(inet_ev_ops == NULL);
82 assert(inet_protocol == 0);
[a35b458]83
[ecff3d9]84 rc = loc_service_get_id(SERVICE_NAME_INET, &inet_svc,
[c76e926]85 IPC_FLAG_BLOCKING);
[ecff3d9]86 if (rc != EOK)
87 return ENOENT;
[a35b458]88
[f9b2cb4c]89 inet_sess = loc_service_connect(inet_svc, INTERFACE_INET,
[c76e926]90 IPC_FLAG_BLOCKING);
91 if (inet_sess == NULL)
92 return ENOENT;
[a35b458]93
[c76e926]94 if (inet_set_proto(protocol) != EOK) {
95 async_hangup(inet_sess);
96 inet_sess = NULL;
97 return EIO;
98 }
[a35b458]99
[c76e926]100 if (inet_callback_create() != EOK) {
101 async_hangup(inet_sess);
102 inet_sess = NULL;
103 return EIO;
104 }
[a35b458]105
[c76e926]106 inet_protocol = protocol;
107 inet_ev_ops = ev_ops;
108
109 return EOK;
110}
111
[b7fd2a0]112errno_t inet_send(inet_dgram_t *dgram, uint8_t ttl, inet_df_t df)
[c76e926]113{
[d8b47eca]114 async_exch_t *exch = async_exchange_begin(inet_sess);
[a35b458]115
[ecff3d9]116 ipc_call_t answer;
[695b6ff]117 aid_t req = async_send_4(exch, INET_SEND, dgram->iplink, dgram->tos,
118 ttl, df, &answer);
[a35b458]119
[b7fd2a0]120 errno_t rc = async_data_write_start(exch, &dgram->src, sizeof(inet_addr_t));
[d8b47eca]121 if (rc != EOK) {
122 async_exchange_end(exch);
123 async_forget(req);
124 return rc;
125 }
[a35b458]126
[d8b47eca]127 rc = async_data_write_start(exch, &dgram->dest, sizeof(inet_addr_t));
128 if (rc != EOK) {
[02a09ed]129 async_exchange_end(exch);
[d8b47eca]130 async_forget(req);
131 return rc;
[02a09ed]132 }
[a35b458]133
[d8b47eca]134 rc = async_data_write_start(exch, dgram->data, dgram->size);
[a35b458]135
[d8b47eca]136 async_exchange_end(exch);
[a35b458]137
[ecff3d9]138 if (rc != EOK) {
[50b581d]139 async_forget(req);
[ecff3d9]140 return rc;
141 }
[a35b458]142
[b7fd2a0]143 errno_t retval;
[ecff3d9]144 async_wait_for(req, &retval);
[a35b458]145
[25a179e]146 return retval;
[c76e926]147}
148
[b7fd2a0]149errno_t inet_get_srcaddr(inet_addr_t *remote, uint8_t tos, inet_addr_t *local)
[19a4f73]150{
[d8b47eca]151 async_exch_t *exch = async_exchange_begin(inet_sess);
[a35b458]152
[d8b47eca]153 ipc_call_t answer;
154 aid_t req = async_send_1(exch, INET_GET_SRCADDR, tos, &answer);
[a35b458]155
[b7fd2a0]156 errno_t rc = async_data_write_start(exch, remote, sizeof(inet_addr_t));
[d8b47eca]157 if (rc != EOK) {
[02a09ed]158 async_exchange_end(exch);
[d8b47eca]159 async_forget(req);
160 return rc;
[02a09ed]161 }
[a35b458]162
[d8b47eca]163 rc = async_data_read_start(exch, local, sizeof(inet_addr_t));
[a35b458]164
[d8b47eca]165 async_exchange_end(exch);
[a35b458]166
[d8b47eca]167 if (rc != EOK) {
168 async_forget(req);
169 return rc;
170 }
[a35b458]171
[b7fd2a0]172 errno_t retval;
[d8b47eca]173 async_wait_for(req, &retval);
[a35b458]174
[25a179e]175 return retval;
[19a4f73]176}
177
[984a9ba]178static void inet_ev_recv(ipc_call_t *icall)
[59157eb]179{
180 inet_dgram_t dgram;
[a35b458]181
[02a09ed]182 dgram.tos = IPC_GET_ARG1(*icall);
[8d48c7e]183 dgram.iplink = IPC_GET_ARG2(*icall);
[a35b458]184
[984a9ba]185 ipc_call_t call;
[02a09ed]186 size_t size;
[984a9ba]187 if (!async_data_write_receive(&call, &size)) {
188 async_answer_0(&call, EINVAL);
189 async_answer_0(icall, EINVAL);
[02a09ed]190 return;
191 }
[a35b458]192
[02a09ed]193 if (size != sizeof(inet_addr_t)) {
[984a9ba]194 async_answer_0(&call, EINVAL);
195 async_answer_0(icall, EINVAL);
[02a09ed]196 return;
197 }
[a35b458]198
[984a9ba]199 errno_t rc = async_data_write_finalize(&call, &dgram.src, size);
[02a09ed]200 if (rc != EOK) {
[984a9ba]201 async_answer_0(&call, rc);
202 async_answer_0(icall, rc);
[02a09ed]203 return;
204 }
[a35b458]205
[984a9ba]206 if (!async_data_write_receive(&call, &size)) {
207 async_answer_0(&call, EINVAL);
208 async_answer_0(icall, EINVAL);
[02a09ed]209 return;
210 }
[a35b458]211
[02a09ed]212 if (size != sizeof(inet_addr_t)) {
[984a9ba]213 async_answer_0(&call, EINVAL);
214 async_answer_0(icall, EINVAL);
[02a09ed]215 return;
216 }
[a35b458]217
[984a9ba]218 rc = async_data_write_finalize(&call, &dgram.dest, size);
[59157eb]219 if (rc != EOK) {
[984a9ba]220 async_answer_0(&call, rc);
221 async_answer_0(icall, rc);
[02a09ed]222 return;
223 }
[a35b458]224
[02a09ed]225 rc = async_data_write_accept(&dgram.data, false, 0, 0, 0, &dgram.size);
226 if (rc != EOK) {
[984a9ba]227 async_answer_0(icall, rc);
[59157eb]228 return;
229 }
[a35b458]230
[59157eb]231 rc = inet_ev_ops->recv(&dgram);
[f1a8c23]232 free(dgram.data);
[984a9ba]233 async_answer_0(icall, rc);
[59157eb]234}
235
[984a9ba]236static void inet_cb_conn(ipc_call_t *icall, void *arg)
[c76e926]237{
238 while (true) {
239 ipc_call_t call;
[984a9ba]240 async_get_call(&call);
[a35b458]241
[c76e926]242 if (!IPC_GET_IMETHOD(call)) {
243 /* TODO: Handle hangup */
244 return;
245 }
[a35b458]246
[c76e926]247 switch (IPC_GET_IMETHOD(call)) {
248 case INET_EV_RECV:
[984a9ba]249 inet_ev_recv(&call);
[c76e926]250 break;
251 default:
[984a9ba]252 async_answer_0(&call, ENOTSUP);
[c76e926]253 }
254 }
255}
256
257/** @}
258 */
Note: See TracBrowser for help on using the repository browser.