**Describe the bug**
malformed packet may lead to unexpected behavior.

This malformed packet will send SUBACK right after CONNECT, and a SUB follows. SUB clients , which should be dropped, will still be inserted into db_tree.

**To Reproduce**
1. start nanomq with ` ./nanomq/nanomq start --url tls+nmq-tcp://0.0.0.0:8883 --http --cacert etc/certs/cacert.pem --cert etc/certs/cert.pem --key etc/certs/key.pem --qos_duration 1 --log_level debug  --log_stdout false --log_file /tmp/nanomq_test.log`
2. get `test.py, fuzzy_test.txt, fuzzy_test.py, rest_api_test.py` and run the python script to test `python3 test.py`
fuzzy file --> [fuzzy_test.txt](https://github.com/nanomq/nanomq/files/15290977/fuzzy_test.txt)

test.py --> 
```
from cmath import log
from fileinput import close
import os
import subprocess
import shlex
iimport requests
import json
from collections import namedtuple

base_url = "http://127.0.0.1:8081/api/v4"

def test_get_api():
    #  not all endpoint is tested.
    paths = ["", "/nodes", "/brokers", "/clients",
             "/subscriptions", "/topic-tree", "/reload", "/configuration"]

    for p in paths:
        print("testing Get API: " + base_url + p)
        response = requests.get(base_url + p, auth=('admin', 'public'), headers={'Connection':'close'})

        if response.status_code != 200:
            print("test get api failed: " + p)
            return False

    return True

def test_post_api():
    Param = namedtuple('Param', ['path', 'payload'])

    param1 = Param(path="/reload", payload={'data': {
        'property_size': 64,
        'max_packet_size': 5120,
        'client_max_packet_size': 5,
        'msq_len': 2048,
        'qos_duration': 10,
        'keepalive_backoff': 1250,
        'allow_anonymous': False
    }})

    param2 = Param(path="/reload", payload={'data': {
        'property_size': 64,
        'max_packet_size': 10240,
        'client_max_packet_size': 5,
        'msq_len': 2048,
        'qos_duration': 90,
        'keepalive_backoff': 1250,
        'allow_anonymous': True
    }})

    param_list = [param1, param2]

    for item in param_list:
        print("testing Post API: " + base_url + item.path)
        response = requests.post(
            base_url + item.path, json.dumps(item.payload), auth=('admin', 'public'), headers={'Connection':'close'})
        if response.status_code != 200:
            print("test Post api failed: " + item.path)
            return False

    return True

def rest_api_test():
    return test_get_api() and test_post_api()mport time
from os.path import exists

from fuzzy_test import fuzzy_test
from rest_api_test import rest_api_test

if __name__=='__main__':

    print("fuzzy test start")
    if( False == fuzzy_test()):
        print("fuzzy test failed")
        raise AssertionError
    print("fuzzy test end")

    print("rest api test start")
    if False == rest_api_test():
        print("rest api test failed")
        raise AssertionError
    print("rest api test end")
```

fuzzy_test.py  (set right path for the files)-->
```
import time 
import socket
import os

data_path = "../../.github/scripts/fuzzy_test.txt"
addr = '127.0.0.1'
port = 1883

def try_connect(bytes_flow, sleep_time = 0.01):
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	while True:
		try:
			s.connect((addr, port))
			s.send(bytes_flow)      
			s.close()
			break
		except ConnectionResetError:
			continue
		except ConnectionRefusedError:
			return False
	time.sleep(sleep_time)
	return True

def start_fuzzy_test(fuzzy_data):
	flag = True
	for hex_flow in reversed(fuzzy_data):
		bytes_flow = bytearray.fromhex(hex_flow)
		status = try_connect(bytes_flow)
		if status == False:
			print('[+] A crash was detected')
			flag = False
	if(flag == True):
		print('[-] No crash..')
	return flag

def fuzzy_test():
    with open(data_path, 'r') as f:
        fuzzy_data = f.readlines()
	
    if (start_fuzzy_test(fuzzy_data) == False):
        return False
    else:
        return True
```
rest_api_test.py -->
```
import requests
import json
from collections import namedtuple

base_url = "http://127.0.0.1:8081/api/v4"

def test_get_api():
    #  not all endpoint is tested.
    paths = ["", "/nodes", "/brokers", "/clients",
             "/subscriptions", "/topic-tree", "/reload", "/configuration"]

    for p in paths:
        print("testing Get API: " + base_url + p)
        response = requests.get(base_url + p, auth=('admin', 'public'), headers={'Connection':'close'})

        if response.status_code != 200:
            print("test get api failed: " + p)
            return False

    return True

def test_post_api():
    Param = namedtuple('Param', ['path', 'payload'])

    param1 = Param(path="/reload", payload={'data': {
        'property_size': 64,
        'max_packet_size': 5120,
        'client_max_packet_size': 5,
        'msq_len': 2048,
        'qos_duration': 10,
        'keepalive_backoff': 1250,
        'allow_anonymous': False
    }})

    param2 = Param(path="/reload", payload={'data': {
        'property_size': 64,
        'max_packet_size': 10240,
        'client_max_packet_size': 5,
        'msq_len': 2048,
        'qos_duration': 90,
        'keepalive_backoff': 1250,
        'allow_anonymous': True
    }})

    param_list = [param1, param2]

    for item in param_list:
        print("testing Post API: " + base_url + item.path)
        response = requests.post(
            base_url + item.path, json.dumps(item.payload), auth=('admin', 'public'), headers={'Connection':'close'})
        if response.status_code != 200:
            print("test Post api failed: " + item.path)
            return False

    return True

def rest_api_test():
    return test_get_api() and test_post_api()
```

Malformed packet may lead to unexpected behavior.
This is a GitHub Issue
repo:nanomq
owner:emqx
Title : Malformed packet may lead to unexpected behavior.
Issue date:

--- start body ---
**Describe the bug**
malformed packet may lead to unexpected behavior.

This malformed packet will send SUBACK right after CONNECT, and a SUB follows. SUB clients , which should be dropped, will still be inserted into db_tree.

**To Reproduce**
1. start nanomq with ` ./nanomq/nanomq start --url tls+nmq-tcp://0.0.0.0:8883 --http --cacert etc/certs/cacert.pem --cert etc/certs/cert.pem --key etc/certs/key.pem --qos_duration 1 --log_level debug  --log_stdout false --log_file /tmp/nanomq_test.log`
2. get `test.py, fuzzy_test.txt, fuzzy_test.py, rest_api_test.py` and run the python script to test `python3 test.py`
fuzzy file --> [fuzzy_test.txt](https://github.com/nanomq/nanomq/files/15290977/fuzzy_test.txt)

test.py --> 
```
from cmath import log
from fileinput import close
import os
import subprocess
import shlex
iimport requests
import json
from collections import namedtuple

base_url = "http://127.0.0.1:8081/api/v4"

def test_get_api():
    #  not all endpoint is tested.
    paths = ["", "/nodes", "/brokers", "/clients",
             "/subscriptions", "/topic-tree", "/reload", "/configuration"]

    for p in paths:
        print("testing Get API: " + base_url + p)
        response = requests.get(base_url + p, auth=('admin', 'public'), headers={'Connection':'close'})

        if response.status_code != 200:
            print("test get api failed: " + p)
            return False

    return True

def test_post_api():
    Param = namedtuple('Param', ['path', 'payload'])

    param1 = Param(path="/reload", payload={'data': {
        'property_size': 64,
        'max_packet_size': 5120,
        'client_max_packet_size': 5,
        'msq_len': 2048,
        'qos_duration': 10,
        'keepalive_backoff': 1250,
        'allow_anonymous': False
    }})

    param2 = Param(path="/reload", payload={'data': {
        'property_size': 64,
        'max_packet_size': 10240,
        'client_max_packet_size': 5,
        'msq_len': 2048,
        'qos_duration': 90,
        'keepalive_backoff': 1250,
        'allow_anonymous': True
    }})

    param_list = [param1, param2]

    for item in param_list:
        print("testing Post API: " + base_url + item.path)
        response = requests.post(
            base_url + item.path, json.dumps(item.payload), auth=('admin', 'public'), headers={'Connection':'close'})
        if response.status_code != 200:
            print("test Post api failed: " + item.path)
            return False

    return True

def rest_api_test():
    return test_get_api() and test_post_api()mport time
from os.path import exists

from fuzzy_test import fuzzy_test
from rest_api_test import rest_api_test

if __name__=='__main__':

    print("fuzzy test start")
    if( False == fuzzy_test()):
        print("fuzzy test failed")
        raise AssertionError
    print("fuzzy test end")

    print("rest api test start")
    if False == rest_api_test():
        print("rest api test failed")
        raise AssertionError
    print("rest api test end")
```

fuzzy_test.py  (set right path for the files)-->
```
import time 
import socket
import os

data_path = "../../.github/scripts/fuzzy_test.txt"
addr = '127.0.0.1'
port = 1883

def try_connect(bytes_flow, sleep_time = 0.01):
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	while True:
		try:
			s.connect((addr, port))
			s.send(bytes_flow)      
			s.close()
			break
		except ConnectionResetError:
			continue
		except ConnectionRefusedError:
			return False
	time.sleep(sleep_time)
	return True

def start_fuzzy_test(fuzzy_data):
	flag = True
	for hex_flow in reversed(fuzzy_data):
		bytes_flow = bytearray.fromhex(hex_flow)
		status = try_connect(bytes_flow)
		if status == False:
			print('[+] A crash was detected')
			flag = False
	if(flag == True):
		print('[-] No crash..')
	return flag

def fuzzy_test():
    with open(data_path, 'r') as f:
        fuzzy_data = f.readlines()
	
    if (start_fuzzy_test(fuzzy_data) == False):
        return False
    else:
        return True
```
rest_api_test.py -->
```
import requests
import json
from collections import namedtuple

base_url = "http://127.0.0.1:8081/api/v4"

def test_get_api():
    #  not all endpoint is tested.
    paths = ["", "/nodes", "/brokers", "/clients",
             "/subscriptions", "/topic-tree", "/reload", "/configuration"]

    for p in paths:
        print("testing Get API: " + base_url + p)
        response = requests.get(base_url + p, auth=('admin', 'public'), headers={'Connection':'close'})

        if response.status_code != 200:
            print("test get api failed: " + p)
            return False

    return True

def test_post_api():
    Param = namedtuple('Param', ['path', 'payload'])

    param1 = Param(path="/reload", payload={'data': {
        'property_size': 64,
        'max_packet_size': 5120,
        'client_max_packet_size': 5,
        'msq_len': 2048,
        'qos_duration': 10,
        'keepalive_backoff': 1250,
        'allow_anonymous': False
    }})

    param2 = Param(path="/reload", payload={'data': {
        'property_size': 64,
        'max_packet_size': 10240,
        'client_max_packet_size': 5,
        'msq_len': 2048,
        'qos_duration': 90,
        'keepalive_backoff': 1250,
        'allow_anonymous': True
    }})

    param_list = [param1, param2]

    for item in param_list:
        print("testing Post API: " + base_url + item.path)
        response = requests.post(
            base_url + item.path, json.dumps(item.payload), auth=('admin', 'public'), headers={'Connection':'close'})
        if response.status_code != 200:
            print("test Post api failed: " + item.path)
            return False

    return True

def rest_api_test():
    return test_get_api() and test_post_api()
```

--- end body ---
