4
This file is based on an example that is part of avahi, which is copyright:
5
Lennart Poettering <lennart (at) poettering (dot) de>
6
Trent Lloyd <lathiat@bur.st>
7
Sebastien Estienne <sebastien.estienne@gmail.com>
9
James Willcox <snorp@snorp.net>
11
Modifications for eucalyptus-udeb are copyright 2009 Canonical Ltd.
12
Modifications for squid-deb-proxy-udeb are copyright 2011 Canonical Ltd.
14
avahi is free software; you can redistribute it and/or modify it
15
under the terms of the GNU Lesser General Public License as
16
published by the Free Software Foundation; either version 2.1 of the
17
License, or (at your option) any later version.
19
avahi is distributed in the hope that it will be useful, but WITHOUT
20
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
22
Public License for more details.
24
You should have received a copy of the GNU Lesser General Public
25
License along with avahi; if not, write to the Free Software
26
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
40
#include <avahi-core/core.h>
41
#include <avahi-core/lookup.h>
42
#include <avahi-core/log.h>
43
#include <avahi-common/simple-watch.h>
44
#include <avahi-common/malloc.h>
45
#include <avahi-common/error.h>
47
static AvahiSimplePoll *simple_poll = NULL;
48
static AvahiServer *server = NULL;
52
static void quiet_logger(AvahiLogLevel level, const char *txt) {
55
static void resolve_callback(
56
AvahiSServiceResolver *r,
57
AVAHI_GCC_UNUSED AvahiIfIndex interface,
58
AVAHI_GCC_UNUSED AvahiProtocol protocol,
59
AvahiResolverEvent event,
63
const char *host_name,
64
const AvahiAddress *address,
67
AvahiLookupResultFlags flags,
68
AVAHI_GCC_UNUSED void* userdata) {
72
/* Called whenever a service has been resolved successfully or timed out */
75
case AVAHI_RESOLVER_FAILURE:
77
fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_server_errno(server)));
80
case AVAHI_RESOLVER_FOUND: {
81
char *human_address = avahi_malloc0(AVAHI_ADDRESS_STR_MAX);
83
AvahiStringList *ipaddr_entry;
84
char *ipaddr_key, *ipaddr_value;
86
ipaddr_entry = avahi_string_list_find(txt, "ipaddr");
87
if (ipaddr_entry && avahi_string_list_get_pair(ipaddr_entry, &ipaddr_key, &ipaddr_value, NULL) == 0) {
88
key = avahi_strdup_printf("%s:%u", ipaddr_value, port);
89
avahi_free(ipaddr_value);
90
avahi_free(ipaddr_key);
92
else if (avahi_address_snprint(human_address, AVAHI_ADDRESS_STR_MAX, address)) {
93
if (address->proto == AVAHI_PROTO_INET6)
94
key = avahi_strdup_printf("[%s]:%u", human_address, port);
95
else if (strncmp(human_address, "169.254.169.254", 15) == 0)
96
key = avahi_strdup_printf("%s:%u", name, port);
98
key = avahi_strdup_printf("%s:%u", human_address, port);
101
fprintf(stderr, "(Resolver) failed to resolve %s to IP address/port\n", key);
103
avahi_free(human_address);
105
printf("http://%s/\n", key);
109
avahi_s_service_resolver_free(r);
112
static void browse_callback(
113
AvahiSServiceBrowser *b,
114
AvahiIfIndex interface,
115
AvahiProtocol protocol,
116
AvahiBrowserEvent event,
120
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
123
AvahiServer *s = userdata;
126
/* Called whenever a new services becomes available on the LAN or is removed from the LAN */
130
case AVAHI_BROWSER_FAILURE:
131
fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_server_errno(server)));
132
avahi_simple_poll_quit(simple_poll);
135
case AVAHI_BROWSER_NEW:
137
fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
139
/* We ignore the returned resolver object. In the callback
140
function we free it. If the server is terminated before
141
the callback function is called the server will free
142
the resolver for us. */
144
if (!(avahi_s_service_resolver_new(s, interface, protocol, name, type, domain, AVAHI_PROTO_INET, 0, resolve_callback, s)))
145
fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_server_errno(s)));
149
case AVAHI_BROWSER_REMOVE:
151
fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
154
case AVAHI_BROWSER_ALL_FOR_NOW:
156
fprintf(stderr, "(Browser) %s\n", "ALL_FOR_NOW");
160
case AVAHI_BROWSER_CACHE_EXHAUSTED:
162
fprintf(stderr, "(Browser) %s\n", "CACHE_EXHAUSTED");
167
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
168
AvahiServerConfig config;
169
AvahiSServiceBrowser *sb = NULL;
173
if (getenv("SQUID_DEB_PROXY_FIND_DEBUG"))
176
/* Initialize the pseudo-RNG */
180
avahi_set_log_function(quiet_logger);
182
/* Allocate main loop object */
183
if (!(simple_poll = avahi_simple_poll_new())) {
184
fprintf(stderr, "Failed to create simple poll object.\n");
188
/* Do not publish any local records */
189
avahi_server_config_init(&config);
190
config.publish_hinfo = 0;
191
config.publish_addresses = 0;
192
config.publish_workstation = 0;
193
config.publish_domain = 0;
195
/* Allocate a new server */
196
server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, NULL, NULL, &error);
198
/* Free the configuration data */
199
avahi_server_config_free(&config);
201
/* Check whether creating the server object succeeded */
203
fprintf(stderr, "Failed to create server: %s\n", avahi_strerror(error));
207
/* Create the service browser */
208
// FIXME: use AVAHI_PROTO_UNSPEC for ipv6 at some point
209
if (!(sb = avahi_s_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_INET, "_apt_proxy._tcp", NULL, 0, browse_callback, server))) {
210
fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_server_errno(server)));
214
/* Run the main loop */
215
avahi_simple_poll_loop(simple_poll);
223
avahi_s_service_browser_free(sb);
226
avahi_server_free(server);
229
avahi_simple_poll_free(simple_poll);