mirror of
https://gitee.com/TarsCloud/TarsCpp.git
synced 2024-12-22 22:16:38 +08:00
add supports ipv6 code
This commit is contained in:
parent
ed4727a484
commit
49b96f7a74
@ -16,6 +16,8 @@
|
||||
|
||||
#include "servant/EndpointInfo.h"
|
||||
#include "servant/TarsLogger.h"
|
||||
#include "servant/NetworkUtil.h"
|
||||
#include "util/tc_socket.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
@ -27,9 +29,10 @@ EndpointInfo::EndpointInfo()
|
||||
, _weight(-1)
|
||||
, _weighttype(0)
|
||||
, _authType(0)
|
||||
, _isIPv6(false)
|
||||
{
|
||||
_setDivision.clear();
|
||||
memset(&_addr,0,sizeof(struct sockaddr_in));
|
||||
memset(&_addr,0,sizeof(_addr));
|
||||
}
|
||||
|
||||
EndpointInfo::EndpointInfo(const string& host, uint16_t port, EndpointInfo::EType type, int32_t grid, const string & setDivision, int qos, int weight, unsigned int weighttype, int authType)
|
||||
@ -43,6 +46,7 @@ EndpointInfo::EndpointInfo(const string& host, uint16_t port, EndpointInfo::ETyp
|
||||
, _weighttype(weighttype)
|
||||
, _authType(authType)
|
||||
{
|
||||
_isIPv6 = TC_Socket::addressIsIPv6(host);
|
||||
try
|
||||
{
|
||||
if(_weighttype == 0)
|
||||
@ -59,7 +63,14 @@ EndpointInfo::EndpointInfo(const string& host, uint16_t port, EndpointInfo::ETyp
|
||||
_weight = (_weight > 100 ? 100 : _weight);
|
||||
}
|
||||
|
||||
NetworkUtil::getAddress(_host, _port, _addr);
|
||||
if (_isIPv6)
|
||||
{
|
||||
NetworkUtil::getAddress(_host, _port, _addr.in6);
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkUtil::getAddress(_host, _port, _addr.in);
|
||||
}
|
||||
|
||||
_cmpDesc = createCompareDesc();
|
||||
|
||||
@ -139,7 +150,12 @@ uint16_t EndpointInfo::port() const
|
||||
|
||||
const struct sockaddr_in& EndpointInfo::addr() const
|
||||
{
|
||||
return _addr;
|
||||
return _addr.in;
|
||||
}
|
||||
|
||||
const struct sockaddr * EndpointInfo::addrPtr() const
|
||||
{
|
||||
return _isIPv6 ? (struct sockaddr *)&_addr.in6 : (struct sockaddr *)&_addr.in;
|
||||
}
|
||||
|
||||
EndpointInfo::EType EndpointInfo::type() const
|
||||
|
@ -216,6 +216,21 @@ void QueryEpBase::setObjName(const string & sObjName)
|
||||
}
|
||||
}
|
||||
|
||||
bool isRealEndpoint(const string & s, const string & s1)
|
||||
{
|
||||
if (s1.empty())
|
||||
return true;
|
||||
|
||||
const string delim = " \t\n\r";
|
||||
string::size_type beg;
|
||||
string::size_type end = 0;
|
||||
|
||||
beg = s1.find_first_not_of(delim, end);
|
||||
if (s1[beg] != 't' && s1[beg] != 'u' && s1[beg] != 's')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void QueryEpBase::setEndpoints(const string & sEndpoints, set<EndpointInfo> & setEndpoints)
|
||||
{
|
||||
if(sEndpoints == "")
|
||||
@ -227,7 +242,7 @@ void QueryEpBase::setEndpoints(const string & sEndpoints, set<EndpointInfo> & se
|
||||
bool bFirstWeightType = true;
|
||||
unsigned int iWeightType = 0;
|
||||
|
||||
vector<string> vEndpoints = TC_Common::sepstr<string>(sEndpoints, ":", false);
|
||||
vector<string> vEndpoints = TC_Common::sepstr<string>(sEndpoints, ":", false, isRealEndpoint);
|
||||
|
||||
for (size_t i = 0; i < vEndpoints.size(); ++i)
|
||||
{
|
||||
|
@ -25,18 +25,12 @@
|
||||
using namespace std;
|
||||
using namespace tars;
|
||||
|
||||
int NetworkUtil::createSocket(bool udp, bool isLocal/* = false*/)
|
||||
int NetworkUtil::createSocket(bool udp, bool isLocal/* = false*/, bool isIpv6/* = false*/)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (udp)
|
||||
{
|
||||
fd = socket((isLocal ? PF_LOCAL : PF_INET), SOCK_DGRAM, IPPROTO_UDP);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = socket((isLocal ? PF_LOCAL : PF_INET), SOCK_STREAM, IPPROTO_TCP);
|
||||
}
|
||||
int domain = isLocal ? PF_LOCAL : (isIpv6 ? PF_INET6 : PF_INET);
|
||||
int type = udp ? SOCK_DGRAM : SOCK_STREAM;
|
||||
int protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
int fd = socket(domain, type, protocol);
|
||||
|
||||
if (fd == INVALID_SOCKET)
|
||||
{
|
||||
@ -127,6 +121,17 @@ void NetworkUtil::doBind(int fd, struct sockaddr_in& addr)
|
||||
getsockname(fd, reinterpret_cast<struct sockaddr*>(&addr), &len);
|
||||
}
|
||||
|
||||
void NetworkUtil::doBind(int fd, const struct sockaddr *addr, socklen_t len)
|
||||
{
|
||||
if (bind(fd, addr, len) == SOCKET_ERROR)
|
||||
{
|
||||
closeSocketNoThrow(fd);
|
||||
ostringstream os;
|
||||
os << "doBind ex:(" << errorToString(errno) << ")" << __FILE__ << ":" << __LINE__;
|
||||
throw TarsNetSocketException(os.str());
|
||||
}
|
||||
}
|
||||
|
||||
bool NetworkUtil::doConnect(int fd, const struct sockaddr_in& addr)
|
||||
{
|
||||
bool bConnected = false;
|
||||
@ -146,6 +151,19 @@ bool NetworkUtil::doConnect(int fd, const struct sockaddr_in& addr)
|
||||
return bConnected;
|
||||
}
|
||||
|
||||
bool NetworkUtil::doConnect(int fd, const struct sockaddr *addr, socklen_t len)
|
||||
{
|
||||
int iRet = ::connect(fd, addr, len);
|
||||
|
||||
if (iRet == -1 && errno != EINPROGRESS)
|
||||
{
|
||||
::close(fd);
|
||||
throw TarsNetConnectException(strerror(errno));
|
||||
}
|
||||
|
||||
return iRet == 0 ? true : false;
|
||||
}
|
||||
|
||||
void NetworkUtil::getAddress(const string& host, int port, struct sockaddr_in& addr)
|
||||
{
|
||||
memset(&addr, 0, sizeof(struct sockaddr_in));
|
||||
@ -188,6 +206,46 @@ void NetworkUtil::getAddress(const string& host, int port, struct sockaddr_in& a
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NetworkUtil::getAddress(const string& host, int port, struct sockaddr_in6& addr)
|
||||
{
|
||||
#define RETRY_TIMES (5)
|
||||
struct addrinfo *res = NULL;
|
||||
struct addrinfo hints;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_INET6;
|
||||
|
||||
ostringstream os;
|
||||
os << port;
|
||||
|
||||
int ret = -1;
|
||||
int retry = RETRY_TIMES;
|
||||
do
|
||||
{
|
||||
ret = getaddrinfo(host.c_str(), os.str().c_str(), &hints, &res);
|
||||
}
|
||||
while (NULL == res && ret == EAI_AGAIN && --retry >= 0);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ostringstream ex;
|
||||
ex << "DNSException ex:(" << errorToString(errno) << ":" << gai_strerror(ret) << ":" << ret << ")" <<
|
||||
"|" << host << ":" << port << "| at " << __FUNCTION__ << ":" << __LINE__;
|
||||
if (res)
|
||||
{
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
throw TarsNetSocketException(ex.str());
|
||||
}
|
||||
assert(res);
|
||||
assert(res->ai_family == PF_INET6);
|
||||
memcpy(&addr, res->ai_addr, sizeof(addr));
|
||||
freeaddrinfo(res);
|
||||
#undef RETRY_TIMES
|
||||
}
|
||||
|
||||
string NetworkUtil::errorToString(int error)
|
||||
{
|
||||
return strerror(error);
|
||||
|
@ -89,16 +89,17 @@ void Transceiver::connect()
|
||||
|
||||
if (_ep.type() == EndpointInfo::UDP)
|
||||
{
|
||||
fd = NetworkUtil::createSocket(true);
|
||||
fd = NetworkUtil::createSocket(true, false, _ep.isIPv6());
|
||||
NetworkUtil::setBlock(fd, false);
|
||||
_connStatus = eConnected;
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = NetworkUtil::createSocket(false);
|
||||
fd = NetworkUtil::createSocket(false, false, _ep.isIPv6());
|
||||
NetworkUtil::setBlock(fd, false);
|
||||
|
||||
bool bConnected = NetworkUtil::doConnect(fd, _ep.addr());
|
||||
socklen_t len = _ep.isIPv6() ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
|
||||
bool bConnected = NetworkUtil::doConnect(fd, _ep.addrPtr(), len);
|
||||
if(bConnected)
|
||||
{
|
||||
setConnected();
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define __TARS_ENDPOINT_INFO_H_
|
||||
|
||||
#include "servant/Global.h"
|
||||
#include "servant/NetworkUtil.h"
|
||||
#include "util/tc_socket.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -122,6 +122,13 @@ public:
|
||||
*/
|
||||
const struct sockaddr_in& addr() const;
|
||||
|
||||
/**
|
||||
* Get ipv4 or ipv6 struct sockaddr
|
||||
*
|
||||
* @return const struct sockaddr *
|
||||
*/
|
||||
const struct sockaddr * addrPtr() const;
|
||||
|
||||
/**
|
||||
* 返回端口类型
|
||||
*
|
||||
@ -148,6 +155,12 @@ public:
|
||||
*/
|
||||
int authType() const { return _authType; }
|
||||
|
||||
/**
|
||||
* @brief is ipv6 socket or not
|
||||
* @return true if is ipv6
|
||||
*/
|
||||
bool isIPv6() const { return _isIPv6; }
|
||||
|
||||
/**
|
||||
* 等于
|
||||
* @param r
|
||||
@ -233,7 +246,11 @@ private:
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
struct sockaddr_in _addr;
|
||||
union
|
||||
{
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr_in6 in6;
|
||||
} _addr;
|
||||
|
||||
/**
|
||||
* 比较的地址字符串描述
|
||||
@ -249,6 +266,11 @@ private:
|
||||
* 认证类型
|
||||
*/
|
||||
int _authType;
|
||||
|
||||
/**
|
||||
* _host is IPv6 or not
|
||||
*/
|
||||
bool _isIPv6;
|
||||
};
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ struct NetworkUtil
|
||||
static const int INVALID_SOCKET = -1;
|
||||
static const int SOCKET_ERROR = -1;
|
||||
|
||||
static int createSocket(bool, bool isLocal = false);
|
||||
static int createSocket(bool, bool isLocal = false, bool isIpv6 = false);
|
||||
|
||||
static void closeSocketNoThrow(int);
|
||||
|
||||
@ -53,10 +53,16 @@ struct NetworkUtil
|
||||
|
||||
static void doBind(int, struct sockaddr_in&);
|
||||
|
||||
static void doBind(int, const struct sockaddr *, socklen_t);
|
||||
|
||||
static bool doConnect(int, const struct sockaddr_in&);
|
||||
|
||||
static bool doConnect(int, const struct sockaddr *, socklen_t);
|
||||
|
||||
static void getAddress(const std::string&, int, struct sockaddr_in&);
|
||||
|
||||
static void getAddress(const std::string&, int, struct sockaddr_in6&);
|
||||
|
||||
static std::string errorToString(int);
|
||||
};
|
||||
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
typedef TC_LoopQueue<MapStatMicMsg*> stat_queue;
|
||||
|
||||
const static int MAX_MASTER_NAME_LEN = 127;
|
||||
const static int MAX_MASTER_IP_LEN = 20;
|
||||
const static int MAX_MASTER_IP_LEN = 50;
|
||||
const static int MAX_REPORT_SIZE = 1400; //上报的最大大小限制
|
||||
const static int MIN_REPORT_SIZE = 500; //上报的最小大小限制
|
||||
const static int STAT_PROTOCOL_LEN = 100; //一次stat mic上报纯协议部分占用大小,用来控制udp大小防止超MTU
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
_weight = l._weight;
|
||||
_weighttype = l._weighttype;
|
||||
_authType = l._authType;
|
||||
_isIPv6 = l._isIPv6;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,6 +120,7 @@ public:
|
||||
_weight = l._weight;
|
||||
_weighttype = l._weighttype;
|
||||
_authType = l._authType;
|
||||
_isIPv6 = l._isIPv6;
|
||||
}
|
||||
|
||||
return *this;
|
||||
@ -132,7 +134,9 @@ public:
|
||||
*/
|
||||
bool operator == (const TC_Endpoint& l)
|
||||
{
|
||||
return (_host == l._host && _port == l._port && _timeout == l._timeout && _type == l._type && _grid == l._grid && _qos == l._qos && _weight == l._weight && _weighttype == l._weighttype && _authType == l._authType);
|
||||
return (_host == l._host && _port == l._port && _timeout == l._timeout && _type == l._type &&
|
||||
_grid == l._grid && _qos == l._qos && _weight == l._weight && _weighttype == l._weighttype &&
|
||||
_authType == l._authType && _isIPv6 == l._isIPv6);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -255,6 +259,12 @@ public:
|
||||
*/
|
||||
bool isUnixLocal() const { return _port == 0; }
|
||||
|
||||
/**
|
||||
* @brief is ipv6 socket or not
|
||||
* @return true if is ipv6
|
||||
*/
|
||||
bool isIPv6() const { return _isIPv6; }
|
||||
|
||||
/**
|
||||
* @brief 获取认证类型
|
||||
*/
|
||||
@ -356,6 +366,11 @@ protected:
|
||||
* 鉴权类型
|
||||
*/
|
||||
int _authType;
|
||||
|
||||
/**
|
||||
* _host is ipv6 or not
|
||||
*/
|
||||
bool _isIPv6;
|
||||
};
|
||||
|
||||
/*************************************TC_ClientSocket**************************************/
|
||||
@ -397,6 +412,7 @@ public:
|
||||
_ip = sIp;
|
||||
_port = iPort;
|
||||
_timeout = iTimeout;
|
||||
_isIPv6 = TC_Socket::addressIsIPv6(sIp);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -450,6 +466,11 @@ protected:
|
||||
* 超时时间, 毫秒
|
||||
*/
|
||||
int _timeout;
|
||||
|
||||
/**
|
||||
* _ip is ipv6 or not
|
||||
*/
|
||||
int _isIPv6;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -241,6 +241,7 @@ public:
|
||||
template<typename T>
|
||||
static T strto(const string &sStr, const string &sDefault);
|
||||
|
||||
typedef bool (*depthJudge)(const string& str1, const string& str2);
|
||||
/**
|
||||
* @brief 解析字符串,用分隔符号分隔,保存在vector里
|
||||
*
|
||||
@ -255,10 +256,11 @@ public:
|
||||
* @param sStr 输入字符串
|
||||
* @param sSep 分隔字符串(每个字符都算为分隔符)
|
||||
* @param withEmpty true代表空的也算一个元素, false时空的过滤
|
||||
* @param depthJudge 对分割后的字符再次进行判断
|
||||
* @return 解析后的字符vector
|
||||
*/
|
||||
template<typename T>
|
||||
static vector<T> sepstr(const string &sStr, const string &sSep, bool withEmpty = false);
|
||||
static vector<T> sepstr(const string &sStr, const string &sSep, bool withEmpty = false, depthJudge judge = nullptr);
|
||||
|
||||
/**
|
||||
* @brief T型转换成字符串,只要T能够使用ostream对象用<<重载,即可以被该函数支持
|
||||
@ -639,45 +641,56 @@ T TC_Common::strto(const string &sStr, const string &sDefault)
|
||||
|
||||
|
||||
template<typename T>
|
||||
vector<T> TC_Common::sepstr(const string &sStr, const string &sSep, bool withEmpty)
|
||||
vector<T> TC_Common::sepstr(const string &sStr, const string &sSep, bool withEmpty, TC_Common::depthJudge judge)
|
||||
{
|
||||
vector<T> vt;
|
||||
|
||||
string::size_type pos = 0;
|
||||
string::size_type pos1 = 0;
|
||||
int pos_tmp = -1;
|
||||
|
||||
while(true)
|
||||
{
|
||||
string s;
|
||||
string s1;
|
||||
pos1 = sStr.find_first_of(sSep, pos);
|
||||
if(pos1 == string::npos)
|
||||
{
|
||||
if(pos + 1 <= sStr.length())
|
||||
{
|
||||
s = sStr.substr(pos);
|
||||
s = sStr.substr(-1 != pos_tmp ? pos_tmp : pos);
|
||||
s1 = "";
|
||||
}
|
||||
}
|
||||
else if(pos1 == pos)
|
||||
else if(pos1 == pos && (pos1 + 1 == sStr.length()))
|
||||
{
|
||||
s = "";
|
||||
s1 = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
s = sStr.substr(pos, pos1 - pos);
|
||||
s = sStr.substr(-1 != pos_tmp ? pos_tmp : pos, pos1 - (-1 != pos_tmp ? pos_tmp : pos));
|
||||
s1 = sStr.substr(pos1 + 1);
|
||||
if (-1 == pos_tmp)
|
||||
pos_tmp = pos;
|
||||
pos = pos1;
|
||||
}
|
||||
|
||||
if(withEmpty)
|
||||
if (nullptr == judge || judge(s, s1))
|
||||
{
|
||||
vt.push_back(strto<T>(s));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!s.empty())
|
||||
if(withEmpty)
|
||||
{
|
||||
T tmp = strto<T>(s);
|
||||
vt.push_back(tmp);
|
||||
vt.push_back(strto<T>(s));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!s.empty())
|
||||
{
|
||||
T tmp = strto<T>(s);
|
||||
vt.push_back(tmp);
|
||||
}
|
||||
}
|
||||
pos_tmp = -1;
|
||||
}
|
||||
|
||||
if(pos1 == string::npos)
|
||||
|
@ -1474,7 +1474,7 @@ public:
|
||||
* 新连接建立
|
||||
* @param fd
|
||||
*/
|
||||
bool accept(int fd);
|
||||
bool accept(int fd, int domain = AF_INET);
|
||||
|
||||
/**
|
||||
* 绑定端口
|
||||
|
@ -433,7 +433,7 @@ public:
|
||||
* @throws TC_Socket_Exception
|
||||
* @return 本地所有ip
|
||||
*/
|
||||
static vector<string> getLocalHosts();
|
||||
static vector<string> getLocalHosts(int domain = AF_INET);
|
||||
|
||||
/**
|
||||
* @brief 设置socket方式.
|
||||
@ -464,6 +464,30 @@ public:
|
||||
*/
|
||||
static void parseAddr(const string &sAddr, struct in_addr &stAddr);
|
||||
|
||||
/**
|
||||
* @brief 解析地址, 从字符串(ipv6或域名), 解析到in6_addr结构.
|
||||
*
|
||||
* @param sAddr 字符串
|
||||
* @param stAddr 地址
|
||||
* @throws TC_Socket_Exception
|
||||
* @return
|
||||
*/
|
||||
static void parseAddr(const string &sAddr, struct in6_addr &stAddr);
|
||||
|
||||
/**
|
||||
* @brief: Determine whether an address is ipv6 by including the character ':'
|
||||
* if address is a domain name, return default(not use now)
|
||||
* @param addr: ip address or domain name
|
||||
* @param def_value: if address is a domain name, return default(not use now)
|
||||
* @return: return true if addr is ipv6, false by ipv4, and default by domain name
|
||||
*/
|
||||
static bool addressIsIPv6(const string& addr, bool def_value = false)
|
||||
{
|
||||
#define IPv6_ADDRESS_CHAR ':'
|
||||
return (addr.find(IPv6_ADDRESS_CHAR) != string::npos) ? true : false;
|
||||
#undef IPv6_ADDRESS_CHAR
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绑定.
|
||||
*
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "util/tc_clientsocket.h"
|
||||
#include "util/tc_epoller.h"
|
||||
#include "util/tc_common.h"
|
||||
#include "util/tc_socket.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
@ -33,6 +34,7 @@ TC_Endpoint::TC_Endpoint()
|
||||
_weight = -1;
|
||||
_weighttype = 0;
|
||||
_authType = 0;
|
||||
_isIPv6 = false;
|
||||
}
|
||||
|
||||
void TC_Endpoint::init(const string& host, int port, int timeout, int type, int grid, int qos, int weight, unsigned int weighttype, int authType)
|
||||
@ -59,6 +61,8 @@ void TC_Endpoint::init(const string& host, int port, int timeout, int type, int
|
||||
}
|
||||
|
||||
_authType = authType;
|
||||
|
||||
_isIPv6 = TC_Socket::addressIsIPv6(_host);
|
||||
}
|
||||
|
||||
void TC_Endpoint::parse(const string &str)
|
||||
@ -239,6 +243,7 @@ void TC_Endpoint::parse(const string &str)
|
||||
{
|
||||
const_cast<string&>(_host) = "0.0.0.0";
|
||||
}
|
||||
_isIPv6 = TC_Socket::addressIsIPv6(_host);
|
||||
|
||||
if (_authType < 0)
|
||||
_authType = 0;
|
||||
@ -256,15 +261,7 @@ int TC_TCPClient::checkSocket()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(_port == 0)
|
||||
{
|
||||
_socket.createSocket(SOCK_STREAM, AF_LOCAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_socket.createSocket(SOCK_STREAM, AF_INET);
|
||||
|
||||
}
|
||||
_socket.createSocket(SOCK_STREAM, _port ? (_isIPv6 ? AF_INET6 : AF_INET) : AF_LOCAL);
|
||||
|
||||
//设置非阻塞模式
|
||||
_socket.setblock(false);
|
||||
@ -631,14 +628,7 @@ int TC_UDPClient::checkSocket()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(_port == 0)
|
||||
{
|
||||
_socket.createSocket(SOCK_DGRAM, AF_LOCAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_socket.createSocket(SOCK_DGRAM, AF_INET);
|
||||
}
|
||||
_socket.createSocket(SOCK_DGRAM, _port ? (_isIPv6 ? AF_INET6 : AF_INET) : AF_LOCAL);
|
||||
}
|
||||
catch(TC_Socket_Exception &ex)
|
||||
{
|
||||
|
@ -630,7 +630,7 @@ TC_EpollServer::NetThread::Connection::Connection(TC_EpollServer::BindAdapter *p
|
||||
|
||||
_iLastRefreshTime = TNOW;
|
||||
|
||||
_sock.init(fd, true, AF_INET);
|
||||
_sock.init(fd, true, pBindAdapter->_ep.isIPv6() ? AF_INET6 : AF_INET);
|
||||
}
|
||||
|
||||
TC_EpollServer::NetThread::Connection::Connection(BindAdapter *pBindAdapter, int fd)
|
||||
@ -651,7 +651,7 @@ TC_EpollServer::NetThread::Connection::Connection(BindAdapter *pBindAdapter, int
|
||||
{
|
||||
_iLastRefreshTime = TNOW;
|
||||
|
||||
_sock.init(fd, false, AF_INET);
|
||||
_sock.init(fd, false, pBindAdapter->_ep.isIPv6() ? AF_INET6 : AF_INET);
|
||||
}
|
||||
|
||||
TC_EpollServer::NetThread::Connection::Connection(BindAdapter *pBindAdapter)
|
||||
@ -1583,7 +1583,7 @@ TC_EpollServer::BindAdapterPtr TC_EpollServer::NetThread::getBindAdapter(const s
|
||||
|
||||
void TC_EpollServer::NetThread::bind(const TC_Endpoint &ep, TC_Socket &s)
|
||||
{
|
||||
int type = ep.isUnixLocal()?AF_LOCAL:AF_INET;
|
||||
int type = ep.isUnixLocal() ? AF_LOCAL : ep.isIPv6() ? AF_INET6 : AF_INET;
|
||||
|
||||
if(ep.isTcp())
|
||||
{
|
||||
@ -1698,11 +1698,13 @@ void TC_EpollServer::NetThread::terminate()
|
||||
_epoller.mod(_shutdown.getfd(), H64(ET_CLOSE), EPOLLOUT);
|
||||
}
|
||||
|
||||
bool TC_EpollServer::NetThread::accept(int fd)
|
||||
bool TC_EpollServer::NetThread::accept(int fd, int domain)
|
||||
{
|
||||
struct sockaddr_in stSockAddr;
|
||||
struct sockaddr_in stSockAddr4;
|
||||
struct sockaddr_in6 stSockAddr6;
|
||||
|
||||
socklen_t iSockAddrSize = sizeof(sockaddr_in);
|
||||
socklen_t iSockAddrSize = (AF_INET6 == domain) ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);
|
||||
struct sockaddr *stSockAddr = (AF_INET6 == domain) ? (struct sockaddr *)&stSockAddr6 : (struct sockaddr *)&stSockAddr4;
|
||||
|
||||
TC_Socket cs;
|
||||
|
||||
@ -1711,9 +1713,9 @@ bool TC_EpollServer::NetThread::accept(int fd)
|
||||
//接收连接
|
||||
TC_Socket s;
|
||||
|
||||
s.init(fd, false, AF_INET);
|
||||
s.init(fd, false, domain);
|
||||
|
||||
int iRetCode = s.accept(cs, (struct sockaddr *) &stSockAddr, iSockAddrSize);
|
||||
int iRetCode = s.accept(cs, stSockAddr, iSockAddrSize);
|
||||
|
||||
if (iRetCode > 0)
|
||||
{
|
||||
@ -1721,14 +1723,12 @@ bool TC_EpollServer::NetThread::accept(int fd)
|
||||
|
||||
uint16_t port;
|
||||
|
||||
char sAddr[INET_ADDRSTRLEN] = "\0";
|
||||
char sAddr[INET6_ADDRSTRLEN] = "\0";
|
||||
|
||||
struct sockaddr_in *p = (struct sockaddr_in *)&stSockAddr;
|
||||
|
||||
inet_ntop(AF_INET, &p->sin_addr, sAddr, sizeof(sAddr));
|
||||
inet_ntop(domain, (AF_INET6 == domain) ? (const void *)&stSockAddr6.sin6_addr : (const void *)&stSockAddr4.sin_addr, sAddr, sizeof(sAddr));
|
||||
|
||||
ip = sAddr;
|
||||
port = ntohs(p->sin_port);
|
||||
port = (AF_INET6 == domain) ? ntohs(stSockAddr6.sin6_port) : ntohs(stSockAddr4.sin_port);
|
||||
|
||||
debug("accept [" + ip + ":" + TC_Common::tostr(port) + "] [" + TC_Common::tostr(cs.getfd()) + "] incomming");
|
||||
|
||||
@ -2085,7 +2085,7 @@ void TC_EpollServer::NetThread::run()
|
||||
bool ret;
|
||||
do
|
||||
{
|
||||
ret = accept(ev.data.u32);
|
||||
ret = accept(ev.data.u32, it->second->_ep.isIPv6() ? AF_INET6 : AF_INET);
|
||||
}while(ret);
|
||||
}
|
||||
}
|
||||
|
@ -75,21 +75,19 @@ void TC_Socket::createSocket(int iSocketType, int iDomain)
|
||||
|
||||
void TC_Socket::getPeerName(string &sPeerAddress, uint16_t &iPeerPort)
|
||||
{
|
||||
assert(_iDomain == AF_INET);
|
||||
assert(_iDomain == AF_INET && _iDomain == AF_INET6);
|
||||
|
||||
struct sockaddr stPeer;
|
||||
bzero(&stPeer, sizeof(struct sockaddr));
|
||||
socklen_t iPeerLen = sizeof(sockaddr);
|
||||
char sAddr[INET6_ADDRSTRLEN] = "\0";
|
||||
struct sockaddr_in stPeer4;
|
||||
struct sockaddr_in6 stPeer6;
|
||||
struct sockaddr *stPeer = (AF_INET6 == _iDomain) ? (struct sockaddr *)&stPeer6 : (struct sockaddr *)&stPeer4;
|
||||
socklen_t iPeerLen = (AF_INET6 == _iDomain) ? sizeof(stPeer6) : sizeof(stPeer4);
|
||||
|
||||
getPeerName(&stPeer, iPeerLen);
|
||||
|
||||
char sAddr[INET_ADDRSTRLEN] = "\0";
|
||||
struct sockaddr_in *p = (struct sockaddr_in *)&stPeer;
|
||||
|
||||
inet_ntop(_iDomain, &p->sin_addr, sAddr, sizeof(sAddr));
|
||||
|
||||
sPeerAddress= sAddr;
|
||||
iPeerPort = ntohs(p->sin_port);
|
||||
bzero(stPeer, iPeerLen);
|
||||
getPeerName(stPeer, iPeerLen);
|
||||
inet_ntop(_iDomain, (AF_INET6 == _iDomain) ? (const void*)&stPeer6.sin6_addr : (const void *)&stPeer4.sin_addr, sAddr, sizeof(sAddr));
|
||||
sPeerAddress = sAddr;
|
||||
iPeerPort = (AF_INET6 == _iDomain) ? ntohs(stPeer6.sin6_port) : ntohs(stPeer4.sin_port);
|
||||
}
|
||||
|
||||
void TC_Socket::getPeerName(string &sPathName)
|
||||
@ -114,21 +112,19 @@ void TC_Socket::getPeerName(struct sockaddr *pstPeerAddr, socklen_t &iPeerLen)
|
||||
|
||||
void TC_Socket::getSockName(string &sSockAddress, uint16_t &iSockPort)
|
||||
{
|
||||
assert(_iDomain == AF_INET);
|
||||
assert(_iDomain == AF_INET || _iDomain == AF_INET6);
|
||||
|
||||
struct sockaddr stSock;
|
||||
bzero(&stSock, sizeof(struct sockaddr));
|
||||
socklen_t iSockLen = sizeof(sockaddr);
|
||||
|
||||
getSockName(&stSock, iSockLen);
|
||||
|
||||
char sAddr[INET_ADDRSTRLEN] = "\0";
|
||||
struct sockaddr_in *p = (struct sockaddr_in *)&stSock;
|
||||
|
||||
inet_ntop(_iDomain, &p->sin_addr, sAddr, sizeof(sAddr));
|
||||
char sAddr[INET6_ADDRSTRLEN] = "\0";
|
||||
struct sockaddr_in6 in6;
|
||||
struct sockaddr_in in4;
|
||||
struct sockaddr *in = (AF_INET6 == _iDomain) ? (struct sockaddr *)&in6 : (struct sockaddr *)&in4;
|
||||
socklen_t len = (AF_INET6 == _iDomain) ? sizeof(in6) : sizeof(in4);
|
||||
|
||||
bzero(in, len);
|
||||
getSockName(in, len);
|
||||
inet_ntop(_iDomain, (AF_INET6 == _iDomain) ? (const void *)&in6.sin6_addr : (const void *)&in4.sin_addr, sAddr, sizeof(sAddr));
|
||||
sSockAddress = sAddr;
|
||||
iSockPort = ntohs(p->sin_port);
|
||||
iSockPort = (AF_INET6 == _iDomain) ? ntohs(in6.sin6_port) : ntohs(in4.sin_port);
|
||||
}
|
||||
|
||||
void TC_Socket::getSockName(string &sPathName)
|
||||
@ -192,29 +188,80 @@ void TC_Socket::parseAddr(const string &sAddr, struct in_addr &stSinAddr)
|
||||
}
|
||||
}
|
||||
|
||||
void TC_Socket::parseAddr(const string &sAddr, struct in6_addr &stSinAddr)
|
||||
{
|
||||
int iRet = inet_pton(AF_INET6, sAddr.c_str(), &stSinAddr);
|
||||
if(iRet < 0)
|
||||
{
|
||||
throw TC_Socket_Exception("[TC_Socket::parseAddr6] inet_pton error", errno);
|
||||
}
|
||||
else if(iRet == 0)
|
||||
{
|
||||
struct hostent stHostent;
|
||||
struct hostent *pstHostent;
|
||||
char buf[2048] = "\0";
|
||||
int iError;
|
||||
|
||||
gethostbyname2_r(sAddr.c_str(), AF_INET6, &stHostent, buf, sizeof(buf), &pstHostent, &iError);
|
||||
|
||||
if (pstHostent == NULL)
|
||||
{
|
||||
throw TC_Socket_Exception("[TC_Socket::parseAddr6] gethostbyname2_r error! :" + string(hstrerror(iError)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pstHostent->h_addrtype != AF_INET6)
|
||||
{
|
||||
throw TC_Socket_Exception("[TC_Socket::parseAddr6] gethostbyname2_r return addrtype is not AF_INET6");
|
||||
}
|
||||
stSinAddr = *(struct in6_addr *) pstHostent->h_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TC_Socket::bind(const string &sServerAddr, int port)
|
||||
{
|
||||
assert(_iDomain == AF_INET);
|
||||
assert(_iDomain == AF_INET || _iDomain == AF_INET6);
|
||||
|
||||
struct sockaddr_in bindAddr;
|
||||
struct sockaddr_in6 bindAddr6;
|
||||
struct sockaddr_in bindAddr4;
|
||||
struct sockaddr *bindAddr = (AF_INET6 == _iDomain) ? (struct sockaddr *)&bindAddr6 : (struct sockaddr *)&bindAddr4;
|
||||
socklen_t len = (AF_INET6 == _iDomain) ? sizeof(bindAddr6) : sizeof(bindAddr4);
|
||||
|
||||
bzero(&bindAddr, sizeof(bindAddr));
|
||||
bzero(bindAddr, len);
|
||||
|
||||
bindAddr.sin_family = _iDomain;
|
||||
bindAddr.sin_port = htons(port);
|
||||
|
||||
if (sServerAddr == "")
|
||||
if (AF_INET6 == _iDomain)
|
||||
{
|
||||
bindAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
bindAddr6.sin6_family = _iDomain;
|
||||
bindAddr6.sin6_port = htons(port);
|
||||
|
||||
if (sServerAddr == "")
|
||||
{
|
||||
bindAddr6.sin6_addr = in6addr_any;
|
||||
}
|
||||
else
|
||||
{
|
||||
parseAddr(sServerAddr, bindAddr6.sin6_addr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parseAddr(sServerAddr, bindAddr.sin_addr);
|
||||
bindAddr4.sin_family = _iDomain;
|
||||
bindAddr4.sin_port = htons(port);
|
||||
|
||||
if (sServerAddr == "")
|
||||
{
|
||||
bindAddr4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
parseAddr(sServerAddr, bindAddr4.sin_addr);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
bind((struct sockaddr *)(&bindAddr), sizeof(bindAddr));
|
||||
bind(bindAddr, len);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
@ -268,28 +315,41 @@ void TC_Socket::close()
|
||||
|
||||
int TC_Socket::connectNoThrow(const string &sServerAddr, uint16_t port)
|
||||
{
|
||||
assert(_iDomain == AF_INET);
|
||||
assert(_iDomain == AF_INET || _iDomain == AF_INET6);
|
||||
|
||||
if (sServerAddr == "")
|
||||
{
|
||||
throw TC_Socket_Exception("[TC_Socket::connect] server address is empty error!");
|
||||
}
|
||||
|
||||
struct sockaddr_in serverAddr;
|
||||
bzero(&serverAddr, sizeof(serverAddr));
|
||||
struct sockaddr_in6 serverAddr6;
|
||||
struct sockaddr_in serverAddr4;
|
||||
struct sockaddr *serverAddr = (AF_INET6 == _iDomain) ? (struct sockaddr *)&serverAddr6 : (struct sockaddr *)&serverAddr4;
|
||||
socklen_t len = (AF_INET6 == _iDomain) ? sizeof(serverAddr6) : sizeof(serverAddr4);
|
||||
|
||||
serverAddr.sin_family = _iDomain;
|
||||
parseAddr(sServerAddr, serverAddr.sin_addr);
|
||||
serverAddr.sin_port = htons(port);
|
||||
bzero(serverAddr, len);
|
||||
|
||||
return connect((struct sockaddr *)(&serverAddr), sizeof(serverAddr));
|
||||
if (AF_INET6 == _iDomain)
|
||||
{
|
||||
serverAddr6.sin6_family = _iDomain;
|
||||
parseAddr(sServerAddr, serverAddr6.sin6_addr);
|
||||
serverAddr6.sin6_port = htons(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
serverAddr4.sin_family = _iDomain;
|
||||
parseAddr(sServerAddr, serverAddr4.sin_addr);
|
||||
serverAddr4.sin_port = htons(port);
|
||||
}
|
||||
|
||||
return connect(serverAddr, len);
|
||||
}
|
||||
|
||||
int TC_Socket::connectNoThrow(struct sockaddr* addr)
|
||||
{
|
||||
assert(_iDomain == AF_INET);
|
||||
assert(_iDomain == AF_INET || _iDomain == AF_INET6);
|
||||
|
||||
return connect(addr, sizeof(struct sockaddr));
|
||||
return connect(addr, (AF_INET6 == _iDomain) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
|
||||
}
|
||||
|
||||
void TC_Socket::connect(const string &sServerAddr, uint16_t port)
|
||||
@ -349,23 +409,21 @@ int TC_Socket::send(const void *pvBuf, size_t iLen, int iFlag)
|
||||
|
||||
int TC_Socket::recvfrom(void *pvBuf, size_t iLen, string &sFromAddr, uint16_t &iFromPort, int iFlags)
|
||||
{
|
||||
struct sockaddr stFromAddr;
|
||||
socklen_t iFromLen = sizeof(struct sockaddr);
|
||||
struct sockaddr_in *p = (struct sockaddr_in *)&stFromAddr;
|
||||
int iBytes;
|
||||
struct sockaddr_in6 stFromAddr6;
|
||||
struct sockaddr_in stFromAddr4;
|
||||
struct sockaddr *stFromAddr = (AF_INET6 == _iDomain) ? (struct sockaddr *)&stFromAddr6 : (struct sockaddr *)&stFromAddr4;
|
||||
socklen_t iFromLen = (AF_INET6 == _iDomain) ? sizeof(stFromAddr6) : sizeof(stFromAddr4);
|
||||
|
||||
bzero(&stFromAddr, sizeof(struct sockaddr));
|
||||
|
||||
int iBytes = recvfrom(pvBuf, iLen, &stFromAddr, iFromLen, iFlags);
|
||||
bzero(stFromAddr, iFromLen);
|
||||
iBytes = recvfrom(pvBuf, iLen, stFromAddr, iFromLen, iFlags);
|
||||
if (iBytes >= 0)
|
||||
{
|
||||
char sAddr[INET_ADDRSTRLEN] = "\0";
|
||||
|
||||
inet_ntop(_iDomain, &p->sin_addr, sAddr, sizeof(sAddr));
|
||||
|
||||
char sAddr[INET6_ADDRSTRLEN] = "\0";
|
||||
inet_ntop(_iDomain, (AF_INET6 == _iDomain) ? (const void *)&stFromAddr6.sin6_addr : (const void *)&stFromAddr4.sin_addr, sAddr, sizeof(sAddr));
|
||||
sFromAddr = sAddr;
|
||||
iFromPort = ntohs(p->sin_port);
|
||||
iFromPort = (AF_INET6 == _iDomain) ? ntohs(stFromAddr6.sin6_port) : ntohs(stFromAddr4.sin_port);
|
||||
}
|
||||
|
||||
return iBytes;
|
||||
}
|
||||
|
||||
@ -376,24 +434,43 @@ int TC_Socket::recvfrom(void *pvBuf, size_t iLen, struct sockaddr *pstFromAddr,
|
||||
|
||||
int TC_Socket::sendto(const void *pvBuf, size_t iLen, const string &sToAddr, uint16_t port, int iFlags)
|
||||
{
|
||||
struct sockaddr_in toAddr;
|
||||
struct sockaddr_in6 toAddr6;
|
||||
struct sockaddr_in toAddr4;
|
||||
struct sockaddr *toAddr = (AF_INET6 == _iDomain) ? (struct sockaddr *)&toAddr6 : (struct sockaddr *)&toAddr4;
|
||||
socklen_t len = (AF_INET6 == _iDomain) ? sizeof(toAddr6) : sizeof(toAddr4);
|
||||
|
||||
bzero(&toAddr, sizeof(struct sockaddr_in));
|
||||
|
||||
toAddr.sin_family = _iDomain;
|
||||
|
||||
if (sToAddr == "")
|
||||
bzero(toAddr, len);
|
||||
if (AF_INET6 == _iDomain)
|
||||
{
|
||||
toAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||
toAddr6.sin6_family = _iDomain;
|
||||
|
||||
if (sToAddr == "")
|
||||
{
|
||||
//toAddr.sin6_addr = in6addr_linklocal_allrouters;
|
||||
}
|
||||
else
|
||||
{
|
||||
parseAddr(sToAddr, toAddr6.sin6_addr);
|
||||
}
|
||||
toAddr6.sin6_port = htons(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
parseAddr(sToAddr, toAddr.sin_addr);
|
||||
toAddr4.sin_family = _iDomain;
|
||||
|
||||
if (sToAddr == "")
|
||||
{
|
||||
toAddr4.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||
}
|
||||
else
|
||||
{
|
||||
parseAddr(sToAddr, toAddr4.sin_addr);
|
||||
}
|
||||
|
||||
toAddr4.sin_port = htons(port);
|
||||
}
|
||||
|
||||
toAddr.sin_port = htons(port);
|
||||
|
||||
return sendto(pvBuf, iLen, (struct sockaddr *)(&toAddr), sizeof(toAddr), iFlags);
|
||||
return sendto(pvBuf, iLen, toAddr, len, iFlags);
|
||||
}
|
||||
|
||||
int TC_Socket::sendto(const void *pvBuf, size_t iLen, struct sockaddr *pstToAddr, socklen_t iToLen, int iFlags)
|
||||
@ -565,12 +642,12 @@ void TC_Socket::createPipe(int fds[2], bool bBlock)
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> TC_Socket::getLocalHosts()
|
||||
vector<string> TC_Socket::getLocalHosts(int domain)
|
||||
{
|
||||
vector<string> result;
|
||||
|
||||
TC_Socket ts;
|
||||
ts.createSocket(SOCK_STREAM, AF_INET);
|
||||
ts.createSocket(SOCK_STREAM, domain);
|
||||
|
||||
int cmd = SIOCGIFCONF;
|
||||
|
||||
@ -619,6 +696,16 @@ vector<string> TC_Socket::getLocalHosts()
|
||||
result.push_back(sAddr);
|
||||
}
|
||||
}
|
||||
else if (ifr[i].ifr_addr.sa_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6* addr = reinterpret_cast<struct sockaddr_in6*>(&ifr[i].ifr_addr);
|
||||
if(!memcmp(&addr->sin6_addr, &in6addr_any, sizeof(addr->sin6_addr)))
|
||||
{
|
||||
char sAddr[INET6_ADDRSTRLEN] = "\0";
|
||||
inet_ntop(AF_INET6, &(*addr).sin6_addr, sAddr, sizeof(sAddr));
|
||||
result.push_back(sAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(ifc.ifc_buf);
|
||||
@ -626,5 +713,12 @@ vector<string> TC_Socket::getLocalHosts()
|
||||
return result;
|
||||
}
|
||||
|
||||
bool addressIsIPv6(const string& addr, bool def_value)
|
||||
{
|
||||
#define IPv6_ADDRESS_CHAR ':'
|
||||
return (addr.find(IPv6_ADDRESS_CHAR) != string::npos) ? true : false;
|
||||
#undef IPv6_ADDRESS_CHAR
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user