Browse Source

update:完善DNS和tls

alienwalker 3 years ago
parent
commit
d9d9b7d96b

+ 555 - 0
components/ethernet/common/dns_client.c

@@ -1,5 +1,560 @@
 #include "luat_base.h"
 #ifdef LUAT_USE_DNS
+#include "luat_network_adapter.h"
+#include "bsp_common.h"
+#include "dns_def.h"
+#include "ctype.h"
+#define dnsONE_QUESTION                 0x0001
+#define dnsFLAG_QUERY_RESPONSE_BIT      0x8000
+#define dnsFLAG_OPERATION_CODE_BITS     0x7800
+#define dnsFLAG_TRUNCATION_BIT          0x0200
+#define dnsFLAG_RESPONSE_CODE_BITS      0x000f
+#define dnsOUTGOING_FLAGS               0x0100 /* Standard query. */
+#define dnsTYPE_IPV4                    0x0001 /* A record (host address. */
+#define dnsCLASS                        0x0001 /* IN */
+#define dnsRX_FLAGS_MASK                0x800f /* The bits of interest in the flags field of incoming DNS messages. */
+#define dnsEXPECTED_RX_FLAGS            0x8000 /* Should be a response, without any errors. */
+#define dnsTYPE_IPV6                    0x001C
+#define dnsNAME_IS_OFFSET               ( ( uint8_t ) 0xc0 )
+#define MAX_DOMAIN_LEN 255
+#define MAX_CHARACTER_NUM_PER_LABEL  63
+#define DNS_TO_BASE (1900)
+#define DNS_TRY_MAX	(3)
+
+
+extern void DBG_Printf(const char* format, ...);
+extern void DBG_HexPrintf(void *Data, unsigned int len);
+#define DBG(x,y...)		DBG_Printf("%s %d:"x"\r\n", __FUNCTION__,__LINE__,##y)
+#define DBG_ERR(x,y...)		DBG_Printf("%s %d:"x"\r\n", __FUNCTION__,__LINE__,##y)
+
+
+typedef struct
+{
+	llist_head node;
+	Buffer_Struct uri_buf;	//静态不用释放
+	luat_dns_ip_result ip_result[MAX_DNS_IP];
+	uint64_t timeout_ms;
+	uint16_t session_id;
+	uint8_t retry_cnt;
+	uint8_t dns_cnt;
+	uint8_t ip_nums;
+	uint8_t is_done;
+}dns_process_t;
+
+typedef struct xDNSMessage
+{
+    uint16_t usIdentifier;
+    uint16_t usFlags;
+    uint16_t usQuestions;
+    uint16_t usAnswers;
+    uint16_t usAuthorityRRs;
+    uint16_t usAdditionalRRs;
+}xDNSMessage_t;
+
+static int32_t dns_find_process(void *pData, void *pParam)
+{
+	uint16_t session_id = (uint32_t)pParam;
+	dns_process_t *process = (dns_process_t *)pData;
+	if (process->session_id == session_id)
+	{
+		return LIST_FIND;
+	}
+	return LIST_PASS;
+}
+
+static int32_t dns_skip_name_field(Buffer_Struct *buf)
+{
+
+	if( ( buf->Data[buf->Pos] & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
+	{
+		/* Jump over the two byte offset. */
+		buf->Pos += sizeof( uint16_t );
+	}
+	else
+	{
+		/* pucByte points to the full name.  Walk over the string. */
+		while( buf->Data[buf->Pos] != 0x00 )
+		{
+			/* The number of bytes to jump for each name section is stored in the byte
+			before the name section. */
+			buf->Pos += ( buf->Data[buf->Pos] + 1 );
+			if (buf->Pos >= buf->MaxLen)
+			{
+				return -1;
+			}
+		}
+		buf->Pos++;
+	}
+	if (buf->Pos >= buf->MaxLen)
+	{
+		return -1;
+	}
+	return 0;
+}
+
+static int32_t dns_set_result(void *pData, void *pParam)
+{
+	int i;
+	dns_process_t *process = (dns_process_t *)pParam;
+	luat_dns_require_t *require = (luat_dns_require_t *)pData;
+	if (!require->result)
+	{
+		if (process->uri_buf.Pos == require->uri.Pos)
+		{
+			if (!memcmp(process->uri_buf.Data, require->uri.Data, require->uri.Pos))
+			{
+				require->result = -1;
+				if (process->ip_nums)
+				{
+					for(i = 0; i < process->ip_nums; i++)
+					{
+						require->ip_result[i] = process->ip_result[i];
+					}
+					require->result = process->ip_nums;
+				}
+			}
+		}
+	}
+
+	return LIST_PASS;
+}
+
+int32_t dns_get_ip(dns_client_t *client, Buffer_Struct *buf, uint16_t answer_num, dns_process_t *process)
+{
+	uint16_t i, usTemp;
+	luat_ip_addr_t ip_addr;
+
+	uint32_t ttl;
+	uint8_t error = 0;
+	if (process)
+	{
+		process->ip_nums = 0;
+	}
+	for(i = 0; i < answer_num; i++)
+	{
+		if (dns_skip_name_field(buf) != ERROR_NONE)
+		{
+			error = 1;
+			goto NET_DNSGETIP_DONE;
+		}
+		usTemp = BytesGetBe16(buf->Data + buf->Pos);
+		switch (usTemp)
+		{
+		case dnsTYPE_IPV4:
+			if ( (buf->Pos + 14) > buf->MaxLen)
+			{
+				error = 1;
+				goto NET_DNSGETIP_DONE;
+			}
+			buf->Pos += 4;
+			ttl = BytesGetBe32FromBuf(buf);
+			usTemp = BytesGetBe16FromBuf(buf);
+			if ( (buf->Pos + usTemp) > buf->MaxLen)
+			{
+				error = 1;
+				goto NET_DNSGETIP_DONE;
+			}
+			ip_addr.ipv4 = BytesGetLe32(buf->Data + buf->Pos);
+			ip_addr.is_ipv6 = 0;
+			buf->Pos += usTemp;
+			if (ttl > 0)
+			{
+				if (process && (process->ip_nums < MAX_DNS_IP))
+				{
+					process->ip_result[process->ip_nums].ip = ip_addr;
+					process->ip_result[process->ip_nums].ttl_end = ttl + ((uint32_t)(GetSysTickMS()/1000));
+					process->ip_nums++;
+				}
+			}
+			break;
+		case dnsTYPE_IPV6:
+			if ( (buf->Pos + 14) > buf->MaxLen)
+			{
+				error = 1;
+				goto NET_DNSGETIP_DONE;
+			}
+			buf->Pos += 4;
+			ttl = BytesGetBe32FromBuf(buf);
+			usTemp = BytesGetBe16FromBuf(buf);
+			if ( (buf->Pos + usTemp) > buf->MaxLen)
+			{
+				error = 1;
+				goto NET_DNSGETIP_DONE;
+			}
+			memcpy(ip_addr.ipv6_u8_addr, buf->Data + buf->Pos, sizeof( uint32_t ) * 4);
+			ip_addr.is_ipv6 = 1;
+			if (ttl > 0)
+			{
+				if (process && (process->ip_nums < MAX_DNS_IP))
+				{
+					process->ip_result[process->ip_nums].ip = ip_addr;
+					process->ip_result[process->ip_nums].ttl_end = ttl + ((uint32_t)(GetSysTickMS()/1000));
+					process->ip_nums++;
+				}
+			}
+			buf->Pos += usTemp;
+			break;
+		default:
+			//DBG("%04x",usTemp);
+			buf->Pos += 8;
+			usTemp = BytesGetBe16FromBuf(buf);
+			buf->Pos += usTemp;
+			//OS(Dump)(buf->Data + buf->Pos, usTemp);
+			break;
+		}
+	}
+NET_DNSGETIP_DONE:
+	if (error)
+	{
+
+		return -1;
+	}
+	else
+	{
+		if (process)
+		{
+			process->is_done = 1;
+			llist_traversal(&client->require_head, dns_set_result, process);
+		}
+		return 0;
+	}
+
+
+}
+
+
+
+uint8_t dns_check_uri(const char *uri, uint32_t uri_len)
+{
+    uint32_t dot_num = 0;
+
+    uint32_t i = 0;
+    uint32_t label_len = 0;
+    char uri_last = 0;
+
+    if(uri ==NULL)
+    {
+        return 0;
+    }
+
+    if(uri_len == 0 || uri_len > MAX_DOMAIN_LEN)  //domain must less than 255
+    {
+         return 0;
+    }
+
+    if (!isalpha(uri[0])) // domain must start with a letter
+    {
+        return 0;
+    }
+
+    uri_last = uri[uri_len - 1];
+    if (!isalnum(uri_last))//end with a letter or digit
+    {
+         return 0;
+    }
+
+    for(i = 0; i < uri_len ; i++)
+    {
+        if(!(isalnum(uri[i]) || uri[i]== '.' || uri[i] == '-'))//must a~z or A~Z or 0~9 or . or -
+        {
+            return 0;
+        }
+
+        if( uri [i] == '.')
+        {
+             dot_num++;
+             if((label_len > MAX_CHARACTER_NUM_PER_LABEL) || (0 == label_len)) //Label must be 63 characters or less
+                 return 0;
+             label_len = 0;
+        }
+        else
+        {
+            label_len++;
+        }
+    }
+    if((label_len > MAX_CHARACTER_NUM_PER_LABEL) || (0 == dot_num))//the last label must be 63 characters or less
+        return 0;
+
+    return 1;
+
+}
+
+
+int32_t dns_make(dns_client_t *client, dns_process_t *process, Buffer_Struct *out)
+{
+	int Result;
+	xDNSMessage_t MsgHead;
+    uint8_t *pucStart, *pucByte;
+//    uint16_t usRecordType;
+//    uint16_t usClass = BSP_Swap16(dnsCLASS);
+	if (process->dns_cnt >= MAX_DNS_SERVER)
+	{
+		return -ERROR_PERMISSION_DENIED;
+	}
+	out->Pos = sizeof(xDNSMessage_t) + 6 + process->uri_buf.Pos;
+
+
+	memset(&MsgHead, 0, sizeof(MsgHead));
+	MsgHead.usIdentifier = BSP_Swap16(process->session_id);
+	MsgHead.usFlags = BSP_Swap16(dnsOUTGOING_FLAGS);
+	MsgHead.usQuestions = BSP_Swap16(dnsONE_QUESTION);
+	memcpy(out->Data, &MsgHead, sizeof(MsgHead));
+
+    pucStart = out->Data + sizeof( MsgHead );
+
+    /* Leave a gap for the first length bytes. */
+    pucByte = pucStart + 1;
+
+    /* Copy in the host name. */
+    memcpy( ( char * ) pucByte, process->uri_buf.Data, process->uri_buf.Pos );
+
+    /* Mark the end of the string. */
+    pucByte += process->uri_buf.Pos;
+    *pucByte = 0x00;
+
+    /* Walk the string to replace the '.' characters with byte counts.
+    pucStart holds the address of the byte count.  Walking the string
+    starts after the byte count position. */
+    pucByte = pucStart;
+
+    do
+    {
+        pucByte++;
+
+        while( ( *pucByte != 0x00 ) && ( *pucByte != '.' ) )
+        {
+            pucByte++;
+        }
+
+        /* Fill in the byte count, then move the pucStart pointer up to
+        the found byte position. */
+        *pucStart = ( uint8_t ) ( ( uint32_t ) pucByte - ( uint32_t ) pucStart );
+        ( *pucStart )--;
+
+        pucStart = pucByte;
+
+    } while( *pucByte != 0x00 );
+    pucByte++;
+    /* Finish off the record. */
+    if (client->dns_server[process->dns_cnt].is_ipv6)
+    {
+    	BytesPutBe16(pucByte, dnsTYPE_IPV6);
+    }
+    else
+    {
+    	BytesPutBe16(pucByte, dnsTYPE_IPV4);
+    }
+    pucByte += sizeof( uint16_t );
+    BytesPutBe16(pucByte, dnsCLASS);
+	process->timeout_ms = GetSysTickMS() + DNS_TO_BASE * (process->retry_cnt + 1);
+    return ERROR_NONE;
+}
+
+
+static int32_t dns_check_process(void *pData, void *pParam)
+{
+	dns_process_t *process = (dns_process_t *)pData;
+	Buffer_Struct *uri_buf = (Buffer_Struct *)pParam;
+	if (uri_buf->Pos == process->uri_buf.Pos)
+	{
+		if (!memcmp(uri_buf->Data, process->uri_buf.Data, uri_buf->Pos))
+		{
+			return LIST_FIND;
+		}
+	}
+	return LIST_PASS;
+}
+
+void dns_require(dns_client_t *client, const char *domain_name, uint32_t len, void *param)
+{
+	luat_dns_require_t *require = zalloc(sizeof(luat_dns_require_t));
+	require->uri.Data = domain_name;
+	require->uri.Pos = len;
+	require->uri.MaxLen = len;
+	require->param = param;
+	dns_process_t *process = llist_traversal(&client->process_head, dns_check_process, &require->uri);
+	// if no same proc
+	if (!process)
+	{
+		process = zalloc(sizeof(dns_process_t));
+		Buffer_StaticInit(&process->uri_buf, require->uri.Data, require->uri.Pos);
+		process->uri_buf.Pos = require->uri.Pos;
+		client->session_id++;
+		if (!client->session_id)
+		{
+			client->session_id++;
+		}
+		process->session_id = client->session_id;
+		llist_add_tail(&process->node, &client->process_head);
+	}
+	llist_add_tail(&require->node, &client->require_head);
+}
+
+static int32_t dns_clear_require(void *pData, void *pParam)
+{
+	luat_dns_require_t *require = (luat_dns_require_t *)pData;
+	free(require->uri.Data);
+	return LIST_DEL;
+}
+
+
+static int32_t dns_clear_process(void *pData, void *pParam)
+{
+	dns_process_t *process = (dns_process_t *)pData;
+	if (pParam)
+	{
+		return process->is_done?LIST_DEL:LIST_PASS;
+	}
+	return LIST_DEL;
+}
+
+
+void dns_clear(dns_client_t *client)
+{
+	uint64_t now_time = GetSysTickMS();
+	llist_traversal(&client->process_head, dns_clear_process, NULL);
+	llist_traversal(&client->require_head, dns_clear_require, NULL);
+}
+
+static int32_t dns_find_need_tx_process(void *pData, void *pParam)
+{
+	dns_process_t *process = (dns_process_t *)pData;
+	if (process->timeout_ms < GetSysTickMS())
+	{
+		return LIST_FIND;
+	}
+	return LIST_PASS;
+}
+
+void dns_run(dns_client_t *client, Buffer_Struct *in, Buffer_Struct *out, int *server_cnt)
+{
+	dns_process_t *process;
+	int i;
+	if (llist_empty(&client->process_head) && !llist_empty(&client->require_head))
+	{
+		dns_clear(client);
+		client->is_run = 0;
+		return;
+	}
+	if (in)
+	{
+		xDNSMessage_t MsgHead;
+		while ( (in->Pos + sizeof(MsgHead)) < in->MaxLen)
+		{
+			memcpy(&MsgHead, in->Data + in->Pos, sizeof(MsgHead));
+			MsgHead.usIdentifier = BSP_Swap16(MsgHead.usIdentifier);
+			MsgHead.usFlags = BSP_Swap16(MsgHead.usFlags);
+			in->Pos += sizeof(MsgHead);
+			process = llist_traversal(&client->process_head, dns_find_process, MsgHead.usIdentifier);
+			if (process)
+			{
+				if ( MsgHead.usFlags & 0x8000)
+				{
+					MsgHead.usQuestions = BSP_Swap16(MsgHead.usQuestions);
+					MsgHead.usAnswers = BSP_Swap16(MsgHead.usAnswers);
+					MsgHead.usAuthorityRRs = BSP_Swap16(MsgHead.usAuthorityRRs);
+					MsgHead.usAdditionalRRs = BSP_Swap16(MsgHead.usAdditionalRRs);
+
+					for(i = 0; i < MsgHead.usQuestions; i++)
+					{
+						if (dns_skip_name_field(in) != ERROR_NONE)
+						{
+							goto NET_DNS_RX_OUT;
+						}
+						in->Pos += 4;
+						if (in->Pos >= in->MaxLen)
+						{
+							goto NET_DNS_RX_OUT;
+						}
+					}
+					if (!(MsgHead.usFlags & 0x000f))
+					{
+						if (dns_get_ip(client, in, MsgHead.usAnswers, process))
+						{
+							goto NET_DNS_RX_OUT;
+						}
+					}
+					else
+					{
+						if (dns_get_ip(client, in, MsgHead.usAnswers, NULL))
+						{
+							goto NET_DNS_RX_OUT;
+						}
+					}
+
+					if (dns_get_ip(client, in, MsgHead.usAuthorityRRs, NULL))
+					{
+						goto NET_DNS_RX_OUT;
+					}
+
+					if (dns_get_ip(client, in, MsgHead.usAdditionalRRs, NULL))
+					{
+						goto NET_DNS_RX_OUT;
+					}
+				}
+				else
+				{
+					goto NET_DNS_RX_OUT;
+				}
+
+			}
+		}
+	}
+	else if (out)
+	{
+NET_DNS_TX:
+
+		process = llist_traversal(&client->process_head, dns_find_need_tx_process, NULL);
+		if (!process)
+		{
+			goto NET_DNS_RX_OUT;
+		}
+		if (process->timeout_ms)
+		{
+			process->retry_cnt++;
+			if (process->retry_cnt >= DNS_TRY_MAX)
+			{
+				process->dns_cnt++;
+				if (process->dns_cnt >= MAX_DNS_SERVER)
+				{
+					process->ip_nums = 0;
+					llist_traversal(&client->require_head, dns_set_result, process);
+					goto NET_DNS_TX;
+				}
+			}
+		}
+		while(0xff == client->dns_server[process->dns_cnt].is_ipv6)
+		{
+			process->dns_cnt++;
+			if (process->dns_cnt >= MAX_DNS_SERVER)
+			{
+				process->ip_nums = 0;
+				llist_traversal(&client->require_head, dns_set_result, process);
+				goto NET_DNS_TX;
+			}
+		}
+		DBG("use dns sever %d", process->dns_cnt);
+		process->is_done = 0;
+		OS_InitBuffer(out, 512);
+		dns_make(client, process, out);
+		*server_cnt = process->dns_cnt;
+	}
+
+NET_DNS_RX_OUT:
+	if (!llist_empty(&client->process_head))
+	{
+		llist_traversal(&client->process_head, dns_clear_process, 1);
+	}
+
+	if (llist_empty(&client->process_head) && llist_empty(&client->require_head))
+	{
+		client->is_run = 0;
+		return;
+	}
+	return ;
+}
+
+
 
 #endif
 

+ 26 - 0
components/ethernet/common/dns_def.h

@@ -9,5 +9,31 @@
 #define __ETHERNET_COMMON_DNS_DEF_H__
 
 #define DNS_SERVER_PORT                    (53)
+#define MAX_DNS_SERVER				4
 
+#include "luat_network_adapter.h"
+
+typedef struct
+{
+	llist_head node;
+	Buffer_Struct uri; //动态需要释放
+	luat_dns_ip_result ip_result[MAX_DNS_IP];
+	void *param;
+	int result;
+}luat_dns_require_t;
+
+typedef struct
+{
+	luat_ip_addr_t dns_server[MAX_DNS_SERVER];
+	llist_head process_head;
+	llist_head require_head;
+	uint16_t session_id;
+	uint8_t is_static_dns[MAX_DNS_SERVER];
+	uint8_t is_run;
+}dns_client_t;
+
+uint8_t dns_check_uri(const char *uri, uint32_t uri_len);
+void dns_require(dns_client_t *client, const char *domain_name, uint32_t len, void *param);
+void dns_clear(dns_client_t *client);
+void dns_run(dns_client_t *client, Buffer_Struct *in, Buffer_Struct *out, int *server_cnt);
 #endif /* __ETHERNET_COMMON_DNS_DEF_H__ */

+ 164 - 42
components/ethernet/w5500/w5500.c

@@ -26,7 +26,6 @@ extern void DBG_HexPrintf(void *Data, unsigned int len);
 #define is_write	(1 << 2)
 
 #define MAX_SOCK_NUM				8
-#define MAX_DNS_SERVER				4
 #define SYS_SOCK_ID					0
 
 #define MR_RST                       0x80		/**< reset */
@@ -176,6 +175,7 @@ typedef struct
 {
 	socket_ctrl_t socket[MAX_SOCK_NUM];
 	dhcp_client_info_t dhcp_client;
+	dns_client_t dns_client;
 	uint64_t last_tx_time;
 	uint64_t tag;
 	CBFuncEx_t socket_cb;
@@ -184,7 +184,6 @@ typedef struct
 	uint32_t static_ip; //大端格式存放
 	uint32_t static_submask; //大端格式存放
 	uint32_t static_gateway; //大端格式存放
-	uint32_t static_dns_server[MAX_DNS_SERVER];
 	uint16_t RTR;
 	uint8_t RCR;
 	uint8_t force_arp;
@@ -195,7 +194,6 @@ typedef struct
 	uint8_t irq_pin;
 	uint8_t link_pin;
 	uint8_t speed_status;
-	uint8_t run_dns;
 	uint8_t link_ready;
 	uint8_t ip_ready;
 	uint8_t network_ready;
@@ -204,7 +202,7 @@ typedef struct
 	uint8_t last_udp_send_ok;
 	uint8_t rx_buf[2048 + 8];
 	uint8_t mac[6];
-	uint8_t next_index;
+	uint8_t next_socket_index;
 }w5500_ctrl_t;
 
 static w5500_ctrl_t *prv_w5500_ctrl;
@@ -226,7 +224,7 @@ static int w5500_next_data_cache(void *p, void *u)
 	socket_data_t *pdata = (socket_data_t *)p;
 	if (socket->tag != pdata->tag)
 	{
-		DBG("tag error");
+//		DBG("tag error");
 		free(pdata->data);
 		return LIST_DEL;
 	}
@@ -251,7 +249,7 @@ static void w5500_callback_to_nw_task(w5500_ctrl_t *w5500, uint32_t event_id, ui
 {
 	luat_network_cb_param_t param = {.tag = 0, .param = w5500->user_data};
 	OS_EVENT event = { .ID = event_id, .Param1 = param1, .Param2 = param2, .Param3 = param3};
-	if (event_id > EV_NW_TIMEOUT)
+	if (event_id > EV_NW_DNS_RESULT)
 	{
 		event.Param3 = prv_w5500_ctrl->socket[param1].param;
 		param.tag = prv_w5500_ctrl->socket[param1].tag;
@@ -522,11 +520,14 @@ static int w5500_socket_rx(w5500_ctrl_t *w5500, uint8_t socket_id, uint8_t *data
 
 static void w5500_nw_state(w5500_ctrl_t *w5500)
 {
+	int i;
 	if (w5500->link_ready && w5500->ip_ready)
 	{
 		if (!w5500->network_ready)
 		{
 			w5500->network_ready = 1;
+			dns_clear(&w5500->dns_client);
+			w5500->socket[0].tx_wait_size = 0;	//dns可以继续发送了
 			w5500_callback_to_nw_task(w5500, EV_NW_STATE, 0, 1, 0);
 			DBG("network ready");
 		}
@@ -536,8 +537,16 @@ static void w5500_nw_state(w5500_ctrl_t *w5500)
 		if (w5500->network_ready)
 		{
 			w5500->network_ready = 0;
+			dns_clear(&w5500->dns_client);
 			w5500_callback_to_nw_task(w5500, EV_NW_STATE, 0, 0, 0);
 			DBG("network not ready");
+			for(i = 0; i < MAX_SOCK_NUM; i++)
+			{
+				w5500->socket[i].tag = 0;
+				w5500->socket[i].tx_wait_size = 0;
+				llist_traversal(&w5500->socket[i].tx_head, w5500_del_data_cache, NULL);
+				llist_traversal(&w5500->socket[i].rx_head, w5500_del_data_cache, NULL);
+			}
 		}
 	}
 }
@@ -559,7 +568,7 @@ static void w5500_check_dhcp(w5500_ctrl_t *w5500)
 		memcpy(&temp[W5500_COMMON_MAC0], w5500->dhcp_client.mac, 6);
 		w5500_xfer(w5500, W5500_COMMON_MR, is_write, temp, W5500_COMMON_INTLEVEL0);
 		w5500->dhcp_client.discover_cnt = 0;
-		w5500_ip_state(w5500, 1);
+
 		uIP.u32 = w5500->dhcp_client.ip;
 		DBG("动态IP:%d.%d.%d.%d", uIP.u8[0], uIP.u8[1], uIP.u8[2], uIP.u8[3]);
 		uIP.u32 = w5500->dhcp_client.submask;
@@ -567,23 +576,35 @@ static void w5500_check_dhcp(w5500_ctrl_t *w5500)
 		uIP.u32 = w5500->dhcp_client.gateway;
 		DBG("网关:%d.%d.%d.%d", uIP.u8[0], uIP.u8[1], uIP.u8[2], uIP.u8[3]);
 		DBG("租约时间:%u秒", w5500->dhcp_client.lease_time);
-		if (w5500->static_dns_server[0])
+		int i;
+		for(i = 0; i < MAX_DNS_SERVER; i++)
 		{
-			int i;
-			for(i = 0; i < MAX_DNS_SERVER;i++)
+			if (w5500->dns_client.is_static_dns[i])
 			{
-				uIP.u32 = w5500->static_dns_server[i];
-				DBG("静态DNS%d:%d.%d.%d.%d",i, uIP.u8[0], uIP.u8[1], uIP.u8[2], uIP.u8[3]);
+				goto PRINT_DNS;
 			}
 		}
-		else
+		if (w5500->dhcp_client.dns_server[0])
 		{
-			uIP.u32 = w5500->dhcp_client.dns_server[0];
-			DBG("动态DNS1:%d.%d.%d.%d", uIP.u8[0], uIP.u8[1], uIP.u8[2], uIP.u8[3]);
-			uIP.u32 = w5500->dhcp_client.dns_server[1];
-			DBG("动态DNS2:%d.%d.%d.%d", uIP.u8[0], uIP.u8[1], uIP.u8[2], uIP.u8[3]);
+			w5500->dns_client.dns_server[0].ipv4 = w5500->dhcp_client.dns_server[0];
+			w5500->dns_client.dns_server[0].is_ipv6 = 0;
 		}
 
+		if (w5500->dhcp_client.dns_server[1])
+		{
+			w5500->dns_client.dns_server[1].ipv4 = w5500->dhcp_client.dns_server[1];
+			w5500->dns_client.dns_server[1].is_ipv6 = 0;
+		}
+PRINT_DNS:
+		for(i = 0; i < MAX_DNS_SERVER; i++)
+		{
+			if (w5500->dns_client.dns_server[1].is_ipv6 != 0xff)
+			{
+				uIP.u32 = w5500->dns_client.dns_server[1].ipv4;
+				DBG("DNS%d:%d.%d.%d.%d",i, uIP.u8[0], uIP.u8[1], uIP.u8[2], uIP.u8[3]);
+			}
+		}
+		w5500_ip_state(w5500, 1);
 
 	}
 	if ((!w5500->last_udp_send_ok && w5500->dhcp_client.discover_cnt >= 1) || (w5500->last_udp_send_ok && w5500->dhcp_client.discover_cnt >= 3))
@@ -757,7 +778,16 @@ static void w5500_init_reg(w5500_ctrl_t *w5500)
 		w5500_xfer(w5500, W5500_COMMON_PHY, is_write, temp, 1);
 	}
 	w5500->inter_error = 0;
-	w5500->next_index = 1;
+	w5500->next_socket_index = 1;
+	int i;
+	for(i = 0; i < MAX_DNS_SERVER; i++)
+	{
+		if (!w5500->dns_client.is_static_dns[i])
+		{
+			w5500->dns_client.dns_server[i].is_ipv6 = 0xff;
+		}
+	}
+
 }
 
 static int32_t w5500_dummy_callback(void *pData, void *pParam)
@@ -797,7 +827,9 @@ static socket_data_t * w5500_create_data_node(w5500_ctrl_t *w5500, uint8_t socke
 
 static void w5500_socket_tx_next_data(w5500_ctrl_t *w5500, uint8_t socket_id)
 {
+	W5500_LOCK;
 	socket_data_t *p = llist_traversal(&w5500->socket[socket_id].tx_head, w5500_next_data_cache, &prv_w5500_ctrl->socket[socket_id]);
+	W5500_UNLOCK;
 	if (p)
 	{
 		if (!w5500->socket[socket_id].is_tcp)
@@ -819,6 +851,50 @@ static void w5500_socket_tx_next_data(w5500_ctrl_t *w5500, uint8_t socket_id)
 	}
 }
 
+static int32_t w5500_dns_check_result(void *data, void *param)
+{
+	luat_dns_require_t *require = (luat_dns_require_t *)data;
+	if (require->result != 0)
+	{
+		if (require->result > 0)
+		{
+			luat_dns_ip_result *ip_result = zalloc(sizeof(luat_dns_ip_result) * require->result);
+			int i;
+			for(i = 0; i < require->result; i++)
+			{
+				ip_result[i] = require->ip_result[i];
+			}
+			w5500_callback_to_nw_task(param, EV_NW_DNS_RESULT, require->result, ip_result, require->param);
+		}
+		else
+		{
+			w5500_callback_to_nw_task(param, EV_NW_DNS_RESULT, 0, 0, require->param);
+		}
+		return LIST_DEL;
+	}
+	else
+	{
+		return LIST_PASS;
+	}
+}
+
+static void w5500_dns_tx_next(w5500_ctrl_t *w5500, Buffer_Struct *tx_msg_buf)
+{
+	int i;
+	if (w5500->socket[SYS_SOCK_ID].tx_wait_size) return;
+	dns_run(&w5500->dns_client, NULL, tx_msg_buf, &i);
+	if (tx_msg_buf->Pos)
+	{
+		w5500_socket_connect(w5500, SYS_SOCK_ID, 0, w5500->dns_client.dns_server[i].ipv4, DNS_SERVER_PORT);
+		if (!w5500_socket_tx(w5500, SYS_SOCK_ID, tx_msg_buf->Data, tx_msg_buf->Pos))
+		{
+			w5500->socket[SYS_SOCK_ID].tx_wait_size = 1;
+		}
+		OS_DeInitBuffer(tx_msg_buf);
+		llist_traversal(&w5500->dns_client.require_head, w5500_dns_check_result, w5500);
+	}
+}
+
 static void w5500_sys_socket_callback(w5500_ctrl_t *w5500, uint8_t socket_id, uint8_t event)
 {
 	Buffer_Struct rx_buf;
@@ -836,10 +912,15 @@ static void w5500_sys_socket_callback(w5500_ctrl_t *w5500, uint8_t socket_id, ui
 		if (!socket_id)
 		{
 			w5500->last_udp_send_ok = 1;
+			if (w5500->network_ready)
+			{
+				w5500->socket[SYS_SOCK_ID].tx_wait_size = 0;
+				w5500_dns_tx_next(w5500, &tx_msg_buf);
+			}
 		}
-		if (w5500->network_ready)
+		else if (w5500->network_ready)
 		{
-			if (socket_id) W5500_LOCK;
+			W5500_LOCK;
 			p = llist_traversal(&w5500->socket[socket_id].tx_head, w5500_next_data_cache, &prv_w5500_ctrl->socket[socket_id]);
 			if (p && !p->is_sending)
 			{
@@ -855,12 +936,13 @@ static void w5500_sys_socket_callback(w5500_ctrl_t *w5500, uint8_t socket_id, ui
 				free(p);
 
 			}
+			W5500_UNLOCK;
 			w5500_socket_tx_next_data(w5500, socket_id);
 			if (llist_empty(&w5500->socket[socket_id].tx_head))
 			{
 				w5500->socket[socket_id].tx_wait_size = 0;
 			}
-			if (socket_id) W5500_UNLOCK;
+
 
 		}
 		break;
@@ -932,6 +1014,22 @@ static void w5500_sys_socket_callback(w5500_ctrl_t *w5500, uint8_t socket_id, ui
 
 						break;
 					case DNS_SERVER_PORT:
+						dns_run(&w5500->dns_client, &msg_buf, NULL, &i);
+						llist_traversal(&w5500->dns_client.require_head, w5500_dns_check_result, w5500);
+						if (!w5500->socket[SYS_SOCK_ID].tx_wait_size)
+						{
+							dns_run(&w5500->dns_client, NULL, &tx_msg_buf, &i);
+							if (tx_msg_buf.Pos)
+							{
+								w5500_socket_connect(w5500, SYS_SOCK_ID, 0, w5500->dns_client.dns_server[i].ipv4, DNS_SERVER_PORT);
+								if (!w5500_socket_tx(w5500, SYS_SOCK_ID, tx_msg_buf.Data, tx_msg_buf.Pos))
+								{
+									w5500->socket[SYS_SOCK_ID].tx_wait_size = 1;
+								}
+								OS_DeInitBuffer(&tx_msg_buf);
+							}
+						}
+
 						break;
 					}
 					rx_buf.Pos += 8 + len;
@@ -942,7 +1040,10 @@ static void w5500_sys_socket_callback(w5500_ctrl_t *w5500, uint8_t socket_id, ui
 		break;
 	case Sn_IR_TIMEOUT:
 //		DBG_ERR("socket %d timeout", socket_id);
-		w5500_callback_to_nw_task(w5500, EV_NW_SOCKET_ERROR, socket_id, 0, 0);
+		if (socket_id)
+		{
+			w5500_callback_to_nw_task(w5500, EV_NW_SOCKET_ERROR, socket_id, 0, 0);
+		}
 		break;
 	case Sn_IR_CON:
 		w5500_callback_to_nw_task(w5500, EV_NW_SOCKET_CONNECT_OK, socket_id, 0, 0);
@@ -1063,7 +1164,7 @@ static void w5500_task(void *param)
 		sleep_time = 100;
 		if (w5500->network_ready)
 		{
-			if (!w5500->run_dns && (w5500->link_pin != 0xff))
+			if (!w5500->dns_client.is_run && (w5500->link_pin != 0xff))
 			{
 				sleep_time = 0;
 			}
@@ -1098,21 +1199,29 @@ static void w5500_task(void *param)
 			w5500_link_state(w5500, w5500->rx_buf[3 + W5500_COMMON_PHY] & 0x01);
 			w5500->speed_status = w5500->rx_buf[3 + W5500_COMMON_PHY] & (3 << 1);
 		}
-
-		if (result && w5500->link_ready)
+		if (result)
 		{
-			result = ip4_dhcp_run(&w5500->dhcp_client, NULL, &tx_msg_buf, &remote_ip);
-			w5500_check_dhcp(w5500);
-			if (tx_msg_buf.Pos)
+			if (w5500->network_ready)
 			{
-				w5500_socket_connect(w5500, SYS_SOCK_ID, 0, remote_ip, DHCP_SERVER_PORT);
-				w5500_socket_tx(w5500, SYS_SOCK_ID, tx_msg_buf.Data, tx_msg_buf.Pos);
-				w5500->last_udp_send_ok = 0;
+				w5500_dns_tx_next(w5500, &tx_msg_buf);
+			}
+			else if (w5500->link_ready)
+			{
+				result = ip4_dhcp_run(&w5500->dhcp_client, NULL, &tx_msg_buf, &remote_ip);
+				w5500_check_dhcp(w5500);
+				if (tx_msg_buf.Pos)
+				{
+					w5500_socket_connect(w5500, SYS_SOCK_ID, 0, remote_ip, DHCP_SERVER_PORT);
+					w5500_socket_tx(w5500, SYS_SOCK_ID, tx_msg_buf.Data, tx_msg_buf.Pos);
+					w5500->last_udp_send_ok = 0;
+				}
+				OS_DeInitBuffer(&tx_msg_buf);
 			}
-			OS_DeInitBuffer(&tx_msg_buf);
-
 			continue;
 		}
+
+
+
 		switch(event.ID)
 		{
 		case EV_W5500_IRQ:
@@ -1185,6 +1294,11 @@ static void w5500_task(void *param)
 			w5500_callback_to_nw_task(w5500, EV_NW_SOCKET_LISTEN, event.Param1, 0, 0);
 			break;
 		case EV_W5500_SOCKET_DNS:
+			if (w5500->network_ready)
+			{
+				dns_require(&w5500->dns_client, event.Param1, event.Param2, event.Param3);
+				w5500_dns_tx_next(w5500, &tx_msg_buf);
+			}
 			break;
 		case EV_W5500_RE_INIT:
 			w5500_init_reg(w5500);
@@ -1282,6 +1396,8 @@ void w5500_init(luat_spi_t* spi, uint8_t irq_pin, uint8_t rst_pin, uint8_t link_
 			INIT_LLIST_HEAD(&w5500->socket[i].tx_head);
 			INIT_LLIST_HEAD(&w5500->socket[i].rx_head);
 		}
+		INIT_LLIST_HEAD(&w5500->dns_client.process_head);
+		INIT_LLIST_HEAD(&w5500->dns_client.require_head);
 
 		w5500->dhcp_client.xid = BytesGetBe32(rands);
 		w5500->dhcp_client.state = DHCP_STATE_NOT_WORK;
@@ -1339,10 +1455,10 @@ static int w5500_create_soceket(uint8_t is_tcp, uint64_t *tag, void *param, uint
 	int i, socket_id;
 	socket_id = -1;
 	W5500_LOCK;
-	if (!prv_w5500_ctrl->socket[prv_w5500_ctrl->next_index].in_use)
+	if (!prv_w5500_ctrl->socket[prv_w5500_ctrl->next_socket_index].in_use)
 	{
-		socket_id = prv_w5500_ctrl->next_index;
-		prv_w5500_ctrl->next_index++;
+		socket_id = prv_w5500_ctrl->next_socket_index;
+		prv_w5500_ctrl->next_socket_index++;
 	}
 	else
 	{
@@ -1351,14 +1467,14 @@ static int w5500_create_soceket(uint8_t is_tcp, uint64_t *tag, void *param, uint
 			if (!prv_w5500_ctrl->socket[i].in_use)
 			{
 				socket_id = i;
-				prv_w5500_ctrl->next_index = i + 1;
+				prv_w5500_ctrl->next_socket_index = i + 1;
 				break;
 			}
 		}
 	}
-	if (prv_w5500_ctrl->next_index >= MAX_SOCK_NUM)
+	if (prv_w5500_ctrl->next_socket_index >= MAX_SOCK_NUM)
 	{
-		prv_w5500_ctrl->next_index = 1;
+		prv_w5500_ctrl->next_socket_index = 1;
 	}
 	if (socket_id > 0)
 	{
@@ -1391,6 +1507,8 @@ static int w5500_socket_connect_ex(int socket_id, uint64_t tag,  uint16_t local_
 	llist_traversal(&prv_w5500_ctrl->socket[socket_id].rx_head, w5500_del_data_cache, NULL);
 	W5500_UNLOCK;
 	platform_send_event(prv_w5500_ctrl->task_handle, EV_W5500_SOCKET_CONNECT, socket_id, remote_ip->ipv4, uPV.u32);
+	uPV.u32 = remote_ip->ipv4;
+	DBG("%u.%u.%u.%u", uPV.u8[0], uPV.u8[1], uPV.u8[2], uPV.u8[3]);
 	return 0;
 }
 //作为server绑定一个port,开始监听
@@ -1599,16 +1717,20 @@ static int w5500_user_cmd(int socket_id, uint64_t tag, uint32_t cmd, uint32_t va
 	return 0;
 }
 
-static int w5500_dns(const char *url, uint32_t len, void *user_data)
+static int w5500_dns(const char *domain_name, uint32_t len, void *param, void *user_data)
 {
 	if (user_data != prv_w5500_ctrl) return -1;
-	return -1;
+	char *prv_domain_name = (char *)malloc(len);
+	memcpy(prv_domain_name, domain_name, len);
+	platform_send_event(prv_w5500_ctrl->task_handle, EV_W5500_SOCKET_DNS, prv_domain_name, len, param);
+	return 0;
 }
+
 static int w5500_set_dns_server(uint8_t server_index, luat_ip_addr_t *ip, void *user_data)
 {
 	if (user_data != prv_w5500_ctrl) return -1;
 	if (server_index >= MAX_DNS_SERVER) return -1;
-	prv_w5500_ctrl->static_dns_server[server_index] = ip->ipv4;
+	prv_w5500_ctrl->dns_client.dns_server[server_index] = *ip;
 	return 0;
 }
 static void w5500_socket_set_callback(CBFuncEx_t cb_fun, void *param, void *user_data)

+ 387 - 24
components/network/adapter/luat_network_adapter.c

@@ -39,8 +39,6 @@ typedef struct
 {
 	int last_adapter_index;
 	llist_head dns_cache_head;
-	llist_head dns_require_head;
-	uint16_t session_id;
 	uint8_t is_init;
 }network_info_t;
 
@@ -60,6 +58,22 @@ static network_info_t prv_network = {
 		.is_init = 0,
 };
 
+static uint8_t network_check_ip_same(luat_ip_addr_t *ip1, luat_ip_addr_t *ip2)
+{
+	if (ip1->is_ipv6 != ip2->is_ipv6)
+	{
+		return 0;
+	}
+	if (ip1->is_ipv6)
+	{
+		return !memcmp(ip1->ipv6_u8_addr, ip2->ipv6_u8_addr, 16);
+	}
+	else
+	{
+		return (ip1->ipv4 == ip2->ipv4);
+	}
+}
+
 static int network_base_tx(network_ctrl_t *ctrl, const uint8_t *data, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t remote_port)
 {
 	int result = -1;
@@ -75,14 +89,7 @@ static int network_base_tx(network_ctrl_t *ctrl, const uint8_t *data, uint32_t l
 		}
 		else
 		{
-			if (ctrl->remote_ip.is_ipv6 != 0xff)
-			{
-				result = network_socket_send(ctrl, data, len, flags, &ctrl->remote_ip, ctrl->remote_port);
-			}
-			else
-			{
-				result = network_socket_send(ctrl, data, len, flags, &ctrl->dns_ip[ctrl->dns_ip_cnt], ctrl->remote_port);
-			}
+			result = network_socket_send(ctrl, data, len, flags, ctrl->online_ip, ctrl->remote_port);
 		}
 	}
 	if (result >= 0)
@@ -96,6 +103,120 @@ static int network_base_tx(network_ctrl_t *ctrl, const uint8_t *data, uint32_t l
 	return result;
 }
 
+static int32_t tls_shorttimeout(void *data, void *param)
+{
+	network_ctrl_t *ctrl = (network_ctrl_t *)param;
+	if (!ctrl->tls_mode)
+	{
+		platform_stop_timer(ctrl->tls_long_timer);
+		return 0;
+	}
+	if (0 == ctrl->tls_timer_state)
+	{
+		ctrl->tls_timer_state = 1;
+	}
+	return 0;
+}
+
+static int32_t tls_longtimeout(void *data, void *param)
+{
+	network_ctrl_t *ctrl = (network_ctrl_t *)param;
+	platform_stop_timer(ctrl->tls_short_timer);
+	if (!ctrl->tls_mode)
+	{
+		return 0;
+	}
+	ctrl->tls_timer_state = 2;
+}
+
+static void tls_settimer( void *data, uint32_t int_ms, uint32_t fin_ms )
+{
+	network_ctrl_t *ctrl = (network_ctrl_t *)data;
+	if (!ctrl->tls_mode)
+	{
+		return;
+	}
+	if (!fin_ms)
+	{
+		platform_stop_timer(ctrl->tls_short_timer);
+		platform_stop_timer(ctrl->tls_long_timer);
+		ctrl->tls_timer_state = -1;
+		return ;
+	}
+	platform_start_timer(ctrl->tls_short_timer, int_ms, 0);
+	platform_start_timer(ctrl->tls_long_timer, fin_ms, 0);
+	ctrl->tls_timer_state = 0;
+}
+
+static int tls_gettimer( void *data )
+{
+	network_ctrl_t *ctrl = (network_ctrl_t *)data;
+	if (!ctrl->tls_mode)
+	{
+		return -ERROR_PARAM_INVALID;
+	}
+	return ctrl->tls_timer_state;
+}
+
+static void tls_dbg(void *data, int level,
+        const char *file, int line,
+        const char *str)
+{
+	DBG_Printf("%s %d:%s", file, line, str);
+}
+
+static int tls_send(void *ctx, const unsigned char *buf, size_t len )
+{
+	network_ctrl_t *ctrl = (network_ctrl_t *)ctx;
+	if (!ctrl->tls_mode)
+	{
+		return -ERROR_PERMISSION_DENIED;
+	}
+	if (network_base_tx(ctrl, buf, len, 0, NULL, 0) != len)
+	{
+		return -0x004E;
+	}
+	else
+	{
+		return len;
+	}
+}
+
+static int tls_recv(void *ctx, unsigned char *buf, size_t len )
+{
+#ifdef LUAT_USE_TLS
+	network_ctrl_t *ctrl = (network_ctrl_t *)ctx;
+	luat_ip_addr_t remote_ip;
+	uint16_t remote_port;
+	int Result = -1;
+	if (!ctrl->tls_mode)
+	{
+		return -1;
+	}
+TLS_RECV:
+	Result = network_socket_receive(ctrl, buf, len, 0, &remote_ip, &remote_port);
+
+	if (Result < 0)
+	{
+		return -0x004C;
+	}
+	if (Result > 0)
+	{
+		if (!ctrl->is_tcp)
+		{
+			if ((remote_port == ctrl->remote_port) && network_check_ip_same(&remote_ip, ctrl->online_ip))
+			{
+				goto TLS_RECV;
+			}
+		}
+		return Result;
+	}
+	return MBEDTLS_ERR_SSL_WANT_READ;
+#else
+	return -1;
+#endif
+}
+
 static int network_get_host_by_name(network_ctrl_t *ctrl)
 {
 	ctrl->remote_ip.is_ipv6 = 0xff;
@@ -121,7 +242,15 @@ static int network_get_host_by_name(network_ctrl_t *ctrl)
 	}
 }
 
+static void network_update_dns_cache(network_ctrl_t *ctrl)
+{
+
+}
+
+static void network_get_dns_cache(network_ctrl_t *ctrl)
+{
 
+}
 
 static int network_base_connect(network_ctrl_t *ctrl, luat_ip_addr_t *remote_ip)
 {
@@ -152,6 +281,7 @@ static int network_base_connect(network_ctrl_t *ctrl, luat_ip_addr_t *remote_ip)
 	{
 		network_user_cmd(ctrl, NW_CMD_AUTO_HEART_TIME, ctrl->tcp_keep_idle);
 	}
+
 	return network_socket_connect(ctrl, remote_ip);
 }
 
@@ -232,21 +362,33 @@ static int network_state_wait_dns(network_ctrl_t *ctrl, OS_EVENT *event, network
 			return -1;
 		}
 		break;
-	case EV_NW_SOCKET_DNS_RESULT:
-		if (event->Param2)
+	case EV_NW_DNS_RESULT:
+		if (event->Param1)
 		{
 			//更新dns cache
+			ctrl->dns_ip = event->Param2;
+			ctrl->dns_ip_nums = event->Param1;
+			network_update_dns_cache(ctrl);
 		}
+		else
+		{
+			ctrl->dns_ip_nums = 0;
+			network_get_dns_cache(ctrl);
+			if (!ctrl->dns_ip_nums)
+			{
+				return -1;
+			}
 
+		}
 		ctrl->dns_ip_cnt = 0;
-		if (network_base_connect(ctrl, &ctrl->dns_ip[ctrl->dns_ip_cnt]))
+		if (network_base_connect(ctrl, &ctrl->dns_ip[ctrl->dns_ip_cnt].ip))
 		{
-			ctrl->state = NW_STATE_OFF_LINE;
+			network_socket_force_close(ctrl);
 			return -1;
 		}
 		else
 		{
-			ctrl->state = NW_STATE_WAIT_DNS;
+			ctrl->state = NW_STATE_CONNECTING;
 			return 1;
 		}
 	default:
@@ -260,10 +402,31 @@ static int network_state_connecting(network_ctrl_t *ctrl, OS_EVENT *event, netwo
 	switch(event->ID)
 	{
 	case EV_NW_RESET:
+		return -1;
 	case EV_NW_SOCKET_ERROR:
 	case EV_NW_SOCKET_REMOTE_CLOSE:
 	case EV_NW_SOCKET_CLOSE_OK:
-		return -1;
+		if (ctrl->remote_ip.is_ipv6 != 0xff)
+		{
+			return -1;
+		}
+		DBG("dns ip %d no connect!", ctrl->dns_ip_cnt);
+		ctrl->dns_ip_cnt++;
+		if (ctrl->dns_ip_cnt >= ctrl->dns_ip_nums)
+		{
+			return -1;
+		}
+		if (network_base_connect(ctrl, &ctrl->dns_ip[ctrl->dns_ip_cnt].ip))
+		{
+			network_socket_force_close(ctrl);
+			return -1;
+		}
+		else
+		{
+			ctrl->state = NW_STATE_CONNECTING;
+			return 1;
+		}
+		break;
 	case EV_NW_STATE:
 		if (!event->Param2)
 		{
@@ -280,6 +443,16 @@ static int network_state_connecting(network_ctrl_t *ctrl, OS_EVENT *event, netwo
 	case EV_NW_SOCKET_CONNECT_OK:
 		if (ctrl->tls_mode)
 		{
+			mbedtls_ssl_free(ctrl->ssl);
+			memset(ctrl->ssl, 0, sizeof(mbedtls_ssl_context));
+			mbedtls_ssl_setup(ctrl->ssl, ctrl->config);
+			ctrl->ssl->f_set_timer = tls_settimer;
+			ctrl->ssl->f_get_timer = tls_gettimer;
+			ctrl->ssl->p_timer = ctrl;
+			ctrl->ssl->p_bio = ctrl;
+			ctrl->ssl->f_send = tls_send;
+			ctrl->ssl->f_recv = tls_recv;
+
 			ctrl->state = NW_STATE_SHAKEHAND;
 	    	do
 	    	{
@@ -321,6 +494,7 @@ static int network_state_shakehand(network_ctrl_t *ctrl, OS_EVENT *event, networ
 	case EV_NW_STATE:
 		if (!event->Param2)
 		{
+			ctrl->need_close = 1;
 			return -1;
 		}
 		break;
@@ -343,13 +517,22 @@ static int network_state_shakehand(network_ctrl_t *ctrl, OS_EVENT *event, networ
     			break;
     		default:
     			DBG_ERR("0x%x, %d", -result, ctrl->ssl->state);
+    			ctrl->need_close = 1;
     			return -1;
     		}
     	}while(ctrl->ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER);
     	ctrl->state = NW_STATE_ONLINE;
     	if (NW_WAIT_TX_OK == ctrl->wait_target_state)
     	{
+    		if (!ctrl->cache_data)
+    		{
+    			ctrl->need_close = 1;
+    			return -1;
+    		}
     		int result = mbedtls_ssl_write(ctrl->ssl, ctrl->cache_data, ctrl->cache_len);
+    		free(ctrl->cache_data);
+    		ctrl->cache_data = NULL;
+    		ctrl->cache_len = 0;
     	    if (result < 0)
     	    {
     	    	DBG("%08x", -result);
@@ -563,7 +746,7 @@ static int32_t network_default_socket_callback(void *data, void *param)
 	NW_LOCK;
 	if (event->ID > EV_NW_TIMEOUT)
 	{
-		if (ctrl && (ctrl->tag == cb_param->tag))
+		if (ctrl && ((ctrl->tag == cb_param->tag) || (event->ID == EV_NW_DNS_RESULT)))
 		{
 			if (ctrl->auto_mode)
 			{
@@ -770,8 +953,6 @@ int network_register_adapter(uint8_t adapter_index, network_adapter_info *info,
 	if (!prv_network.is_init)
 	{
 		INIT_LLIST_HEAD(&prv_network.dns_cache_head);
-		INIT_LLIST_HEAD(&prv_network.dns_require_head);
-		prv_network.session_id = 1;
 		prv_network.is_init = 0;
 	}
 
@@ -822,6 +1003,11 @@ void network_release_ctrl(network_ctrl_t *ctrl)
 		if (&adapter->ctrl_table[i] == ctrl)
 		{
 			network_deinit_tls(ctrl);
+			if (ctrl->cache_data)
+			{
+				free(ctrl->cache_data);
+				ctrl->cache_data = NULL;
+			}
 			adapter->ctrl_busy[i] = 0;
 			break;
 		}
@@ -917,6 +1103,7 @@ int network_socket_connect(network_ctrl_t *ctrl, luat_ip_addr_t *remote_ip)
 {
 	network_adapter_t *adapter = &prv_adapter_table[ctrl->adapter_index];
 	ctrl->is_server_mode = 0;
+	ctrl->online_ip = remote_ip;
 	return adapter->opt->socket_connect(ctrl->socket_id, ctrl->tag, ctrl->local_port, remote_ip, ctrl->remote_port, adapter->user_data);
 }
 
@@ -1016,10 +1203,8 @@ int network_user_cmd(network_ctrl_t *ctrl,  uint32_t cmd, uint32_t value)
 int network_dns(network_ctrl_t *ctrl)
 {
 	network_adapter_t *adapter = &prv_adapter_table[ctrl->adapter_index];
-	luat_dns_require_t *require = zalloc(sizeof(luat_dns_require_t));
-	require->uri.Data = ctrl->domain_name;
-	require->uri.Pos = ctrl->domain_name_len;
-	return adapter->opt->dns(require->uri.Data, require->uri.Pos, adapter->user_data);
+
+	return adapter->opt->dns(ctrl->domain_name, ctrl->domain_name_len, ctrl, adapter->user_data);
 }
 
 int network_get_local_ip_info(network_ctrl_t *ctrl, luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, void *user_data)
@@ -1037,6 +1222,13 @@ void network_force_close_socket(network_ctrl_t *ctrl)
 	}
 	ctrl->need_close = 0;
 	ctrl->socket_id = -1;
+	if (ctrl->dns_ip)
+	{
+		free(ctrl->dns_ip);
+		ctrl->dns_ip = NULL;
+	}
+	ctrl->dns_ip_cnt = 0;
+	ctrl->dns_ip_nums = 0;
 }
 
 void network_clean_invaild_socket(uint8_t adapter_index)
@@ -1065,6 +1257,154 @@ void network_clean_invaild_socket(uint8_t adapter_index)
 	NW_UNLOCK;
 }
 
+
+
+static int tls_verify(void *ctx, mbedtls_x509_crt *crt, int Index, uint32_t *Result)
+{
+	network_ctrl_t *ctrl = (network_ctrl_t *)ctx;
+	DBG("%d, %08x", Index, *Result);
+	return 0;
+}
+
+int network_set_psk_info(network_ctrl_t *ctrl,
+		const unsigned char *psk, size_t psk_len,
+		const unsigned char *psk_identity, size_t psk_identity_len)
+{
+#ifdef LUAT_USE_TLS
+	if (!ctrl->tls_mode)
+	{
+		return -ERROR_PERMISSION_DENIED;
+	}
+
+//	DBG("%.*s, %.*s", psk_len, psk, psk_identity_len, psk_identity);
+	int ret = mbedtls_ssl_conf_psk( ctrl->config,
+			psk, psk_len, psk_identity, psk_identity_len );
+	if (ret != 0)
+	{
+		DBG("0x%x", -ret);
+		return -ERROR_OPERATION_FAILED;
+	}
+	return ERROR_NONE;
+#else
+	return -1;
+#endif
+}
+
+int network_set_server_cert(network_ctrl_t *ctrl, const unsigned char *cert, size_t cert_len)
+{
+#ifdef LUAT_USE_TLS
+	int ret;
+	if (!ctrl->tls_mode)
+	{
+		return -ERROR_PERMISSION_DENIED;
+	}
+    ret = mbedtls_x509_crt_parse( ctrl->ca_cert, cert, cert_len);
+	if (ret != 0)
+	{
+		DBG("%08x", -ret);
+		return -ERROR_OPERATION_FAILED;
+	}
+
+	return ERROR_NONE;
+#else
+	return -1;
+#endif
+}
+
+int network_set_client_cert(network_ctrl_t *ctrl,
+		const unsigned char *cert, size_t certLen,
+        const unsigned char *key, size_t keylen,
+        const unsigned char *pwd, size_t pwdlen)
+{
+#ifdef LUAT_USE_TLS
+	int ret;
+	mbedtls_x509_crt *client_cert = NULL;
+	mbedtls_pk_context *pkey = NULL;
+	if (!ctrl->tls_mode)
+	{
+		return -ERROR_PERMISSION_DENIED;
+	}
+	client_cert = zalloc(sizeof(mbedtls_x509_crt));
+	pkey = zalloc(sizeof(mbedtls_pk_context));
+	if (!client_cert || !pkey)
+	{
+		goto ERROR_OUT;
+	}
+    ret = mbedtls_x509_crt_parse( client_cert, cert, certLen );
+    if (ret != 0)
+    {
+    	DBG("%08x", -ret);
+    	goto ERROR_OUT;
+    }
+    ret = mbedtls_pk_parse_key( pkey, key, keylen, pwd, pwdlen );
+    if (ret != 0)
+    {
+		DBG("%08x", -ret);
+		goto ERROR_OUT;
+    }
+    ret = mbedtls_ssl_conf_own_cert( ctrl->config, client_cert, pkey );
+    if (ret != 0)
+    {
+		DBG("%08x", -ret);
+		goto ERROR_OUT;
+    }
+    return ERROR_NONE;
+ERROR_OUT:
+	if (client_cert) free(client_cert);
+	if (pkey) free(pkey);
+	return -1;
+#else
+	return -1;
+#endif
+}
+
+int network_cert_verify_result(network_ctrl_t *ctrl)
+{
+#ifdef LUAT_USE_TLS
+	if (!ctrl->tls_mode)
+	{
+		return -1;
+	}
+	return mbedtls_ssl_get_verify_result(ctrl->ssl);
+#else
+	return -1;
+#endif
+}
+
+static int tls_random( void *p_rng,
+        unsigned char *output, size_t output_len )
+{
+	platform_random(output, output_len);
+	return 0;
+}
+
+void network_init_tls(network_ctrl_t *ctrl, int verify_mode)
+{
+#ifdef LUAT_USE_TLS
+	ctrl->tls_mode = 1;
+	if (!ctrl->ssl)
+	{
+		ctrl->ssl = zalloc(sizeof(mbedtls_ssl_context));
+		ctrl->ca_cert = zalloc(sizeof(mbedtls_x509_crt));
+		ctrl->config = zalloc(sizeof(mbedtls_ssl_config));
+		mbedtls_ssl_config_defaults( ctrl->config, MBEDTLS_SSL_IS_CLIENT, ctrl->is_tcp?MBEDTLS_SSL_TRANSPORT_STREAM:MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT);
+		ctrl->config->authmode = verify_mode;
+		ctrl->config->hs_timeout_min = 20000;
+		ctrl->config->f_rng = tls_random;
+		ctrl->config->p_rng = NULL;
+		ctrl->config->f_dbg = tls_dbg;
+		ctrl->config->p_dbg = NULL;
+		ctrl->config->f_vrfy = tls_verify;
+		ctrl->config->p_vrfy = ctrl;
+		ctrl->config->ca_chain = ctrl->ca_cert;
+		ctrl->config->read_timeout = ctrl->tcp_timeou_ms;
+	    ctrl->tls_long_timer = platform_create_timer(tls_longtimeout, ctrl, NULL);
+	    ctrl->tls_short_timer = platform_create_timer(tls_shorttimeout, ctrl, NULL);
+	}
+	ctrl->tls_timer_state = -1;
+#endif
+}
+
 void network_deinit_tls(network_ctrl_t *ctrl)
 {
 #ifdef LUAT_USE_TLS
@@ -1167,7 +1507,18 @@ int network_connect(network_ctrl_t *ctrl, const char *domain_name, uint32_t doma
 	{
 		return -1;
 	}
+
 	NW_LOCK;
+	if (ctrl->dns_ip)
+	{
+		free(ctrl->dns_ip);
+		ctrl->dns_ip = NULL;
+	}
+	if (ctrl->cache_data)
+	{
+		free(ctrl->cache_data);
+		ctrl->cache_data = NULL;
+	}
 	ctrl->need_close = 0;
 	ctrl->domain_name = domain_name;
 	ctrl->domain_name_len = domain_name_len;
@@ -1242,7 +1593,13 @@ int network_listen(network_ctrl_t *ctrl, uint16_t local_port, uint32_t timeout_m
 
 int network_close(network_ctrl_t *ctrl, uint32_t timeout_ms)
 {
+
 	NW_LOCK;
+	if (ctrl->cache_data)
+	{
+		free(ctrl->cache_data);
+		ctrl->cache_data = NULL;
+	}
 	uint8_t old_state = ctrl->state;
 	ctrl->auto_mode = 1;
 	ctrl->need_close = 0;
@@ -1340,7 +1697,13 @@ int network_tx(network_ctrl_t *ctrl, const uint8_t *data, uint32_t len, int flag
 		if (ctrl->tls_need_reshakehand)
 		{
 			ctrl->tls_need_reshakehand = 0;
-			ctrl->cache_data = data;
+			if (ctrl->cache_data)
+			{
+				free(ctrl->cache_data);
+				ctrl->cache_data = NULL;
+			}
+			ctrl->cache_data = malloc(len);
+			memcpy(ctrl->cache_data, data, len);
 			ctrl->cache_len = len;
 	    	mbedtls_ssl_session_reset(ctrl->ssl);
 	    	do

+ 16 - 23
components/network/adapter/luat_network_adapter.h

@@ -15,20 +15,21 @@
 #include "mbedtls/sha1.h"
 #endif
 
-#define MAX_URI_DNS_IP		(4)	//每个URL最多保留4个IP
+#define MAX_DNS_IP		(4)	//每个URL最多保留4个IP
 
 enum
 {
 	EV_NW_RESET = USER_EVENT_ID_START + 0x1000000,
 	EV_NW_STATE,
 	EV_NW_TIMEOUT,
+	EV_NW_DNS_RESULT,
 	EV_NW_SOCKET_TX_OK,
 	EV_NW_SOCKET_RX_NEW,
 	EV_NW_SOCKET_RX_FULL,
 	EV_NW_SOCKET_CLOSE_OK,
 	EV_NW_SOCKET_REMOTE_CLOSE,
 	EV_NW_SOCKET_CONNECT_OK,
-	EV_NW_SOCKET_DNS_RESULT,
+
 	EV_NW_SOCKET_ERROR,
 	EV_NW_SOCKET_LISTEN,
 	EV_NW_SOCKET_NEW_CONNECT,	//作为server接收到新的connect,只有允许accept操作的才有,否则直接上报CONNECT_OK
@@ -89,7 +90,7 @@ typedef struct
 
 typedef struct
 {
-	uint64_t ttl_end;
+	uint32_t ttl_end;
 	luat_ip_addr_t ip;
 }luat_dns_ip_result;
 
@@ -99,16 +100,10 @@ typedef struct
 	/* data */
 	llist_head node;
 	Buffer_Struct uri;
-	luat_dns_ip_result result[MAX_URI_DNS_IP];
+	luat_dns_ip_result result[MAX_DNS_IP];
+	uint8_t ip_nums;
 }luat_dns_cache_t;
 
-typedef struct
-{
-	llist_head node;
-	Buffer_Struct uri;
-	uint16_t session_id;
-}luat_dns_require_t;
-
 typedef struct
 {
 	uint64_t tx_size;
@@ -125,30 +120,27 @@ typedef struct
 	void *socket_param;			//一般用来存放network_ctrl本身,用于快速查找
 	HANDLE	task_handle;
 	HANDLE timer;
-#ifdef LUAT_USE_TLS
 	HANDLE tls_short_timer;
 	HANDLE tls_long_timer;
-#endif
 	uint32_t tcp_keep_idle;
 	int socket_id;
 	const char *domain_name;
 	uint32_t domain_name_len;
 	luat_ip_addr_t remote_ip;
-	luat_ip_addr_t *dns_ip;
+	luat_dns_ip_result *dns_ip;
+	luat_ip_addr_t *online_ip;
 	uint16_t remote_port;
 	uint16_t local_port;
-#ifdef LUAT_USE_TLS
 	const uint8_t *cache_data;
 	uint32_t cache_len;
 	int tls_timer_state;
-	uint32_t tls_send_timeout_ms;
+	uint32_t tcp_timeou_ms;
 	uint8_t tls_mode;
     uint8_t tls_need_reshakehand;
-    uint8_t tls_init_done;
-#endif
     uint8_t need_close;
     uint8_t new_rx_flag;
     uint8_t dns_ip_cnt;
+    uint8_t dns_ip_nums;
     uint8_t tcp_keep_alive;
 	uint8_t tcp_keep_interval;
 	uint8_t tcp_keep_cnt;
@@ -221,12 +213,13 @@ typedef struct
 	//非posix的socket,用这个根据实际硬件设置参数
 	int (*user_cmd)(int socket_id, uint64_t tag, uint32_t cmd, uint32_t value, void *user_data);
 
-	int (*dns)(const char *domain_name, uint32_t len, void *user_data);
+	int (*dns)(const char *domain_name, uint32_t len, void *param,  void *user_data);
 	int (*set_dns_server)(uint8_t server_index, luat_ip_addr_t *ip, void *user_data);
 	int (*get_local_ip_info)(luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, void *user_data);
 	//所有网络消息都是通过cb_fun回调
-	//cb_fun回调时第一个参数为OS_EVENT,包含了socket的必要信息,第二个是luat_network_cb_param_t,其中的param是这里传入的param
-	//OS_EVENT ID为EV_NW_XXX,param1是socket id param2是各自参数 param3是
+	//cb_fun回调时第一个参数为OS_EVENT,包含了socket的必要信息,第二个是luat_network_cb_param_t,其中的param是这里传入的param(就是适配器序号)
+	//OS_EVENT ID为EV_NW_XXX,param1是socket id param2是各自参数 param3是create_soceket传入的socket_param(就是network_ctrl *)
+	//dns结果是特别的,ID为EV_NW_SOCKET_DNS_RESULT,param1是获取到的IP数据量,0就是失败了,param2是ip组,动态分配的, param3是dns传入的param(就是network_ctrl *)
 	void (*socket_set_callback)(CBFuncEx_t cb_fun, void *param, void *user_data);
 
 	char *name;
@@ -337,13 +330,13 @@ int network_set_psk_info(network_ctrl_t *ctrl,
 /*
  * TLS设置验证服务器的证书,可以不用
  */
-int network_set_server_cert(network_ctrl_t *ctrl, const unsigned char *cert, size_t certLen);
+int network_set_server_cert(network_ctrl_t *ctrl, const unsigned char *cert, size_t cert_len);
 /*
  * TLS设置验证客户端的证书,只有双向认证才需要,而且一般只有金融领域才需要
  */
 int network_set_client_cert(network_ctrl_t *ctrl,
 		const unsigned char *cert, size_t certLen,
-        const unsigned char *pkey, size_t pkeylen,
+        const unsigned char *key, size_t keylen,
         const unsigned char *pwd, size_t pwdlen);
 /*
  * 获取证书验证结果