Commit 85da5246 authored by Ian Craggs's avatar Ian Craggs

Bug #409267 - add multiple server list to the connectOptions

parent adaada7f
This diff is collapsed.
......@@ -13,6 +13,7 @@
* Contributors:
* Ian Craggs - initial API and implementation
* Ian Craggs, Allan Stockdill-Mander - SSL connections
* Ian Craggs - multiple server connection support
*******************************************************************************/
/********************************************************************/
......@@ -541,7 +542,10 @@ typedef struct
{
/** The eyecatcher for this structure. must be MQTC. */
char struct_id[4];
/** The version number of this structure. Must be 0 or 1. 0 signifies no SSL options */
/** The version number of this structure. Must be 0, 1 or 2.
* 0 signifies no SSL options and no serverURIs
* 1 signifies no serverURIs
*/
int struct_version;
/** The "keep alive" interval, measured in seconds, defines the maximum time
* that should pass without communication between the client and the server
......@@ -629,10 +633,23 @@ typedef struct
* provide access to the context information in the callback.
*/
void* context;
/**
* The number of entries in the serverURIs array.
*/
int serverURIcount;
/**
* An array of null-terminated strings specifying the servers to
* which the client will connect. Each string takes the form <i>protocol://host:port</i>.
* <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>. For <i>host</i>, you can
* specify either an IP address or a domain name. For instance, to connect to
* a server running on the local machines with the default MQTT port, specify
* <i>tcp://localhost:1883</i>.
*/
char** serverURIs;
} MQTTAsync_connectOptions;
#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 1, 60, 1, 10, NULL, NULL, NULL, 30, 20, NULL, NULL }
#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 2, 60, 1, 10, NULL, NULL, NULL, 30, 20, NULL, NULL, 0, NULL}
/**
* This function attempts to connect a previously-created client (see
......
......@@ -15,6 +15,7 @@
* Ian Craggs - bug 384016 - segv setting will message
* Ian Craggs - bug 384053 - v1.0.0.7 - stop MQTTClient_receive on socket error
* Ian Craggs, Allan Stockdill-Mander - add ability to connect with SSL
* Ian Craggs - multiple server connection support
*******************************************************************************/
#include <stdlib.h>
......@@ -704,55 +705,14 @@ void Protocol_processPublication(Publish* publish, Clients* client)
}
int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options)
int MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectOptions* options, char* serverURI)
{
MQTTClients* m = handle;
int rc = SOCKET_ERROR;
START_TIME_TYPE start;
long millisecsTimeout = 30000L;
int rc = SOCKET_ERROR;
FUNC_ENTRY;
Thread_lock_mutex(mqttclient_mutex);
if (options == NULL)
{
rc = MQTTCLIENT_NULL_PARAMETER;
goto exit;
}
if (strncmp(options->struct_id, "MQTC", 4) != 0 || (options->struct_version != 0 && options->struct_version != 1))
{
rc = MQTTCLIENT_BAD_STRUCTURE;
goto exit;
}
if (options->will) /* check validity of will options structure */
{
if (strncmp(options->will->struct_id, "MQTW", 4) != 0 || options->will->struct_version != 0)
{
rc = MQTTCLIENT_BAD_STRUCTURE;
goto exit;
}
}
#if defined(OPENSSL)
if (options->struct_version != 0 && options->ssl) /* check validity of SSL options structure */
{
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version != 0)
{
rc = MQTTCLIENT_BAD_STRUCTURE;
goto exit;
}
}
#endif
if ((options->username && !UTF8_validateString(options->username)) ||
(options->password && !UTF8_validateString(options->password)))
{
rc = MQTTCLIENT_BAD_UTF8_STRING;
goto exit;
}
millisecsTimeout = options->connectTimeout * 1000;
start = MQTTClient_start_clock();
if (m->ma && !running)
......@@ -788,11 +748,11 @@ int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options)
m->c->password = options->password;
m->c->retryInterval = options->retryInterval;
Log(TRACE_MIN, -1, "Connecting to serverURI %s", m->serverURI);
Log(TRACE_MIN, -1, "Connecting to serverURI %s", serverURI);
#if defined(OPENSSL)
rc = MQTTProtocol_connect(m->serverURI, m->c, m->ssl);
rc = MQTTProtocol_connect(serverURI, m->c, m->ssl);
#else
rc = MQTTProtocol_connect(m->serverURI, m->c);
rc = MQTTProtocol_connect(serverURI, m->c);
#endif
if (rc == SOCKET_ERROR)
goto exit;
......@@ -919,7 +879,84 @@ exit:
MQTTClient_disconnect(handle, 0); /* not "internal" because we don't want to call connection lost */
Thread_lock_mutex(mqttclient_mutex);
}
FUNC_EXIT_RC(rc);
return rc;
}
int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options)
{
MQTTClients* m = handle;
int rc = SOCKET_ERROR;
FUNC_ENTRY;
Thread_lock_mutex(mqttclient_mutex);
if (options == NULL)
{
rc = MQTTCLIENT_NULL_PARAMETER;
goto exit;
}
if (strncmp(options->struct_id, "MQTC", 4) != 0 ||
(options->struct_version != 0 && options->struct_version != 1 && options->struct_version != 2))
{
rc = MQTTCLIENT_BAD_STRUCTURE;
goto exit;
}
if (options->will) /* check validity of will options structure */
{
if (strncmp(options->will->struct_id, "MQTW", 4) != 0 || options->will->struct_version != 0)
{
rc = MQTTCLIENT_BAD_STRUCTURE;
goto exit;
}
}
#if defined(OPENSSL)
if (options->struct_version != 0 && options->ssl) /* check validity of SSL options structure */
{
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version != 0)
{
rc = MQTTCLIENT_BAD_STRUCTURE;
goto exit;
}
}
#endif
if ((options->username && !UTF8_validateString(options->username)) ||
(options->password && !UTF8_validateString(options->password)))
{
rc = MQTTCLIENT_BAD_UTF8_STRING;
goto exit;
}
if (options->struct_version < 2 || options->serverURIcount == 0)
rc = MQTTClient_connectURI(handle, options, m->serverURI);
else
{
int i;
for (i = 0; i < options->serverURIcount; ++i)
{
char* serverURI = options->serverURIs[i];
if (strncmp(URI_TCP, serverURI, strlen(URI_TCP)) == 0)
serverURI += strlen(URI_TCP);
#if defined(OPENSSL)
else if (strncmp(URI_SSL, serverURI, strlen(URI_SSL)) == 0)
{
serverURI += strlen(URI_SSL);
m->ssl = 1;
}
#endif
if ((rc = MQTTClient_connectURI(handle, options, serverURI)) == MQTTCLIENT_SUCCESS)
break;
}
}
exit:
if (m->c->will)
{
free(m->c->will);
......
......@@ -13,6 +13,7 @@
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs, Allan Stockdill-Mander - SSL updates
* Ian Craggs - multiple server connection support
*******************************************************************************/
/**
......@@ -544,9 +545,22 @@ typedef struct
* application does not make use of SSL, set this pointer to NULL.
*/
MQTTClient_SSLOptions* ssl;
/**
* The number of entries in the serverURIs array.
*/
int serverURIcount;
/**
* An array of null-terminated strings specifying the servers to
* which the client will connect. Each string takes the form <i>protocol://host:port</i>.
* <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>. For <i>host</i>, you can
* specify either an IP address or a domain name. For instance, to connect to
* a server running on the local machines with the default MQTT port, specify
* <i>tcp://localhost:1883</i>.
*/
char** serverURIs;
} MQTTClient_connectOptions;
#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 1, 60, 1, 1, NULL, NULL, NULL, 30, 20, NULL }
#define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 2, 60, 1, 1, NULL, NULL, NULL, 30, 20, NULL, 0, NULL }
/**
* MQTTClient_libraryInfo is used to store details relating to the currently used
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment