Giter VIP home page Giter VIP logo

eclipse / paho.mqtt.c Goto Github PK

View Code? Open in Web Editor NEW
1.9K 109.0 1.1K 11.13 MB

An Eclipse Paho C client library for MQTT for Windows, Linux and MacOS. API documentation: https://eclipse.github.io/paho.mqtt.c/

Home Page: https://eclipse.org/paho

License: Other

Makefile 0.98% HTML 0.50% C 86.78% Shell 0.46% CMake 4.71% Python 6.53% Batchfile 0.03% Dockerfile 0.01%
eclipseiot mqtt iot internet-of-things eclipse-paho

paho.mqtt.c's Introduction

Build Status Total Alerts Coverity Scan Build Status

Eclipse Paho C Client Library for the MQTT Protocol

This repository contains the source code for the Eclipse Paho MQTT C client library.

This code builds libraries which enable applications to connect to an MQTT broker to publish messages, and to subscribe to topics and receive published messages.

Synchronous and various asynchronous programming models are supported.

Information About MQTT

Libraries

The Paho C client comprises four variant libraries, shared or static:

  • paho-mqtt3a - asynchronous (MQTTAsync)
  • paho-mqtt3as - asynchronous with SSL/TLS (MQTTAsync)
  • paho-mqtt3c - "classic" / synchronous (MQTTClient)
  • paho-mqtt3cs - "classic" / synchronous with SSL/TLS (MQTTClient)

Which Paho C API to use, with some history, for context

Usage and API

Detailed API documentation is available online. It is also available by building the Doxygen docs in the doc directory.

Samples are available in the Doxygen docs and also in src/samples for reference. These are:

  • paho_c_pub.c and paho_c_sub.c: command line utilities to publish and subscribe, -h will give help
  • paho_cs_pub.c and paho_cs_sub.c: command line utilities using MQTTClient to publish and subscribe
  • MQTTClient_publish.c, MQTTClient_subscribe.c and MQTTClient_publish_async.c: MQTTClient simple code examples
  • MQTTAsync_publish.c and MQTTAsync_subscribe.c: MQTTAsync simple code examples

Some potentially useful blog posts:

Various MQTT and MQTT-SN talks I've given.

Runtime tracing

A number of environment variables control runtime tracing of the C library.

Tracing is switched on using MQTT_C_CLIENT_TRACE (a value of ON traces to stdout, any other value should specify a file to trace to).

The verbosity of the output is controlled using the MQTT_C_CLIENT_TRACE_LEVEL environment variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM (from least to most verbose).

The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output.

export MQTT_C_CLIENT_TRACE=ON
export MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL

Reporting bugs

Please open issues in the Github project: https://github.com/eclipse/paho.mqtt.c/issues.

More information

Discussion of the Paho clients takes place on the Eclipse paho-dev mailing list.

Follow Eclipse Paho on Twitter: @eclipsepaho

General questions about the MQTT protocol are discussed in the MQTT Google Group.

There is more information available via the MQTT community site.

Building with CMake

The build process currently supports a number of Linux "flavors" including ARM and s390, OS X, AIX and Solaris as well as the Windows operating system. The build process requires the following tools:

On Debian based systems this would mean that the following packages have to be installed:

$ apt-get install build-essential gcc make cmake cmake-gui cmake-curses-gui

Also, in order to build a debian package from the source code, the following packages have to be installed

$ apt-get install fakeroot devscripts dh-make lsb-release

Ninja can be downloaded from its github project page in the "releases" section. Optionally it is possible to build binaries with SSL/TLS support. This requires the OpenSSL libraries and includes to be available. E. g. on Debian:

$ apt-get install libssl-dev

The documentation requires doxygen and optionally graphviz:

$ apt-get install doxygen graphviz

Building your application with CMake

If the Paho C library was built with CMake and is already installed on the system, it is relatively easy to set up a CMake build for your application. (If it's not already built and installed read the next section).

The library can be built with several options which create variations of the library for asynchronous or synchronous use; encryption (SSL/TLS) support or not; and whether the library is shared or static. CMake exports all of the libraries that were built as targets, and the user can chose which is best suited for an application.

The package is named: eclipse-paho-mqtt-c

The namespace for all the targets is also: eclipse-paho-mqtt-c

The target names are the same as the library names. The static libraries append -static to the target name even for platforms that use the same base name for shared and static libraries. So:

Target Description
paho-mqtt3a asynchronous, no encryption
paho-mqtt3as asynchronous with SSL/TLS support
paho-mqtt3c synchronous, no encryption
paho-mqtt3cs synchronous with SSL/TLS support
paho-mqtt3a-static asynchronous, no encryption, static linkage
paho-mqtt3as-static asynchronous with SSL/TLS support, static linkage
paho-mqtt3c-static synchronous, no encryption, static linkage
paho-mqtt3cs-static synchronous with SSL/TLS support, static linkage

Remember, though, that not all of these targets may be available. It depends on how the library was built.

A sample CMakeLists.txt for an application that uses the asynchronous library with encryption support (paho-mqtt3as) might look like this:

cmake_minimum_required(VERSION 3.5)
project(MyMQTTApp VERSION 1.0.0 LANGUAGES C)

find_package(eclipse-paho-mqtt-c REQUIRED)

add_executable(MyMQTTApp MyMQTTApp.c)
target_link_libraries(MQTTVersion eclipse-paho-mqtt-c::paho-mqtt3as) 

If the library was installed to a non-traditional location, you may need to tell CMake where to find it using CMAKE_PREFIX_PATH. For example, if you installed it in /opt/mqtt/paho.mqtt.c

$ cmake -DCMAKE_PREFIX_PATH=/opt/mqtt/paho.mqtt.c ..

Building the Paho C library with CMake

Before compiling, determine the value of some variables in order to configure features, library locations, and other options:

Variable Default Value Description
PAHO_BUILD_SHARED TRUE Build a shared version of the libraries
PAHO_BUILD_STATIC FALSE Build a static version of the libraries
PAHO_HIGH_PERFORMANCE FALSE When set to true, the debugging aids internal tracing and heap tracking are not included.
PAHO_WITH_SSL FALSE Flag that defines whether to build ssl-enabled binaries too.
OPENSSL_ROOT_DIR "" (system default) Directory containing your OpenSSL installation (i.e. /usr/local when headers are in /usr/local/include and libraries are in /usr/local/lib)
PAHO_BUILD_DOCUMENTATION FALSE Create and install the HTML based API documentation (requires Doxygen)
PAHO_BUILD_SAMPLES FALSE Build sample programs
PAHO_ENABLE_TESTING TRUE Build test and run
MQTT_TEST_BROKER tcp://localhost:1883 MQTT connection URL for a broker to use during test execution
MQTT_TEST_PROXY tcp://localhost:1883 Hostname of the test proxy to use
MQTT_SSL_HOSTNAME localhost Hostname of a test SSL MQTT broker to use
PAHO_BUILD_DEB_PACKAGE FALSE Build debian package

Using these variables CMake can be used to generate your Ninja or Make files. Using CMake, building out-of-source is the default. Therefore it is recommended to invoke all build commands inside your chosen build directory but outside of the source tree.

An example build session targeting the build platform could look like this:

$ mkdir /tmp/build.paho ; cd /tmp/build.paho
$ cmake -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_DOCUMENTATION=TRUE \
    -DPAHO_BUILD_SAMPLES=TRUE ~/paho.mqtt.c

Invoking cmake and specifying build options can also be performed using cmake-gui or ccmake (see https://cmake.org/runningcmake/). For example:

$ ccmake ~/paho.mqtt.c

To compile/link the binaries, to install, or to generate packages, use these commands:

$ cmake --build .

$ cmake --build . --target install

$ cmake --build . --target package

To build, install, or generate packages, you can also use the generated builder like ninja or make directly after invoking the initial CMake configuration step, such as ninja package or make -j <number-of-jpbs> package.

Debug builds

Debug builds can be performed by defining the value of the CMAKE_BUILD_TYPE option to Debug. For example:

$ cmake -DCMAKE_BUILD_TYPE=Debug ~/paho.mqtt.c

Running the tests

Test code is available in the test directory. The tests can be built and executed with the CMake build system. The test execution requires a MQTT broker running. By default, the build system uses localhost, however it is possible to configure the build to use an external broker. These parameters are documented in the Build Requirements section above.

After ensuring a MQTT broker is available, it is possible to execute the tests by starting the proxy and running ctest as described below:

$ python ../test/mqttsas.py &
$ ctest -VV

Cross compilation

Cross compilation using CMake is performed by using so called "toolchain files" (see: http://www.vtk.org/Wiki/CMake_Cross_Compiling).

The path to the toolchain file can be specified by using CMake's -DCMAKE_TOOLCHAIN_FILE option. In case no toolchain file is specified, the build is performed for the native build platform.

For your convenience toolchain files for the following platforms can be found in the cmake directory of Eclipse Paho:

  • Linux x86
  • Linux ARM11 (a.k.a. the Raspberry Pi)
  • Windows x86_64
  • Windows x86

The provided toolchain files assume that required compilers/linkers are to be found in the environment, i. e. the PATH-Variable of your user or system. If you prefer, you can also specify the absolute location of your compilers in the toolchain files.

Example invocation for the Raspberry Pi:

$ cmake -GNinja -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_SAMPLES=TRUE \
    -DPAHO_BUILD_DOCUMENTATION=TRUE \
    -DOPENSSL_LIB_SEARCH_PATH=/tmp/libssl-dev/usr/lib/arm-linux-gnueabihf \
    -DOPENSSL_INC_SEARCH_PATH="/tmp/libssl-dev/usr/include/openssl;/tmp/libssl-dev/usr/include/arm-linux-gnueabihf" \
    -DCMAKE_TOOLCHAIN_FILE=~/paho.mqtt.c/cmake/toolchain.linux-arm11.cmake \
    ~/paho.mqtt.c

Compilers for the Raspberry Pi and other ARM targets can be obtained from ARM (https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads)

This example assumes that OpenSSL-libraries and includes have been installed in the /tmp/libssl-dev directory.

Example invocation for Windows 64 bit:

$ cmake -DPAHO_BUILD_SAMPLES=TRUE \
    -DCMAKE_TOOLCHAIN_FILE=~/paho.mqtt.c/cmake/toolchain.win64.cmake \
    ~/paho.mqtt.c

In this case the libraries and executable are not linked against OpenSSL Libraries. Cross compilers for the Windows platform can be installed on Debian like systems like this:

$ apt-get install gcc-mingw-w64-x86-64 gcc-mingw-w64-i686

Build instructions for GNU Make

Ensure the OpenSSL development package is installed. Then from the client library base directory run:

$ make
$ sudo make install

This will build and install the libraries. To uninstall:

$ sudo make uninstall

To build the documentation requires doxygen and optionally graphviz.

$ make html

The provided GNU Makefile is intended to perform all build steps in the build directory within the source-tree of Eclipse Paho. Generated binares, libraries, and the documentation can be found in the build/output directory after completion.

Options that are passed to the compiler/linker can be specified by typical Unix build variables:

Variable Description
CC Path to the C compiler
CFLAGS Flags passed to compiler calls
LDFLAGS Flags passed to linker calls

Building paho-mqtt - Using vcpkg

You can download and install paho-mqtt using the vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install paho-mqtt

The paho-mqtt port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

Fully static builds with musl libc

(By Frank Pagliughi)

musl libc is is an implementation of the C standard library built on top of the Linux system call API, including interfaces defined in the base language standard, POSIX, and widely agreed-upon extensions.

Users of the Rust library, which wraps this one, had been complaining that they could not compile using the musl build tools. Musl is a small std C lib that can be statically linked. With the latest Paho C library (and a very minor tweak to the build), we're now able to build Rust apps using musl and Paho C that are fully static; no runtime dependencies on the platform; not even on the standard C lib.

$ ./async_publish Publishing a message on the 'test' topic

$ ldd async_publish not a dynamic executable

So, for example, if maintaining a suite of apps for some newer and older embedded Linux boards, the same executables could be deployed without worry about the C ABI on the particular boards.

Certainly C apps using the Paho library could do this also.

Microsoft Windows

Calling convention

As is normal for C programs on Windows, the calling convention is __cdecl. See the Microsoft documentation here:

https://docs.microsoft.com/en-us/cpp/cpp/cdecl?view=vs-2019

If you call this library from another language, you may need to take this into account.

paho.mqtt.c's People

Contributors

adrianmoranmontes avatar aggresss avatar ashechol avatar cjxd avatar dpostorivo avatar fpagliughi avatar gambels avatar gitplcc avatar guilhermeferreira avatar icraggs avatar ivoshopov avatar jpwsutton avatar juergenkosel avatar jumoog avatar klaussnd avatar krzysztofc-rst avatar leon-anavi avatar lt-holman avatar momobel avatar orpiske avatar ralight avatar raphexion avatar roman3349 avatar rpendleton avatar rpoisel avatar tbeu avatar tkanoh avatar tucic avatar vm-vloz avatar waltronix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paho.mqtt.c's Issues

Unable to connect to certain brokers with non-default port

migrated from Bugzilla #478678
status RESOLVED severity blocker in component MQTT-C for 1.2
Reported in version unspecified on platform All
Assigned to: Ian Craggs

On 2015-09-29 19:12:07 -0400, Chris Watts wrote:

Running on the master branch @5f1bfae Merge branch 'develop'

I have been unsuccessful in trying to connect to two disjoint services:

  1. broker.mqttdashboard.com:8000
    The broker interface is at http://www.hivemq.com/demos/websocket-client/
    Strangely, if I leave out the port and connect to 1883, it connects successfully. I guess they have another broker on that server running on the default port.
  2. quickstart.messaging.internetofthings.ibmcloud.com:8883

At first I was invoking MQTTClient_connect programatically on a cross-compiled shared library for armv7l BeagleBone Black and noting a return code of -1, but I have since reproduced this problem using samples/stdinpub compiled normally for Debian x86_64.

I have managed to connect to both of these brokers with different technologies.

On 2015-09-29 19:13:03 -0400, Chris Watts wrote:

The quickstart interface is at https://quickstart.internetofthings.ibmcloud.com/#/

On 2015-09-30 05:30:32 -0400, Ian Craggs wrote:

Hi Chris.

  1. Port 8000 on the HiveMQ broker is evidently used for a WebSockets client connection - which is what the web interface is using. The C client at the moment does not support WebSockets, only straight TCP, which is why you can connect at port 1883.

  2. Port 8883 of quickstart.messaging.internetofthings.ibmcloud.com is for TLS connections. I can connect with samples/stdinpub if I use port 1883, like this:

LD_LIBRARY_PATH=.. ./stdoutsub topic_name --host quickstart.messaging.internetofthings.ibmcloud.com --clientid a:quickstart:myapp

On 2015-09-30 13:42:14 -0400, Chris Watts wrote:

Hi Ian,

You are correct! I used port 1883 with IBM and was able to connect fine.

I guess this issue should instead be a feature request for WebSockets support.

Thanks

Call sites of MQTTClient_cycle are not concurrency-safe.

migrated from Bugzilla #474748
status CLOSED severity major in component MQTT-C for 1.2
Reported in version v0.5 on platform PC
Assigned to: Ian Craggs

On 2015-08-11 18:23:17 -0400, Joe McIlvain wrote:

The way MQTTClient_cycle is called/used internally causes protocol-level race conditions for concurrent synchronous clients. This makes it impossible to have a safe application with concurrent synchronous clients (separated, with each in their own thread) without wrapping all functions that wait for a server response in a global application-level mutex shared by all clients.

MQTTClient_cycle only knows how to handle certain incoming packets internally.
https://github.com/eclipse/paho.mqtt.c/blob/SHA: 5f1bfae/src/MQTTClient.c#L1584-L1610

For all other packet types, it is returned to the caller to handle.
https://github.com/eclipse/paho.mqtt.c/blob/SHA: 5f1bfae/src/MQTTClient.c#L1616

However, some of the call sites of MQTTClient_cycle will discard the returned packet under all or some circumstances. Many of these call sites are waiting for a specific packet from a specific handle/socket, but discard other packets that come in, meaning that the other threads that are waiting for those specific packets will never get them, and will time out.

On 2015-08-12 05:18:29 -0400, Ian Craggs wrote:

The MQTTClient API was not intended to be thread safe, whereas the MQTTAsync API is. We need to call this out prominently in the documentation. We could look into making the MQTTClient API thread safe, but at this point I don't know when that would happen. My recommendation would be to use MQTTAsync.

On 2015-08-12 11:28:09 -0400, Joe McIlvain wrote:

Thanks for the quick response, Ian.

If the MQTTClient API is not intended to be concurrently from multiple threads (with one client in each thread), then why does the implementation make such frequent use of mutexes? To be clear, I am not sharing any client handles between threads, but the implementation of MQTTClient_yield (and every function that uses MQTTClient_cycle) is inherently shared between all clients, and is not isolated by client handle.

Actually, before filing this ticket, I saw this ticket, which seems to suggest that both the synchronous and asynchronous APIs are intended to be usable with multiple, isolated clients in multiple, isolated threads:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=441950

In fact, that ticket implies that help is needed to determine whether this is safe or not with the current implementation, and this ticket is intended to help show at least one specific aspect that is not safe.

To give some context, I am writing a higher-level language binding that uses this library as the backend via native FFI calls, and I am not using the MQTTAsync API because having callbacks invoked across thread boundaries is a dealbreaker for me.

On 2015-08-12 12:52:05 -0400, Ian Craggs wrote:

Yes, I saw that bug (441950) too, after I'd responded here. Apparently I didn't remember my intentions in writing the library! I've started writing the tests described in that bug, so I can try it out and fix it up. I was hoping to get some help in writing those tests but apparently it hasn't turned out that way.

There are some calls which only apply in single threaded mode (by not setting callbacks), and which definitely won't be covered:

MQTTClient_yield()
MQTTClient_receive()

These were only created to allow single-threaded programs to exist.

On 2015-08-12 15:17:47 -0400, Joe McIlvain wrote:

Okay, thank you for the clarification.

I'll change the direction of my project to use libmosquitto instead.

On 2015-08-13 06:23:04 -0400, Ian Craggs wrote:

I think I need to explain further:

MQTTClient_yield() is only needed when there are no background threads running (when MQTTClient_setCallback is not used). If you want to have a single threaded application, then you can use MQTTClient_yield() and MQTTClient_receive() to have the background processing occur on the same thread.

In a multi threaded environment, you call MQTTClient_setCallback(), and a background thread is started. Calls to yield() and receive() are not necessary, and for that reason are not synchronized. All the other calls are synchronized and should work, and I will fix anything I find in my testing. I may reopen this bug for any fixes that are needed.

So I don't think of this bug as "won't fix". I will fix any bugs related to the use of MQTTClient in multi-threaded environments, except for the yield() and receive() functions which are not intended for use under those circumstances.

On 2015-08-13 12:00:55 -0400, Ian Craggs wrote:

For info:

I've added code to make if clear that receive() is not intended to be called when the background thread is running (messages are received by callback function). A fix has been added to make sure that subscribe, unsubscribe and connect operations can safely be called from multiple threads.

On 2015-08-13 20:19:18 -0400, Joe McIlvain wrote:

Ian, thanks for the additional response.

The core of my use case demands a synchronous API (that does not invoke callbacks from background threads, violating thread boundaries and complicating call code), but that allows me to use multiple single-threaded clients from multiple threads (so that a single process can host multiple "actors", each one of which is an MQTT client.

I marked as "won't fix" because I thought you understood my constraints and decided that it would be too much work or too far out of scope to fix the race conditions that arise in this use case.

I don't find this to be an unreasonable answer, as the API was clearly not designed with this in mind, and to fix it elegantly may require some breaking changes (like having the MQTTClient_yield function be specific to only one client handle at a time).

I appreciate your responsiveness in answering my ticket, and the dialog we have had here, and I bear the paho project no ill will, but I cannot operate within the false dichotomy of choosing either a "synchronous" or "multi-threaded" approach when what I need is both.

Luckily, the libmosquitto library's synchronous API meets my constraints because individual clients are fully decoupled from one another, with all state being passed within the client handle. I've been able to proceed with my work using it instead, and am grateful to Eclipse for supporting both projects.

On 2015-08-14 06:45:02 -0400, Ian Craggs wrote:

Thanks for your comments, Joe. One reason I added my further comments was to make sure that anyone reading this bug in future understands the intent and use of the API, although I've striven to make that clearer in the code as well.

I'm happy that libmosquitto provides the solution that you want. I'm not sure it's possible or desirable to satisfy all requirements for everyone all the time! This API does have the feature of using only one background thread regardless of the number of client objects, which was what I was aiming for, but this decision does constrain some other use cases.

SSL Connection Failing

migrated from Bugzilla #479376
status UNCONFIRMED severity major in component MQTT-C for 1.2
Reported in version future on platform PC
Assigned to: Ian Craggs

On 2015-10-08 21:04:55 -0400, Angelo Ribeiro wrote:

I am using MQTT-C (paho) library paho-mqtt3cs and SSL Connection was failing on method: MQTTProtocol_connect file: MQTTProtocolOut.c.

If you take a look on line 105 It calls: SSLSocket_setSocketForSSL(&aClient->net, aClient->sslopts), but it tests if It is != 1 as if 1 would be an error.

But if you take a look into the implementation of SSLSocket_setSocketForSSL (File SSLSocket.c) this method returns 1 in case of success.

So, it was not sending CONNECT because of that.

If you change the code to:
SSLSocket_setSocketForSSL(&aClient->net, aClient->sslopts) == 1
It will work corretly.

Let me know if you want me to do a PULL request or if you have any questions.

Thanks,

Angelo Ribeiro.

Segmentation fault or hi CPU load

migrated from Bugzilla #478734
status ASSIGNED severity normal in component MQTT-C for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2015-09-30 11:02:47 -0400, Gianluca Costa wrote:

Environment:
OS: Ubuntu 14.04.3 LTS
CPU: x86 64bit
Version: paho-1.0.3 (application is linked with libpaho-mqtt3c.so)

The application that generate the issue is:

include <stdio.h>

include "MQTTClient.h"

int main()
{
int rc;

MQTTClient client = NULL;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;

conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;

while (1) {
    printf("Create...\n");
    rc = MQTTClient_create(&client, "192.168.1.123", "Menego", MQTTCLIENT_PERSISTENCE_NONE, NULL);
    if (rc == MQTTCLIENT_SUCCESS) {
        printf("Try...\n");
        if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
            printf("Fault\n");
            MQTTClient_destroy(&client);
            client = NULL;
        }
        else
            break;
    }
    else {
        printf("End");
        break;
    }
}

return 0;

}

The main part of the test is that the connection fails, therefore the MQTTClient_destroy is called and after that it is called MQTTClient_create.

Using valgrind I have these errors:
==3973== Invalid read of size 4
==3973== at 0x54B8414: pthread_mutex_lock (pthread_mutex_lock.c:66)
==3973== by 0x570937B: ??? (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==3973== by 0x570B388: SSL_COMP_get_compression_methods (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==3973== by 0x5710708: SSL_library_init (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==3973== by 0x4E46DCB: SSLSocket_initialize (SSLSocket.c:400)
==3973== by 0x4E3F6AE: MQTTClient_create (MQTTClient.c:272)
==3973== by 0x40095F: main (main.c:17)
==3973== Address 0x5f7c6c4 is 660 bytes inside a block of size 1,656 free'd
==3973== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3973== by 0x4E3B373: myfree (Heap.c:242)
==3973== by 0x4E46EC4: SSLSocket_terminate (SSLSocket.c:445)
==3973== by 0x4E3CC66: MQTTClient_terminate (MQTTClient.c:332)
==3973== by 0x4E3CDE3: MQTTClient_destroy (MQTTClient.c:399)
==3973== by 0x4009CA: main (main.c:23)

Where line 17 is on MQTTClient_create, and line 23 is on MQTTClient_destroy

On 2015-09-30 11:31:06 -0400, Ian Craggs wrote:

Hi.

That program doesn't show any errors when I run it under valgrind linked against libpaho-mqtt3c.so. However, the valgrind output shows OpenSSL calls which won't be made unless you link with libpaho-mqtt3cs.so. It did show the errors then, which I will look into.

But also, why are you destroying the client object at that point, rather than trying to reconnect, after a delay for instance? You don't need to recreate the client object to be able to reconnect. Is this just to demonstrate the problem?

If you want to try to connect to a number of possible MQTT host/port combinations in sequence if one doesn't work, then you can also use the serverURIs connect option, which would also avoid having to destroy and recreate the client object.

On 2015-10-01 04:16:14 -0400, Gianluca Costa wrote:

Hi,
yes the issue comes using libpaho-mqtt3cs.so (I forgot the 's'... I'm sorry).
Yes, the code demonstrates the problem, but thanks for the very helpful suggestion about try to reconnect without destroying the client object.

Race condition for MQTTAsync_token in MQTTAsync.c

migrated from Bugzilla #444093
status RESOLVED severity normal in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2014-09-15 07:59:58 -0400, Juergen Denner wrote:

There is a race condition that makes the usage of the MQTTAsync_token in publish, subscribe, unsubscribe potentially complicated or even impossible.

It is possible that these methods return after the onSuccess or onFailure callback already has been invoked. This happens if the MQTTAsync_addCommand is already invoked but the method (publish, subscribe, unsubscribe) did not return because of the OS scheduler. So creating any structure related to the token is potentially too late.

Git version:
master/2014-09-04 13:06:27/commit SHA: 48550c7

On 2014-09-15 10:54:36 -0400, Ian Craggs wrote:

Hi Juergen. Is this a theoretical occurrence, or have you seen it happen? If you have seen this happen, what sort of platform, and how often (percentage of the time)?

Thanks.

On 2014-09-16 03:41:20 -0400, Juergen Denner wrote:

Hello Ian,

I found this by looking at the source and have no test to reproduce the situation (in this sense it's theoretical).

--- code snippet ---
int MQTTAsync_send(
MQTTAsync handle, const char* destinationName, size_t payloadlen,
void* payload, int qos, int retained,
MQTTAsync_responseOptions* response)

{
...
if (response)
{
...
response->token = pub->command.token;
}

...
rc = MQTTAsync_addCommand(pub, sizeof(pub));
exit:
FUNC_EXIT_RC(rc);
return rc;

}

There is no threading guarantee that MQTTAsync_send may
a) return before the command has been processed (=> callback not invoked).
Even then there is still a race between the creation of a token related
structure with the callback invocation.

  • or -
    b) return after the command has been processed (=> callback invoked)

IMO the only race condition free moment use the token, is before MQTTAsync_addCommand (and after the token creation).

On 2014-09-16 06:33:33 -0400, Ian Craggs wrote:

Close to the last thing that addCommand does is to release the command mutex. There is very little code between releasing the mutex and returning to the application - mostly just unwinding the stack. While I can see that this is a theoretical possibility, I would rather focus on problems that actually occur.

By the way, what was your proposed solution?

On 2014-09-16 07:09:06 -0400, Juergen Denner wrote:

The proposed solution was a callback that is invoked before MQTTAsync_addCommand. Here any companion structure can be created safely.

In my evaluation I solve this problem differently.

I provide a dedicated (maybe freshly allocated) context to each invocation of send, subscribe or unsubscribe. This BTW also prevents the potential ABA problem with the token (i.e. the message is processed and the same token value is reused for another asynchronous operation).

With this approach I ran into the problem of missing callbacks (Bug 444103) which is mandatory for resource cleanup.

I'm fine with rating this behavior as accepted but then a comment on the API should document the possible runtime behavior.

Something like:
The callbacks may have been invoked, before the function returns.

On 2014-10-01 11:34:23 -0400, Ian Craggs wrote:

I will add a comment on the API that documents this possible runtime behaviour, and of course fix bug 444103.

On 2015-08-13 11:52:12 -0400, Ian Craggs wrote:

I've noted the possibility in the Threading section of the MQTTAsync documentation, and fixed bug 444103 (both in the develop branch for now).

Async client varying delay between messages

migrated from Bugzilla #465369
status RESOLVED severity normal in component MQTT-C for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2015-04-24 03:38:39 -0400, Ian Craggs wrote:

Hi all,

I am experiencing some behavior I cannot explain.

Here is what I do.

I am using the paho-c library and as a reference the paho python library. My Broker is mosquitto.

The goal of my experiments is to measure the application layer roundtrip time. Therefore I have the following setup

Application <----> Broker <---> Reflector

What I do is:

  • I take the time in the application, put it into a packet and send it to the broker. (QoS 0)
  • The reflector is subscribed to theses messages, receives them, packs them into a new packet and sends the back to the broker using a different topic.
  • Finally I receive the message back at the application, take the current time and calculate the time difference between the current time and the time contained in the packet.

I have this implementation, both in C and in Python. All processes are running on the same machine.

No here are the observations that keep me busy.

If I watch the application delay for the c implementation I get something like
5, 1005, 106, 5, 1005, 104, 6 ...

For the python implementation it is like:
5, 5, 5, 6, 4, ....

You see the difference, unfortunately I need an implementation in C thanks to the target platform. I checked my code several times, there is nothing I could pinpoint to cause the delay.

To me, it resembles effects that I have seen in other projects when using TCP. Could it be, that somewhere in the library code there is some issue with the socket handling?

Any other ideas? Did I miss a configuration flag or something?

On 2015-04-24 03:43:08 -0400, Ian Craggs wrote:

I could see the delay, using the code that Frank supplied.

On 2015-04-24 04:51:29 -0400, Ian Craggs wrote:

Added a fix to the develop branch. The method for working out whether processCommand had actually done any work was flawed - the information could be updated by another thread.

Add C client sample code

migrated from Bugzilla #402253
status ASSIGNED severity normal in component MQTT-C for ---
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2013-03-03 18:01:12 -0500, Ian Craggs wrote:

In the src/samples directory

On 2013-03-03 18:02:38 -0500, Ian Craggs wrote:

Sample code added.

On 2013-03-04 10:02:27 -0500, Andy Piper wrote:

*** Bug 401722 has been marked as a duplicate of this bug. ***

On 2013-03-04 10:38:03 -0500, Andy Piper wrote:

So we now have

MQTTAsync_publish.c
MQTTAsync_subscribe.c
pubasync.c
pubsync.c
stdinpub.c
stdoutsub.c
stdoutsuba.c
subasync.c

There appear to be duplicates here (pubasync and MQTTAsync_publish?) etc.

There are strings defining the swtest.hursley.ibm.com broker as the test broker.

Need to replace localhost with m2m.eclipse.org to match Java samples.

In addition, the Makefile SAMPLES build rules do not match up with these filenames so setting BUILD_SAMPLES=TRUE does not cause the samples to be built.

On 2013-03-04 11:00:35 -0500, Ian Craggs wrote:

pubasync and MQTTAsync_publish are not duplicates. One uses the MQTTClient API, the other uses the MQTTAsync API, corresponding to the samples in the html documentation.

On 2013-03-04 11:02:21 -0500, Andy Piper wrote:

(In reply to comment # 4)

pubasync and MQTTAsync_publish are not duplicates. One uses the MQTTClient
API, the other uses the MQTTAsync API, corresponding to the samples in the
html documentation.

Apologies I'd taken a very hasty look! was surprised that there were 8 rather than the 4 accounted for in the makefile :-)

On 2013-03-04 11:30:07 -0500, Andy Piper wrote:

Committed the OS X build change to the Makefile, but the samples chunk will need updating in line with this.

On 2013-03-04 18:01:12 -0500, Ian Craggs wrote:

I added some samples that I had written a long time ago, which I think are actually useful as utilities as well. There is another to come as well: stdinpuba.c. But I haven't written it yet!

Where to document, is the next question.

On 2013-03-04 18:08:12 -0500, Andy Piper wrote:

(In reply to comment # 7)

I added some samples that I had written a long time ago, which I think are
actually useful as utilities as well. There is another to come as well:
stdinpuba.c. But I haven't written it yet!

Where to document, is the next question.

I think a brief summary of the samples in README.md is appropriate?

If a deep dive is needed it could go in a tentative doc/Samples.txt

On 2013-04-15 08:35:06 -0400, Andy Piper wrote:

Assigning to MQTT-C since this is C client specific.

On 2014-08-28 10:58:49 -0400, Ian Craggs wrote:

Assigning to Rong.

On 2015-01-16 06:44:51 -0500, Ian Craggs wrote:

Taking back.

Extra Thread_wait_cond

migrated from Bugzilla #486805
status UNCONFIRMED severity critical in component MQTT-C for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2016-01-29 06:10:28 -0500, Kazuma MISHIMAGI wrote:

"Thread_wait_cond" in MQTTAsync.c L1275 seems to be extra.
(v1.0.3)

This line seems to make extra waiting time to send next command.
Sending commands one after another has 1 second waiting time between each commands.

This line is added in commit e3e40d1 .

Is this designed behaviour?

On 2016-02-01 10:36:02 -0500, Ian Craggs wrote:

When a command is sent, the condition variable should be signalled to release the wait_cond and thus the send thread. This signalling is done in addCommand, at

rc = Thread_signal_cond(send_cond);

So, do you think this is not working, or there should be a signal somewhere else? Can you get a trace?

To get a trace, use the following environment variables:

MQTT_C_CLIENT_TRACE=ON or filename
MQTT_C_CLIENT_TRACE_MAX_LINES to control the nubmer of lines in the trace file.

compilation error found when compiling the source files in Xcode

migrated from Bugzilla #460420
status RESOLVED severity normal in component MQTT-C for 1.1
Reported in version 1.0 on platform Macintosh
Assigned to: Ian Craggs

On 2015-02-20 05:04:44 -0500, Angshuk Nag wrote:

duplicate symbol _clientSockCompare in:
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTClient.o
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTAsync.o
duplicate symbol _bstate in:
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTClient.o
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTAsync.o
duplicate symbol _MQTTProtocol_checkPendingWrites in:
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTClient.o
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTAsync.o
duplicate symbol _Protocol_processPublication in:
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTClient.o
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTAsync.o
duplicate symbol _MQTTProtocol_closeSession in:
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTClient.o
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTAsync.o
duplicate symbol _pubCompare in:
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTClient.o
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTAsync.o
duplicate symbol _client_timestamp_eye in:
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTClient.o
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTAsync.o
duplicate symbol _client_version_eye in:
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTClient.o
/Users/bharathbalaraj/Library/Developer/Xcode/DerivedData/newpaho-bthxvicxffppjpawnvkhjnylxjmr/Build/Intermediates/newpaho.build/Debug/newpaho.build/Objects-normal/x86_64/MQTTAsync.o
ld: 8 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

These are the errors which are coming . These are mostly variable name clashes. and there are function name clashes also. Since the variables have been refferenced as extern from some other file, in that file there becomes a conflict as in which variable to actually refference, since there are two global variables with the same name in two separate files. same is the case with functions also.

Mostly the clashes are occuring between MQTTAsync.c and MQTTClient.c files. I think the global variables and functions in MQTTClient only have been refferenced in other files , and the duplicates found in MQTTAsync.c can be made as static. Jst my opinion.

Thanks & Regards
Angshuk Nag

On 2015-02-20 10:58:22 -0500, Ian Craggs wrote:

Hi.

MQTTAsync.c and MQTTClient.c are mutually exclusive, you need to pick one or the other. They are two separate APIs. The Makefile, which works for the Mac as well, can be used as a guide.

MQTTAsync_connect .onFailure callback MQTTAsync_failureData* is NULL

migrated from Bugzilla #472250
status ASSIGNED severity normal in component MQTT-C for 1.2
Reported in version future on platform Macintosh
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-07-09 03:38:08 -0400, Andres Vahter wrote:

Created attachment 255073
testcase

Using develop branch from: https://github.com/eclipse/paho.mqtt.c.

If MQTT broker is not running and connect attempt is made we get success here:

if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start sendMessage, return code %d\n", rc);
exit(-1);
}

.. and then callback with response NULL is called:

void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
if (response == NULL) {
printf("Connect response is NULL\n");
}
printf("Connect failed, rc %d\n", response ? response->code : 0);
finished = 1;
}

The problem is that application does not get any information why it is unable to connect, because MQTTAsync_sendMessage returns 0 (success) and inside callback we have NULL pointer, so we do not get more information from there either.

On 2015-08-11 06:13:22 -0400, Ian Craggs wrote:

When I was writing the library I just returned the data from the connack in the failure response code. When there was no connack, the failure data response was not filled in. I could add response codes for each connect failure so that each different occurrence did have some information with it.

On 2015-08-11 06:54:58 -0400, Andres Vahter wrote:

(In reply to Ian Craggs from comment # 1)

When I was writing the library I just returned the data from the connack in
the failure response code. When there was no connack, the failure data
response was not filled in. I could add response codes for each connect
failure so that each different occurrence did have some information with it.

That would be reasonable.

Callback onSuccess or onFailure not invoked from MQTTAsync client

migrated from Bugzilla #444103
status RESOLVED severity normal in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2014-09-15 08:20:53 -0400, Juergen Denner wrote:

Created attachment 247065
Paho trace without callback invocation

In my scenario I need to do a cleanup on the provided context for callback methods. Therefore it is crucial that one of the callback methods is invoked by the MQTTAsync.c client.

A trace is attached that documents the following flow:

  1. SEND. TOPIC="test", qos = 1, Payload = "Msg before disconnect. ...", Payload length = 144
  2. Immediate disconnect with timeout = 0

Line 152 shows the freeing of the message. No callback was executed.

On 2014-09-16 11:47:44 -0400, Ian Craggs wrote:

Ah, I see. Calling disconnect before waiting for the publish to complete. Presumably you connected cleansession=true? If we had connected cleansession=false then the message could complete at a later stage, when the client reconnects.

On 2014-09-17 03:09:23 -0400, Juergen Denner wrote:

Correct, cleansession was set to true.

On 2015-08-10 17:54:55 -0400, Ian Craggs wrote:

So finally I am thinking about addressing this bug. There are a number of cases.

  1. Disconnect clean session while there are outstanding publish requests. We should call onFailure, it is clear.

  2. Disconnect non clean session, while there are outstanding publish requests. These could be completed on reconnect, so we should not make any callback calls at this point (no change needed).

  3. The client object is destroyed while there are outstanding publish requests. This implies a previous disconnect non clean session. If persistence is enabled, the client objects could be recreated at a later date, and the publish requests continued. However the callbacks would not be re-instantiated then, but the global callbacks messageArrived() and deliveryComplete() would be called appropriately. I propose calling onFailure, with an "interrupted" or similar return code.

On 2015-08-10 23:50:29 -0400, Frank Pagliughi wrote:

This affects the upcoming C++ and D language wrapper libraries as well. In both of those libraries an MqttToken object is created on the heap and passed to the C library via the "context" pointer. Both libraries/languages have automatic memory management (shared pointers for C++ and garbage collection in D), but in both cases, the library must insure that the Token stays valid at least until the callback happens, otherwise the callback might operate on an object that was already deleted. So if the callback never fires, the libraries would seem to leak memory.

On 2015-08-11 10:32:59 -0400, Ian Craggs wrote:

Fix added to the develop branch. Call the onFailure callback on disconnect cleansession, or destroy, whichever comes first.

Fallback from 3.1.1 to 3.1 not always working

migrated from Bugzilla #447113
status ASSIGNED severity major in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2014-10-14 10:30:29 -0400, Nicolas Schneider wrote:

Created attachment 247861
Trace showing a working and a not working fallback

Tested using the asynchronous library v1.0.2 and mosquitto v1.2 running on localhost.

Trace file, which includes two traces � one when the fallback worked, one when it did not � is attached.

It seems like the socket, which is used during the fallback, gets closed because of an error during the previous handshake sometimes.

On 2014-10-14 10:38:35 -0400, Nicolas Schneider wrote:

Also, the onFailure callback for the connect command is not invoked.

On 2015-08-10 09:18:13 -0400, Ian Craggs wrote:

Nicolas,

I realize it's a long time since this was raised, but I did start to look at it last week. My simple test program has not reproduced the problem so far, but from the traces it looks like that setting

*rc = 0;

to initialize the return code in MQTTAsync_cycle should fix it. Does the problem still happen with the latest code? Are you able to test a fix?

Thanks

LinkedList segfaults

migrated from Bugzilla #458099
status RESOLVED severity critical in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-01-22 03:28:19 -0500, Kim Poulsen wrote:

In a performance test setup I create 300 instances which all due to network constraints fail to connect.

Eventually the MQTT library starts closing the sockets ending up in a segfault in intcompare() being called from ListFindItem().

One of the arguments is NULL.

Seems like the List is messed up. First object in list has a content=NULL. Next in list has content pointing at unaccessible memory.

Version used is git tag 1.0.2, commit hash 8ffd07f

On 2015-01-30 16:26:04 -0500, Bernard Opic wrote:

Could you please provide me with the test source code?

On 2015-02-05 11:29:24 -0500, Ian Craggs wrote:

Hi Kim. A fix for this bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=447672, which could have this effect, is in the develop branch. Are you able to try the latest develop branch out?

On 2015-02-05 12:03:16 -0500, Ian Craggs wrote:

Bernard, thanks for taking an interest in this. Did you attempt to reproduce it?

On 2015-02-05 12:23:18 -0500, Bernard Opic wrote:

(In reply to Ian Craggs from comment # 3)

Bernard, thanks for taking an interest in this. Did you attempt to
reproduce it?

Ian,

Kim should send me a

On 2015-02-05 12:25:45 -0500, Bernard Opic wrote:

(In reply to Bernard Opic from comment # 4)

(In reply to Ian Craggs from comment # 3)

Bernard, thanks for taking an interest in this. Did you attempt to
reproduce it?

Ian,

Kim should soon send me a test source code to reproduce the issue.

On 2015-02-06 05:44:18 -0500, Ian Craggs wrote:

Bernard,

ok that's great. First thing to do will be to try with the fix to bug 447672 included, to see if that addresses the problem. I'll be cutting a 1.0.3 very soon with that fix in.

On 2015-02-09 02:25:09 -0500, Kim Poulsen wrote:

Hi guys

Right now I've been assigned for some emergency work in another project.
I'll therefor at least not within the next one or two weeks have any time for verifying the suggested commit nor will I get the time for providing any test code.

I'll let you know when I'm back on track

/Kim

On 2015-04-09 11:28:03 -0400, Ian Craggs wrote:

Hi guys. Any news on this?

As I said before, the symptoms sound similar to bug 447672, the fix for which is in version 1.0.3. If you can try that version...

On 2015-04-24 04:53:23 -0400, Ian Craggs wrote:

In the absence of further information, I'm going to mark this as a duplicate of 447672. Please reopen if this is not the case. Thanks.

*** This bug has been marked as a duplicate of bug 447672 ***

sleep() in fast path (publish) when QoS>0 (MQTTClient)

migrated from Bugzilla #460853
status UNCONFIRMED severity normal in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-02-25 14:32:31 -0500, Pierre-Luc Lacroix wrote:

Sample code:

MQTTClient_publishMessage(client, "topic", &pubmsg, &token);
MQTTClient_waitForCompletion(client, token, 10000L);

The code will be limited to sending ~10 messages/second when using QoS>0 because of a 100ms sleep in the MQTTClient_yield() function.

I have a simple (naive) fix that pushes the theoretical maximum sending rate to 100k messages/second. I could implement a better fix but I figured this was a good first step.

Here's my implementation of the fix on my git fork:
https://github.com/pl89/paho.mqtt.c/commit/SHA: b16df7337c364e90b34edbd6d6ea9a67393bd74a
https://github.com/pl89/paho.mqtt.c/commit/SHA: ee29fb8584c17d50abad711ce4bceef1d0907d4a

On 2015-02-25 15:05:29 -0500, Pierre-Luc Lacroix wrote:

Created attachment 251109
Lower the sleep() length in MQTTClient_yield() method.

Attaching patches to bug.

This contribution complies with http://www.eclipse.org/legal/CoO.php

On 2015-02-25 15:07:18 -0500, Pierre-Luc Lacroix wrote:

Created attachment 251110
Fix compile warning, further improve fast path by using modified version of MQTTClient_yield().

This contribution complies with http://www.eclipse.org/legal/CoO.php

Null pointer access if the server URI does not contain a ':'

migrated from Bugzilla #484386
status UNCONFIRMED severity normal in component MQTT-C for 1.2
Reported in version 1.2 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-12-15 07:43:27 -0500, Juergen Kosel wrote:

Created attachment 258686
Patch to fix this issue

If the user accidentally provided a bad server URI without port and without ':'
the paho-mqtt library crashes due to null pointer access.
The fix is simple, please look at the attached patch.

Building paho-mqtt3a v1.0.2 with Visual Studio 2010 fails

migrated from Bugzilla #447089
status RESOLVED severity normal in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2014-10-14 09:18:33 -0400, Nicolas Schneider wrote:

paho-mqtt3a v1.0.2 does not build on Visual Studio 2010.

Steps to reproduce:

  1. Download and extract eclipse-paho-mqtt-c-src-1.0.2.tar.gz from http://build.eclipse.org/technology/paho/C/1.0.2/
  2. Open "Windows Build\Paho C MQTT APIs.sln" in Visual Studio 2010.
  3. Change "Platform Toolset" in paho-mqtt3a settings to v100.
  4. Rebuild paho-mqtt3a.

Error:
mqttasync.c(2716): error C2275: 'ListElement': illegal use of this type as an expression
linkedlist.h(58): see declaration of 'ListElement'
mqttasync.c(2716): error C2065: 'current': undeclared identifier
mqttasync.c(2717): error C2143: syntax error : missing ';' before 'type'
mqttasync.c(2729): error C2065: 'current': undeclared identifier
...

paho-mqtt3c builds fine.

On 2014-10-14 10:43:24 -0400, Ian Craggs wrote:

Fixed in the develop branch. Apparently the version of Visual Studio I used (2012) doesn't care about the positioning of declarations any more.

"Debug" configuration not compile under Visual Studio 2013

migrated from Bugzilla #443722
status RESOLVED severity normal in component MQTT-C for 1.1
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2014-09-10 11:28:03 -0400, Paolo Patierno wrote:

Hi,
the two projects "test1" and "test4" for Visual Studio 2013 compile fine in "Release" configuration but not in "Debug".
They need some changes to project files to include some directories for headers and some preprocessor definitios.
How can I propose a pull request to the git repository ?

Thanks,
Paolo Patierno

On 2014-09-16 11:18:00 -0400, Paolo Patierno wrote:

Created attachment 247126
test1 project file

On 2014-09-16 11:18:23 -0400, Paolo Patierno wrote:

Created attachment 247127
test4 project file

On 2014-09-16 11:18:40 -0400, Paolo Patierno wrote:

I attached the modified project files.

Paolo.

On 2015-11-04 17:17:11 -0500, Ian Craggs wrote:

Thanks Paolo. After a long time, this is now fixed in the develop branch.

Unreachable broker connection blocks 2nd working connection

migrated from Bugzilla #483296
status CLOSED severity normal in component MQTT-C for 1.2
Reported in version 1.2 on platform PC
Assigned to: Ian Craggs

On 2015-11-30 06:10:40 -0500, Juergen Kosel wrote:

Imagine the following situation:
A MQTT client should connect to more than 1 broker and publish some topics.
But unfortunately one of the brokers is (temporary) unreachable.

Since there is only one MQTTAsync_sendThread for all connections to MQTT brokers,
any publish transaction to a reachable broker is blocked, while the MQTTAsync_sendThread tries to connect to the unreachable one.

And to make things even more worse, the client may
try to connect again, by calling MQTTAsync_connect().
Internally the new connect request is placed into the first position of the command list. So any write request to a well reachable broker would be blocked
again.

On 2015-12-08 02:43:22 -0500, Juergen Kosel wrote:

While view at the code, I had seen that there is only one thread doing all the work.
But I have overseen, that the sockets are opened in none blocking mode.
So attempts to open a connection to a not reachable broker decrease performance, but do not block other connections at all.

Sorry for reporting this false bug.
Juergen

On 2015-12-08 09:04:24 -0500, Ian Craggs wrote:

Hi Jurgen,

thanks for the update. I had been thinking about this, and the only potentially blocking call is getaddrinfo(), to resolve hostnames. This could be improved by having DNS lookups in a separate thread or by using a non-blocking DNS lookup library.

Most of the time, DNS lookups are quick, so you wouldn't see an adverse effect, and I've not had it reported as a problem. But it is a possible improvement that could be made.

Paho last will & testament doesn't support binary payloads

migrated from Bugzilla #461411
status ASSIGNED severity normal in component MQTT-C for 1.1
Reported in version 1.1 on platform Other
Assigned to: Ian Craggs

On 2015-03-04 11:02:43 -0500, Michael Smosna wrote:

When publishing a message using MQTTAsync_sendMessage(), the third parameter of type MQTTAsync_message contains fields for specifying the payload (as void *) and payloadlen (as int) which allows a binary payload to be sent.

When creating a session, there is the option of specifying a last will and testament. When populating the MQTTAsync_willOptions struct, only a 'const char *message' parameter is available for specifying the payload. Since there is no message length parameter, I assumed that 'message' could only be a text string. I tested this by first setting message to the string 'LOST_CONNECTION'. I non-gracefully disconnected from the central broker (in this case I'm using mosquitto) and shortly after received 15 bytes as the LW&T message. I then set 'message' to {0x30,0x31,0x32,0x33,0x34,0x0,0x35,0x36,0x0} and repeated the same test. The LW&T message came through with 5 bytes.

Our use case involves publishing binary payloads to topics and is also needed for the LW&T message. Is it possible to expand the MQTTAsync_willOptions structure to include a message length parameter and allow for binary payloads?

On 2015-04-20 11:51:57 -0400, Ian Craggs wrote:

Hi. Yes, it is possible. A new version of the willOptions structure will be needed. (I updated the component for this bug because this is not about the embedded client).

Deadlock in MQTTClient_disconnect1 after calling MQTTClient_waitForCompletion

migrated from Bugzilla #459791
status RESOLVED severity blocker in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-02-12 10:16:28 -0500, Sathya Laufer wrote:

You can reproduce the error with the current version on GitHub (commit SHA: 5f1bfae) like this:

  • Connect to a MQTT broker
  • Wait a minute
  • Call MQTTClient_publishMessage
  • Call MQTTClient_waitForCompletion
  • => Deadlock

Here's the function call path causing the deadlock:

MQTTClient_waitForCompletion => MQTTClient_yield => MQTTClient_cycle (locks mqttclient_mutex) => MQTTClient_retry => MQTTProtocol_keepalive => MQTTProtocol_closeSession => MQTTClient_disconnect_internal => MQTTClient_disconnect1 => tries to lock the Mutex again => Deadlock

I quickly fixed the issue by moving "Thread_unlock_mutex" before "MQTTClient_retry" in "MQTTClient_cycle". I don't know, if that might be dangerous though.

Cheers,

Sathya

On 2015-02-20 10:54:18 -0500, Ian Craggs wrote:

So, do you get this very often? It should only happen if the client has been disconnected by the server, which you would try to avoid most of the time.

I've added a proposed fix to the develop branch. It's a bit different to yours.

On 2015-02-20 11:37:53 -0500, Sathya Laufer wrote:

Hey Ian,

thanks for fixing this :-). Actually I got the error with every start of my test program. The default Mosquitto installation in Ubuntu 14.04 seems to disconnect the client after a minute or so... I need to check that. Of course the connection should be kept open.

Cheers,

Sathya

Inaccurate keepalive timeout processing

migrated from Bugzilla #485807
status ASSIGNED severity normal in component MQTT-C for 1.2
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2016-01-13 23:07:42 -0500, Peng Liu wrote:

In current implementation, the interval that client sends PINGREQ to broker is not the same as the "keepalive interval" specified for the connection. For example, if we specify the interval to be 5 seconds, the real interval could be 7 seconds. This behavior can lead to timeout error in some broker, e.g. mosquitto.

I guess the "keepalive interval" should be set to large value, what is the recommended value for it?
Thanks.

On 2016-01-14 06:38:42 -0500, Ian Craggs wrote:

The reason for setting the keepalive interval to a short period would be to limit the amount of time to discover that a socket has been disconnected (under certain circumstances). It is possible for a socket to continue accepting data for a time after an error has occurred. In this case, the ping request is sent to force a response from the server, to check that packets are actually reaching that server. If there is no response to the pingreq after a "reasonable" amount of time then the client can assume the socket connection is no longer working, and try a new one.

When keeping a connection alive, the MQTT server should also allow a grace period on ping requests before disconnecting the client. This is to allow for network or client processing overheads or timing variances. 50% is a common grace period -- you could check what Mosquitto uses. Of course, the shorter the keepalive interval the larger the percentage error could easily be, and could give rise to the sort of error you are seeing.

To balance the requirements, the most common keepalive interval we use is 60 seconds.

On 2016-01-14 14:47:55 -0500, Peng Liu wrote:

Hi Ian, thanks for your clear explanation.

Yes, you are right, 50% is a common grace period. The inaccuracy of 2 seconds is not big deal for 60s keepalive interval, but for short interval (e.g. 4 seconds) it is. Do you think we need to change the implementation to minimize the inaccuracy? I have this question because I am aware of another mqtt client implementation (mqtt.js) follow the keepalive interval parameter strictly.

MQTT C Client causes Segmentation fault

migrated from Bugzilla #447673
status CLOSED severity normal in component MQTT-C for 1.1
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2014-10-17 05:55:12 -0400, Franz Schnyder wrote:

My gateway run for more than a week an crashed with a Segmentation fault. My guess is that the Segmentation fault is due to a race condition caused by a missing lock(mutex) for s.cur_clientsds inside of Socket.c.

Followed I provide the information and reasoning for my guess:

Info of the segmentation fault:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb4509460 (LWP 17845)]
0x00080750 in Socket_getReadySocket (more_work=0, tp=0xb4508d88)
at source/lib/Mqtt.C/src/Socket.c:278

the code there looks like this:

274 if (s.cur_clientsds == NULL)
275 rc = 0;
276 else
277 {
278 rc = ((int)(s.cur_clientsds->content));
279 ListNextElement(s.clientsds, &s.cur_clientsds);
280 }

the backtrace of the crash is:

(gdb) bt

0 0x00080750 in Socket_getReadySocket (more_work=0, tp=0xb4508d88)

   at source/lib/Mqtt.C/src/Socket.c:278

1 0x00077518 in MQTTClient_cycle (sock=0xb4508dc4, timeout=1000, rc=0xb4508dc8)

   at source/lib/Mqtt.C/src/MQTTClient.c:1547

2 0x00074a90 in MQTTClient_run (n=0x12a9b4)

   at source/lib/Mqtt.C/src/MQTTClient.c:483

3 0xb6e40bfc in start_thread (arg=0xb4509460)

   at pthread_create.c:306

4 0xb6dd5968 in ?? ()

   at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:116

and a the variables are:

(gdb) p s
$1 = {rset = {__fds_bits = {2048, 0 <repeats 31 times>}}, rset_saved = {
__fds_bits = {1024, 0 <repeats 31 times>}}, maxfdp1 = 11,
clientsds = 0x12a774, cur_clientsds = 0x0, connect_pending = 0x12a804,
write_pending = 0x12a894, pending_wset = {__fds_bits = {
0 <repeats 32 times>}}}
(gdb) p s.cur_clientsds
$2 = (ListElement *) 0x0

The Segmentation fault is because s.cur_clientsds is NULL when line 278 is executed. Since line 278 is actually inside an else of a (s.cur_clientsds == NULL) check I guess that s.cur_clientsds must have be changed by an other thread in between the check (line 274) and the access (line 278). So I searched where s.cur_clientsds is changed and found that the Socket_close() function sets it to NULL:

void Socket_close(int socket)
{
FUNC_ENTRY;
Socket_close_only(socket);
FD_CLR(socket, &(s.rset_saved));
if (FD_ISSET(socket, &(s.pending_wset)))
FD_CLR(socket, &(s.pending_wset));
if (s.cur_clientsds != NULL && (int)(s.cur_clientsds->content) == socket)
s.cur_clientsds = s.cur_clientsds->next;
...

Therefore s.cur_clientsds is accessed and changed by multiple threads: By the libraries 'worker thread' during the MQTTClient_run() and by a client thread when the client calls MQTTClient_disconnect() since this calls Socket_close(). So I checked the call trees for mutex locks: The Socket_close() is inside a Thread_lock_mutex(mqttclient_mutex) but the Socket_getReadySocket() is not inside any mutex lock since MQTTClient_cycle() is explicitly called outside of the mqttclient_mutex:

Thread_unlock_mutex(mqttclient_mutex);
pack = MQTTClient_cycle(&sock, timeout, &rc); ==> Socket_getReadySocket()
Thread_lock_mutex(mqttclient_mutex);

On 2014-10-17 05:58:06 -0400, Franz Schnyder wrote:

We added the same bug at the same time.

*** This bug has been marked as a duplicate of bug 447672 ***

When a paho client connect a server.The socket is set to nonblocking,the system call connect will return immediately. And the connect function will return -1.

migrated from Bugzilla #458003
status RESOLVED severity normal in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-01-20 21:13:49 -0500, Yu Shifa wrote:

int Socket_addSocket(int newSd)
{
int rc = 0;

FUNC_ENTRY;
if (ListFindItem(s.clientsds, &newSd, intcompare) == NULL) /* make sure we don't add the same socket twice /
{
int
pnewSd = (int*)malloc(sizeof(newSd));
*pnewSd = newSd;
ListAppend(s.clientsds, pnewSd, sizeof(newSd));
FD_SET(newSd, &(s.rset_saved));
s.maxfdp1 = max(s.maxfdp1, newSd + 1);
rc = Socket_setnonblocking(newSd);
}
else
Log(TRACE_MIN, -1, "addSocket: socket %d already in the list", newSd);

FUNC_EXIT_RC(rc);
return rc;
}

This function is called before connect and the connect will be return immediately.But the return value is -1.

On 2015-01-21 04:20:59 -0500, Ian Craggs wrote:

Hello. The socket is intentionally set to nonblocking, because we use a single thread for multiple client objects. This has been working for several years, so I don't think it is the cause of your problem.

Can you take a trace of your connect call, and attach it here please?

To do this, set the environment variable

MQTT_C_CLIENT_TRACE=ON (which will print the trace to stdout)

or

MQTT_C_CLIENT_TRACE= (which will write the trace to the named file)

and then run your program again.

You should also check the MQTT server for any error messages, although it sounds as if the connection attempt is not getting that far.

On 2015-01-21 04:35:10 -0500, Yu Shifa wrote:

Hello .I capture packages for serveral times and I found the client allows close the socket.The Server prints(trace) the client is connected(only the tcp connection),and then the client is disconnected.I look up some books and they all show that the socket is nonblocking, then the connect(System call ) will be return immediately, and the return value possibility would be -1.And I have test for a lot of times.
When I set the socket nonblocking after the connection(system call ) is finished, the client works normally.

On 2015-01-21 04:36:19 -0500, Yu Shifa wrote:

(In reply to Ian Craggs from comment # 1)

Hello. The socket is intentionally set to nonblocking, because we use a
single thread for multiple client objects. This has been working for
several years, so I don't think it is the cause of your problem.

Can you take a trace of your connect call, and attach it here please?

To do this, set the environment variable

MQTT_C_CLIENT_TRACE=ON (which will print the trace to stdout)

or

MQTT_C_CLIENT_TRACE= (which will write the trace to the named file)

and then run your program again.

You should also check the MQTT server for any error messages, although it
sounds as if the connection attempt is not getting that far.

Hello .I capture packages for serveral times and I found the client allows close the socket.The Server prints(trace) the client is connected(only the tcp connection),and then the client is disconnected.I look up some books and they all show that the socket is nonblocking, then the connect(System call ) will be return immediately, and the return value possibility would be -1.And I have test for a lot of times.
When I set the socket nonblocking after the connection(system call ) is finished, the client works normally.

On 2015-01-21 04:38:43 -0500, Yu Shifa wrote:

(In reply to Ian Craggs from comment # 1)

Hello. The socket is intentionally set to nonblocking, because we use a
single thread for multiple client objects. This has been working for
several years, so I don't think it is the cause of your problem.

Can you take a trace of your connect call, and attach it here please?

To do this, set the environment variable

MQTT_C_CLIENT_TRACE=ON (which will print the trace to stdout)

or

MQTT_C_CLIENT_TRACE= (which will write the trace to the named file)

and then run your program again.

You should also check the MQTT server for any error messages, although it
sounds as if the connection attempt is not getting that far.

The attachment I will be sent you later.

On 2015-02-20 09:24:47 -0500, Ian Craggs wrote:

I've not received the trace, so I'm going to set this to resolved, for now. If you need a fix, please reopen, adding the trace. Thanks.

Update Makefile to build in Cygwin

migrated from Bugzilla #486095
status UNCONFIRMED severity enhancement in component MQTT-C for 1.2
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2016-01-19 06:28:14 -0500, Stavros Vagionitis wrote:

Created attachment 259254
Patch for updating the Makefile to build in Cygwin

Hi all,

Recently I needed to build the paho client library in Cygwin, but there was no support in the Makefile. So I made some changes in the Makefile and I was able to build it. I have attached a patch with the changes I made.

Changes

Next following the major changes in order to build the libraries in Cygwin:
- In Cygwin the libraries need executable permissions in order to work,
currently during installation the libraries have only read/write
permissions (-m 0644). Removing the option -m 0644 from the install
command, the libraries are installed with their default permissions.
- The filename format of the libraries in Cygwin is different from Linux and
also have different options to build shared libraries. More information can
be found in https://cygwin.com/cygwin-ug-net/dll.html
- The ldconfig utility does not exist in Cygwin, so the install and uninstall
targets needed to modified.

Testing

I was able to run the test and sample files. The testing has been performed on a Ubuntu 14.04 64 bit and a Windows 7 Enterprise 64 bit machine. The Windows machine had installed Cygwin 2.4.0 64 bit.

Please review my changes.

Regards,

Stavros

On 2016-01-19 13:00:48 -0500, Stavros Vagionitis wrote:

Created attachment 259264
Latest Patch for updating the Makefile to build in Cygwin

Ignore the previous patch, I had added accidentally the CFLAGS of the Darwin to Cygwin. With this patch I removed them.

"Socket error Network is unreachable in connect" on DNS64/NAT64 environment

migrated from Bugzilla #483646
status UNCONFIRMED severity normal in component MQTT-C for 1.2
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2015-12-04 05:02:45 -0500, Kazuma MISHIMAGI wrote:

Actually we are facing this issue on Mac OS X, iOS and Android.

We are testing mqtt connectivity on local IPv6 Wi-Fi network using Internet Sharing feature of Mac OS X.

Then the program cause "Socket error Network is unreachable in connect".

20151204 164838.603 (25825280) (3)> Socket_new:601
20151204 164838.603 New socket 29 for xxx.xxx.com, port 8883
20151204 164838.603 (25825280) (4)> Socket_addSocket:162
20151204 164838.603 Allocating 16 bytes in heap at file ...
20151204 164839.472 Allocating 32 bytes in heap at file ...
20151204 164839.472 (25825280) (5)> Socket_setnonblocking:72
20151204 164839.472 (25825280) (5)< Socket_setnonblocking:77 (0)
20151204 164839.472 (25825280) (4)< Socket_addSocket:175 (0)
20151204 164839.472 (25825280) (4)> Socket_error:94
20151204 164839.472 Socket error Network is unreachable in connect for socket 29
20151204 164839.472 (25825280) (4)< Socket_error:103 (51)
20151204 164839.472 (25825280) (3)< Socket_new:688 (51)

I found that one of the problem is
uninitialized property of struct sockaddr_in6.

sockaddr_in6 has more properties than sockaddr_in
and some properties (such as scope_id) seem to be uninitialized.
Then the network will be unreachable.

In addition, this client tries only one addrinfo to connect
and prefers ipv4 is the problem too.
If both ipv4 and ipv6 addresses are provided and v4-one is unreachable,
v6-one seems to be never used and the client would just fail to connect.

MQTT- C Client not cleaning Open SSL Properly, causing crashes

migrated from Bugzilla #480363
status ASSIGNED severity major in component MQTT-C for 1.2
Reported in version 1.2 on platform PC
Assigned to: Ian Craggs

On 2015-10-21 20:38:14 -0400, Angelo Ribeiro wrote:

I'm using: paho-mqtt3cs.

We've identified that on SSLSocket.c we are not cleaning CRYPTO_set_locking_callback.

So, if another client (Paho or other client that uses SSL), tries to use OpenSSL, it will crash.

Basically, when Paho calls SSLSocket_terminate() we should add the code to reset the locking_callback.

Suggested code:
void SSLSocket_terminate()
{
FUNC_ENTRY;
CRYPTO_set_locking_callback(NULL);
free(sslLocks);
sslLocks = NULL;
FUNC_EXIT;
}

Let me know if you have problem reproducing this error.

Thanks,

Angelo Ribeiro.

On 2015-10-26 17:50:54 -0400, Eclipse Genie wrote:

GitHub Pull Request 3 created by [aribeironovaes]
#3

On 2015-11-10 11:42:45 -0500, Ian Craggs wrote:

Thanks. I'll get this in asap.

segfault in MQTTProtocol_keepalive

migrated from Bugzilla #470858
status UNCONFIRMED severity normal in component MQTT-C for 1.2
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-06-24 03:49:16 -0400, Ruslan Filipenko wrote:

MQTTClient.c: while destroying the last mqtt client (MQTTClient_destroy) MQTTClient_terminate is called. MQTTClient_terminate calls ListFree(bstate->clients) which causes bstate->clients to become an invalid pointer. But a thread function MQTTClient_run may still be running calling MQTTProtocol_keepalive function.

The line

Clients* client = (Clients*)(current->content);

results in segfault as bstate->clients is no longer a valid pointer.

I've ended with the following fix:

--- a/src/LinkedList.c
+++ b/src/LinkedList.c
@@ -399,6 +399,12 @@ void ListFreeNoContent(List* aList)
/
ListElement
ListNextElement(List* aList, ListElement** pos)
{

  • if (!aList || !aList->count)
  • {
  •    *pos = 0;
    
  •    return 0;
    
  • }

return _pos = (_pos == NULL) ? aList->first : (*pos)->next;
}

diff --git a/src/MQTTClient.c b/src/MQTTClient.c
index 0511d58..7d7cd39 100644
--- a/src/MQTTClient.c
+++ b/src/MQTTClient.c
@@ -325,6 +325,7 @@ void MQTTClient_terminate(void)
if (initialized)
{
ListFree(bstate->clients);

  •           bstate = &ClientState;
    
    ListFree(handles);
    handles = NULL;
    Socket_outTerminate();

On 2015-08-11 11:08:32 -0400, Ian Craggs wrote:

The first call in MQTTClient_terminate() is to call MQTTClient_stop() whose job it is to stop the background thread. The intention is that the background thread is stopped before cleaning up the client list, so this situation would not occur.

Can you get a trace of the event (environment variable MQTT_C_CLIENT_TRACE=filename)?

On 2015-08-13 11:54:06 -0400, Ian Craggs wrote:

Or do you have a test program which reproduces the problem?

Some resources are not freed in SSLSocket_terminate function

migrated from Bugzilla #453883
status RESOLVED severity normal in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2014-12-02 08:37:37 -0500, Roman Bogus wrote:

Some resources are not freed in SSLSocket_terminate function:
CloseHandle is not called for handles stored in sslLocks before deleting the array.
Cleanup of OpenSSL library is not done (EVP_cleanup and ERR_free_strings functions).

On 2015-04-08 08:54:42 -0400, Sathya Laufer wrote:

Fixing this would be nice as it also causes the library to crash regularly with "Signal 6" when "SSLSocket_initialize" is called a second time on reconnect.

On 2015-04-08 09:00:59 -0400, Sathya Laufer wrote:

I quickly fixed it in my GitHub fork: https://github.com/Homegear/paho.mqtt.c/commit/SHA: cb324bf2154617dcfbd085e66097d5872608fb34

On 2015-04-08 11:35:04 -0400, Ian Craggs wrote:

Thanks Roman and Sathya. I've added the fix to the develop branch. Let me know if that works for you... or not.

On 2015-04-08 11:39:25 -0400, Sathya Laufer wrote:

Thanks Ian!!!

pub0sub1_nb.c does not receive published message

migrated from Bugzilla #476397
status UNCONFIRMED severity critical in component MQTT-C for 1.2
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2015-09-02 03:31:11 -0400, philippe smadja wrote:

pub0sub1.c and pub0sub1_nb.c do not work (receive message)
qos0pub.c published properly (I gor the message with java client.
Environement: windows 7.
NOTE. I updated transport.c for Windows: call to WSAStartup() to initialize socket library
Any idea.?
Thanks
Philippe

Don't use "typedef struct" or "typedef union"

migrated from Bugzilla #470624
status ASSIGNED severity minor in component MQTT-C for 1.2
Reported in version unspecified on platform All
Assigned to: Ian Craggs

On 2015-06-19 14:16:46 -0400, Jerry Hicks wrote:

There are good reasons to not ever combine the keywords 'typedef struct' and 'typedef union'.

Foremost is the unnecessary global name space pollution that such usage imposes when structs and unions already enjoy their own name-spaces.

Please consider separating the declarations of the structs into a separate header and place the typedefs into a separate and optional header if you must.

On 2015-08-10 09:56:38 -0400, Ian Craggs wrote:

This is not a discussion I was previously aware of. I see that pros and cons have been fairly well discussed here:

http://stackoverflow.com/questions/252780/why-should-we-typedef-a-struct-so-often-in-c

The arguments make sense. I don't mind changing the approach when I have the time (or accepting a contribution), as long as existing application programs do not need to change.

On 2015-08-11 10:35:42 -0400, Ian Craggs wrote:

Changing title to be more meaningful

Makefile for openwrt systems

migrated from Bugzilla #477704
status UNCONFIRMED severity blocker in component MQTT-C for 1.2
Reported in version unspecified on platform Other
Assigned to: Ian Craggs

On 2015-09-17 08:35:20 -0400, prem singhania wrote:

I am trying to use eclipse paho's C client library in an openwrt system(its a cloudgate to be precise). In order to use the library in that environment I need a makefile that installs the package on the go, but the current makefile(one that comes with the package) doesnot have the link from where the openwrt environment can download the package. So if you can please tell me what needs to be added to the makefile so that it works or even better if you could send me different makefile.

Thanks in advance.

MQTT client disconnection after sending payload bigger than 4 KB

migrated from Bugzilla #448297
status RESOLVED severity major in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2014-10-22 08:04:52 -0400, Baptiste Robert wrote:

My MQTT client is being disconnect if I sent a payload bigger than 4 KB, but the function return MQTTCLIENT_SUCCESS.

Piece of code :

int ret = MQTTClient_publishMessage(m_client, p_topic, &pubmsg, &token);

if (ret != MQTTCLIENT_SUCCESS) {
std::cout << "Error Code (Publish): " << ret << std::endl;
}

ret = MQTTClient_waitForCompletion(m_client, token, 10000);

if (ret != MQTTCLIENT_SUCCESS) {
std::cout << "Error Code (WaitForCompletion) : " << ret << std::endl;
}

On 2014-10-22 08:16:08 -0400, Ian Craggs wrote:

What MQTT broker are you using? Are there any error messages when you attempt this publish? Most brokers will have a maximum message size configuration parameter, and if you exceed it may disconnect the client.

You could also take a trace of the occurrence and attach it here. Set the environment variable:

MQTT_C_CLIENT_TRACE=filename

to get the trace to a file.

On 2014-10-22 08:23:55 -0400, Baptiste Robert wrote:

I'm using this broker : messaging.internetofthings.ibmcloud.com. I don't have any error and the MQTTClient_publishMessage return MQTTCLIENT_SUCCESS. I'll ask if the broker have any limitation.

(In reply to Ian Craggs from comment # 1)

What MQTT broker are you using? Are there any error messages when you
attempt this publish? Most brokers will have a maximum message size
configuration parameter, and if you exceed it may disconnect the client.

You could also take a trace of the occurrence and attach it here. Set the
environment variable:

MQTT_C_CLIENT_TRACE=filename

to get the trace to a file.

On 2014-10-22 08:34:40 -0400, Ian Craggs wrote:

I just checked and was told that the maximum message size for the IBM IoT cloud is 4k, which corresponds to what you are seeing.

The current version MQTT is limited in the amount of error information that can be sent back to the client -- disconnecting the client is the only option in many cases.

On 2014-10-22 08:39:50 -0400, Baptiste Robert wrote:

OK. thank you for your time and this useful information.

MQTTClient: insufficient synchronization for subscribe, unsubscribe, connect

migrated from Bugzilla #474905
status RESOLVED severity normal in component MQTT-C for 1.2
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-08-13 10:05:53 -0400, Ian Craggs wrote:

When calling subscribe, unsubscribe and connect on the MQTTClient API from multiple threads, there is only one semaphore for these calls to indicate completion. However, multiple invocations of each could be running as they release the mqttclient_mutex when MQTTClient_waitfor is called. So we need to make sure that only one instance of each call runs simultaneously, with mutexes for each.

On 2015-08-13 10:10:47 -0400, Ian Craggs wrote:

Fix added to develop branch.

ServerURI with IPv6 not supported for Windows

migrated from Bugzilla #484496
status UNCONFIRMED severity normal in component MQTT-C for 1.2
Reported in version 1.2 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-12-16 10:32:52 -0500, Juergen Kosel wrote:

If the server URI contains an IPv6 address, e.g.
"tcp://[2002:3e92:dead:beef:250:56ff:fe28:1234]:1883" (invalidated address in example)
then MQTTAsync_create fails with return value -2 on Windows machines.

If you use the same valid serverURI on a Linux machine, for example within test/test4.c, then the test passes.

On 2015-12-16 11:06:39 -0500, Juergen Kosel wrote:

Created attachment 258731
Partial fix for bug 484496

With this fix MQTTAsync_Create does not fail with -2 any more.
But there are other issues, which prevent MQTT and IPv6 from working on Windows.

On 2015-12-17 05:51:58 -0500, Juergen Kosel wrote:

Created attachment 258751
Patch to remove the leading '[' from IPv6 addresses

With this 2nd patch the socket could be created.
But connecting to a broker with IPv6 address still fails.

paho not reconnecting after many connection & disconnections

migrated from Bugzilla #435665
status RESOLVED severity normal in component MQTT-C for 0.9
Reported in version 1.0 on platform Other
Assigned to: Ian Craggs

On 2014-05-23 13:13:58 -0400, Enrique Rebollo wrote nothing.
On 2014-05-23 13:19:16 -0400, Enrique Rebollo wrote:

My process tries to reconnect every 60 sec interval.
It works fine in serveral disconnection/reconnection cycles but after a long period disconnected it doesn't reconnect anymore (MQTTClient_connect keep returning -1 although there is network connection to the broker).
top command output is OK (cpu & memory usage)
After restarting the client it works again.

On 2014-05-24 10:06:50 -0400, Ian Craggs wrote:

Hello Enrique,

are you using callbacks in the API (using setCallbacks)?

Are you using the same client object each time you connect, or creating a new one each time? If you are creating a new object each time, could you try reusing the same object to see if that makes a difference?

Is the client receiving or sending messages when it connects, or both? If receiving, do you use a callback or MQTTClient_receive()?

Is the long period disconnected because the client does not try to reconnect, or because the network connection has dropped?

Can you take a trace of the failing connect? (set the environment variable MQTT_C_CLIENT_TRACE=ON or MQTT_C_CLIENT_TRACE=filename)

On 2014-05-26 11:15:09 -0400, Enrique Rebollo wrote:

Hi Ian,

I'm using callbacks.

I also use a callback for message reception (in the test I described I do not send or receive anything).

I simulate network failure switching off my router. MQTT client realizes there is no connection after some seconds and It tries to reconnect.

My process keeps trying to reconnect every 60 seconds.

I reuse the same MQTTClient object and options. I just recall MQTTClient_connect() function. Before, I tried creating a new MQTTClient object from scratch but it results the same.

It works fine if I restore the network connection after some minutes (even 1 or 2 hours), but if I restore it after a long period (let's say 8 hours) it never reconnects again (MQTTClient_connect returns -1).

I have to restart the process to connect.

I'll get back to you with the trace (sorry, I'm on a trip until wednesday).

Thanks for your help.

Enrique.

On 2015-01-16 06:39:04 -0500, Ian Craggs wrote:

Enrique,

you were going to get back to me with a trace.

Is this still a problem for you, or can we close the bug?

Thanks

On 2015-02-20 11:01:51 -0500, Ian Craggs wrote:

As I've not had a trace or other info since May of last year, I'm going to set this to resolved, for now. Please reopen if you have more info. Thanks.

[feature] Automatic reconnect and Offline Buffering

migrated from Bugzilla #486951
status ASSIGNED severity normal in component MQTT-C for 1.2
Reported in version 1.2 on platform PC
Assigned to: Ian Craggs

On 2016-02-01 11:39:36 -0500, Ian Craggs wrote:

Similar to 486843 for Java

On 2016-02-01 11:40:04 -0500, Ian Craggs wrote:

This one is mine :-)

Check client use from multiple threads

migrated from Bugzilla #441950
status ASSIGNED severity normal in component MQTT-C for 1.1
Reported in version 1.1 on platform PC
Assigned to: Ian Craggs

On 2014-08-18 05:29:04 -0400, Ian Craggs wrote:

A new test should be created which checks the use of both C client libraries (multi-threaded mode for the sync library) from multiple client threads.

I expect the locking to work correctly. What I suspect may be a problem is the starting of the background thread(s). Only one instance of each should be started. This depends on the variables storing the thread state being shared.

Needs to be checked on all operating systems (Linux, Windows, Mac), as it may be OS dependent.

On 2015-02-09 06:19:15 -0500, Ian Craggs wrote:

Adding helpwanted flag

On 2015-08-13 11:50:41 -0400, Ian Craggs wrote:

I've created test2 which test multiple thread access to the same client object for MQTTClient.

Remaining tests:

  • multiple thread access to multiple client objects for MQTTClient
  • the same two tests for MQTTAsync

Enhancement:Topic based Authentication in MQTT CClient

migrated from Bugzilla #447835
status RESOLVED severity normal in component MQTT-C for 1.1
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2014-10-20 00:03:48 -0400, Harikrishnan P wrote:

Since most of the MQTT-brokers(like Apollo) now support Topic based Authentication, is it possible to implement the same in Paho MQTT CClient.
Moreover, i am willing to work on the same.

On 2014-10-20 17:12:49 -0400, Ian Craggs wrote:

Hi. Basically, no :-) Because it's not part of the MQTT protocol. The only authentication tokens in MQTT are sent on connect. To get this changed, you'll have to lobby the MQTT standardization effort.

Unless you have a different idea?

On 2014-10-21 00:10:28 -0400, Harikrishnan P wrote:

Hai Ian,
Is is possible to provide authentication to each of the publishing messages after the MQTT Connection is established.I know that its possible to sent authentication tokens while MQTT Connection establishment, but want to know if this can be extended.

Thanks.

Cppcheck static code analyzer complains on Paho MQTT-C...

migrated from Bugzilla #462753
status UNCONFIRMED severity normal in component MQTT-C for 1.1
Reported in version 1.0 on platform All
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-03-21 06:26:04 -0400, Lionel Debroux wrote:

Created attachment 251803
Patches fixing several cppcheck complaints and performing several other janitorial changes

Recently, I ran cppcheck on the code base of another project which embeds Paho MQTT-C (an outdated copy thereof, but that's another story), and it found several low-impact things to rightfully complain about. Analyzing HEAD upstream version finds the same issues.

So here are a couple patches:

  • the first one fixes the complaints of highest severity, and makes several nearby changes while at it (one of them related to bug # 444229: checking the return value of malloc);
  • the second one uses angle brackets for including system headers, as is usually recommended, and for consistency with most other files in the MQTT-C code base. Noticed when using cppcheck --check-config.

Note that cppcheck also produces dozens of lower-level notes, such as dead assignments, variables whose scopes can be reduced, etc.

That's clearly a tiny contribution, but integrating (some of) these changes will avoid someone else having to reinvent them later :)

Return Code to string

migrated from Bugzilla #460856
status ASSIGNED severity enhancement in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-02-25 15:23:39 -0500, Pierre-Luc Lacroix wrote:

It would be nice if there would be a helper function that would convert a return code to a human readable string.

For example, here's a partial implementation:

const char *
MQTTClient_returnCodeToString (int returnCode)
{
static const char _mqttClient_returnCodeSuccess [] = "MQTTCLIENT_SUCCESS";
static const char _mqttClient_returnCodeFailure [] = "MQTTCLIENT_FAILURE";
static const char _mqttClient_returnCodeUnknown [] = "MQTTCLIENT_UNKNOWN";

switch (returnCode) {
case MQTTCLIENT_SUCCESS:
    return _mqttClient_returnCodeSuccess;
case MQTTCLIENT_FAILURE:
    return _mqttClient_returnCodeFailure;
default:
    return _mqttClient_returnCodeUnknown;
}

}

This code sample complies with http://www.eclipse.org/legal/CoO.php

On 2015-04-24 03:29:41 -0400, Ian Craggs wrote:

Yes, it would be nice. Thanks.

Segmentation Fault in Socket_getReadySocket

migrated from Bugzilla #447672
status RESOLVED severity normal in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2014-10-17 05:51:15 -0400, Ian Craggs wrote:

I'm still working on implement a MQTT-SN gateway using the Paho 'MQTT
C Client for Posix and Windows'. And now had another problem. This
time I think it is a concurrency bug of the MQTT.C library:

My gateway run for more than a week an crashed with a Segmentation
fault. My guess is that the Segmentation fault is due to a race
condition caused by a missing lock(mutex) for s.cur_clientsds inside
of Socket.c.

Followed I provide the information and reasoning for my guess:

Info of the segmentation fault:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb4509460 (LWP 17845)]
0x00080750 in Socket_getReadySocket (more_work=0, tp=0xb4508d88)
at source/lib/Mqtt.C/src/Socket.c:278

the code there looks like this:

274 if (s.cur_clientsds == NULL)
275 rc = 0;
276 else
277 {
278 rc = ((int)(s.cur_clientsds->content));
279 ListNextElement(s.clientsds, &s.cur_clientsds);
280 }

the backtrace of the crash is:

(gdb) bt

0 0x00080750 in Socket_getReadySocket (more_work=0, tp=0xb4508d88)

   at source/lib/Mqtt.C/src/Socket.c:278

1 0x00077518 in MQTTClient_cycle (sock=0xb4508dc4, timeout=1000,

rc=0xb4508dc8)
at source/lib/Mqtt.C/src/MQTTClient.c:1547

2 0x00074a90 in MQTTClient_run (n=0x12a9b4)

   at source/lib/Mqtt.C/src/MQTTClient.c:483

3 0xb6e40bfc in start_thread (arg=0xb4509460)

   at pthread_create.c:306

4 0xb6dd5968 in ?? ()

   at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:116

and a the variables are:

(gdb) p s
$1 = {rset = {__fds_bits = {2048, 0 <repeats 31 times>}}, rset_saved = {
__fds_bits = {1024, 0 <repeats 31 times>}}, maxfdp1 = 11,
clientsds = 0x12a774, cur_clientsds = 0x0, connect_pending = 0x12a804,
write_pending = 0x12a894, pending_wset = {__fds_bits = {
0 <repeats 32 times>}}}
(gdb) p s.cur_clientsds
$2 = (ListElement *) 0x0

The Segmentation fault is because s.cur_clientsds is NULL when line
278 is executed. Since line 278 is actually inside an else of a
(s.cur_clientsds == NULL) check I guess that s.cur_clientsds must
have be changed by an other thread in between the check (line 274) and
the access (line 278). So I searched where s.cur_clientsds is changed
and found that the Socket_close() function sets it to NULL:

void Socket_close(int socket)
{
FUNC_ENTRY;
Socket_close_only(socket);
FD_CLR(socket, &(s.rset_saved));
if (FD_ISSET(socket, &(s.pending_wset)))
FD_CLR(socket, &(s.pending_wset));
if (s.cur_clientsds != NULL && (int)(s.cur_clientsds->content)
== socket)
s.cur_clientsds = s.cur_clientsds->next;
...

Therefore s.cur_clientsds is accessed and changed by multiple threads:
By the libraries 'worker thread' during the MQTTClient_run() and by a
client thread when the client calls MQTTClient_disconnect() since this
calls Socket_close(). So I checked the call trees for mutex locks: The
Socket_close() is inside a Thread_lock_mutex(mqttclient_mutex) but the
Socket_getReadySocket() is not inside any mutex lock since
MQTTClient_cycle() is explicitly called outside of the
mqttclient_mutex:

Thread_unlock_mutex(mqttclient_mutex);
pack = MQTTClient_cycle(&sock, timeout, &rc); ==> Socket_getReadySocket()
Thread_lock_mutex(mqttclient_mutex);

Therefore I think my guess is correct that a race condition, because
of missing synchronization for s.cur_clientsds, caused the
Segmentation fault.

My quick solution would be to introduce a new socket_mutex inside
Socket.c to protect accesses to :
/**

  • Structure to hold all socket data for the module
    */
    Sockets s;

but I would need to invest some more time to fully grasp the locking
strategy of the library. Therefore should I try to invest some time to
understand the internals and introduce this mutex to create a patch?
Or is it not worth my effort because one of the commiters quickly can
confirm and fix this problem.

On 2014-10-17 05:52:34 -0400, Ian Craggs wrote:

I'm implementing a fix, like you suggested. Thanks for the analysis!

On 2014-10-17 05:58:06 -0400, Franz Schnyder wrote:

*** Bug 447673 has been marked as a duplicate of this bug. ***

On 2014-10-17 06:30:59 -0400, Ian Craggs wrote:

Franz, thanks. I was just about to mark this as a duplicate of yours.

I've just pushed a proposed fix to the development branch.

On 2015-04-24 04:53:23 -0400, Ian Craggs wrote:

*** Bug 458099 has been marked as a duplicate of this bug. ***

On 2015-12-11 09:38:47 -0500, Juergen Kosel wrote:

Created attachment 258620
Simple test program for parallel connections

The test program open 2 connections to an existing broker
and 6 connection which will allays fail, because there is no responding broker.

On 2015-12-11 09:42:14 -0500, Juergen Kosel wrote:

Hello,

please reopen this bug for version 1.3, for plattform Windows, build with Visual Studio 2010.

My application crashes in Socket_getReadySocket() and Socket_close()
because the pointer s.cur_clientsds becomes 0xdddddddd. Which is obviously an
invalid pointer.
It usually happens while some other part (none mqtt part) of my application does
some other socket operation (listen, accept connection, release connection, ...).

I have tried to write some simple test program, which does something similar
to my application. But so far I have not reproduced the crash with the attached
test application. (But maybe you could use it to improve the test collection.)

Greetings
Juergen

On 2015-12-11 09:56:54 -0500, Ian Craggs wrote:

Hi. Can you get a client trace of the situation by setting environment variable

MQTT_C_CLIENT_TRACE=ON (or a filename)?

I presume the "some other socket operation", is on another socket, not one used by the MQTT client library?

On 2015-12-11 10:35:02 -0500, Juergen Kosel wrote:

Created attachment 258621
trace file shortly before the segmentation fault

Appended to the trace you find some more information from the
debugger.

Greetings
Juergen

On 2015-12-11 12:06:27 -0500, Ian Craggs wrote:

So the trace shows a socket being closed because of some sort of socket error or timeout. I assume this is expected?

I don't see why an operation on another socket should have any bearing on this situation unless it causes this socket error/close sequence somehow. Do you have any idea?

On 2015-12-14 03:41:32 -0500, Juergen Kosel wrote:

(In reply to Ian Craggs from comment # 9)

So the trace shows a socket being closed because of some sort of socket
error or timeout. I assume this is expected?

yes,
as in the test_AsyncParrallel.c there are several connect attempts to
unreachable brokers.

I don't see why an operation on another socket should have any bearing on
this situation unless it causes this socket error/close sequence somehow.
Do you have any idea?

The same for me. It seems that the additional task changes / wake ups
make it easier to trigger this bug.

From the pointer list in paho-trace.log after the crash, it looks like a
use after free problem. But I have also seen crashes occurred in
Socket_close():

if (s.cur_clientsds != NULL && (int)(s.cur_clientsds->content) == socket)

When it occured at this location, s.cur_clientsds was also an invalid
pointer (0xddddddd).

Greetings
Juergen

On 2015-12-14 05:55:00 -0500, Juergen Kosel wrote:

Created attachment 258646
Another trace of a segmentation fault - with traces of mutex lock/unlock.

Another trace of a segmentation fault.
This time with additional trace output in the async mutex lock and unlock functions.

On 2015-12-14 05:58:19 -0500, Juergen Kosel wrote:

Created attachment 258647
Patch to trace MQTTAsync_lock_mutex

Patch which were used to generate the trace file of attachment 258646.

On 2015-12-14 07:50:36 -0500, Juergen Kosel wrote:

Created attachment 258650
Fix for the outstanding part of bug 447672

With this patch applied, the segmentation fault does not occur anymore
in my test-setup.

On 2015-12-14 18:28:18 -0500, Ian Craggs wrote:

Thanks Juergen. The same fix is apparently needed in MQTTAsync.c as was applied to MQTTClient.c for this bug. I want to track the fixes separately so I've raised a new bug, 484363. Your fix will work, but will also hold a lock longer than necessary.

Thanks for the traces and diagnostics.

Create Linux packages for Debian and Red Hat

migrated from Bugzilla #405837
status NEW severity normal in component MQTT-C for ---
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2013-04-16 18:59:38 -0400, Andy Piper wrote:

Tracking bug to note that we should make .deb and .rpm packages for our Linux builds.

On 2013-04-16 19:09:18 -0400, Andy Piper wrote:

Depends on versioning tickets.

On 2015-02-09 06:19:46 -0500, Ian Craggs wrote:

Adding helpwanted flag

Possible segmentation fault in application callback function caused by not properly initialized argument

migrated from Bugzilla #486548
status UNCONFIRMED severity normal in component MQTT-C for 1.2
Reported in version 1.2 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2016-01-26 07:15:05 -0500, Juergen Kosel wrote:

The functions MQTTAsync_removeResponsesAndCommands() and
MQTTAsync_removeResponsesAndCommands() do not initialize the pointer data.message.
So if a on command failure callback tries to use this given pointer,
it has no chance to see that there is no valid message. And then it triggers a
segmentation fault exception.

On 2016-01-26 07:16:37 -0500, Juergen Kosel wrote:

Created attachment 259382
Git commit which fixes this problem

Initialize the message to null pointer

To prevent segmentation fault in application, the message pointer needs
to be initialized.

Application getting segfault and signal 134 when i send mqtt messages to cloud 5 times per second continously.

migrated from Bugzilla #475697
status UNCONFIRMED severity major in component MQTT-C for 1.2
Reported in version unspecified on platform Other
Assigned to: Ian Craggs

On 2015-08-24 06:11:17 -0400, Siva Subrahmanyam Nallamalli wrote:

We have some mqtt related issues we need to take care of. After some number of mqtt messages are sent to the cloud, the app gets a segment violation (signal 139). The app restarts, but this is still an issue.

If you run gdb ./ble_app_xxaa_s120_xxaa.out and run bt, you should be able to see the back trace. It segfaults at SSLSocket_continueWrite().

On 2015-08-24 06:16:51 -0400, Siva Subrahmanyam Nallamalli wrote:

Also sometimes we get signal 134 - this may be stack corruption.

This is happening when mqtt traffic to the cloud was heavy.

On 2015-08-24 06:52:41 -0400, Ian Craggs wrote:

Do you have a core file? Even if you do, on its own, this is unlikely to help much. I will need more details of your application -- a test program which reproduces the problem, or a trace of the problem. To get a trace, set the environment variables:

MQTT_C_CLIENT_TRACE to ON (which will write to stdout), or a filename
MQTT_C_CLIENT_TRACE_MAX_LINES to the maximum number of lines to add to the trace file, to make sure the event is captured.

Thanks.

On 2015-08-24 07:28:10 -0400, Siva Subrahmanyam Nallamalli wrote:

yes i had core file. I will come up a complete trace as we are linking this with our propietary application

On 2015-08-25 07:56:04 -0400, Siva Subrahmanyam Nallamalli wrote:

This is the backtrace with gdb using core file.

clf@arm:~$ gdb ./ble__app_xxaa.out_crash jcore_0.keep
GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
http://www.gnu.org/software/gdb/documentation/.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./ble_cloudleaf_app_xxaa_s120_xxaa.out_crash...done.

warning: core file may not match specified executable file.
[New LWP 1233]
[New LWP 1235]
[New LWP 1230]
[New LWP 1232]
[New LWP 1237]
[New LWP 1236]
[New LWP 1238]
[New LWP 1239]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
Core was generated by `/home/clf/ble_cloudleaf_app_xxaa_s120_xxaa.out'.
Program terminated with signal SIGSEGV, Segmentation fault.

0 0x00000180 in ?? ()

(gdb) bt

0 0x00000180 in ?? ()

1 0xb6ed1f84 in SSLSocket_continueWrite (pw=0xb5c2753c) at src/SSLSocket.c:807

2 0xb6ed0e28 in Socket_continueWrite (socket=socket@entry=4) at src/Socket.c:720

3 0xb6ed0f7c in Socket_continueWrites (pwset=pwset@entry=0xb5bfec60) at src/Socket.c:781

4 0xb6ed1124 in Socket_getReadySocket (more_work=more_work@entry=0, tp=tp@entry=0xb5bfed24) at src/Socket.c:246

5 0xb6ecb42a in MQTTAsync_cycle (sock=sock@entry=0xb5bfedc0, timeout=timeout@entry=1000, rc=rc@entry=0xb5bfedbc) at src/MQTTAsync.c:2584

6 0xb6ecb79a in MQTTAsync_receiveThread (n=) at src/MQTTAsync.c:1477

7 0xb6f71fbc in start_thread (arg=0xb5bff430) at pthread_create.c:314

8 0xb6d5eb3c in ?? () at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:92 from /lib/arm-linux-gnueabihf/libc.so.6

Backtrace stopped: previous frame identical to this frame (corrupt stack?)

On 2015-08-25 09:09:52 -0400, Ian Craggs wrote:

So I determine from the stack trace that you are using the asynchronous client with an SSL connection. I'm going to need some more information to go on. Are you able to get an MQTT client trace, as outlined above?

Does this situation occur after a predictable number of messages, or variable? Are there any error messages or more information on the server when this happens?

What QoS are you using? What does your MQTT application look like - like any of the SSL Async tests in test/test5.c? If you were to write a test to reproduce the problem, what would it look like?

And, what version of the client library are you using?

Thanks

On 2015-09-07 07:58:19 -0400, Siva Subrahmanyam Nallamalli wrote:

So I determine from the stack trace that you are using the asynchronous client with an SSL connection. I'm going to need some more information to go on. Are you able to get an MQTT client trace, as outlined above?

It is very intermittent issue. I didnt got the clients trace still it was not reproduced with MQTT client trace enable.

Does this situation occur after a predictable number of messages, or variable? Are there any error messages or more information on the server when this happens?
This Happens when No of MQTT client publish messages/sec(traffic) to cloud increases drastically.There are no error messages.

What QoS are you using? What does your MQTT application look like - like any of the SSL Async tests in test/test5.c? If you were to write a test to reproduce the problem, what would it look like?
QoS set 1.
We are also trying to reproduce with standalone application, that generates mqtt messages to the cloud. i.e in while(1) send mqtt publish messages.
we had written a separate thread to enque mqtt messages & dequeue it and process. Finally calling MQTTAsync_sendMessage function.

And, what version of the client library are you using?
latest version i.e 1.0.3.

Create pahopub and pahosub from stdinpub and stdoutsub

migrated from Bugzilla #442034
status NEW severity normal in component MQTT-C for 1.1
Reported in version v0.5 on platform PC
Assigned to: Ian Craggs

On 2014-08-19 06:10:11 -0400, Ian Craggs wrote:

The sample programs stdinpub and stdoutsub are actually very useful.

They should be renamed to pahopub and pahosub and SSL enabled. Then they should be part of the Makefile as utility programs which get installed along with the libraries.

On 2014-08-28 10:59:33 -0400, Ian Craggs wrote:

Assigning to Rong.

On 2015-01-16 06:45:38 -0500, Ian Craggs wrote:

Taking back.

On 2015-02-09 06:15:09 -0500, Ian Craggs wrote:

Adding helpwanted flag

On 2015-02-09 06:16:06 -0500, Ian Craggs wrote:

Also resetting to NEW

On 2015-02-15 09:07:15 -0500, Bernard Opic wrote:

Do you simply target [SAMPLE_FILES_C = stdinpub stdoutsub pubsync pubasync subasync], or also [SAMPLE_FILES_A = stdoutsuba MQTTAsync_subscribe MQTTAsync_publish]?

On 2015-03-02 08:53:48 -0500, Ian Craggs wrote:

It would be nice to have both sets, synchronous and asynchronous. :-)

Allow the network interface to be specified for connect

migrated from Bugzilla #460695
status NEW severity enhancement in component MQTT-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-02-24 09:14:11 -0500, Ian Craggs wrote:

The serverURI on the MQTTClient_create call allows the specification of the destination TCP hostname or address, and destination port.

This request is to allow the network interface to be specified as well, for the case where there is more than one on the local machine.

On 2015-02-24 09:39:32 -0500, Ian Craggs wrote:

Requested by Sven Henze ([email protected]).

A quick read of "Unix Network Programming" seems to indicate we need to use bind() for this. But you can't bind directly to an interface, so we would have to query the address for an interface and bind to that, I assume.

The easiest way to allow this to be specified would be to add it to the serverURI. Something like tcp://<network_interface>hostname:port. I don't know if there is a standard notation for this already.

Out of memory handling in MQTTAsync client

migrated from Bugzilla #444229
status ASSIGNED severity normal in component MQTT-C for 1.2
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2014-09-16 06:20:32 -0400, Ian Craggs wrote:

  1. NULL checks
    There are no NULL checks on malloc. The current implementation will end up with segmentation faults on low memory situations.
    I assume this is not uncommon on small devices.
  1. NULL checks for malloc are handled in Heap.c. The malloc call is
    overridden. This will result in error messages in the trace.

Looking into Heap.c reveals that this code is aware of OOM situations and reacts appropriately.
So Heap.c may return NULL to the MQTTAsync.c where no check happens.

However,
the question is what should the action be in the case of malloc
failure? I guess the best solution is that the API call returns with
failure - memory error.

Agreed on API level.
For code running in background threads it will be more complicated since it has potentially to report the OOM situation to the API consumer.
And if this paths also require memory then they need to be changed.

However that would add considerable complexity
and code for handling the error and cleaning up partially allocated
memory structures.
Yes. OOM handling is IMO part of the essential complexity of any C/C++ component.

On 2014-09-16 06:30:00 -0400, Ian Craggs wrote:

Out of memory handling is "essential". It's also a balance of risk vs implementation complexity - that is, what is it worth?

I think that I became less motivated to handle these situations after seeing how in general Java applications cope with the same situation - usually badly.

However, I think there are some relatively high risk situtations here which we should cope with. While there are small data structures allocated, the biggest risk comes from topic strings and MQTT payloads, which have a maximum size of 64k and 256MB respectively. So I would suggest we cater for those situations first, and assess whether the rest are needed.

There is an MQTT problem with the receipt of messages larger than we can handle - if the message is QoS 1 or 2 and we close the connection because we cannot receive the message, then the server will send it again. We could receive the entire message piecemeal and then pass it incomplete to the application, but that would violate the spirit of QoS 1 or 2. There is no clean solution to this, save changing the protocol

(For all the small allocations which could fail, I would rather implement one global strategy rather than every individual check. Using setjmp/longjmp comes to mind. But these are relatively low risk, except perhaps if we have a lot of buffered messages. The amount of buffering can be controlled by the application however.)

On 2014-09-17 08:35:33 -0400, Juergen Denner wrote:

I think the goals could be:

  1. Stability
    a) Never segfault in any case and inform the consumer.
    b) Reach a deterministic state and try to recover.
    If recover is not possible the shutdown safely and refuse new API calls
    with a clear error message.
  2. Handle OOM 'appropriately' according to the MQTT protocol for oversized
    messages.

I see the following approaches on handling oversized payloads (oversized is determined by the execution context).

  1. Reject or skip the message - this seems not to be supported by the MQTT spec.
    Is this a gap?
  2. What you name 'piecemeal' can be named streaming.
    Streaming is a pretty common strategy in handling arbitrary data size.
    So the message could be either
    a) Send partially to the receiver including a marker for the last segment.
    (data push). No trivial to get it right including error handling.
  • or -
    b) First received to the persistence and then it could be consumed by the
    client, without the risk on blocking due to network (data pull).
    However, I don't see the relevance for this approach on small devices.
  1. Consume and 'drop' the data, inform the client that an oversized message was
    dropped. This would at least unblock the client.

(Java related comments)
Java never segfaults on OOM (at least due to Java heap ; an empty C heap do crash some JVM types). Java has a clear OOM strategy where you normally never react directly on OOM. If you take care for (runtime) exception and do a proper resource cleanup then you are normally safe. Some containers recover from such situations � most don�t.

On 2014-09-17 11:11:19 -0400, Ian Craggs wrote:

Java might have a clear out of memory strategy, but whenever I've tried to recover from those situations in real tests, it never worked. This was some time ago, so things might have changed. Anyway that's a digression.

I think a goal should also be that the fixes ought to be testable and cater for likely to happen scenarios. Note that the Linux man page for malloc says:

   By  default,  Linux  follows an optimistic memory allocation strategy.  This means that when
   malloc() returns non-NULL there is no guarantee that the memory really is  available.   This
   is  a  really  bad  bug.  In case it turns out that the system is out of memory, one or more
   processes will be killed by the infamous OOM killer.  In case Linux is employed  under  circumstances
   where it would be less desirable to suddenly lose some randomly picked processes,
   and moreover the kernel version is sufficiently recent, one can switch off this  overcommitting
   behavior using a command like:

       # echo 2 > /proc/sys/vm/overcommit_memory

   See   also   the   kernel   Documentation   directory,  files  vm/overcommit-accounting  and
   sysctl/vm.txt.

So, we can't guarantee freedom from segfaults.

Goals:

a) impossible in the face of OS bugs. For allocation failures internal to this API, ideally yes.
b) I think trying to recover is too much work for out of memory conditions for this API. Unless by recovering you mean removing all the library state and requiring the application to start again.

  1. "Oversized" MQTT messages. Two cases: incoming and outgoing.

Outgoing: just return failure to the application. Most likely to happen on topic or payload allocation. There could be a max message size config parameter.

Incoming:

  1. rejecting the message is not supported by MQTT. This is a well known requirement for improvement.
    Skipping the message is not allowed for QoS 1 or 2. It is allowed for QoS 0.

  2. I think streaming or fragmentation is over complicated for the goals of this API.

  3. not strictly allowed by the MQTT specification.

The only strictly allowed action for a message to big to be received when the QoS > 0, is to close the session. But also in the case of QoS > 0, this will result in the message being sent again, unless we have connected or will connect with clean session = true.

Given the likelihood of occurrence vs cost of implementation I suggest this approach:

  1. deal with incoming over-sized topics/payloads by closing the connection when memory allocation failures are detected, with an appropriate reason code to connectionLost.

  2. deal with outgoing "over-sized" topics/payloads by returning memory allocation error to the application.

  3. For any other situations, allocating small data structures in the depths of a function, I think cleaning up the API state entirely and requiring the application to start again is the best option. All memory can be freed using the heap tracking routines. But I rate this as a relatively low priority because of the low likelihood of occurrence, and low likelihood of recovery.

On 2014-09-24 02:51:37 -0400, Juergen Denner wrote:

Yes, malloc on Linux has a really wired behavior. However - malloc for windows returns NULL in OOM situations. At least for this platform segfaults can be avoided.

Comments for goals:
1b)
A valid way for me is to free the paho client and create a new one. However it must be detectable by the error code.
2) Many thanks for detailing this out
On way of reducing the used memory for outgoing messages could be that the implementation does not create a copy of the topic & payload (maybe by an additional publish/send API)
If the consumer creates the message structure using the malloc functions from the Paho client then the contract would be to hand over the memory ownership to the PahoClient which releases the memory (payload, topic name) after processing.

Comments on your suggested approach:
1 & 2 Yes
3) > requiring the application to start again �
Do you mean destroying and recreating the PahoClient or do you mean the whole process that is using the Paho client?

On 2015-01-19 11:52:38 -0500, Ian Craggs wrote:

Moving to later milestone

Apple OSX 'roundup' macro interferes with MQTT-C code

migrated from Bugzilla #446324
status RESOLVED severity blocker in component MQTT-C for 1.1
Reported in version 1.0 on platform Macintosh
Assigned to: Ian Craggs

On 2014-10-08 10:24:24 -0400, Guy Dillen wrote:

Building the MQTT C client on OSX gives problems. The Apple OSX macro (defined in param.h) interferes with the 'roundup' function in Heap.c.

During pre-compilation (the function) 'roundup' in Heap.c tries to replace its entry with the contents of the macro 'roundup' in param.h.

This results in an error during compilation.

A workaround putting '#undef roundup' before the function 'roundup' in 'Heap.c' (although I don't know if this results in implications on other code of the package) results in a succesful build.

On 2014-10-09 18:03:40 -0400, Ian Craggs wrote:

I will change the name of the function.

On 2014-10-10 06:54:19 -0400, Ian Craggs wrote:

I've updated the develop branch by changing the name of the function to Heap_roundup.

Segmentation fault in Socket_getReadySocket for MQTTAsync

migrated from Bugzilla #484363
status RESOLVED severity normal in component MQTT-C for 1.2
Reported in version v0.5 on platform PC
Assigned to: Ian Craggs

On 2015-12-14 18:23:46 -0500, Ian Craggs wrote:

Hello,

please reopen this bug for version 1.3, for plattform Windows, build with Visual Studio 2010.

My application crashes in Socket_getReadySocket() and Socket_close()
because the pointer s.cur_clientsds becomes 0xdddddddd. Which is obviously an
invalid pointer.
It usually happens while some other part (none mqtt part) of my application does
some other socket operation (listen, accept connection, release connection, ...).

I have tried to write some simple test program, which does something similar
to my application. But so far I have not reproduced the crash with the attached
test application. (But maybe you could use it to improve the test collection.)

Greetings
Juergen

copied from bug 447672

On 2015-12-14 18:30:33 -0500, Ian Craggs wrote:

The same fix is needed for MQTTAsync.c as was applied to MQTTClient.c in bug 447672, to stop a socket being closed when its data structure is still being used in getReadySocket.

On 2015-12-15 07:42:00 -0500, Ian Craggs wrote:

Added fix to the develop branch.

64 bits version of paho not available

migrated from Bugzilla #480160
status RESOLVED severity normal in component MQTT-C for 1.2
Reported in version 1.2 on platform PC
Assigned to: Ian Craggs

On 2015-10-19 15:47:21 -0400, Angelo Ribeiro wrote:

Hi,

We are using paho on our project, however we require to have a 64 bit (Debug and Release) version of our libraries.
Since Paho doesn't compile/build for 64 bits, I have submit a PR (master...aribeironovaes:master), but I'm not getting answers to the PR.

Can you take a look if you can add 64 bits configuration to Paho-C For Windows?

Thanks,

Angelo Ribeiro.

On 2015-11-04 18:27:55 -0500, Ian Craggs wrote:

I've pulled in your Github PR and added the changes to the develop branch. I've also fixed the compile warnings (that took me a while).

It would be good if you could try it out. Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.