fflewddur / hola Goto Github PK
View Code? Open in Web Editor NEWHola is a minimalist Java implementation of Multicast DNS Service Discovery (mDNS-SD)
License: MIT License
Hola is a minimalist Java implementation of Multicast DNS Service Discovery (mDNS-SD)
License: MIT License
We should use a modern build system and remove the IDE-specific files from source control. Gradle looks like a good candidate.
Service.fromName("_services._dns-sd._udp")
(request all services) throws the following exception:
Exception in thread "main" java.lang.IllegalArgumentException: A Service's name can't be null or empty
at [email protected]/net.straylightlabs.hola.sd.Service.<init>(Service.java:52)
at [email protected]/net.straylightlabs.hola.sd.Service.fromName(Service.java:44)
at XXXX/XXXX.main(XXXX.java:34)
The DNS discovery spec (RFC 6763) allows binary data to be included (see section 6.5) in TXT records.
"The value is opaque binary data. Often the value for a particular attribute will be US-ASCII [RFC20] or UTF-8 [RFC3629] text, but it is legal for a value to be any binary data."
"Authors defining DNS-SD profiles SHOULD NOT generically convert binary attribute data types into printable text using hexadecimal representation, Base-64 [RFC4648], or Unix-to-Unix (UU) encoding"
If a TXT record does contain binary data the readStringsFromBuffer method can fail, as it uses label.length() to count its bytes read rather than using stringLength directly. That can result in the byte count being one fewer than it should be. Here is a corrected version of readStringsFromBuffer to accommodate that:
public static List<String> readStringsFromBuffer(ByteBuffer buffer, int length) {
List<String> strings = new ArrayList<>();
int bytesRead = 0;
do {
int stringLength = buffer.get() & 0xFF;
String label = readLabel(buffer, stringLength);
bytesRead += stringLength + 1;
strings.add(label);
} while (bytesRead < length);
return strings;
}
The current runOnce() method may get into a loop if the user's network is constantly sending mDNS traffic, even if it's unrelated to our query. We need need an upper bound on how long this function will listen for packets before returning its list of discovered instances.
Exception in thread "Thread-2" java.nio.BufferUnderflowException
at java.base/java.nio.HeapByteBuffer.get(HeapByteBuffer.java:178)
at java.base/java.nio.ByteBuffer.get(ByteBuffer.java:762)
at net.straylightlabs.hola.dns.Record.readLabel(Record.java:122)
at net.straylightlabs.hola.dns.Record.readStringsFromBuffer(Record.java:137)
at net.straylightlabs.hola.dns.TxtRecord.(TxtRecord.java:39)
at net.straylightlabs.hola.dns.Record.fromBuffer(Record.java:74)
at net.straylightlabs.hola.dns.Response.parseRecords(Response.java:77)
at net.straylightlabs.hola.dns.Response.createFrom(Response.java:45)
at net.straylightlabs.hola.sd.Query.collectResponses(Query.java:218)
First and foremost, thank you for this great library.
When I run the HolaDriver.java
with different type of services, I've noticed that I don't get the back devices that our over my VPN, unlike what my Discovery shows. Could it be possible / feasible support fot this?
Great project, probably the only mDNS library in Java that actually works as advertised. However... GPL somewhat restricts the usage for commercial purposes - would you consider changing the license to Apache or similar, or did you have licensing in mind for the future?
Cheers!
Roman
The pattern defined in net.straylightlabs.hola.sd.Service#SERVICE_PATTERN
is slightly too restrictive. Additionally, I suspect there might be a bug with the trailing -
in the first group.
Currently the pattern is ^((_[a-zA-Z0-9-]+\.)?_(tcp|udp))\.?|$
(escaped as a Java String this is "^((_[a-zA-Z0-9-]+\\.)?_(tcp|udp))\\.?|$"
I believe it should be the following, instead: ^((_[a-zA-Z0-9_\-]+\.)?_(tcp|udp))\.?|$
(escaped as a Java String this is ^((_[a-zA-Z0-9_\\-]+\\.)?_(tcp|udp))\\.?|$
)
The current SERVICE_PATTERN
won't recognize service names like _my_service._tcp
, due to the 2nd underscore in _my_service
. However, I do believe this is still a valid service name.
I was looking in the Query class and found
/**
* Asynchronously runs the Query in a new thread.
*/
@SuppressWarnings("unused")
public void start() {
throw new RuntimeException("Not implemented yet");
}
I'd like to propose a solution to the missing asynchronous operation by converting Hola to a multi-module Gradle project and introducing a second module that handles the asynchronous parts.
I use a lot of RxJava on other projects and have an Rx implementation that allows me to asynchronously enumerate printers on my local network -
Service service = Service.fromName("_ipp._tcp");
RxQuery.createFor(service, Domain.LOCAL)
.subscribeOn(Schedulers.newThread())
.subscribe(System.err::println);
Taking the multi-module approach would let you tackle the threading in other ways with other modules and not force people to pull in RxJava if they would rather use standard Java threads, for instance. The core module could stay synchronous.
I also noticed that I wasn't getting responses and it turned out that on a multi-home machine Java can pick the wrong network interface when you call InetAddress.getLocalHost()
- in my case I have VirtualBox installed and it created a couple of extra network interfaces. I worked around the issue by iterating over the addresses on each item from NetworkInterface.getNetworkInterfaces()
and collected the results, using the newly created Query method (that came from Issue #5).
If you like the idea, I can submit a pull request with my code.
Need to add test cases for parsing mDNS queries and responses. This will require code to dump mDNS packets to disk and replay them on-demand.
Hi,
I tried to integrate 0.2.3 with my Java 8 project and got this error:
error: cannot access Domain
bad class file: /Users/cesar/.gradle/caches/modules-2/files-2.1/net.straylightlabs/hola/0.2.3/469845a2252068c45c82f2ab520b40e1fdb4de69/hola-0.2.3.jar(net/straylightlabs/hola/dns/Domain.class)
class file has wrong version 54.0, should be 52.0
It seems that it was compiled with Java 10, forcing the dependency to Java 10.
cheers
César
Hello,
Is possible to define the network interface where we want to search the Instances(mdns)?
Thanks
After I updated my dependencies from hola 0.2.1 to 0.2.2 my app is running into following Exception when run on my Rasperry Pi 3 with Jessie:
java.net.SocketException: bad argument for IP_MULTICAST_IF: address not bound to any interface at java.net.PlainDatagramSocketImpl.socketSetOption0(Native Method) at java.net.PlainDatagramSocketImpl.socketSetOption(PlainDatagramSocketImpl.java:74) at java.net.AbstractPlainDatagramSocketImpl.setOption(AbstractPlainDatagramSocketImpl.java:309) at java.net.MulticastSocket.setInterface(MulticastSocket.java:471) at net.straylightlabs.hola.sd.Query.openSocket(Query.java:186) at net.straylightlabs.hola.sd.Query.runOnceOn(Query.java:122) at net.straylightlabs.hola.sd.Query.runOnce(Query.java:107) ...
It trys to find a service running on the same machine. It works on my Windows 64bit machine, but does not once deployed to the Raspberry. Going back to 0.2.1 fixed the issue for me.
Java, write once, debug everywhere...
In Query.java runOnce() the call to InetAddress.getLocalHost() may return the loopback address in some circumstances - observed on some macOS installations, though I don't know the underlying cause. A possible workaround is to change runOnce() as follows:
public Set<Instance> runOnce() throws IOException {
InetAddress address = null;
try(final Socket socket = new Socket()){
socket.connect(new InetSocketAddress("google.com", 80));
address = socket.getLocalAddress();
}
return runOnceOn(address);
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.