Get DNS name of local machine as seen by a remote machine - java

I'm making a peer-to-peer instant messaging application.
Currently, if UserA.pool.net says "hello" to UserB.pool.net, User A sees "You: hello" and User B sees "UserA.pool.net: hello".
Rather than User A seeing "You", I want them to see the hostname of their own machine so that User A sees the same text as User B.

See these functions of java.net.InetAddress - getLocalHost and getHostName :
String localhostname = java.net.InetAddress.getLocalHost().getHostName();
Note that this gets you the hostname as the machine sees itself; others may see it with a different one (e.g. the local hosts file says something different than DNS). In other words, it is not guaranteed that machine A will be seen with the same hostname from machine A, machine B, or machine C.
As #biniam_Ethiopia points out, it is not even guaranteed that you'll get the same result from different programs on the same machine, as they may be using network-based name resolution (seen e.g. here).
It may be more useful to send the whole identifier: piskvor#lachtan.my.network.example.com , instead of just piskvor.

The short answer is that if you really want User A and User B to see the same text, you can't rely on finding out your hostname yourself. You need User B to transmit their view of User A's hostname to User A and vice versa. Due to NAT, you won't be able to just check your own computer's hostname.
Alternatively, (Jonathon beat me to this in the question comments) you can have each user send their own private hostname as part of the connection handshake and use that to print messages on the remote end.

I've gotten the hostname of the local machine in the past using something like this:
InetAddress addr = InetAddress.getLocalHost();
String hostname = addr.getHostName();
You could refer to: InetAddress.getHostName()

You may need to use getCanonicalHostName() to get full qualified host name which include domain name also.
Code -
String fullHostName = java.net.InetAddress.getLocalHost().getCanonicalHostName();

Related

InetAddress.getByName returns "akamaitechnologies.com for non-existent host

I have found that resolution of a hostname that does NOT exist always returns an address belonging to "akamaitechnologies.com" (e.g. 23.221.222.250). It does work correctly for hosts that do exist.
Code:
InetAddress addr = InetAddress.getByName( "NON-EXISTING.com" );
The documentation for InetAddress or a Google search provide little help. It is claimed that an UnknownHostException should occur but that does not happen for me.
Why is this happening?
This is not an Android/Java defect. It turns out it was a DNS issue. Namely, my AT&T phone uses AT&T's default DNS server (sbcglobal.net). This P.O.S. server returns a valid IP address even for non-existent domains. After I changed to "dns.google" (8.8.8.8), everything worked as expected.
This DNS spoofing is a Bad Thing because many apps depened on a Unknown-Host-Exception to detect an incorrectly entered domain, e.g. in an email address.

Getting client static IP address

I am deplyong a web application in the Internet and I am checking whether the user's login is valid by checking its client IP address (e.g. 192.168.2.XXX). Actually, I have found a working code (below). This code was completely working before, but after some time, its output is not the same anymore. Now, this code only gives me 1 IP address which is the server's IP address. What is wrong with my code? How can I get the client's static IP address rather than the server's IP address? I have also tried other solutions such as getRemoteAddr() and request.getHeader("PROXY-CLIENT-IP") but it is not working.
Java:
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if(ipAddress == null)
ipAddress = InetAddress.getLocalHost().getHostAddress();
Your are mixing two levels of abstractions and that is rarely a good thing.
The header X-FORWARDED_FOR is inserted by a load balancer or proxy. If the client reaches the server directly, then this header isn't present and you are executing this code InetAddress.getLocalHost().getHostAddress();. Which does exactly what you say: It is retrieving the IP address of the host where this piece of code is running, i.e. the web server.
See also here: Getting the client IP address: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, what else could be useful?

Skip DNS lookup in Java

For an app I'm writing I want to completely avoid DNS host name resolution: I'm using numeric IPv4 and IPv6 addresses and I have no use for lookups. I've googled a bit but I can't find a class that allows me to open a connection without causing a DNS request to occur. Any hints?
TIA
If you invoke InetAddress.getByName() with a name that's not really a name, but is an IP address, Java won't perform the DNS lookup.
Another option is to use InetAddress.getByAddress() like so:
byte[] numericAddress = new byte[]{127,0,0,1};
InetAddress.getByAddress(numericAddress); //Will return an InetAddress that points to 127.0.0.1

RMI connection with wifi and dialup internet

I have created a simple database application using rmi. It works fine with my local wireless network. But now i want to connect my client to the server through the internet. I know that, this can be achieved with setting up port forwarding in the router. But i want it to work in any computer which is connected to the internet using wifi connections, dialup
connections etc. How to do that?
what to write here? Naming.lookup ("rmi://?????????????");
As I am quite new to java, Please give me a detailed answer with a simple code example.
Thanks in advance
I hope you are messed up with Java RMI Concept. Irony is that a few days ago I was also thinking up the same except that I was thinking to connect up on my internal network.
There are two kinds of classes that can be used in Java RMI.
A Remote class is one whose instances can be used remotely. An object
of such a class can be referenced in two different ways:
1. Within the address space where the object was constructed, the object is an ordinary object which can be used like any other object.
2. Within other address spaces, the object can be referenced using an object handle. While there are limitations on how one can use an
object handle compared to an object, for the most part one can use
object handles in the same way as an ordinary object.
A Serializable class is one whose instances can be copied from one
address space to another. An instance of a Serializable class will be
called a serializable object. In other words, a serializable object is
one that can be marshaled.
SO, HERE COMES THE ANSWER TO YOUR QUESTION,ASSUMING YOU ARE TALKING ABOUT REMOTE CLASS ON DIFFERENT SYSTEM(SERVER).
The name of a remote object includes the following information:
The Internet name (or address) of the machine that is running the
Object Registry with which the remote object is being registered. If
the Object Registry is running on the same machine as the one that is
making the request, then the name of the machine can be omitted.
The port to which the Object Registry is listening. If the Object
Registry is listening to the default port, 1099, then this does not
have to be included in the name.
The local name of the remote object within the Object Registry.
The URL for a remote object is specified using the usual host, port and name:
rmi://host:port/name
host = host name of registry (defaults to current host)
port = port number of registry (defaults to the registry port number)
name = name for remote object
Assuming that your code is lying on the server having host-name as "XYZ.edu/home/CLasses"(you can give the DNS/IP-Address of server and include the location of the Class file),port-number="1099"(default) and name of the remote Object="abc" for your ABC.java Class in Server. In this way one will be able to call the Remote Object from different machines. Also, you need to keep the whole Server code on the Internet Address so that Clients can access them from the Internet(one can't access the offline-code present in your machine). Then only it can happen!!!
Here is the example Client program:
/**
* Client program for the "Hello, world!" example.
* #param argv The command line arguments which are ignored.
*/
public static void main (String[] argv) {
try {
HelloInterface hello =
(HelloInterface) Naming.lookup ("//ortles.ccs.neu.edu/Hello"); //see here the address of the server hosting the Server file,you can omit port number,it'll take default port 1099.
System.out.println (hello.say());
} catch (Exception e) {
System.out.println ("HelloClient exception: " + e);
}
}

On Linux, Java issues reverse DNS lookups when a socket is opened. Why, and how can I stop it?

We are experiencing a quite weird behaviour on Linux w.r.t. Java DNS lookups (update: happens also on Mac OS X—I was wrong).
We set the Google public DNS server 8.8.8.8 as the JVM DNS server. The system (/etc/resolv.conf) server, however, remains out standard server ghost.di.unimi.it.
When an address is looked up using InetAddress.getAllByName() or DNSJava's Addess.getAllByName(), everything works as expected (in particular, this is DNSJava):
01:39:11.832438 IP nexus.law.di.unimi.it.33195 > google-public-dns-a.google.com.domain: 46509+ A? www.uffa.com. (30)
01:39:11.832820 IP nexus.law.di.unimi.it.52782 > ghost.di.unimi.it.domain: 42740+ PTR? 8.8.8.8.in-addr.arpa. (38)
01:39:11.833510 IP ghost.di.unimi.it.domain > nexus.law.di.unimi.it.52782: 42740 1/2/0 PTR google-public-dns-a.google.com. (128)
01:39:11.865165 IP google-public-dns-a.google.com.domain > nexus.law.di.unimi.it.33195: 46509 1/0/0 A 208.87.35.103 (46)
As you can see, we resolve www.uffa.com, and then there is a reverse lookup (happens just one time at the first lookup) of 8.8.8.8 for authentication purposes. At this point, the IP address of www.uffa.com is cached and no lookups should happen if we make another call within the TTL.
Nonetheless, when we actually try to open a socket on www.uffa.com using Apache HTTP Component's DefaultHttpClient, we see this:
01:40:06.892383 IP nexus.law.di.unimi.it.53977 > ghost.di.unimi.it.domain: 22255+ PTR? 103.35.87.208.in-addr.arpa. (44)
01:40:07.204359 IP ghost.di.unimi.it.domain > nexus.law.di.unimi.it.53977: 22255 1/2/2 PTR 208-87-35-103.securehost.com. (154)
That is, Java (or something else on the machine) is performing a reverse lookup of www.uffa.com's address to our system server, instead than to Google's server. The same happens using URL.openConnection().getContent().
We used BTrace to instrument InetAddress/Address code, and no calls that could imply a reverse DNS lookup are performed.
Frankly, we do not even know what to look for.
Our big problem is that we're writing a high-performance crawler, and while we try to pace carefully DNS lookups, there is nothing we can do to pace this reverse lookups because they are performed when the socket is opened, which happens in crawling threads whose number is in the thousands.
An an additional information, wget performs a reverse DNS lookup, too, but an nc on port 80 (which of course gives nothing) doesn't.
As usual, any help is appreciated.
The reverse DNS lookups are done by the SecurityManager, and you can't disable them.
In the end, the only real problem was that I was not giving tcpdump the -n option. The reverse lookup I was observing were just tcpdump's.

Categories