Stdout to UDP socket in inetd

O

Obi-Wan

I'm trying to write a daemon in C that runs under (x)inetd that
communicates over UDP. I'm trying to write a simple DNS server that
returns the same IP for every query it receives. Things work just
fine reading the request, but when I try to write(2) the response, it
returns -1 with errno 89: "Destination address required". This seems
to indicate the wrong setting on a socket. Here's my xinetd config
paragraph:

------------------------- Achilles tendon - cut here -------------------------
service domain
{
port = 53
protocol = udp
socket_type = dgram
wait = yes
only_from = 127.0.0.1
user = root
server = /usr/local/sbin/dns
log_on_failure += USERID
disable = no
}
------------------------- Achilles tendon - cut here -------------------------

The write that's failing is the first one I'm calling, and it takes
place less than a second after the request comes in. I verified this
with the following program:

------------------------- Achilles tendon - cut here -------------------------
main() {
int err;
char *buf = "hello";

openlog("dns", LOG_PID, LOG_DAEMON);
if ((err = write(1, buf, 1)) != 1)
syslog(LOG_ERR, "write returned %d: errno %d: %s",
err, errno, strerror(errno));
closelog();
return 0;
}
------------------------- Achilles tendon - cut here -------------------------

If I run that from the command line, it prints an "h". From xinetd,
it logs:
write returned -1: errno 89: Destination address required

What am I doing wrong?

I suppose I could rewrite this thing to act as a standalone daemon,
but that's more work & a lot of refresher reading on socket programming.

If it matters, this is CentOS (RedHat) linux with a 2.4 kernel.
 
M

Maxim Yegorushkin

Obi-Wan said:
I'm trying to write a daemon in C that runs under (x)inetd that
communicates over UDP. I'm trying to write a simple DNS server that
returns the same IP for every query it receives. Things work just
fine reading the request, but when I try to write(2) the response, it
returns -1 with errno 89: "Destination address required". This seems
to indicate the wrong setting on a socket.

To be able to call write() on a UDP socket you first need to set the
default destination address by calling connect() on the socket. I don't
know if xinetd can does that for you.
 
J

James Carlson

Obi-Wan said:
I'm trying to write a daemon in C that runs under (x)inetd that
communicates over UDP. I'm trying to write a simple DNS server that
returns the same IP for every query it receives. Things work just
fine reading the request, but when I try to write(2) the response, it
returns -1 with errno 89: "Destination address required". This seems
to indicate the wrong setting on a socket. Here's my xinetd config
paragraph:

That's not going to work. As a UDP wait-type service, you're given
the actual socket that the inetd process has.

In other words, you should be doing something like this:

char buffer[1024];
struct sockaddr_in from;
int fromlen, retv;

for (;;) {
/* Kill myself if I've been idle for a while */
alarm(10);
fromlen = sizeof (from);
retv = recvfrom(0, buffer, sizeof (buffer), 0, &from,
&fromlen);
... do something ...
sendto(1, replymsg, replylen, 0, &from, fromlen);
}

I think there are some useful examples of this in the Stevens
networking books.
 
K

Keith Thompson

Obi-Wan said:
I'm trying to write a daemon in C that runs under (x)inetd that
communicates over UDP.
[...]

Standard C does not provide any form of networking. Please drop
comp.lang.c from the newsgroups line if you post a followup. Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top