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 @@ ...@@ -13,6 +13,7 @@
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation * Ian Craggs - initial API and implementation
* Ian Craggs, Allan Stockdill-Mander - SSL connections * Ian Craggs, Allan Stockdill-Mander - SSL connections
* Ian Craggs - multiple server connection support
*******************************************************************************/ *******************************************************************************/
/********************************************************************/ /********************************************************************/
...@@ -541,7 +542,10 @@ typedef struct ...@@ -541,7 +542,10 @@ typedef struct
{ {
/** The eyecatcher for this structure. must be MQTC. */ /** The eyecatcher for this structure. must be MQTC. */
char struct_id[4]; 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; int struct_version;
/** The "keep alive" interval, measured in seconds, defines the maximum time /** The "keep alive" interval, measured in seconds, defines the maximum time
* that should pass without communication between the client and the server * that should pass without communication between the client and the server
...@@ -629,10 +633,23 @@ typedef struct ...@@ -629,10 +633,23 @@ typedef struct
* provide access to the context information in the callback. * provide access to the context information in the callback.
*/ */
void* context; 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; } 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 * This function attempts to connect a previously-created client (see
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* Ian Craggs - bug 384016 - segv setting will message * Ian Craggs - bug 384016 - segv setting will message
* Ian Craggs - bug 384053 - v1.0.0.7 - stop MQTTClient_receive on socket error * 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, Allan Stockdill-Mander - add ability to connect with SSL
* Ian Craggs - multiple server connection support
*******************************************************************************/ *******************************************************************************/
#include <stdlib.h> #include <stdlib.h>
...@@ -704,55 +705,14 @@ void Protocol_processPublication(Publish* publish, Clients* client) ...@@ -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; MQTTClients* m = handle;
int rc = SOCKET_ERROR;
START_TIME_TYPE start; START_TIME_TYPE start;
long millisecsTimeout = 30000L; long millisecsTimeout = 30000L;
int rc = SOCKET_ERROR;
FUNC_ENTRY; 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; millisecsTimeout = options->connectTimeout * 1000;
start = MQTTClient_start_clock(); start = MQTTClient_start_clock();
if (m->ma && !running) if (m->ma && !running)
...@@ -788,11 +748,11 @@ int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options) ...@@ -788,11 +748,11 @@ int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options)
m->c->password = options->password; m->c->password = options->password;
m->c->retryInterval = options->retryInterval; 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) #if defined(OPENSSL)
rc = MQTTProtocol_connect(m->serverURI, m->c, m->ssl); rc = MQTTProtocol_connect(serverURI, m->c, m->ssl);
#else #else
rc = MQTTProtocol_connect(m->serverURI, m->c); rc = MQTTProtocol_connect(serverURI, m->c);
#endif #endif
if (rc == SOCKET_ERROR) if (rc == SOCKET_ERROR)
goto exit; goto exit;
...@@ -919,7 +879,84 @@ exit: ...@@ -919,7 +879,84 @@ exit:
MQTTClient_disconnect(handle, 0); /* not "internal" because we don't want to call connection lost */ MQTTClient_disconnect(handle, 0); /* not "internal" because we don't want to call connection lost */
Thread_lock_mutex(mqttclient_mutex); 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) if (m->c->will)
{ {
free(m->c->will); free(m->c->will);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* Contributors: * Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation * Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs, Allan Stockdill-Mander - SSL updates * Ian Craggs, Allan Stockdill-Mander - SSL updates
* Ian Craggs - multiple server connection support
*******************************************************************************/ *******************************************************************************/
/** /**
...@@ -544,9 +545,22 @@ typedef struct ...@@ -544,9 +545,22 @@ typedef struct
* application does not make use of SSL, set this pointer to NULL. * application does not make use of SSL, set this pointer to NULL.
*/ */
MQTTClient_SSLOptions* ssl; 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; } 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 * 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