Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux TCP server: reading client's IP address before accepting connection

Related: C++ Winsock API how to get connecting client IP before accepting the connection?

Hi, when you are running a TCP server (written in C, using the Berkeley Socket API) is it possible to read a client's IP address/port before actually accepting the connection?

As far as I know you have to accept the connection first and shutdown it directly thereafter, if you don't want to communicate with a given client because of its IP address.

Pseudo-code (I am looking for the peek and refuse method):

 int serverfd = listen(...);
 for(;;) {
     struct sockaddr_in clientAddr;
     peek(serverfd, &clientAddr, sizeof(clientAddr));
     if(isLegit(&clientAddr)) {
         int clientfd = accept(serverfd, &clientAddr, sizeof(clientAddr));
         handleClient(clientfd);
     } else {
         refuse(serverfd, &clientAddr, sizeof(clientAddr));
     }
 }
like image 453
kay Avatar asked Jun 20 '11 23:06

kay


People also ask

How do TCP IP clients and servers communicate with each other?

TCP Connections Overview Systems communicate with each other through a TCP port. The processes at both ends of the connection must use the same port number. You specify either the TCP port number, or the devicename of the device that represents it, as the device in InterSystems IRIS OPEN, USE, and CLOSE commands.

What is TCP Echo client server?

In the TCP Echo client a socket is created. Using the socket a connection is made to the server using the connect() function. After a connection is established , we send messages input from the user and display the data received from the server using send() and read() functions.

How is a TCP connection opened?

TCP Open Connection is a synchronous activity that opens a connection to a TCP server. After establishing the connection, the activity places a handle to the open connection in the connection output element.

What is the return value of a read () call when its TCP receives a fin?

If the peer TCP sends a FIN (the peer process terminates), the socket becomes readable and read returns 0 (EOF). If the peer TCP sends an RST (the peer host has crashed and rebooted), the socket becomes readable, read returns –1, and errno contains the specific error code.


2 Answers

I think what your trying to do is prevent the TCP negotiation from occurring if it matches a specific IP. As far as I know, that is not possible at the sockets layer. The TCP negotiation will occur, and by the time you come to accept the socket, the negotiation has already happened.

Technically it is possible that you could somehow peek at that state information, but, it wouldn't be doing what you expect it to do. Accepting the socket is the interface between the kernel, which already did the work, and your program which would like to read the data. The easiest thing to do is accept the socket, and boot it if you don't want it.

If you want to prevent the TCP negotiation from occurring in the first place, you need to use iptables.

like image 95
Clarus Avatar answered Oct 21 '22 02:10

Clarus


No such API is available for TCP w/ BSD sockets. Suggestions: use tcp-wrappers or iptables to do the heavy lifting. One is more automatic than the other.

UDP allows you to use MSG_PEEK which might let you see who it is from with recvfrom, but you are still going to have to read the packet off anyway, so that is no win.

like image 23
Seth Robertson Avatar answered Oct 21 '22 01:10

Seth Robertson