How to Know Which Version of the Internet Protocol (Ip) a Client Is Using When Connecting to My Server

How does a server know which domain name was used?

The Internet works in layers. Each layer uses different kind of parameters to do its work.

Layer 3 is typically IP aka Internet Protocol. To work it uses IP addresses, each computer has at least one to be able to discuss with another one. And there are two families in fact: version 4 and version 6.

Since multiple services can be on any given computer at some point, you need a layer on top of that, layer 4, that deals with transport. The "predominant" one is TCP aka Transport Control Protocol, but there is also UDP. TCP and UDP uses ports: a 2 bytes integer that encodes for a specific protocol.

For example, HTTP was given port number 80 (completely arbitrary), and HTTPS port 443.

The DNS, which itself uses UDP and TCP (on port 53), allows, among other things, to map a given hostname to a given IP address or multiple IP addresses. This is the typical A and AAAA records. There is also a CNAME record that maps one domain name to another. There also exists a SRV record that maps a service (which is a protocol name + a transport) to a given hostname and port number.

When one computer connects to another, its first step for all the above is to find out which IP address to use to connect to. It can use the DNS for that. Typically it will get only the IP address, but, depending on the protocol (layer above 4), may also get a port (if using SRV records).

The HTTP world does not use SRV records. So a browser just uses the hardcoded 80 or 443 ports, or the port number appearing in the URL.

Then we are at the transport level, let us say TCP.
The connection is done (since now the remote IP address and port are known) and the protocol above TCP, like HTTP, is free to convey any kind of extra data, such as the hostname that the client initially used (as taken from the URL) to find out the IP address.
This is done through the HTTP host header, see RFC 2616

Note that if you do things through TLS (which conceptually sits between TCP and HTTP) there is even something else happening: SNI or Server Name Indication.

When doing the TLS handshake, so before any kind of HTTP headers or content, the client will send the final hostname desired in some specific TLS message. Why? So that the server can find which specific certificate it should answer which as otherwhise it would not be able to know which hostname is requested as this sits in some HTTP header which do not exist until the TLS handshake is finished.

A webserver will be able to see both the SNI content to find out which certificate to send back and then the host header to find out which VirtualHost (in Apache) section is relevant to the query being processed.

If you are not in HTTP world, then it all depends on the protocol used. Older protocols, like FTP, did not plan for "multihoming" at the beginning, a given IP address meant only one hostname and service for example.

How the clients (client sockets) are identified?

The server listens on an address and port. For example, your server's IP address is 10.0.0.1, and it is listening on port 8000.

Your client IP address is 10.0.0.2, and the client "connects" to the server at 10.0.0.1 port 8000. In the TCP connect, you are giving the port of the server that you want to connect to. Your client will actually get its own port number, but you don't control this, and it will be different on each connection. The client chooses the server port that it wants to connect to and not the client port that it is connecting from.

For example, on the first connection, your client may get client-side port 12345. It is connecting from 10.0.0.2 port 12345 to the server 10.0.0.1 port 8000. Your server can see what port the client is connecting from by calling getpeername on its side of the connection.

When the client connects a second time, the port number is going to be different, say port 12377. The server can see this by calling getpeername on the second connection -- it will see a different port number on the client side. (getpeername also shows the client's IP address.)

Also, each time you call accept on the server, you are getting a new socket. You still have the original socket listening, and on each accept you get a new socket. Call getpeername on the accepted socket to see which client port the connection is coming from. If two clients connect to your server, you now have three sockets -- the original listening socket, and the sockets of each of the two clients.

You can have many clients connected to the same server port 8000 at the same time. And, many clients can be connected from the same client port (e.g. port 12345), only not from the same IP address. From the same client IP address, e.g. 10.0.0.2, each client connection to the server port 8000 will be from a unique client port, e.g. 12345, 12377, etc. You can tell the clients apart by their combination of IP address and port.

The same client can also have multiple connections to the server at the same time, e.g. one connection from client port 12345 and another from 12377 at the same time. By client I mean the originating IP address, and not a particular software object. You'll just see two active connections having the same client IP address.

Also, eventually over time, the combination of client-address and client-port can be reused. That is, eventually, you may see a new client come in from 10.0.0.2 port 12345, long after the first client at 10.0.0.2 port 12345 has disconnected.

Is possible know who is requesting my server through GET request using Servlet?

Since you are on a servlet environment, and quoting from here:

  • ServletRequest.getRemoteAddr(): Returns the Internet Protocol (IP) address of the client or last proxy that sent the request.
  • ServletRequest.getRemoteHost(): Returns the fully qualified name of the client or the last proxy that sent the request.

There are more in the ServletRequest class and the HttpServletRequest (ref) - the class of the parameter that gets passed to the servlet service methods.

Why tcp server can get client's ip?

TCP is based on IP: it uses IP packets to carry data around the Internet. More specifically, the whole TCP packet is fitted into an IP packet's body before being sent.

So you won't find the IP address in the TCP packet because such information belongs to the IP packet. When the client receives a TCP segment, it receives it inside an IP packet containing the IP address.

Get Twisted server's IP address

Twisted will tell you the address you've bound the server to using just the method you found, getHost on the listening port. Unfortunately, it has the big limitation that you found which is that when the server is listening on all local addresses (INADDR_ANY) it gives you 0.0.0.0 (the canonical IPv4 dotted-quad representation of INADDR_ANY).

When this happens, you have to go outside of Twisted. I've found the netifaces package to be pretty good for this. From the docs:

>>> netifaces.interfaces()
['lo0', 'gif0', 'stf0', 'en0', 'en1', 'fw0']
>>> >>> addrs = netifaces.ifaddresses('lo0')
>>> addrs[netifaces.AF_INET]
[{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]

By combining this information with the observation that 0.0.0.0 means "all local addresses" you can figure out what local addresses the server will accept connections on.

Network protocol for surviving client IP address/network changes, among other problems

There are many efforts within the internetworking community to address precisely these "network mobility" concerns.

In particular, Mobile IP (and its IPv6 big sister, Proxy Mobile IPv6) is a broad term for efforts to make IP addresses themselves portable across networks, however I doubt these technologies have reached sufficient maturation/deployment for production use today.

To undertake such mobility without support from the network requires a means of the host announcing to you its new address in an authenticated manner; this is what the Host Identity Protocol is designed for, but it is still at the "experimental" stage of the RFC process. From the abstract of RFC 5201:

HIP allows consenting hosts to securely establish and maintain shared
IP-layer state, allowing separation of the identifier and locator
roles of IP addresses, thereby enabling continuity of communications
across IP address changes.

There are several open-source implementations that are known to interoperate. Without claiming that this is a complete list, nor vouching for any of them (they're just a few picked off a Google search for "Host Identity Protocol implementations"), there is:

  • OpenHIP for multiple operating systems;
  • HIPL for Linux;
  • cutehip for Java;
  • HIP for inter.net for *BSD/Linux.

How to determine a user's IP address in node

In your request object there is a property called socket, which is a net.Socket object. The net.Socket object has a property remoteAddress, therefore you should be able to get the IP with this call:

request.socket.remoteAddress

(if your node version is below 13, use the deprecated now request.connection.remoteAddress)

EDIT

As @juand points out in the comments, the correct method to get the remote IP, if the server is behind a proxy, is request.headers['x-forwarded-for']

EDIT 2

When using express with Node.js:

If you set app.set('trust proxy', true), req.ip will return the real IP address even if behind proxy. Check the documentation for further information

How to check if a website has HTTP/2 protocol support

You can just check it in: Chrome Dev Tool (F12) → NetworkProtocol.

It will tell you the protocol used and the domain of each transfer.

Chrome Dev Tool (F12) -> Network -> Protocol

Legend

http/1.1 = HTTP/1.1

h2          = HTTP/2


Note: If you cannot see the Protocol column, just right-click on any header and check the "Protocol" label.



Related Topics



Leave a reply



Submit