diff options
Diffstat (limited to 'libs/libmosquitto/src/srv_mosq.c')
| -rw-r--r-- | libs/libmosquitto/src/srv_mosq.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/libs/libmosquitto/src/srv_mosq.c b/libs/libmosquitto/src/srv_mosq.c new file mode 100644 index 0000000000..d08c2bd0cc --- /dev/null +++ b/libs/libmosquitto/src/srv_mosq.c @@ -0,0 +1,112 @@ +/* +Copyright (c) 2013-2019 Roger Light <roger@atchoo.org> + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#include "config.h" + +#ifdef WITH_SRV +# include <ares.h> + +# include <arpa/nameser.h> +# include <stdio.h> +# include <string.h> +#endif + +#include "logging_mosq.h" +#include "memory_mosq.h" +#include "mosquitto_internal.h" +#include "mosquitto.h" + +#ifdef WITH_SRV +static void srv_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) +{ + struct mosquitto *mosq = arg; + struct ares_srv_reply *reply = NULL; + if(status == ARES_SUCCESS){ + status = ares_parse_srv_reply(abuf, alen, &reply); + if(status == ARES_SUCCESS){ + // FIXME - choose which answer to use based on rfc2782 page 3. */ + mosquitto_connect(mosq, reply->host, reply->port, mosq->keepalive); + } + }else{ + log__printf(mosq, MOSQ_LOG_ERR, "Error: SRV lookup failed (%d).", status); + /* FIXME - calling on_disconnect here isn't correct. */ + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_disconnect){ + mosq->in_callback = true; + mosq->on_disconnect(mosq, mosq->userdata, MOSQ_ERR_LOOKUP); + mosq->in_callback = false; + } + if(mosq->on_disconnect_v5){ + mosq->in_callback = true; + mosq->on_disconnect_v5(mosq, mosq->userdata, MOSQ_ERR_LOOKUP, NULL); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); + } +} +#endif + +int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address) +{ +#ifdef WITH_SRV + char *h; + int rc; + if(!mosq) return MOSQ_ERR_INVAL; + + rc = ares_init(&mosq->achan); + if(rc != ARES_SUCCESS){ + return MOSQ_ERR_UNKNOWN; + } + + if(!host){ + // get local domain + }else{ +#ifdef WITH_TLS + if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){ + h = mosquitto__malloc(strlen(host) + strlen("_secure-mqtt._tcp.") + 1); + if(!h) return MOSQ_ERR_NOMEM; + sprintf(h, "_secure-mqtt._tcp.%s", host); + }else{ +#endif + h = mosquitto__malloc(strlen(host) + strlen("_mqtt._tcp.") + 1); + if(!h) return MOSQ_ERR_NOMEM; + sprintf(h, "_mqtt._tcp.%s", host); +#ifdef WITH_TLS + } +#endif + ares_search(mosq->achan, h, ns_c_in, ns_t_srv, srv_callback, mosq); + mosquitto__free(h); + } + + pthread_mutex_lock(&mosq->state_mutex); + mosq->state = mosq_cs_connect_srv; + pthread_mutex_unlock(&mosq->state_mutex); + + mosq->keepalive = keepalive; + + return MOSQ_ERR_SUCCESS; + +#else + UNUSED(mosq); + UNUSED(host); + UNUSED(keepalive); + UNUSED(bind_address); + + return MOSQ_ERR_NOT_SUPPORTED; +#endif +} + + |
