Stdout to UDP socket in inetd

Discussion in 'C Programming' started by Obi-Wan, Mar 10, 2006.

  1. Obi-Wan

    Obi-Wan Guest

    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.

    --
    Ben "Obi-Wan" Hollingsworth
    The stuff of earth competes for the allegiance I owe only to the
    Giver of all good things, so if I stand, let me stand on the
    promise that You will pull me through. -- Rich Mullins

    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
    Obi-Wan, Mar 10, 2006
    #1
    1. Advertising

  2. Obi-Wan wrote:
    > 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.
    Maxim Yegorushkin, Mar 10, 2006
    #2
    1. Advertising

  3. Obi-Wan <> writes:
    > 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.

    --
    James Carlson, KISS Network <>
    Sun Microsystems / 1 Network Drive 71.232W Vox +1 781 442 2084
    MS UBUR02-212 / Burlington MA 01803-2757 42.496N Fax +1 781 442 1677
    James Carlson, Mar 10, 2006
    #3
  4. Obi-Wan <> writes:
    > 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.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Mar 11, 2006
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sakagami Hiroki

    inetd like server socket supervisor in Java

    Sakagami Hiroki, Jun 7, 2006, in forum: Java
    Replies:
    2
    Views:
    2,082
    Martin Gregorie
    Jun 7, 2006
  2. Jan

    inetd script in python?

    Jan, Feb 27, 2004, in forum: Python
    Replies:
    4
    Views:
    2,495
    Donn Cave
    Mar 1, 2004
  3. Marek Kubica

    SimpleXMLServer meets inetd

    Marek Kubica, Mar 12, 2005, in forum: Python
    Replies:
    0
    Views:
    312
    Marek Kubica
    Mar 12, 2005
  4. Tim
    Replies:
    7
    Views:
    582
    Nobody
    Feb 18, 2011
  5. Kishore_R

    Socket() failed for UDP socket

    Kishore_R, Oct 11, 2005, in forum: Perl Misc
    Replies:
    2
    Views:
    217
    Anno Siegel
    Oct 11, 2005
Loading...

Share This Page