source: mainline/uspace/srv/net/dnsrsrv/dnsrsrv.c@ 25a179e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 25a179e was 25a179e, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

IPC return values are always errno constants. Adjust types to reflect that.

In principle, IPC server is not allowed to return non-errno values via
the "main" return value, because kernel interprets it (e.g. EHANGUP).
It's still possible to return arbitrary additional return values alongside EOK,
which are not interpreted in normal communication.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 * Copyright (c) 2013 Jiri Svoboda
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/** @addtogroup dnsres
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <async.h>
37#include <errno.h>
38#include <str_error.h>
39#include <io/log.h>
40#include <ipc/dnsr.h>
41#include <ipc/services.h>
42#include <loc.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <task.h>
46
47#include "dns_msg.h"
48#include "dns_std.h"
49#include "query.h"
50#include "transport.h"
51
52#define NAME "dnsres"
53
54static void dnsr_client_conn(ipc_callid_t, ipc_call_t *, void *);
55
56static int dnsr_init(void)
57{
58 int rc;
59 log_msg(LOG_DEFAULT, LVL_DEBUG, "dnsr_init()");
60
61 rc = transport_init();
62 if (rc != EOK) {
63 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing transport.");
64 return EIO;
65 }
66
67 async_set_fallback_port_handler(dnsr_client_conn, NULL);
68
69 rc = loc_server_register(NAME);
70 if (rc != EOK) {
71 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc));
72 transport_fini();
73 return EEXIST;
74 }
75
76 service_id_t sid;
77 rc = loc_service_register(SERVICE_NAME_DNSR, &sid);
78 if (rc != EOK) {
79 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service: %s.", str_error(rc));
80 transport_fini();
81 return EEXIST;
82 }
83
84 return EOK;
85}
86
87static void dnsr_name2host_srv(dnsr_client_t *client, ipc_callid_t iid,
88 ipc_call_t *icall)
89{
90 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()");
91
92 ip_ver_t ver = IPC_GET_ARG1(*icall);
93
94 char *name;
95 int rc = async_data_write_accept((void **) &name, true, 0,
96 DNS_NAME_MAX_SIZE, 0, NULL);
97 if (rc != EOK) {
98 async_answer_0(iid, rc);
99 return;
100 }
101
102 dns_host_info_t *hinfo;
103 rc = dns_name2host(name, &hinfo, ver);
104 if (rc != EOK) {
105 async_answer_0(iid, rc);
106 return;
107 }
108
109 ipc_callid_t callid;
110 size_t size;
111 if (!async_data_read_receive(&callid, &size)) {
112 async_answer_0(callid, EREFUSED);
113 async_answer_0(iid, EREFUSED);
114 return;
115 }
116
117 if (size != sizeof(inet_addr_t)) {
118 async_answer_0(callid, EINVAL);
119 async_answer_0(iid, EINVAL);
120 return;
121 }
122
123 rc = async_data_read_finalize(callid, &hinfo->addr, size);
124 if (rc != EOK) {
125 async_answer_0(callid, rc);
126 async_answer_0(iid, rc);
127 return;
128 }
129
130 if (!async_data_read_receive(&callid, &size)) {
131 async_answer_0(callid, EREFUSED);
132 async_answer_0(iid, EREFUSED);
133 return;
134 }
135
136 size_t act_size = str_size(hinfo->cname);
137 if (act_size > size) {
138 async_answer_0(callid, EINVAL);
139 async_answer_0(iid, EINVAL);
140 return;
141 }
142
143 rc = async_data_read_finalize(callid, hinfo->cname, act_size);
144 if (rc != EOK)
145 async_answer_0(callid, rc);
146
147 async_answer_0(iid, rc);
148
149 dns_hostinfo_destroy(hinfo);
150}
151
152static void dnsr_get_srvaddr_srv(dnsr_client_t *client, ipc_callid_t iid,
153 ipc_call_t *icall)
154{
155 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()");
156
157 ipc_callid_t callid;
158 size_t size;
159 if (!async_data_read_receive(&callid, &size)) {
160 async_answer_0(callid, EREFUSED);
161 async_answer_0(iid, EREFUSED);
162 return;
163 }
164
165 if (size != sizeof(inet_addr_t)) {
166 async_answer_0(callid, EINVAL);
167 async_answer_0(iid, EINVAL);
168 return;
169 }
170
171 // FIXME locking
172
173 int rc = async_data_read_finalize(callid, &dns_server_addr, size);
174 if (rc != EOK)
175 async_answer_0(callid, rc);
176
177 async_answer_0(iid, rc);
178}
179
180static void dnsr_set_srvaddr_srv(dnsr_client_t *client, ipc_callid_t iid,
181 ipc_call_t *icall)
182{
183 log_msg(LOG_DEFAULT, LVL_DEBUG, "dnsr_set_srvaddr_srv()");
184
185 ipc_callid_t callid;
186 size_t size;
187 if (!async_data_write_receive(&callid, &size)) {
188 async_answer_0(callid, EREFUSED);
189 async_answer_0(iid, EREFUSED);
190 return;
191 }
192
193 if (size != sizeof(inet_addr_t)) {
194 async_answer_0(callid, EINVAL);
195 async_answer_0(iid, EINVAL);
196 return;
197 }
198
199 // FIXME locking
200
201 int rc = async_data_write_finalize(callid, &dns_server_addr, size);
202 if (rc != EOK) {
203 async_answer_0(callid, rc);
204 async_answer_0(iid, rc);
205 }
206
207 async_answer_0(iid, rc);
208}
209
210static void dnsr_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
211{
212 dnsr_client_t client;
213
214 log_msg(LOG_DEFAULT, LVL_DEBUG, "dnsr_conn()");
215
216 /* Accept the connection */
217 async_answer_0(iid, EOK);
218
219 while (true) {
220 ipc_call_t call;
221 ipc_callid_t callid = async_get_call(&call);
222 sysarg_t method = IPC_GET_IMETHOD(call);
223
224 if (!method) {
225 /* The other side has hung up */
226 async_answer_0(callid, EOK);
227 return;
228 }
229
230 switch (method) {
231 case DNSR_NAME2HOST:
232 dnsr_name2host_srv(&client, callid, &call);
233 break;
234 case DNSR_GET_SRVADDR:
235 dnsr_get_srvaddr_srv(&client, callid, &call);
236 break;
237 case DNSR_SET_SRVADDR:
238 dnsr_set_srvaddr_srv(&client, callid, &call);
239 break;
240 default:
241 async_answer_0(callid, EINVAL);
242 }
243 }
244}
245
246int main(int argc, char *argv[])
247{
248 int rc;
249
250 printf("%s: DNS Resolution Service\n", NAME);
251
252 if (log_init(NAME) != EOK) {
253 printf(NAME ": Failed to initialize logging.\n");
254 return 1;
255 }
256
257 rc = dnsr_init();
258 if (rc != EOK)
259 return 1;
260
261 printf(NAME ": Accepting connections.\n");
262 task_retval(0);
263 async_manager();
264
265 return 0;
266}
267
268/** @}
269 */
Note: See TracBrowser for help on using the repository browser.