Mercurial > louis > mq > lightsd
changeset 409:6bc379a8f256
wip
author | Louis Opter <kalessin@kalessin.fr> |
---|---|
date | Thu, 31 Dec 2015 10:14:10 +0100 |
parents | 28915b460db7 |
children | 1830822a9f63 |
files | add_power_transition.patch doc_semver.patch dont_use_ev_assign.patch network_discovery.patch optional_jsonrpc_args.patch series |
diffstat | 6 files changed, 350 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/add_power_transition.patch Tue Dec 29 18:40:32 2015 +0100 +++ b/add_power_transition.patch Thu Dec 31 10:14:10 2015 +0100 @@ -1,21 +1,10 @@ # HG changeset patch -# Parent 87ea0f02cb6990de202d043b7ff05c9dbca83296 +# Parent dfd2e5cf185c1db0f2072f78528a8d4cf0118043 Add a transition argument to the power functions diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -4,8 +4,8 @@ - PROJECT(LIGHTSD C) - - SET(CPACK_PACKAGE_VERSION_MAJOR "1") --SET(CPACK_PACKAGE_VERSION_MINOR "1") --SET(CPACK_PACKAGE_VERSION_PATCH "2") -+SET(CPACK_PACKAGE_VERSION_MINOR "2") -+SET(CPACK_PACKAGE_VERSION_PATCH "0") - SET(LIGHTSD_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") - - MESSAGE(STATUS "lightsd version: ${LIGHTSD_VERSION}") @@ -88,6 +88,7 @@ ADD_SUBDIRECTORY(compat) @@ -536,7 +525,7 @@ diff --git a/core/lightsd.c b/core/lightsd.c --- a/core/lightsd.c +++ b/core/lightsd.c -@@ -52,6 +52,7 @@ +@@ -51,6 +51,7 @@ #include "timer.h" #include "listen.h" #include "daemon.h" @@ -544,7 +533,7 @@ #include "lightsd.h" struct lgtd_opts lgtd_opts = { -@@ -81,6 +82,7 @@ +@@ -181,6 +182,7 @@ lgtd_listen_close_all(); lgtd_command_pipe_close_all(); lgtd_client_close_all();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc_semver.patch Thu Dec 31 10:14:10 2015 +0100 @@ -0,0 +1,24 @@ +# HG changeset patch +# Parent bfa59be534ab65b5caff5b25d70a1d9fa961bfbb +Document semver a little bit better + +diff --git a/docs/changelog.rst b/docs/changelog.rst +--- a/docs/changelog.rst ++++ b/docs/changelog.rst +@@ -1,7 +1,15 @@ + Changelog + ========= + +-lightsd uses `semantic versionning <http://semver.org/>`_. ++lightsd uses `semantic versionning <http://semver.org/>`_, here is the summary: ++ ++Given a version number MAJOR.MINOR.PATCH: ++ ++- MAJOR version gets incremented when you may need to modify your lightsd ++ configuration to keep your setup running; ++- MINOR version gets incremented when functionality or substantial improvements ++ are added in a backwards-compatible manner; ++- PATCH version gets incremented for backwards-compatible bug fixes. + + 1.1.2 (2015-11-30) + ------------------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dont_use_ev_assign.patch Thu Dec 31 10:14:10 2015 +0100 @@ -0,0 +1,136 @@ +# HG changeset patch +# Parent eaec17795512845ed7a35e486ee5e9d61aa429a2 +Avoid event_assign for better compatibility across libevent versions + +diff --git a/core/lightsd.c b/core/lightsd.c +--- a/core/lightsd.c ++++ b/core/lightsd.c +@@ -36,7 +36,6 @@ + #include <unistd.h> + + #include <event2/event.h> +-#include <event2/event_struct.h> + + #include "lifx/wire_proto.h" + #include "time_monotonic.h" +@@ -72,34 +71,16 @@ + + struct event_base *lgtd_ev_base = NULL; + ++static const int lgtd_signals[] = { SIGINT, SIGTERM, SIGQUIT }; ++static struct event *lgtd_signal_evs[LGTD_ARRAY_SIZE(lgtd_signals)] = { NULL }; ++ + static int lgtd_last_signal_received = 0; + +-void +-lgtd_cleanup(void) +-{ +- lgtd_lifx_discovery_close(); +- lgtd_listen_close_all(); +- lgtd_command_pipe_close_all(); +- lgtd_client_close_all(); +- lgtd_lifx_broadcast_close(); +- lgtd_lifx_gateway_close_all(); +- lgtd_timer_stop_all(); +- event_base_free(lgtd_ev_base); +-#if LIBEVENT_VERSION_NUMBER >= 0x02010100 +- libevent_global_shutdown(); +-#endif +- if (lgtd_opts.pidfile) { +- unlink(lgtd_opts.pidfile); +- } +-} +- + static void + lgtd_signal_event_callback(int signum, short events, void *ctx) + { + assert(ctx); + +- // NOTE: syslog isn't signal safe, don't log anything in this function. +- + lgtd_last_signal_received = signum; + event_del((struct event *)ctx); // restore default behavior + event_base_loopbreak(lgtd_ev_base); +@@ -126,20 +107,18 @@ + } + + static void +-lgtd_configure_signal_handling(void) ++lgtd_setup_signal_handling(void) + { +- const int signals[] = {SIGINT, SIGTERM, SIGQUIT}; +- static struct event sigevs[LGTD_ARRAY_SIZE(signals)]; +- +- for (int i = 0; i != LGTD_ARRAY_SIZE(signals); i++) { +- evsignal_assign( +- &sigevs[i], +- lgtd_ev_base, +- signals[i], +- lgtd_signal_event_callback, +- &sigevs[i] ++ for (intptr_t i = 0; i != LGTD_ARRAY_SIZE(lgtd_signals); i++) { ++ lgtd_signal_evs[i] = evsignal_new( ++ // event_self_cbarg() would make things cleaner, but this was ++ // unfortunately added in libevent 2.1 which hasn't been released ++ // as of 2016: ++ lgtd_ev_base, lgtd_signals[i], lgtd_signal_event_callback, (void *)i + ); +- evsignal_add(&sigevs[i], NULL); ++ if (!lgtd_signal_evs[i] || evsignal_add(lgtd_signal_evs[i], NULL)) { ++ lgtd_err(1, "can't configure signal handling"); ++ } + } + + struct sigaction act = { .sa_handler = SIG_IGN }; +@@ -149,6 +128,15 @@ + } + + static void ++lgtd_close_signal_handling(void) ++{ ++ for (int i = 0; i != LGTD_ARRAY_SIZE(lgtd_signals); i++) { ++ event_del(lgtd_signal_evs[i]); ++ event_free(lgtd_signal_evs[i]); ++ } ++} ++ ++static void + lgtd_usage(const char *progname) + { + printf( +@@ -186,6 +174,26 @@ + exit(0); + } + ++void ++lgtd_cleanup(void) ++{ ++ lgtd_lifx_discovery_close(); ++ lgtd_listen_close_all(); ++ lgtd_command_pipe_close_all(); ++ lgtd_client_close_all(); ++ lgtd_lifx_broadcast_close(); ++ lgtd_lifx_gateway_close_all(); ++ lgtd_timer_stop_all(); ++ lgtd_close_signal_handling(); ++ event_base_free(lgtd_ev_base); ++#if LIBEVENT_VERSION_NUMBER >= 0x02010100 ++ libevent_global_shutdown(); ++#endif ++ if (lgtd_opts.pidfile) { ++ unlink(lgtd_opts.pidfile); ++ } ++} ++ + int + main(int argc, char *argv[], char *envp[]) + { +@@ -195,7 +203,7 @@ + lgtd_daemon_setup_proctitle(argc, argv, envp); + + lgtd_configure_libevent(); +- lgtd_configure_signal_handling(); ++ lgtd_setup_signal_handling(); + + static const struct option long_opts[] = { + {"listen", required_argument, NULL, 'l'},
--- a/network_discovery.patch Tue Dec 29 18:40:32 2015 +0100 +++ b/network_discovery.patch Thu Dec 31 10:14:10 2015 +0100 @@ -1,6 +1,172 @@ # HG changeset patch -# Parent bfa59be534ab65b5caff5b25d70a1d9fa961bfbb -Discover NICs connect to LANs and only discover bulbs on those +# Parent 2f53e91d85172265ef669ad34b90677f25e25d43 +Properly broadcast LIFX discovery packets on all networks (closes GH-2) + +It does solve the issue but only is half the solution I'd like to have. + +This is really the proper way of achieving the same semantic as +broadcasting to 255.255.255.255 and is kinda half the solution only. +What I'd like to add is: + +- bind to all local-only networks (right now lightsd binds on 0.0.0.0); +- watch for network interfaces changes so we can re-bind if necessary, + this is really the hard and annoying part as each OS has its own + mechanism for this and some (e.g: BSDs) don't even have it AFAIK. + +So that people running lightsd on a machine connected to Internet (that +can happen quickly on a laptop or a phone/tabled) don't have to firewall +56700. -Closes GH-2. - +diff --git a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -4,8 +4,8 @@ + PROJECT(LIGHTSD C) + + SET(CPACK_PACKAGE_VERSION_MAJOR "1") +-SET(CPACK_PACKAGE_VERSION_MINOR "1") +-SET(CPACK_PACKAGE_VERSION_PATCH "3") ++SET(CPACK_PACKAGE_VERSION_MINOR "2") ++SET(CPACK_PACKAGE_VERSION_PATCH "0") + SET(LIGHTSD_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + + MESSAGE(STATUS "lightsd version: ${LIGHTSD_VERSION}") +diff --git a/lifx/broadcast.c b/lifx/broadcast.c +--- a/lifx/broadcast.c ++++ b/lifx/broadcast.c +@@ -17,11 +17,14 @@ + + #include <sys/queue.h> + #include <sys/tree.h> ++#include <sys/socket.h> + #include <arpa/inet.h> ++#include <net/if.h> + #include <assert.h> + #include <endian.h> + #include <err.h> + #include <errno.h> ++#include <ifaddrs.h> + #include <stdarg.h> + #include <stdbool.h> + #include <stdint.h> +@@ -51,16 +54,35 @@ + }; + + static bool ++lgtd_lifx_broadcast_send_packet(void *pkt, ++ int pkt_sz, ++ const struct sockaddr *addr, ++ ev_socklen_t addrlen) ++{ ++ char addr_str[INET6_ADDRSTRLEN]; ++ LGTD_SOCKADDRTOA(addr, addr_str); ++ lgtd_debug("broadcasting LIFX discovery packet on %s", addr_str); ++ ++ int nbytes, socket = lgtd_lifx_broadcast_endpoint.socket; ++ do { ++ nbytes = sendto(socket, pkt, pkt_sz, 0, addr, addrlen); ++ } while (nbytes == -1 && EVUTIL_SOCKET_ERROR() == EINTR); ++ ++ if (nbytes != pkt_sz) { ++ lgtd_warn("couldn't broadcast LIFX discovery packet on %s", addr_str); ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool + lgtd_lifx_broadcast_handle_write(void) + { + assert(lgtd_lifx_broadcast_endpoint.socket != -1); + +- struct sockaddr_in lifx_addr = { +- .sin_family = AF_INET, +- .sin_addr = { INADDR_BROADCAST }, +- .sin_port = htons(LGTD_LIFX_PROTOCOL_PORT), +- .sin_zero = { 0 } +- }; ++ uint16_t lifx_port = htons(LGTD_LIFX_PROTOCOL_PORT); ++ + struct lgtd_lifx_packet_header get_pan_gateway; + lgtd_lifx_wire_setup_header( + &get_pan_gateway, +@@ -70,31 +92,56 @@ + LGTD_LIFX_GET_PAN_GATEWAY + ); + +- int nbytes; +-retry: +- nbytes = sendto( +- lgtd_lifx_broadcast_endpoint.socket, +- (void *)&get_pan_gateway, +- sizeof(get_pan_gateway), +- 0, +- (const struct sockaddr *)&lifx_addr, +- sizeof(lifx_addr) +- ); +- if (nbytes == sizeof(get_pan_gateway)) { +- if (event_del(lgtd_lifx_broadcast_endpoint.write_ev)) { +- lgtd_err(1, "can't setup events"); ++ bool ok = true; ++ struct ifaddrs *ifaddrs = NULL; ++ if (getifaddrs(&ifaddrs)) { ++ struct sockaddr_in lifx_bcast_addr = { ++ .sin_family = AF_INET, ++ .sin_addr = { INADDR_BROADCAST }, ++ .sin_port = lifx_port, ++ .sin_zero = { 0 } ++ }; ++ char addr_str[INET6_ADDRSTRLEN]; ++ lgtd_warn( ++ "can't fetch the list of network interfaces, falling back on %s", ++ LGTD_SOCKADDRTOA((struct sockaddr *)&lifx_bcast_addr, addr_str) ++ ); ++ ok = lgtd_lifx_broadcast_send_packet( ++ &get_pan_gateway, ++ sizeof(get_pan_gateway), ++ (struct sockaddr *)&lifx_bcast_addr, ++ sizeof(lifx_bcast_addr) ++ ); ++ } else { ++ for (struct ifaddrs *ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { ++ if (ifa->ifa_broadaddr != NULL ++ && (ifa->ifa_flags & IFF_BROADCAST) ++ && ifa->ifa_netmask != NULL) { ++ ev_socklen_t addrlen; ++ struct sockaddr *addr = ifa->ifa_broadaddr; ++ if (addr->sa_family == AF_INET) { ++ ((struct sockaddr_in *)addr)->sin_port = lifx_port; ++ addrlen = sizeof(struct sockaddr_in); ++ } else if (addr->sa_family == AF_INET6) { ++ // TODO: add support for IPv6 on the receive path. ++ ((struct sockaddr_in6 *)addr)->sin6_port = lifx_port; ++ addrlen = sizeof(struct sockaddr_in6); ++ } else { ++ continue; ++ } ++ ok = ok || lgtd_lifx_broadcast_send_packet( ++ &get_pan_gateway, sizeof(get_pan_gateway), addr, addrlen ++ ); ++ } + } +- return true; ++ freeifaddrs(ifaddrs); + } +- if (nbytes == -1) { +- if (EVUTIL_SOCKET_ERROR() == EINTR) { +- goto retry; +- } +- lgtd_warn("can't broadcast discovery packet"); +- } else { +- lgtd_warnx("can't broadcast discovery packet"); ++ ++ if (ok && event_del(lgtd_lifx_broadcast_endpoint.write_ev)) { ++ lgtd_err(1, "can't setup events"); + } +- return false; ++ ++ return ok; + } + + static void
--- a/optional_jsonrpc_args.patch Tue Dec 29 18:40:32 2015 +0100 +++ b/optional_jsonrpc_args.patch Thu Dec 31 10:14:10 2015 +0100 @@ -2,6 +2,20 @@ # Parent bfa59be534ab65b5caff5b25d70a1d9fa961bfbb Correctly support optional arguments in the JSON-RPC API +Passing too many arguments as an array also properly fails now. + +diff --git a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -5,7 +5,7 @@ + + SET(CPACK_PACKAGE_VERSION_MAJOR "1") + SET(CPACK_PACKAGE_VERSION_MINOR "1") +-SET(CPACK_PACKAGE_VERSION_PATCH "2") ++SET(CPACK_PACKAGE_VERSION_PATCH "3") + SET(LIGHTSD_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + + MESSAGE(STATUS "lightsd version: ${LIGHTSD_VERSION}") diff --git a/core/jsonrpc.c b/core/jsonrpc.c --- a/core/jsonrpc.c +++ b/core/jsonrpc.c
--- a/series Tue Dec 29 18:40:32 2015 +0100 +++ b/series Thu Dec 31 10:14:10 2015 +0100 @@ -1,6 +1,8 @@ +doc_semver.patch optional_jsonrpc_args.patch +network_discovery.patch +dont_use_ev_assign.patch add_power_transition.patch -network_discovery.patch make_gateway_write_callbacks_low_priority.patch #+future use_echo_request_reply_to_measure_latency.patch #+future add_ipv4_to_ieee8023mac.patch #+future #+linux