From owner-freebsd-hackers Fri Jun 18 10:57: 1 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from axl.noc.iafrica.com (axl.noc.iafrica.com [196.31.1.175]) by hub.freebsd.org (Postfix) with ESMTP id 3EE9514C9C for ; Fri, 18 Jun 1999 10:56:50 -0700 (PDT) (envelope-from sheldonh@axl.noc.iafrica.com) Received: from sheldonh (helo=axl.noc.iafrica.com) by axl.noc.iafrica.com with local-esmtp (Exim 3.02 #1) id 10v2sk-000DMS-00 for hackers@freebsd.org; Fri, 18 Jun 1999 19:56:50 +0200 From: Sheldon Hearn To: hackers@freebsd.org Subject: Obtaining client host IP before accept() Date: Fri, 18 Jun 1999 19:56:49 +0200 Message-ID: <51363.929728609@axl.noc.iafrica.com> Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 #include #include #include #include #include #include #include #include #include /* * 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 majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message