Как я могу обнаружить проблемы с пользователем/паролем при подключении к брокеру MQTT во время подключения с помощью библиотеки libmosquitto?

#mqtt #mosquitto #libmosquitto

Вопрос:

Я тестирую библиотеку MQTT mosquitto с помощью этой небольшой программы:

 /*
  compile using:
  $ gcc -o libmosq libmosq.c -lmosquitto
*/
#include <stdio.h>
#include <mosquitto.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
  struct mosquitto *mosq = NULL;
 
  mosquitto_lib_init();
  mosq = mosquitto_new(NULL, true, NULL);
  if(!mosq) {
     fprintf(stderr, "Error: Out of memory.n");
     exit(1);
  } 
    
  mosquitto_username_pw_set(mosq, "user1", "passwd1");

  int resultCode = mosquitto_connect(mosq, "localhost", 1883, 60);
  if (resultCode != MOSQ_ERR_SUCCESS) {
    fprintf(stderr, "connection errorn");
    exit(1);
  }
  else {
    printf("connection successn");
  }
  // wait until control C is done
  sleep(1000000);
}
 

Я запускаю брокера MQTT (брокер mosquitto версии 1.6.10) на локальном хосте в порту 1883.

Когда я запускаю программу, я получаю "connection success" и вижу в журнале mosquitto:

 iot-mosquitto    | 2021-10-06T10:16:11: New connection from 172.17.0.1 on port 1883.
iot-mosquitto    | 2021-10-06T10:16:11: New client connected from 172.17.0.1 as auto-51085B64-A53B-DBE1-DBFB-A6D9D702B69C (p2, c1, k60, u'user1').
 

Я понимаю, что в данном случае связь правильная. Пока все хорошо.

Однако, если я использую неверного пользователя/пропуск (например mosquitto_username_pw_set(mosq, "user1", "xxxxx") ) или не использую пользователя/пропуск (т. Е. Удаляю mosquitto_username_pw_set() карту) Я вхожу в журнал брокера mosquitto:

 iot-mosquitto    | 2021-10-06T10:27:58: New connection from 172.17.0.1 on port 1883.
iot-mosquitto    | 2021-10-06T10:27:58: Socket error on client <unknown>, disconnecting.
 

и это прекрасно. Проблема в том, что в моей программе я получаю "connection success" вместо "connection error" . Другими словами, я получаю MOSQ_ERR_SUCCESS в качестве возвращаемого значения mosquitto_connect() вместо MOSQ_ERR_ERRNO .

Глядя на трассировки брокера MQTT, похоже, что моя программа подключается (что объясняет MOSQ_ERR_SUCCESS ), но мгновенно отключается…

Как я могу обнаружить проблемы с пользователем/паролем в соединении во время подключения, используя библиотеку libmosquitto, пожалуйста?

Заранее спасибо!

РЕДАКТИРОВАТЬ: Я понимаю, что есть какой-то способ решить эту проблему, поскольку mosquitto_sub (который, как я понимаю, основан в той же библиотеке) способен обнаруживать. Напр.:

 $ mosquitto_sub -p 1883 -t '#' -u user1 -P xxxxxx
Connection error: Connection Refused: not authorised.
 

Комментарии:

1. Вы смотрели исходный код mosquitto_sub?

2. Спасибо за подсказку! Я так и сделаю, если не получу здесь ответа 🙂

3. Похоже, это исходный код для mosquito_sub: github.com/eclipse/mosquitto/blob/master/client/sub_client.c

4. Вам, вероятно, нужен этот файл

Ответ №1:

Я, наконец, решил эту проблему, используя следующую программу:

 /*
  compile using:
  $ gcc -o libmosq libmosq.c -lmosquitto
*/
#include <stdio.h>
#include <mosquitto.h>
#include <stdlib.h>
#include <unistd.h>

void connection_callback(struct mosquitto* mosq, void *obj, int rc)
{
  if (rc) {
    printf("connection error: %d (%s)n", rc, mosquitto_connack_string(rc));
    exit(1);
  }
  else {
    printf("connection successn");
  }
}

int main(int argc, char *argv[])
{
  struct mosquitto *mosq = NULL;
  
  mosquitto_lib_init();
  mosq = mosquitto_new(NULL, true, NULL);
  if(!mosq) {
     fprintf(stderr, "Error: Out of memory.n");
     exit(1);
  }

  mosquitto_connect_callback_set(mosq, connection_callback);
  mosquitto_username_pw_set(mosq, "user1", "passwd1");

  int resultCode = mosquitto_connect(mosq, "localhost", 1883, 60);
  if (resultCode != MOSQ_ERR_SUCCESS) {
    fprintf(stderr, "error calling mosquitto_connectn");
    exit(1);
  }

  int loop = mosquitto_loop_start(mosq);
  if(loop != MOSQ_ERR_SUCCESS){
    fprintf(stderr, "Unable to start loop: %in", loop);
    exit(1);
  }

  // hang until control C is done
  sleep(1000000);
}
 

Основные отличия по сравнению с первой версией:

  • Используется mosquitto_connect_callback_set() для установки функции обратного вызова для события подключения
  • С помощью mosquitto_loop_start() . Если я не добавлю это утверждение, обратный вызов не будет вызван при подключении

С помощью этой программы я получаю следующее сообщение при успешном подключении:

 connection success
 

и это, когда пароль неверен или если я удалю mosquitto_username_pw_set() заявление:

 connection error: 5 (Connection Refused: not authorised.)