summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuxueli <[email protected]>2021-07-07 18:04:52 +0800
committerliuxueli <[email protected]>2021-07-07 18:04:52 +0800
commit72769f0d4306b82c382bae45d7bede26153839ce (patch)
treec847b3e54db1ee0364f66d0caf36c7192044ab47
parente083fec85105194eb946966e02c4d298b966be00 (diff)
TSG-6935: 修复DNS解析层处理TCP的DNS流量,返回DROPME时未调用业务层CLOSE状态导致内存泄漏v2.0.13
-rw-r--r--src/dns.cpp38
1 files changed, 26 insertions, 12 deletions
diff --git a/src/dns.cpp b/src/dns.cpp
index 7e2f58d..77b06b2 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -1663,10 +1663,10 @@ int parse_dns_protocol(struct streaminfo *a_stream, unsigned char opstate, char
unsigned long long register_flag = dns_register_flag;
save_dns_business_info_t *context = (save_dns_business_info_t *)(*pme);
- if(payload_len < 12 )
+ if(payload_len<12 || payload==NULL)
{
FS_operate(g_dns_proto_info.stat_handle, g_dns_proto_info.fild_id[ERR_PKT], 0, FS_OP_ADD, 1);
- MESA_handle_runtime_log(g_dns_proto_info.logger, RLOG_LV_FATAL, "parse_dns_protocol", "tuple4: %s payload_len < 12", printaddr(&a_stream->addr, thread_seq));
+ MESA_handle_runtime_log(g_dns_proto_info.logger, RLOG_LV_DEBUG, "parse_dns_protocol", "tuple4: %s payload_len<12 or payload==NULL", printaddr(&a_stream->addr, thread_seq));
return APP_STATE_DROPME;
}
@@ -1694,10 +1694,12 @@ int parse_dns_protocol(struct streaminfo *a_stream, unsigned char opstate, char
if(context->session_state&SESSION_STATE_PENDING)
{
session_state = SESSION_STATE_CLOSE;
+ context->session_state=SESSION_STATE_CLOSE;
}
else
{
session_state = SESSION_STATE_PENDING|SESSION_STATE_DATA|SESSION_STATE_CLOSE;
+ context->session_state=SESSION_STATE_CLOSE;
}
}
@@ -1851,12 +1853,18 @@ char DNS_UDP_ENTRY(struct streaminfo *a_udp, void **pme, int thread_seq, void *a
state=parse_dns_protocol(a_udp, a_udp->opstate, payload, payload_len, pme, thread_seq, a_packet);
break;
case OP_STATE_CLOSE:
- state=callback_dns_business_plug(a_udp, pme, NULL, DNS_ALL, SESSION_STATE_CLOSE, thread_seq, a_packet);
+ state=parse_dns_protocol(a_udp, a_udp->opstate, payload, payload_len, pme, thread_seq, a_packet);
break;
}
if(state&APP_STATE_DROPME || a_udp->opstate==OP_STATE_CLOSE)
{
+ save_dns_business_info_t *context=(save_dns_business_info_t *)(*pme);
+ if((context->session_state&SESSION_STATE_CLOSE)!=SESSION_STATE_CLOSE)
+ {
+ state=callback_dns_business_plug(a_udp, pme, NULL, DNS_ALL, SESSION_STATE_CLOSE, thread_seq, a_packet);
+ }
+
dictator_free(thread_seq, *pme);
*pme = NULL;
}
@@ -1871,7 +1879,7 @@ char DNS_TCP_ENTRY(struct streaminfo *a_tcp, void **pme, int thread_seq, void *a
char *payload = NULL;
char state=APP_STATE_GIVEME;
struct tcpdetail* tcp_detail = (struct tcpdetail*)a_tcp->pdetail;
- save_dns_business_info_t *dns_pme=(save_dns_business_info_t*)*pme;
+ save_dns_business_info_t *context=(save_dns_business_info_t*)*pme;
if(!check_port(a_tcp->addr, DNS_PORT))
{
@@ -1894,8 +1902,8 @@ char DNS_TCP_ENTRY(struct streaminfo *a_tcp, void **pme, int thread_seq, void *a
{
*pme = dictator_malloc(thread_seq, sizeof(save_dns_business_info_t));
memset(*pme, 0, sizeof(save_dns_business_info_t));
- dns_pme = (save_dns_business_info_t *)*pme;
- dns_pme->skip_len=2;
+ context = (save_dns_business_info_t *)*pme;
+ context->skip_len=2;
}
/* no break here!!!! */
@@ -1919,17 +1927,17 @@ char DNS_TCP_ENTRY(struct streaminfo *a_tcp, void **pme, int thread_seq, void *a
if(tcp_detail->serverbytes <= 2)
{
- dns_pme->skip_len -= payload_len;
+ context->skip_len -= payload_len;
break;
}
else
{
- if(dns_pme->skip_len!=0)
+ if(context->skip_len!=0)
{
- payload_len -= dns_pme->skip_len;
- payload += dns_pme->skip_len;
+ payload_len -= context->skip_len;
+ payload += context->skip_len;
- dns_pme->skip_len=0;
+ context->skip_len=2; //https://datatracker.ietf.org/doc/html/rfc7766#section-8
}
}
@@ -1944,12 +1952,18 @@ char DNS_TCP_ENTRY(struct streaminfo *a_tcp, void **pme, int thread_seq, void *a
state=parse_dns_protocol(a_tcp, a_tcp->opstate, payload, payload_len, pme, thread_seq, a_packet);
break;
case OP_STATE_CLOSE:
- state=callback_dns_business_plug(a_tcp, pme, NULL, DNS_UNKOWN, SESSION_STATE_CLOSE, thread_seq, a_packet);
+ state=parse_dns_protocol(a_tcp, a_tcp->opstate, payload, payload_len, pme, thread_seq, a_packet);
break;
}
if(state&APP_STATE_DROPME || a_tcp->opstate==OP_STATE_CLOSE)
{
+ save_dns_business_info_t *context=(save_dns_business_info_t *)(*pme);
+ if((context->session_state&SESSION_STATE_CLOSE)!=SESSION_STATE_CLOSE)
+ {
+ state=callback_dns_business_plug(a_tcp, pme, NULL, DNS_ALL, SESSION_STATE_CLOSE, thread_seq, a_packet);
+ }
+
dictator_free(thread_seq, *pme);
*pme = NULL;
}