dongola7 / tcl_bonjour Goto Github PK
View Code? Open in Web Editor NEWA Tcl package for publishing and subscribing to network services via Multicast DNS/DNS-SD (also known as Bonjour on OS X).
License: Other
A Tcl package for publishing and subscribing to network services via Multicast DNS/DNS-SD (also known as Bonjour on OS X).
License: Other
I would really love to use this package, but I'm having trouble isolating a weird error coming out of the avahi dns_sd compatibility library as soon as I go to use the resolve command.
First off, running on Ubuntu 10.04 64 bit with a tcl8.5 tclsh, things seem to work fine. Running on Centos 5, however, I get a weird dns_sd assertion error. It looks like:
tclsh8.5: compat.c:442: sdref_free: Assertion `__ret == 0' failed.
It appears that the dns_sd library is dying when it tries to destroy the mutex associated with the sdref.
So, I began troubleshooting. I have found the following differences between the machine that works and the one that doesn't, beyond the obvious OS and 32/64 bit difference:
setenv LD_LIBRARY_PATH /home/frankie/installs/tcl8.5.8/unix
../../tcl8.5.8/unix/tclsh
% info exists ::tcl_platform(threaded)
0
% exit
../../tcl8.5.8/unix/tclsh client_edge.tcl
and it worked fine. This makes me think the issue is not due to the missing thread support in the tcl library.
Any ideas? I've looked through the tcl_bonjour code and don't see anything obviously wrong.
FG
Unfortunately I have stumbled across an issue. When a PowerPC machine is running the library (I compiled your lib for Universal) the port that gets reported is wrong to the Bonjour client. So this is bound to be some kind of byte order problem. I actually had the same problem when running a PPC version of your lib on an Intel machine in a PPC WiSH interpreter.
i think the current client example may be a bit misleading for the usage of the resolve_address command. It appears that the input to this command is the hostname, which is expected, but the client example is showing it by passing in the service name, which could be the hostname only, but in my case, rarely is.
The service name comes back during the browse, but the hostname comes back as part of the resolve on the service, so I suggest the example be updated to look like this:
# Example client using the bonjour package.
package require Tcl 8.5
package require bonjour
# Called when a service is resolved (details are retrieved).
proc serviceResolved {serviceName hostname port txtRecords} {
puts "Resolved: $serviceName on $hostname:$port"
puts " txtRecords: $txtRecords"
# Try resolving an address for the hostname
::bonjour::resolve_address $hostname [list addressResolved $hostname]
}
# Called when a service address is resolved.
proc addressResolved {name address} {
puts "Host \"$name\" resolved to: $address"
}
# Called when a service is found.
proc serviceFound {regType action name domain} {
puts "$regType on $name.$domain: $action"
if {$action eq "add"} {
::bonjour::resolve $name $regType $domain serviceResolved
}
}
# Start looking for ssh services.
::bonjour::browse start _ssh._tcp [list serviceFound _ssh._tcp]
# Start looking for myservice services.
::bonjour::browse start _myservice._tcp [list serviceFound _myservice._tcp]
::bonjour::browse start _myotherservice._tcp [list serviceFound _myotherservice._tcp]
# Enter the event loop.
vwait forever
i think it might be useful to have a new command which will let us complete the service resolve process. Once we browse, we are able to then resolve using your commands which is great, but this only gives us the hostname and port. The documentation for bonjour says that we can call "DNSServiceQueryRecord" to get the address for a particular hostname. If we had a quick tcl command in the package that lets us take the hostname coming from the resolve callback and get the ip, that would be great. I'm thinking a general "::bonjour::gethostbyname" function would make this very easy.
the documentation I was reading about resolving a service all the way to an IP address is here:
i noticed new compile errors trying to compile the latest version. It looks like the last few error codes are not in the dns_sd.h that I have in any version of avahi i have checked. I commented them out so I could build, but I'm guessing it needs some sort of #ifdef to check the dns_sd version. My changes:
diff --git a/generic/bonjour.c b/generic/bonjour.c index 0676533..514c1ef 100644 --- a/generic/bonjour.c +++ b/generic/bonjour.c @@ -139,22 +139,22 @@ static const char *get_dnsserviceerror_string(DNSServiceErrorType errorCode) return "DoubleNAT"; case kDNSServiceErr_BadTime: return "BadTime"; - case kDNSServiceErr_BadSig: - return "BadSig"; - case kDNSServiceErr_BadKey: - return "BadKey"; - case kDNSServiceErr_Transient: - return "Transient"; - case kDNSServiceErr_ServiceNotRunning: - return "ServiceNotRunning"; - case kDNSServiceErr_NATPortMappingUnsupported: - return "NATPortMappingUnsupported"; - case kDNSServiceErr_NATPortMappingDisabled: - return "NATPortMappingDisabled"; - case kDNSServiceErr_NoRouter: - return "NoRouter"; - case kDNSServiceErr_PollingMode: - return "PollingMode"; + //case kDNSServiceErr_BadSig: + //return "BadSig"; + //case kDNSServiceErr_BadKey: + //return "BadKey"; + //case kDNSServiceErr_Transient: + //return "Transient"; + //case kDNSServiceErr_ServiceNotRunning: + //return "ServiceNotRunning"; + //case kDNSServiceErr_NATPortMappingUnsupported: + //return "NATPortMappingUnsupported"; + //case kDNSServiceErr_NATPortMappingDisabled: + //return "NATPortMappingDisabled"; + //case kDNSServiceErr_NoRouter: + //return "NoRouter"; + //case kDNSServiceErr_PollingMode: + //return "PollingMode"; } // end switch(errorCode) return NULL;
FG
As mentioned in the "1 in a million crash" thread on tcl-core, the table argument for a Tcl_GetIndexFromObj{Struct} call must live at a fixed address. The inlined patch fixes this for the places in tcl_bonjour where this contract is violated.
diff --git a/generic/browse.c b/generic/browse.c
index 89ef22a..ca11fcf 100644
--- a/generic/browse.c
+++ b/generic/browse.c
@@ -119,7 +119,7 @@ static int bonjour_browse(
int objc,
Tcl_Obj *const objv[]
) {
- char *subcommands[] = {
+ static char *subcommands[] = {
"start", "stop", NULL
};
const char *regtype = NULL;
diff --git a/generic/register.c b/generic/register.c
index d4a5f46..54d309b 100644
--- a/generic/register.c
+++ b/generic/register.c
@@ -107,7 +107,7 @@ static int bonjour_register(
uint16_t txtLen = 0;
void *txtRecord = NULL;
- const char *options[] = { "-name", "--", NULL };
+ static const char *options[] = { "-name", "--", NULL };
enum optionIndex { OPT_NAME, OPT_END };
// parse options
on Linux ( Fedora 14 ) with avahi :
avahi-devel-0.6.27-2.fc14.x86_64
avahi-glib-0.6.27-2.fc14.x86_64
avahi-gobject-0.6.27-2.fc14.x86_64
avahi-autoipd-0.6.27-2.fc14.x86_64
avahi-compat-libdns_sd-0.6.27-2.fc14.x86_64
avahi-0.6.27-2.fc14.x86_64
avahi-tools-0.6.27-2.fc14.x86_64
avahi-compat-libdns_sd-devel-0.6.27-2.fc14.x86_64
followng code segfaults using interactive shell :
$ /opt/usr8.6b.5/bin/tclsh8.6
% package require bonjour
1.1
% proc chuck { args } {
puts "$args"
}
% bounjour::browse start * chuck
*** WARNING *** The program 'tclsh8.6' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointer.de/avahi-compat?s=libdns_sd&e=tclsh8.6
Segmentation fault (core dumped)
$
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.