diff --git a/Makefile b/Makefile index c1837100..d18310dc 100755 --- a/Makefile +++ b/Makefile @@ -152,15 +152,19 @@ PAHO_C_SUB_TARGET = ${blddir}/samples/${PAHO_C_SUB_NAME} PAHO_CS_PUB_TARGET = ${blddir}/samples/${PAHO_CS_PUB_NAME} PAHO_CS_SUB_TARGET = ${blddir}/samples/${PAHO_CS_SUB_NAME} -CCFLAGS_SO = -g -fPIC $(CFLAGS) -Os -Wall -fvisibility=hidden -I$(blddir_work) -FLAGS_EXE = $(LDFLAGS) -I ${srcdir} -lpthread -L ${blddir} -FLAGS_EXES = $(LDFLAGS) -I ${srcdir} ${START_GROUP} -lpthread -lssl -lcrypto ${END_GROUP} -L ${blddir} +#CCFLAGS_SO = -g -fPIC $(CFLAGS) -Os -Wall -fvisibility=hidden -I$(blddir_work) +#FLAGS_EXE = $(LDFLAGS) -I ${srcdir} -lpthread -L ${blddir} +#FLAGS_EXES = $(LDFLAGS) -I ${srcdir} ${START_GROUP} -lpthread -lssl -lcrypto ${END_GROUP} -L ${blddir} + +CCFLAGS_SO = -g -fPIC $(CFLAGS) -D_GNU_SOURCE -Os -Wall -fvisibility=hidden -I$(blddir_work) +FLAGS_EXE = $(LDFLAGS) -I ${srcdir} ${START_GROUP} -lpthread ${GAI_LIB} ${END_GROUP} -L ${blddir} +FLAGS_EXES = $(LDFLAGS) -I ${srcdir} ${START_GROUP} -lpthread ${GAI_LIB} -lssl -lcrypto ${END_GROUP} -L ${blddir} LDCONFIG ?= /sbin/ldconfig -LDFLAGS_C = $(LDFLAGS) -shared -Wl,-init,$(MQTTCLIENT_INIT) -lpthread -LDFLAGS_CS = $(LDFLAGS) -shared $(START_GROUP) -lpthread $(EXTRA_LIB) -lssl -lcrypto $(END_GROUP) -Wl,-init,$(MQTTCLIENT_INIT) -LDFLAGS_A = $(LDFLAGS) -shared -Wl,-init,$(MQTTASYNC_INIT) -lpthread -LDFLAGS_AS = $(LDFLAGS) -shared $(START_GROUP) -lpthread $(EXTRA_LIB) -lssl -lcrypto $(END_GROUP) -Wl,-init,$(MQTTASYNC_INIT) +LDFLAGS_C = $(LDFLAGS) -shared -Wl,-init,$(MQTTCLIENT_INIT) $(START_GROUP) -lpthread $(GAI_LIB) $(END_GROUP) +LDFLAGS_CS = $(LDFLAGS) -shared $(START_GROUP) -lpthread $(GAI_LIB) $(EXTRA_LIB) -lssl -lcrypto $(END_GROUP) -Wl,-init,$(MQTTCLIENT_INIT) +LDFLAGS_A = $(LDFLAGS) -shared -Wl,-init,$(MQTTASYNC_INIT) $(START_GROUP) -lpthread $(GAI_LIB) $(END_GROUP) +LDFLAGS_AS = $(LDFLAGS) -shared $(START_GROUP) -lpthread $(GAI_LIB) $(EXTRA_LIB) -lssl -lcrypto $(END_GROUP) -Wl,-init,$(MQTTASYNC_INIT) SED_COMMAND = sed \ -e "s/@CLIENT_VERSION@/${release.version}/g" \ @@ -173,6 +177,7 @@ MQTTASYNC_INIT = MQTTAsync_init START_GROUP = -Wl,--start-group END_GROUP = -Wl,--end-group +GAI_LIB = -lanl EXTRA_LIB = -ldl LDFLAGS_C += -Wl,-soname,lib$(MQTTLIB_C).so.${MAJOR_VERSION} @@ -187,6 +192,7 @@ MQTTASYNC_INIT = _MQTTAsync_init START_GROUP = END_GROUP = +GAI_LIB = EXTRA_LIB = -ldl CCFLAGS_SO += -Wno-deprecated-declarations -DOSX -I /usr/local/opt/openssl/include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 14846abe..5f306d0c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -58,7 +58,8 @@ IF (WIN32) SET(LIBS_SYSTEM ws2_32) ELSEIF (UNIX) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - SET(LIBS_SYSTEM c dl pthread) + SET(LIBS_SYSTEM c dl pthread anl) + ADD_DEFINITIONS(-D_GNU_SOURCE) ELSEIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") SET(LIBS_SYSTEM compat pthread) ELSE() diff --git a/src/MQTTAsync.c b/src/MQTTAsync.c index 6bc627e0..7587ea61 100644 --- a/src/MQTTAsync.c +++ b/src/MQTTAsync.c @@ -44,7 +44,6 @@ * */ -#define _GNU_SOURCE /* for pthread_mutexattr_settype */ #include #include #if !defined(WIN32) && !defined(WIN64) @@ -1500,12 +1499,23 @@ static int MQTTAsync_processCommand(void) Log(TRACE_PROTOCOL, -1, "Connecting to serverURI %s with MQTT version %d", serverURI, command->command.details.conn.MQTTVersion); #if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) + rc = MQTTProtocol_connect(serverURI, command->client->c, command->client->ssl, command->client->websocket, + command->command.details.conn.MQTTVersion, command->client->connectProps, command->client->willProps, 100); +#else rc = MQTTProtocol_connect(serverURI, command->client->c, command->client->ssl, command->client->websocket, command->command.details.conn.MQTTVersion, command->client->connectProps, command->client->willProps); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) + rc = MQTTProtocol_connect(serverURI, command->client->c, command->client->websocket, + command->command.details.conn.MQTTVersion, command->client->connectProps, command->client->willProps, 100); #else rc = MQTTProtocol_connect(serverURI, command->client->c, command->client->websocket, command->command.details.conn.MQTTVersion, command->client->connectProps, command->client->willProps); #endif +#endif + if (command->client->c->connect_state == NOT_IN_PROGRESS) rc = SOCKET_ERROR; diff --git a/src/MQTTClient.c b/src/MQTTClient.c index 1d269142..4ce6ebb8 100644 --- a/src/MQTTClient.c +++ b/src/MQTTClient.c @@ -43,7 +43,6 @@ * */ -#define _GNU_SOURCE /* for pthread_mutexattr_settype */ #include #include #if !defined(WIN32) && !defined(WIN64) @@ -1108,9 +1107,19 @@ static MQTTResponse MQTTClient_connectURIVersion(MQTTClient handle, MQTTClient_c Log(TRACE_MIN, -1, "Connecting to serverURI %s with MQTT version %d", serverURI, MQTTVersion); #if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) + rc = MQTTProtocol_connect(serverURI, m->c, m->ssl, m->websocket, MQTTVersion, connectProperties, willProperties, + millisecsTimeout - MQTTClient_elapsed(start)); +#else rc = MQTTProtocol_connect(serverURI, m->c, m->ssl, m->websocket, MQTTVersion, connectProperties, willProperties); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) + rc = MQTTProtocol_connect(serverURI, m->c, m->websocket, MQTTVersion, connectProperties, willProperties, + millisecsTimeout - MQTTClient_elapsed(start)); #else rc = MQTTProtocol_connect(serverURI, m->c, m->websocket, MQTTVersion, connectProperties, willProperties); +#endif #endif if (rc == SOCKET_ERROR) goto exit; diff --git a/src/MQTTProtocolOut.c b/src/MQTTProtocolOut.c index 779cbc51..6d8e2f4c 100644 --- a/src/MQTTProtocolOut.c +++ b/src/MQTTProtocolOut.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2018 IBM Corp. + * Copyright (c) 2009, 2019 IBM Corp. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -98,15 +98,26 @@ size_t MQTTProtocol_addressPort(const char* uri, int* port, const char **topic) * @param aClient a structure with all MQTT data needed * @param int ssl * @param int MQTTVersion the MQTT version to connect with (3 or 4) + * @param long timeout how long to wait for a new socket to be created * @return return code */ #if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* aClient, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout) +#else int MQTTProtocol_connect(const char* ip_address, Clients* aClient, int ssl, int websocket, int MQTTVersion, MQTTProperties* connectProperties, MQTTProperties* willProperties) +#endif +#else +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* aClient, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout) #else int MQTTProtocol_connect(const char* ip_address, Clients* aClient, int websocket, int MQTTVersion, MQTTProperties* connectProperties, MQTTProperties* willProperties) #endif +#endif { int rc, port; size_t addr_len; @@ -115,7 +126,16 @@ int MQTTProtocol_connect(const char* ip_address, Clients* aClient, int websocket aClient->good = 1; addr_len = MQTTProtocol_addressPort(ip_address, &port, NULL); + +#if defined(__GNUC__) && defined(__linux__) + if (timeout < 0) + rc = -1; + else + rc = Socket_new(ip_address, addr_len, port, &(aClient->net.socket), timeout); +#else rc = Socket_new(ip_address, addr_len, port, &(aClient->net.socket)); +#endif + if (rc == EINPROGRESS || rc == EWOULDBLOCK) aClient->connect_state = TCP_IN_PROGRESS; /* TCP connect called - wait for connect completion */ else if (rc == 0) diff --git a/src/MQTTProtocolOut.h b/src/MQTTProtocolOut.h index e2c26458..460d359f 100644 --- a/src/MQTTProtocolOut.h +++ b/src/MQTTProtocolOut.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2018 IBM Corp. + * Copyright (c) 2009, 2019 IBM Corp. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -34,12 +34,22 @@ size_t MQTTProtocol_addressPort(const char* uri, int* port, const char **topic); void MQTTProtocol_reconnect(const char* ip_address, Clients* client); #if defined(OPENSSL) +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); +#else int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int ssl, int websocket, int MQTTVersion, MQTTProperties* connectProperties, MQTTProperties* willProperties); +#endif +#else +#if defined(__GNUC__) && defined(__linux__) +int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, + MQTTProperties* connectProperties, MQTTProperties* willProperties, long timeout); #else int MQTTProtocol_connect(const char* ip_address, Clients* acClients, int websocket, int MQTTVersion, MQTTProperties* connectProperties, MQTTProperties* willProperties); #endif +#endif int MQTTProtocol_handlePingresps(void* pack, int sock); int MQTTProtocol_subscribe(Clients* client, List* topics, List* qoss, int msgID, MQTTSubscribe_options* opts, MQTTProperties* props); diff --git a/src/Socket.c b/src/Socket.c index 5d79240c..a7d5c26a 100644 --- a/src/Socket.c +++ b/src/Socket.c @@ -646,9 +646,14 @@ void Socket_close(int socket) * @param addr the address string * @param port the TCP port * @param sock returns the new socket + * @param timeout the timeout in milliseconds * @return completion code */ +#if defined(__GNUC__) && defined(__linux__) +int Socket_new(const char* addr, size_t addr_len, int port, int* sock, long timeout) +#else int Socket_new(const char* addr, size_t addr_len, int port, int* sock) +#endif { int type = SOCK_STREAM; char *addr_mem; @@ -679,7 +684,29 @@ int Socket_new(const char* addr, size_t addr_len, int port, int* sock) memcpy( addr_mem, addr, addr_len ); addr_mem[addr_len] = '\0'; - if ((rc = getaddrinfo(addr_mem, NULL, &hints, &result)) == 0) +//#if defined(__GNUC__) && defined(__linux__) +#if 0 + struct gaicb ar = {addr_mem, NULL, &hints, NULL}; + struct gaicb *reqs[] = {&ar}; + + unsigned long int seconds = timeout / 1000L; + unsigned long int nanos = (timeout - (seconds * 1000L)) * 1000000L; + struct timespec timeoutspec = {seconds, nanos}; + + rc = getaddrinfo_a(GAI_NOWAIT, reqs, 1, NULL); + if (rc == 0) + rc = gai_suspend((const struct gaicb* const *) reqs, 1, &timeoutspec); + + if (rc == 0) + { + rc = gai_error(reqs[0]); + result = ar.ar_result; + } +#else + rc = getaddrinfo(addr_mem, NULL, &hints, &result); +#endif + + if (rc == 0) { struct addrinfo* res = result; diff --git a/src/Socket.h b/src/Socket.h index e0420693..eec16346 100644 --- a/src/Socket.h +++ b/src/Socket.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. + * Copyright (c) 2009, 2019 IBM Corp. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -131,7 +131,12 @@ int Socket_getch(int socket, char* c); char *Socket_getdata(int socket, size_t bytes, size_t* actual_len); int Socket_putdatas(int socket, char* buf0, size_t buf0len, int count, char** buffers, size_t* buflens, int* frees); void Socket_close(int socket); +#if defined(__GNUC__) && defined(__linux__) +/* able to use GNU's getaddrinfo_a to make timeouts possible */ +int Socket_new(const char* addr, size_t addr_len, int port, int* socket, long timeout); +#else int Socket_new(const char* addr, size_t addr_len, int port, int* socket); +#endif int Socket_noPendingWrites(int socket); char* Socket_getpeer(int sock);