Fix getpeername memory problem

This commit is contained in:
Kirigaya Kazuto 2018-06-05 13:13:06 +08:00
parent fc9e9578d9
commit 23dbae63e4
2 changed files with 32 additions and 24 deletions

View File

@ -75,6 +75,19 @@ public:
} }
} _init_winsock2_2_obj; } _init_winsock2_2_obj;
static inline const char* get_family_name(int family)
{
switch (family)
{
case AF_INET:
return "AF_INET";
case AF_INET6:
return "AF_INET6";
default:
return "Unknown";
}
}
struct vsock::_impl struct vsock::_impl
{ {
int sfd; int sfd;
@ -276,23 +289,30 @@ int sock::setrecvtime(int Second)
//forgive me, but writing code in hospital is really not a good experience. //forgive me, but writing code in hospital is really not a good experience.
using _sock_getname_callback_t = decltype(getsockname); using _sock_getname_callback_t = decltype(getsockname);
union _sock_getname_pack
{
sockaddr saddr;
sockaddr_in saddr4;
sockaddr_in6 saddr6;
};
static int _sock_getname_call(int sfd,std::string& ip,int& port,_sock_getname_callback_t fn) static int _sock_getname_call(int sfd,std::string& ip,int& port,_sock_getname_callback_t fn)
{ {
struct sockaddr saddr; _sock_getname_pack pack;
socklen_t saddrlen=sizeof(saddr); socklen_t saddrlen=sizeof(pack);
memset(&saddr,0,saddrlen); memset(&pack,0,saddrlen);
int ret=fn(sfd,&saddr,&saddrlen); int ret=fn(sfd,&pack.saddr,&saddrlen);
if(ret<0) return ret; //don't bother errno. stop here. if(ret<0) return ret; //don't bother errno. stop here.
if (saddr.sa_family == AF_INET) if (pack.saddr.sa_family == AF_INET)
{ {
struct sockaddr_in* paddr = (sockaddr_in*)&saddr; struct sockaddr_in* paddr = &pack.saddr4;
char ip_buff[64] = { 0 }; char ip_buff[64] = { 0 };
const char* pret = inet_ntop(AF_INET, paddr, ip_buff, 64); const char* pret = inet_ntop(AF_INET, paddr, ip_buff, 64);
if (pret) if (pret)
{ {
ip = std::string(ip_buff); ip = std::string(ip_buff);
port = ntohs(paddr->sin_port); port = ntohs(paddr->sin_port);
return GSOCK_OK; return 0;
} }
else else
{ {
@ -300,16 +320,16 @@ static int _sock_getname_call(int sfd,std::string& ip,int& port,_sock_getname_ca
return GSOCK_ERROR_NTOP; return GSOCK_ERROR_NTOP;
} }
} }
else if (saddr.sa_family == AF_INET6) else if (pack.saddr.sa_family == AF_INET6)
{ {
struct sockaddr_in6* paddr = (sockaddr_in6*)&saddr; struct sockaddr_in6* paddr = &pack.saddr6;
char ip_buff[128] = { 0 }; char ip_buff[128] = { 0 };
const char* pret = inet_ntop(AF_INET6, paddr, ip_buff, 128); const char* pret = inet_ntop(AF_INET6, paddr, ip_buff, 128);
if (pret) if (pret)
{ {
ip = std::string(ip_buff); ip = std::string(ip_buff);
port = ntohs(paddr->sin6_port); port = ntohs(paddr->sin6_port);
return GSOCK_OK; return 1;
} }
else else
{ {
@ -521,19 +541,6 @@ struct udpsock::_impl
} }
}; };
static inline const char* get_family_name(int family)
{
switch (family)
{
case AF_INET:
return "AF_INET";
case AF_INET6:
return "AF_INET6";
default:
return "Unknown";
}
}
udpsock::udpsock(int use_family) : _pp(new _impl) udpsock::udpsock(int use_family) : _pp(new _impl)
{ {

View File

@ -62,7 +62,8 @@ public:
int setrecvtime(int Second); int setrecvtime(int Second);
/// Return: /// Return:
/// 0: Success. No Error. /// 0: Success. No Error. IPv4
/// 1: Success. No Error. IPv6
/// -1: getlocalname() or getpeername() call error. See errno. /// -1: getlocalname() or getpeername() call error. See errno.
/// -2: Socket not created. /// -2: Socket not created.
int getlocal(std::string& IPStr,int& Port); int getlocal(std::string& IPStr,int& Port);