Hi folks,

I found a thread in the freebsd-hackers archive from 1997 that covered
my question, but the answers didn't nail it down to a "yes" or "no"
satisfactorily.

We could save ourselves a lot of angst in the work we're doing on inetd
if we could determine the client IP address of a TCP socket before
calling accept(). Alternatively, we'd love a way to accept() without
acknowledging a connection, so that the connection request could be left
for a child that expected to do its own socket() and bind() calls.

My take on the previous thread is that this is impossible in userland.
I'd appreciate it someone who knows the answer for a fact could look at
the code below and answer the following question:

        Will the IP address of the client host ever enter buf[] if the
        accept() is _not_ uncommented?

I don't need portability, since this is for use within the FreeBSD inetd
exclusively.

Thanks,
Sheldon.

--------
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>

/*
 * Use an arbitrary port that you know isn't in use on the system. I
 * don't run ircd, so this is safe for me.
 */
#define LISTEN_PORT     (6667)

#define BUFSIZE         (1500)

int
main(void)
{
        int ctl;
        int peek;
        int i = 1;
        int port = LISTEN_PORT;
        char buf[BUFSIZE];
        struct sockaddr_in      server_addr;
        struct sockaddr_in      client_addr;
        struct in_addr          bind_address;
        struct msghdr           msg;

        if ((ctl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
                err(errno, "error creating socket");
        printf("socket number %d created\n", ctl);

        if (setsockopt(ctl, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)))
                err(errno, "error setsockopt(SO_REUSEADDR): ");
        if (setsockopt(ctl, SOL_SOCKET, SO_REUSEPORT, (char *)&i, sizeof(i)))
                err(errno, "error setsockopt(SO_REUSEPORT): ");
        printf("setsockopt(SO_REUSEADDR|SO_REUSEPORT) successful\n");

        bind_address.s_addr = htonl(INADDR_ANY);
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr = bind_address;
        server_addr.sin_port = htons(port);

        if (bind(ctl, (struct sockaddr *)&server_addr, sizeof(server_addr)))
                err(errno, "error (%d) bind(%lu:%d)", errno,
                    server_addr.sin_addr.s_addr, port);
        printf("bound to port %d\n", port);

        if (listen(ctl, 0))
                err(errno, "error listening: ");
        printf("listening...\n");

/*
        i = sizeof(client_addr);
        if (peek = accept(ctl, (struct sockaddr *)&client_addr, &i) < 0)
                err(errno, "accept() failed: ");
        printf("connection accepted from %s\n",
            inet_ntoa(client_addr.sin_addr));
*/

        msg.msg_name = (void *)&server_addr;
        msg.msg_namelen = sizeof(server_addr);
        msg.msg_iovlen = 0;
        msg.msg_control = (caddr_t)&buf;
        msg.msg_controllen = 1;
        while (recvmsg(ctl, &msg, MSG_PEEK) < 0) {
                warn("recvmsg failed: ");
                printf("msg_flags = %i\n", msg.msg_flags);
                sleep(2);
        }
        printf("recvmsg successful, wtf?\n");

        close(ctl);
/*
        close(peek);
*/
        return(0);
}


To Unsubscribe: send mail to majord...@freebsd.org
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to