Android Network Service Discovery get hostname (mDNS/Zeroconf) - android

I am trying to get the hostname from a service that is advertising itself on my local network using mDNS/Zeroconf. I am using Android's Network Service Discovery API, but it seems as if Android doesn't use the advertised hostname but tries to do a reverse DNS lookup and if that fails only returns the IP address.
On my Macbook I do can do the following:
$ dns-sd -B _myservice._tcp
DATE: ---Mon 29 Oct 2018---
17:35:25.332 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
17:35:25.333 Add 2 10 local. _myservice._tcp. My Service Name
$ dns-sd -L "My Service Name" _myservice._tcp
DATE: ---Mon 29 Oct 2018---
17:38:35.423 ...STARTING...
17:38:35.423 My\032Service\032Name._myservice._tcp.local. can be reached at test.my.service.local.:443 (interface 10)
I can then use the returned hostname (test.my.service.local) to find the corresponding IP. I've got this working correctly on iOS using NSNetServiceBrowser.
On Android in my onServiceDiscovered if I do the following:
private static Map<String, Object> OnServiceDiscovered(NsdServiceInfo info) {
Log.d(TAG, info.getHost().getHostAddress());
Log.d(TAG, info.getHost().getHostName());
}
I do get the correct IP address, but getHostName returns "raspberrypi.local" (from /etc/hostname) or on another network only the IP address. My suspicion is that on Android getHost().getHostName() is doing a reverse DNS lookup and ignores the hostname being advertised with mDNS altogether.
Is there any way to get the hostname from mDNS on Android?

Related

Can't ping Gateway if Access Point has no internet connection

In my app I programmatically connect to an Access Point that has no access to the internet via WifiManager and WifiConfiguration. Later on I have to access a device connected to it to read data – but I didn't get that far.
After connecting to the Wifi I'm getting my DHCP setup just fine, but if I try to ping the Gateway address by typing:
$ adb shell
OnePlus6:/ $ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
^C
--- 192.168.1.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1015ms
The gateway is unreacheable...
I suspect this has to do with the fact that Android (9?) re-routes all traffic in case of a "dead" Wifi over to mobile data – for example you can still browse the internet just fine.
You can easily replicate the issue like this:
Connect to an Access Point w/o internet access
Check if your internet still works (e.g. go to google.com)
Connect you phone via adb and ping the address of your AP
Any ideas on how to force the traffic trough Wifi, even if it's "offline"?
Edit: Output of ip route show:
OnePlus6:/ $ ip route show
10.16.52.64/29 dev rmnet_data0 proto kernel scope link src 10.16.52.67
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.116
Ok, I've found a solution. One has to bind the current process to the correct network, which can be done like this:
connectionManager = (ConnectivityManager)
context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder request = new NetworkRequest.Builder();
request.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
connectionManager.registerNetworkCallback(request.build(), new ConnectivityManager.NetworkCallback() {
public void onAvailable(Network network) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectionManager.bindProcessToNetwork(network);
} else {
ConnectivityManager.setProcessDefaultNetwork(network);
}
}
});

Bonjour local host names in Android

How can I make an Android network request lookup a local domain name registered with Bonjour?
I get this error when trying to fetch data using Volley.
java.net.UnknownHostException: Unable to resolve host "xxxxx.local": No address associated with hostname
If you control the whole network stack, you can perform DNS service discovery (DNS-SD) through Android's NsdManager. I recommend this guide from the documentation:
https://developer.android.com/training/connect-devices-wirelessly/nsd
In short, it boils down to:
mNsdManager.discoverServices(
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
You can cross-reference the service you wish to resolve to by inspecting the response from dns-sd on Mac:
$ dns-sd -Z . .
_http._tcp PTR myserver._http._tcp
myserver._http._tcp SRV 0 0 80 myserver.local. ; Replace with unicast FQDN of target host
myserver._http._tcp TXT ""
In the NsdManager.DiscoveryListener callback, you can obtain the corresponding IP address from NsdServiceInfo.getHost().
Have you tried with the IP of localhost ? 127.0.0.1 or 10.0.2.2:80 ?

QTcpServer - Unsupported Socket Operation on Android

I am trying to start a server on Android using QTcpServer with Qt 5.3.1 but the server does not start and I get "Unsupported Socket Operation". It works fine on Windows.
Code below:
void StartListening()
{
QHostAddress hostAddress;
hostAddress.setAddress(QString("localhost"));
hostAddress.toIPv4Address();
quint16 portNumber = 9878;
server->setMaxPendingConnections(1);
server->setProxy(QNetworkProxy::NoProxy);
if (server->listen(hostAddress, portNumber))
{
// Ok
}
else
{
Debug("Server did not start. " + server->errorString());
}
}
server->errorString() returns "Unsupported Socket Operation when it runs on Android
Isn't this supported by Qt Android or am I doing something wrong?
Thx
OK! I worked it out.
The problem is with this line:
hostAddress.setAddress(QString("localhost"));
If I replace "localhost" with "127.0.0.1", the server starts fine but no one outside the "device the server is running on" can connect to it. This means, let's say your network is using 192.168.1.xx and your Android device has the following IP address: 192.168.1.2. If you start the server with "127.0.0.1" on your Android device which has an IP address: "192.168.1.2" and then using your PC with an IP address 192.168.1.3 you do telnet 192.168.1.2 9878 it will fail to connect!
So then I decided to start the server by specifying the IP address of the Android device: 192.168.1.2
hostAddress.setAddress(QString("192.168.1.2"));
Voila! That works too! The server starts and I can connect from outside the device! For example if I do telnet 192.168.1.2 9878 from my PC while the server is started on Android, it connects! So all I need to do now is replace the hard coded IP address with the actual IP address of the device! I think QNetworkInterface::allInterfaces() or something like that will give me the ability to get the default IP address.
So just use the actual IP address of the network card rather than localhost or 127.0.0.1 and all should be Ok. All working now.

How to configure Acralyzer?

I've installed Acralyzer using this tutorial and got following parameters for integrating Acra into my Android app:
httpMethod = Method.PUT,
reportType = Type.JSON,
formUri = "http://localhost:5984/acra-myap/_design/acra-storage/_update/report",
formUriBasicAuthLogin = "myap-reporter",
formUriBasicAuthPassword = "a11youneedisl0v3"
Before installing Acralyzer, I ran
ssh -L5984:127.0.0.1:5984 user#AAA.BBB.CCC.DDD
(establishes a tunnel to CouchDB running at AAA.BBB.CCC.DDD) where AAA.BBB.CCC.DDD is the address of my instance at DigitalOcean.
Smart as I am, after installing Acralyzer, I killed the ssh process and tried to open the URL http://AAA.BBB.CCC.DDD:5984/acra-myap/_design/acra-storage/_update/report.
I could not connect to it from my browser, which means that the the Android app will not be able to send crash reports to Acralyzer.
What can I do in order for the Acralyzer's URL (http://AAA.BBB.CCC.DDD:5984/acra-myap/_design/acra-storage/_update/report) to become available without ssh tunnel?
It seems that the port you are trying to contact is not open. You should inform iptables (the linux firewall), to accept the incoming traffic on port 5984:
sudo iptables -A INPUT -p tcp --dport 5984 -j ACCEPT
You can find more information on how to create iptables rules and how to save them here.
Digital Ocean could have a firewall that will block you before reaching your server, but to open the port on your instance worth a try.
By default the firewall on DigitalOcean machines is setup to accept all traffic, so the iptables rule shouldn't be necessary. The problem is more likely to be that the couchdb bind_address is still set to the default "127.0.0.1" -- i.e. localhost. After defining an admin user account, you can set bind_address to "0.0.0.0" under configuration in the Futon control panel, which will make it listen to all ip addresses, or another specific address.

How to get IP Address of Server (Socket) in Android?

I'm creating a simple chat program that connects two android devices and they can send simple message
I run the server with Socket on a port (1234 for example)
The problem is from the client i do not know the server IP Address. (and i dont want to enter it manually)
is there a way to find a server that is running on a specific port?or can i run the server on some specific static IP that i can give it to clients?
if not is there another way to communicate with android devices that works on Android 2.2+(don't want to use wifi direct) ?
Thanks in Advance
You can broadcast a udp message from the server specifying your ip in the message. Let the client receive the broadcast and use that msg as the ip address to connect to the socket. (PS : The broadcast receiver must b allowed to receive broadcasts). And you are done!
Assign one SERVER predominantly for getting details such as IP ADDRESS, PORT number,etc.. from all the clients.
Each client when activated will contact the SERVER to register itself first and will get the details(IP ADDRESS,etc) of other device to communicate.
Now they can start waiting for specific device.
On 4.1 you can use Mutlicast DNS for service discovery via the NsdManager (if you are on the same network). If you need this to work over the Internet/3G there is really no good way to do it. You could use Google Cloud Messaging (GCM) to notify clients about the server address, but in any case you will need one 'real' server on a stable address that all participants can reach.
http://developer.android.com/reference/android/net/nsd/NsdManager.html
InetAddress.getLocalHost(); doesnot work for me but ya below code work for me
DhcpInfo dhcp = mWifiManager.getDhcpInfo();
int dhc = dhcp.serverAddress;
String dhcS = ( dhc & 0xFF)+ "."+((dhc >> 8 ) & 0xFF)+"."+((dhc >> 16 ) & 0xFF)+"."+((dhc >> 24 ) & 0xFF);
dhcS contains IP address of server,I used for Wireless connection between multiple devices.
You can use this code
connectionSocket.getRemoteSocketAddress();
No the port can never be fixed with a IP. It is always provided by the user. To know the IP address of the server automatically, you can run this program associated with the chat program.
public class Net {
public Net() throws UnknownHostException {
InetAddress ia = InetAddress.getLocalHost();
System.out.println(ia);
ia = InetAddress.getByName("local host");
System.out.println(ia);
}
public static void main(String args[]) throws UnknownHostException {
Net a = new Net();
}
}
You run can this program by the help of a button which is associated with your chat program.

Categories

Resources