HelenOS sources
This source file includes following definitions.
- dnsr_init
- dnsr_name2host_srv
- dnsr_get_srvaddr_srv
- dnsr_set_srvaddr_srv
- dnsr_client_conn
- main
#include <async.h>
#include <errno.h>
#include <str_error.h>
#include <io/log.h>
#include <ipc/dnsr.h>
#include <ipc/services.h>
#include <loc.h>
#include <stdio.h>
#include <stdlib.h>
#include <str.h>
#include <task.h>
#include "dns_msg.h"
#include "dns_std.h"
#include "query.h"
#include "transport.h"
#define NAME "dnsres"
static void dnsr_client_conn(ipc_call_t *, void *);
static errno_t dnsr_init(void)
{
loc_srv_t *srv;
errno_t rc;
log_msg(LOG_DEFAULT, LVL_DEBUG, "dnsr_init()");
rc = transport_init();
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing transport.");
return EIO;
}
async_set_fallback_port_handler(dnsr_client_conn, NULL);
rc = loc_server_register(NAME, &srv);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc));
transport_fini();
return EEXIST;
}
service_id_t sid;
rc = loc_service_register(srv, SERVICE_NAME_DNSR, &sid);
if (rc != EOK) {
loc_server_unregister(srv);
log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service: %s.", str_error(rc));
transport_fini();
return EEXIST;
}
return EOK;
}
static void dnsr_name2host_srv(dnsr_client_t *client, ipc_call_t *icall)
{
log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()");
ip_ver_t ver = ipc_get_arg1(icall);
char *name;
errno_t rc = async_data_write_accept((void **) &name, true, 0,
DNS_NAME_MAX_SIZE, 0, NULL);
if (rc != EOK) {
async_answer_0(icall, rc);
return;
}
dns_host_info_t *hinfo;
rc = dns_name2host(name, &hinfo, ver);
if (rc != EOK) {
async_answer_0(icall, rc);
return;
}
ipc_call_t call;
size_t size;
if (!async_data_read_receive(&call, &size)) {
async_answer_0(&call, EREFUSED);
async_answer_0(icall, EREFUSED);
return;
}
if (size != sizeof(inet_addr_t)) {
async_answer_0(&call, EINVAL);
async_answer_0(icall, EINVAL);
return;
}
rc = async_data_read_finalize(&call, &hinfo->addr, size);
if (rc != EOK) {
async_answer_0(&call, rc);
async_answer_0(icall, rc);
return;
}
if (!async_data_read_receive(&call, &size)) {
async_answer_0(&call, EREFUSED);
async_answer_0(icall, EREFUSED);
return;
}
size_t act_size = str_size(hinfo->cname);
if (act_size > size) {
async_answer_0(&call, EINVAL);
async_answer_0(icall, EINVAL);
return;
}
rc = async_data_read_finalize(&call, hinfo->cname, act_size);
if (rc != EOK)
async_answer_0(&call, rc);
async_answer_0(icall, rc);
dns_hostinfo_destroy(hinfo);
}
static void dnsr_get_srvaddr_srv(dnsr_client_t *client, ipc_call_t *icall)
{
log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()");
ipc_call_t call;
size_t size;
if (!async_data_read_receive(&call, &size)) {
async_answer_0(&call, EREFUSED);
async_answer_0(icall, EREFUSED);
return;
}
if (size != sizeof(inet_addr_t)) {
async_answer_0(&call, EINVAL);
async_answer_0(icall, EINVAL);
return;
}
errno_t rc = async_data_read_finalize(&call, &dns_server_addr, size);
if (rc != EOK)
async_answer_0(&call, rc);
async_answer_0(icall, rc);
}
static void dnsr_set_srvaddr_srv(dnsr_client_t *client, ipc_call_t *icall)
{
log_msg(LOG_DEFAULT, LVL_DEBUG, "dnsr_set_srvaddr_srv()");
ipc_call_t call;
size_t size;
if (!async_data_write_receive(&call, &size)) {
async_answer_0(&call, EREFUSED);
async_answer_0(icall, EREFUSED);
return;
}
if (size != sizeof(inet_addr_t)) {
async_answer_0(&call, EINVAL);
async_answer_0(icall, EINVAL);
return;
}
errno_t rc = async_data_write_finalize(&call, &dns_server_addr, size);
if (rc != EOK) {
async_answer_0(&call, rc);
async_answer_0(icall, rc);
return;
}
async_answer_0(icall, rc);
}
static void dnsr_client_conn(ipc_call_t *icall, void *arg)
{
dnsr_client_t client;
log_msg(LOG_DEFAULT, LVL_DEBUG, "dnsr_conn()");
async_accept_0(icall);
while (true) {
ipc_call_t call;
async_get_call(&call);
sysarg_t method = ipc_get_imethod(&call);
if (!method) {
async_answer_0(&call, EOK);
return;
}
switch (method) {
case DNSR_NAME2HOST:
dnsr_name2host_srv(&client, &call);
break;
case DNSR_GET_SRVADDR:
dnsr_get_srvaddr_srv(&client, &call);
break;
case DNSR_SET_SRVADDR:
dnsr_set_srvaddr_srv(&client, &call);
break;
default:
async_answer_0(&call, EINVAL);
}
}
}
int main(int argc, char *argv[])
{
errno_t rc;
printf("%s: DNS Resolution Service\n", NAME);
if (log_init(NAME) != EOK) {
printf(NAME ": Failed to initialize logging.\n");
return 1;
}
rc = dnsr_init();
if (rc != EOK)
return 1;
printf(NAME ": Accepting connections.\n");
task_retval(0);
async_manager();
return 0;
}
HelenOS homepage, sources at GitHub