From fb2aef2ce65d605cf0e56c3ab926be01545d2c58 Mon Sep 17 00:00:00 2001 From: Plamen Todorov Date: Sun, 6 Oct 2019 22:08:43 +0300 Subject: [PATCH 1/3] MQTT clientId should be unique Each mqtt hook establishes separate connection to the MQTT broker. If their clientIds are all equal the MQTT broker will disconnect the clients - the protocol does not allow 2 connected clients with the same name --- internal/endpoint/mqtt.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/endpoint/mqtt.go b/internal/endpoint/mqtt.go index eea4682f..3bd6431f 100644 --- a/internal/endpoint/mqtt.go +++ b/internal/endpoint/mqtt.go @@ -83,7 +83,9 @@ func (conn *MQTTConn) Send(msg string) error { } ops = ops.SetTLSConfig(&config) } - ops = ops.SetClientID("tile38").AddBroker(uri) + nano := time.Now().UnixNano() + clientID := fmt.Sprintf("tile38_%x", nano) //the id of connected clients should be unique + ops = ops.SetClientID(clientID).AddBroker(uri) c := paho.NewClient(ops) if token := c.Connect(); token.Wait() && token.Error() != nil { From c3b9a689bb0fbb6986259f373213ad4240abef65 Mon Sep 17 00:00:00 2001 From: Plamen Todorov Date: Tue, 8 Oct 2019 09:34:31 +0300 Subject: [PATCH 2/3] Use uuid as mqtt clientId Use crypto/random to generate unique mqtt client id. The tile38 prefix makes the connections easily identifiable in the mqtt broker logs. --- internal/endpoint/mqtt.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/internal/endpoint/mqtt.go b/internal/endpoint/mqtt.go index 3bd6431f..f4184725 100644 --- a/internal/endpoint/mqtt.go +++ b/internal/endpoint/mqtt.go @@ -3,12 +3,14 @@ package endpoint import ( "crypto/tls" "crypto/x509" + "crypto/rand" "fmt" "io/ioutil" "sync" "time" paho "github.com/eclipse/paho.mqtt.golang" + "github.com/tidwall/tile38/internal/log" ) const ( @@ -83,9 +85,16 @@ func (conn *MQTTConn) Send(msg string) error { } ops = ops.SetTLSConfig(&config) } - nano := time.Now().UnixNano() - clientID := fmt.Sprintf("tile38_%x", nano) //the id of connected clients should be unique - ops = ops.SetClientID(clientID).AddBroker(uri) + //generate UUID for the client-id. + b := make([]byte, 16) + _, err := rand.Read(b) + if err != nil { + log.Debugf("Failed to generate guid for the mqtt client. The endpoint will not work") + return err; + } + uuid := fmt.Sprintf("tile38-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]) + + ops = ops.SetClientID(uuid).AddBroker(uri) c := paho.NewClient(ops) if token := c.Connect(); token.Wait() && token.Error() != nil { From 6b82fd94eb9f179d6cb5389af6b1531e6a3c1939 Mon Sep 17 00:00:00 2001 From: Plamen Todorov Date: Tue, 8 Oct 2019 20:24:31 +0300 Subject: [PATCH 3/3] randomize mqtt client id with math/rand Cryptographic randomizer is not required for mqtt clientIds. They should be unique only among currently selected clients. --- internal/endpoint/mqtt.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/endpoint/mqtt.go b/internal/endpoint/mqtt.go index f4184725..98003675 100644 --- a/internal/endpoint/mqtt.go +++ b/internal/endpoint/mqtt.go @@ -3,7 +3,7 @@ package endpoint import ( "crypto/tls" "crypto/x509" - "crypto/rand" + "math/rand" "fmt" "io/ioutil" "sync"