Ejemplo n.º 1
0
// validate validates the options.
func (opts *PUBLISHOptions) validate() error {
	// Check the QoS.
	if !mqtt.ValidQoS(opts.QoS) {
		return ErrInvalidQoS
	}

	// Check the length of the Topic Name.
	if len(opts.TopicName) > maxStringsLen {
		return ErrTopicNameExceedsMaxStringsLen
	}

	// Check if the Topic Name contains the wildcard characters.
	if bytes.IndexAny(opts.TopicName, wildcards) != -1 {
		return ErrTopicNameContainsWildcards
	}

	// Check the length of the Application Message.
	if len(opts.Message) > maxStringsLen {
		return ErrMessageExceedsMaxStringsLen
	}

	// End the validation if the QoS equals to QoS 0.
	if opts.QoS == mqtt.QoS0 {
		return nil
	}

	// Check the Packet Identifier.
	if opts.PacketID == 0 {
		return ErrInvalidPacketID
	}

	return nil
}
Ejemplo n.º 2
0
func (opts *CONNECTOptions) validate() error {
	// Check the length of the Client Identifier.
	if len(opts.ClientID) > maxStringsLen {
		return ErrClientIDExceedsMaxStringsLen
	}

	// Check the combination of the Client Identifier and the Clean Session.
	if len(opts.ClientID) == 0 && !opts.CleanSession {
		return ErrInvalidClientIDCleanSession
	}

	// Check the length of the User Name.
	if len(opts.UserName) > maxStringsLen {
		return ErrUserNameExceedsMaxStringsLen
	}

	// Check the length of the Password.
	if len(opts.Password) > maxStringsLen {
		return ErrPasswordExceedsMaxStringsLen
	}

	// Check the combination of the Client Identifier and the Password.
	if len(opts.UserName) == 0 && len(opts.Password) > 0 {
		return ErrInvalidClientIDPassword
	}

	// Check the length of the Will Topic.
	if len(opts.WillTopic) > maxStringsLen {
		return ErrWillTopicExceedsMaxStringsLen
	}

	// Check the length of the Will Message.
	if len(opts.WillMessage) > maxStringsLen {
		return ErrWillMessageExceedsMaxStringsLen
	}

	// Check the combination of the Will Topic and the Will Message.
	if (len(opts.WillTopic) > 0 && len(opts.WillMessage) == 0) || (len(opts.WillTopic) == 0 && len(opts.WillMessage) > 0) {
		return ErrInvalidWillTopicMessage
	}

	// Check the Will QoS.
	if !mqtt.ValidQoS(opts.WillQoS) {
		return ErrInvalidWillQoS
	}

	// Check the combination of the Will Topic, the Will Message and the Will QoS.
	if len(opts.WillTopic) == 0 && len(opts.WillMessage) == 0 && opts.WillQoS != mqtt.QoS0 {
		return ErrInvalidWillTopicMessageQoS
	}

	// Check the combination of the Will Topic, the Will Message and the Will Retain.
	if len(opts.WillTopic) == 0 && len(opts.WillMessage) == 0 && opts.WillRetain {
		return ErrInvalidWillTopicMessageRetain
	}

	return nil
}
Ejemplo n.º 3
0
// validateSUBACKBytes validates the fixed header and the remaining.
func validateSUBACKBytes(fixedHeader FixedHeader, remaining []byte) error {
	// Extract the MQTT Control Packet type.
	ptype, err := fixedHeader.ptype()
	if err != nil {
		return err
	}

	// Check the length of the fixed header.
	if len(fixedHeader) < minLenSUBACKFixedHeader {
		return ErrInvalidFixedHeaderLen
	}

	// Check the MQTT Control Packet type.
	if ptype != TypeSUBACK {
		return ErrInvalidPacketType
	}

	// Check the reserved bits of the fixed header.
	if fixedHeader[0]<<4 != 0x00 {
		return ErrInvalidFixedHeader
	}

	// Check the length of the remaining.
	if len(remaining) < lenSUBACKVariableHeader+1 {
		return ErrInvalidRemainingLen
	}

	// Extract the Packet Identifier.
	packetID, _ := decodeUint16(remaining[0:lenSUBACKVariableHeader])

	// Check the Packet Identifier.
	if packetID == 0 {
		return ErrInvalidPacketID
	}

	// Check each Return Code.
	for _, b := range remaining[lenSUBACKVariableHeader:] {
		if !mqtt.ValidQoS(b) && b != SUBACKRetFailure {
			return ErrInvalidSUBACKReturnCode
		}
	}

	return nil
}
Ejemplo n.º 4
0
// validate validates the subscription request.
func (s *SubReq) validate() error {
	// Check the length of the Topic Filter.
	l := len(s.TopicFilter)

	if l == 0 {
		return ErrNoTopicFilter
	}

	if l > maxStringsLen {
		return ErrTopicFilterExceedsMaxStringsLen
	}

	// Check the QoS.
	if !mqtt.ValidQoS(s.QoS) {
		return ErrInvalidQoS
	}

	return nil
}
Ejemplo n.º 5
0
// validatePUBLISHBytes validates the fixed header and the variable header.
func validatePUBLISHBytes(fixedHeader FixedHeader, remaining []byte) error {
	// Extract the MQTT Control Packet type.
	ptype, err := fixedHeader.ptype()
	if err != nil {
		return err
	}

	// Check the length of the fixed header.
	if len(fixedHeader) < minLenPUBLISHFixedHeader {
		return ErrInvalidFixedHeaderLen
	}

	// Check the MQTT Control Packet type.
	if ptype != TypePUBLISH {
		return ErrInvalidPacketType
	}

	// Get the QoS.
	qos := (fixedHeader[0] & 0x06) >> 1

	// Check the QoS.
	if !mqtt.ValidQoS(qos) {
		return ErrInvalidQoS
	}

	// Check the length of the remaining.
	if l := len(remaining); l < minLenPUBLISHVariableHeader || l > maxRemainingLength {
		return ErrInvalidRemainingLen
	}

	// Extract the length of the Topic Name.
	lenTopicName, _ := decodeUint16(remaining[0:2])

	// Calculate the length of the variable header.
	var lenVariableHeader int

	if qos == mqtt.QoS0 {
		lenVariableHeader = 2 + int(lenTopicName)
	} else {
		lenVariableHeader = 2 + int(lenTopicName) + 2
	}

	// Check the length of the remaining.
	if len(remaining) < lenVariableHeader {
		return ErrInvalidRemainingLength
	}

	// End the validation if the QoS equals to QoS 0.
	if qos == mqtt.QoS0 {
		return nil
	}

	// Extract the Packet Identifier.
	packetID, _ := decodeUint16(remaining[2+int(lenTopicName) : 2+int(lenTopicName)+2])

	// Check the Packet Identifier.
	if packetID == 0 {
		return ErrInvalidPacketID
	}

	return nil
}