From: Lennart Poettering Date: Mon, 15 Aug 2005 16:07:29 +0000 (+0000) Subject: * fix a bad memory access bug in avahi_strndup() X-Git-Url: https://git.meshlink.io/?a=commitdiff_plain;h=7ada090e70d25937d27b2e93b0dab4d9d68c5d23;p=catta * fix a bad memory access bug in avahi_strndup() * some small optimizations to call gettimeofday() less often * fix dbus-watch-glue to call dbus_connection_dispatch() git-svn-id: file:///home/lennart/svn/public/avahi/trunk@333 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- diff --git a/avahi-common/dbus-watch-glue.c b/avahi-common/dbus-watch-glue.c index 20f8796..11192f8 100644 --- a/avahi-common/dbus-watch-glue.c +++ b/avahi-common/dbus-watch-glue.c @@ -20,6 +20,7 @@ ***/ #include +#include #include @@ -55,6 +56,50 @@ static unsigned int translate_avahi_to_dbus(AvahiWatchEvent e) { return f; } +typedef struct { + DBusConnection *connection; + const AvahiPoll *poll_api; + AvahiTimeout *dispatch_timeout; + int ref; +} ConnectionData; + +static ConnectionData *connection_data_ref(ConnectionData *d) { + assert(d); + assert(d->ref >= 1); + + d->ref++; + return d; +} + +static void connection_data_unref(ConnectionData *d) { + assert(d); + assert(d->ref >= 1); + + if (--d->ref <= 0) { + d->poll_api->timeout_free(d->dispatch_timeout); + avahi_free(d); + } +} + +static void request_dispatch(ConnectionData *d) { + static const struct timeval tv = { 0, 0 }; + assert(d); + + assert(dbus_connection_get_dispatch_status(d->connection) == DBUS_DISPATCH_DATA_REMAINS); + + d->poll_api->timeout_update(d->dispatch_timeout, &tv); +} + +static void dispatch_timeout_callback(AvahiTimeout *t, void *userdata) { + ConnectionData *d = userdata; + assert(t); + assert(d); + + if (dbus_connection_dispatch(d->connection) == DBUS_DISPATCH_DATA_REMAINS) + /* If there's still data, request that this handler is called again */ + request_dispatch(d); +} + static void watch_callback(AvahiWatch *avahi_watch, int fd, AvahiWatchEvent events, void *userdata) { DBusWatch *dbus_watch = userdata; assert(avahi_watch); @@ -101,34 +146,34 @@ static dbus_bool_t update_watch(const AvahiPoll *poll_api, DBusWatch *dbus_watch } static dbus_bool_t add_watch(DBusWatch *dbus_watch, void *userdata) { - const AvahiPoll *poll_api = (const AvahiPoll*) userdata; + ConnectionData *d = userdata; assert(dbus_watch); - assert(poll_api); + assert(d); - return update_watch(poll_api, dbus_watch); + return update_watch(d->poll_api, dbus_watch); } static void remove_watch(DBusWatch *dbus_watch, void *userdata) { - const AvahiPoll *poll_api = (const AvahiPoll*) userdata; + ConnectionData *d = userdata; AvahiWatch *avahi_watch; assert(dbus_watch); - assert(poll_api); + assert(d); if ((avahi_watch = dbus_watch_get_data(dbus_watch))) { - poll_api->watch_free(avahi_watch); + d->poll_api->watch_free(avahi_watch); dbus_watch_set_data(dbus_watch, NULL, NULL); } } static void watch_toggled(DBusWatch *dbus_watch, void *userdata) { - const AvahiPoll *poll_api = (const AvahiPoll*) userdata; + ConnectionData *d = userdata; assert(dbus_watch); - assert(poll_api); + assert(d); - update_watch(poll_api, dbus_watch); + update_watch(d->poll_api, dbus_watch); } typedef struct TimeoutData { @@ -164,24 +209,24 @@ static void timeout_callback(AvahiTimeout *avahi_timeout, void *userdata) { static dbus_bool_t add_timeout(DBusTimeout *dbus_timeout, void *userdata) { TimeoutData *timeout; - const AvahiPoll *poll_api = (const AvahiPoll*) userdata; + ConnectionData *d = userdata; struct timeval tv; dbus_bool_t b; assert(dbus_timeout); - assert(poll_api); + assert(d); if (!(timeout = avahi_new(TimeoutData, 1))) return FALSE; timeout->dbus_timeout = dbus_timeout; - timeout->poll_api = poll_api; + timeout->poll_api = d->poll_api; if ((b = dbus_timeout_get_enabled(dbus_timeout))) avahi_elapse_time(&tv, dbus_timeout_get_interval(dbus_timeout), 0); - if (!(timeout->avahi_timeout = poll_api->timeout_new( - poll_api, + if (!(timeout->avahi_timeout = d->poll_api->timeout_new( + d->poll_api, b ? &tv : NULL, timeout_callback, dbus_timeout))) { @@ -194,42 +239,75 @@ static dbus_bool_t add_timeout(DBusTimeout *dbus_timeout, void *userdata) { } static void remove_timeout(DBusTimeout *dbus_timeout, void *userdata) { + ConnectionData *d = userdata; TimeoutData *timeout; - const AvahiPoll *poll_api = (const AvahiPoll*) userdata; assert(dbus_timeout); - assert(poll_api); + assert(d); timeout = dbus_timeout_get_data(dbus_timeout); assert(timeout); - poll_api->timeout_free(timeout->avahi_timeout); + d->poll_api->timeout_free(timeout->avahi_timeout); avahi_free(timeout); dbus_timeout_set_data(dbus_timeout, NULL, NULL); } static void timeout_toggled(DBusTimeout *dbus_timeout, void *userdata) { TimeoutData *timeout; - const AvahiPoll *poll_api = (const AvahiPoll*) userdata; assert(dbus_timeout); - assert(poll_api); - timeout = dbus_timeout_get_data(dbus_timeout); assert(timeout); update_timeout(timeout); } +static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_status, void *userdata) { + ConnectionData *d = userdata; + + if (new_status == DBUS_DISPATCH_DATA_REMAINS) + request_dispatch(d); + } + int avahi_dbus_connection_glue(DBusConnection *c, const AvahiPoll *poll_api) { + ConnectionData *d = NULL; + assert(c); assert(poll_api); - if (!(dbus_connection_set_watch_functions(c, add_watch, remove_watch, watch_toggled, (void*) poll_api, NULL))) - return -1; + if (!(d = avahi_new(ConnectionData, 1))) + goto fail;; - if (!(dbus_connection_set_timeout_functions(c, add_timeout, remove_timeout, timeout_toggled, (void*) poll_api, NULL))) - return -1; + d->poll_api = poll_api; + d->connection = c; + d->ref = 1; + + if (!(d->dispatch_timeout = poll_api->timeout_new(poll_api, NULL, dispatch_timeout_callback, d))) + goto fail; + + if (!(dbus_connection_set_watch_functions(c, add_watch, remove_watch, watch_toggled, connection_data_ref(d), connection_data_unref))) + goto fail; + if (!(dbus_connection_set_timeout_functions(c, add_timeout, remove_timeout, timeout_toggled, connection_data_ref(d), connection_data_unref))) + goto fail; + + dbus_connection_set_dispatch_status_function(c, dispatch_status, connection_data_ref(d), connection_data_unref); + + if (dbus_connection_get_dispatch_status(c) == DBUS_DISPATCH_DATA_REMAINS) + request_dispatch(d); + + connection_data_unref(d); + return 0; + +fail: + + if (d) { + d->poll_api->timeout_free(d->dispatch_timeout); + + avahi_free(d); + } + + return -1; } diff --git a/avahi-common/malloc.c b/avahi-common/malloc.c index 018a0c0..9b0e22e 100644 --- a/avahi-common/malloc.c +++ b/avahi-common/malloc.c @@ -169,16 +169,16 @@ char *avahi_strdup(const char *s) { char *avahi_strndup(const char *s, size_t max) { char *r; size_t size; + const char *p; if (!s) return NULL; - size = strlen(s); - - if (size > max) - size = max; + for (p = s, size = 0; + size < max && *p; + p++, size++); - if (!(r = avahi_malloc(size+1))) + if (!(r = avahi_new(char, size+1))) return NULL; memcpy(r, s, size); diff --git a/avahi-common/simple-watch.c b/avahi-common/simple-watch.c index 770cf4f..4bb763a 100644 --- a/avahi-common/simple-watch.c +++ b/avahi-common/simple-watch.c @@ -393,6 +393,17 @@ int avahi_simple_poll_iterate(AvahiSimplePoll *s, int timeout) { int t; AvahiUsec usec; + if (next_timeout->expiry.tv_sec == 0 && + next_timeout->expiry.tv_usec == 0) { + + /* Just a shortcut so that we don't need to call gettimeofday() */ + + /* The events poll() returned in the last call are now no longer valid */ + s->events_valid = 0; + return start_timeout_callback(next_timeout); + } + + gettimeofday(&now, NULL); usec = avahi_timeval_diff(&next_timeout->expiry, &now); diff --git a/avahi-core/iface.c b/avahi-core/iface.c index 3d90657..b2c52f9 100644 --- a/avahi-core/iface.c +++ b/avahi-core/iface.c @@ -507,7 +507,7 @@ static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdat m->list = LIST_ADDR; } else { m->list = LIST_DONE; - avahi_log_debug("Networ interface enumeration completed"); + avahi_log_debug("Network interface enumeration completed"); } } else if (n->nlmsg_type == NLMSG_ERROR && (n->nlmsg_seq == m->query_link_seq || n->nlmsg_seq == m->query_addr_seq)) { diff --git a/avahi-core/timeeventq.c b/avahi-core/timeeventq.c index 5e24ba3..a259ba6 100644 --- a/avahi-core/timeeventq.c +++ b/avahi-core/timeeventq.c @@ -70,14 +70,14 @@ static void update_timeout(AvahiTimeEventQueue *q) { } static void expiration_event(AvahiTimeout *timeout, void *userdata) { - struct timeval now; AvahiTimeEventQueue *q = userdata; AvahiTimeEvent *e; - gettimeofday(&now, NULL); - if ((e = avahi_time_event_queue_root(q))) { + struct timeval now; + gettimeofday(&now, NULL); + /* Check if expired */ if (avahi_timeval_compare(&now, &e->expiry) >= 0) { @@ -88,9 +88,13 @@ static void expiration_event(AvahiTimeout *timeout, void *userdata) { /* Run it */ assert(e->callback); e->callback(e, e->userdata); - } + + update_timeout(q); + return; + } } + avahi_log_debug(__FILE__": Strange, expiration_event() called, but nothing really happened."); update_timeout(q); } @@ -98,6 +102,8 @@ static void fix_expiry_time(AvahiTimeEvent *e) { struct timeval now; assert(e); + return; /*** DO WE REALLY NEED THIS? ***/ + gettimeofday(&now, NULL); if (avahi_timeval_compare(&now, &e->expiry) > 0) diff --git a/avahi-daemon/static-services.c b/avahi-daemon/static-services.c index 2e6c1bb..c155c22 100644 --- a/avahi-daemon/static-services.c +++ b/avahi-daemon/static-services.c @@ -280,8 +280,6 @@ static void XMLCALL xml_start(void *data, const char *el, const char *attr[]) { if (attr[2]) goto invalid_attr; - - } else if (u->current_tag == XML_TAG_SERVICE_GROUP && strcmp(el, "service") == 0) { if (attr[0]) goto invalid_attr; @@ -409,6 +407,7 @@ static char *append_cdata(char *t, const char *n, int length) { if (!length) return t; + k = avahi_strndup(n, length); if (t) {