Skip to content

Commit d592d66

Browse files
author
yutianzuo
committed
dns name compression a pointer bug
1 parent 0a10276 commit d592d66

File tree

2 files changed

+94
-24
lines changed

2 files changed

+94
-24
lines changed

nativesock/src/main/cpp/netutils/dns.h

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ class DNSQuery final : public SimpleUdpClient
308308
continue;
309309
}
310310
int ip = *((int *) (&str_respones[index_inner]));
311-
std::string str_ip = NetHelper::int32_to_string_addr(ip);
311+
std::string str_ip = NetHelper::ipv4_to_string_addr(ip);
312312
ips.emplace_back(std::move(str_ip));
313313
index_inner += 4;
314314
}
@@ -319,27 +319,27 @@ class DNSQuery final : public SimpleUdpClient
319319
return ret;
320320
}
321321

322-
bool analyze_queries(int &index, const std::string &str_respones, std::string &str_host)
322+
int getName(const std::string &str_respones, int index_inner, std::string &str_host)
323323
{
324-
bool ret = false;
325-
int index_inner = index;
326-
str_host.clear();
327-
FUNCTION_BEGIN ;
324+
int jump = 0;
325+
while (str_respones[index_inner] != 0)
326+
{
328327
if (!check_index(index_inner, str_respones))
329328
{
330-
FUNCTION_LEAVE;
329+
index_inner = str_respones.size();
330+
break;
331331
}
332-
333-
int jump = 0;
334-
while (str_respones[index_inner] != 0)
332+
if (jump == 0)
335333
{
336-
if (!check_index(index_inner, str_respones))
337-
{
338-
break;
339-
}
340-
if (jump == 0)
334+
jump = (unsigned char) str_respones[index_inner++];
335+
}
336+
else
337+
{
338+
if (jump & 0xc0) //encounter a pointer
341339
{
342-
jump = (unsigned char) str_respones[index_inner++];
340+
//just move on
341+
++index_inner;
342+
jump = 0;
343343
}
344344
else
345345
{
@@ -352,11 +352,37 @@ class DNSQuery final : public SimpleUdpClient
352352
jump = 0;
353353
}
354354
}
355-
if (str_host.size())
355+
}
356+
if (str_host.size())
357+
{
358+
str_host.erase(str_host.size() - 1);
359+
}
360+
++index_inner; //jump '\0'
361+
return index_inner;
362+
}
363+
364+
bool analyze_queries(int &index, const std::string &str_respones, std::string &str_host)
365+
{
366+
bool ret = false;
367+
int index_inner = index;
368+
str_host.clear();
369+
FUNCTION_BEGIN ;
370+
if (!check_index(index_inner, str_respones))
371+
{
372+
FUNCTION_LEAVE;
373+
}
374+
375+
if (str_respones[index_inner] & 0xc0) //name is a pointer
356376
{
357-
str_host.erase(str_host.size() - 1);
377+
int index_pointer = (((~0xc0 & 0xff) & str_respones[index_inner]) << 8) |
378+
(str_respones[index_inner + 1] & 0xff);
379+
getName(str_respones, index_pointer, str_host);
380+
index_inner += 2;
381+
}
382+
else
383+
{ //name can be labels combines pointer, which is not handled
384+
index_inner = getName(str_respones, index_inner, str_host);
358385
}
359-
++index_inner; //jump '\0'
360386

361387
if (!check_index(index_inner + 4, str_respones))
362388
{
@@ -472,7 +498,9 @@ class DNSQuery final : public SimpleUdpClient
472498

473499
bool check_index(int index, const std::string &respones)
474500
{
475-
if (index >= respones.size())
501+
//如果index溢出,index将变为一个负数,但是respones.size()返回的是一个size_t(unsigned int),比较会隐式转换
502+
//将index这个int提升为unsigned int, 这时会是一个巨大的数。从而可能带来意外的结果。这里不判断index>=0,结果也是正确的。
503+
if (index >= 0 && index >= respones.size())
476504
{
477505
return false;
478506
}

nativesock/src/main/cpp/netutils/errorhunter.h

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,42 @@
2020
#include "../toolbox/string_x.h"
2121

2222

23+
inline std::string get_error_info(const std::string& msg)
24+
{
25+
std::ostringstream ss;
26+
ss << "error(";
27+
ss << msg;
28+
ss << ") in";
29+
ss << __FILE__;
30+
ss << ", line:";
31+
ss << __LINE__;
32+
return ss.str();
33+
}
34+
35+
inline std::string get_errorno_info(const std::string& msg)
36+
{
37+
std::ostringstream ss;
38+
ss << "error(";
39+
ss << msg;
40+
ss << ") errorno(";
41+
ss << std::strerror(errno);
42+
ss << ") in";
43+
ss << __FILE__;
44+
ss << ", line:";
45+
ss << __LINE__;
46+
return ss.str();
47+
}
48+
49+
50+
2351

2452
///////////////////////////////////
2553
#ifndef NORMAL_ERROR_MSG
26-
#define NORMAL_ERROR_MSG(msg) (std::ostringstream() << "error(" << msg << ") in " << __FILE__ << ", line:" << __LINE__).str()
54+
#define NORMAL_ERROR_MSG(msg) get_error_info(msg)
2755
#endif
2856

2957
#ifndef NORMAL_ERROR_NUM
30-
#define NORMAL_ERROR_NUM(msg) (std::ostringstream() << "error(" << msg << ") errorno(" << std::strerror(errno) << ") in "\
31-
<< __FILE__ << ", line:" << __LINE__).str()
58+
#define NORMAL_ERROR_NUM(msg) get_errorno_info(msg)
3259
#endif
3360

3461
#ifndef STD_COUT_ERRORMSG
@@ -51,12 +78,27 @@ class NetHelper final
5178
{
5279
public:
5380
NetHelper() = delete;
54-
static std::string int32_to_string_addr(int addr)
81+
static std::string ipv4_to_string_addr(int addr)
5582
{
5683
in_addr addrin = {0};
5784
addrin.s_addr = addr;
5885
return stringxa(::inet_ntoa(addrin));
5986
}
87+
88+
static std::string safe_ipv4_to_string_addr(int addr)
89+
{
90+
const int len = 32;
91+
char buff[len] = {0};
92+
return stringxa(::inet_ntop(AF_INET, &addr, buff, len));
93+
}
94+
95+
static std::string safe_ipv6_to_string_addr(const in6_addr* addr)
96+
{
97+
const int len = 64;
98+
char buff[len] = {0};
99+
return stringxa(::inet_ntop(AF_INET6, addr, buff, len));
100+
}
101+
60102
};
61103

62104
#endif //SIMPLESOCKET_ERRORHUNTER_H

0 commit comments

Comments
 (0)