inetAddressUtil no more new vector

no more allocating vector.
This commit is contained in:
Michael Davidsaver
2017-08-31 14:32:13 -05:00
parent 0f8865e1ea
commit 27ec187bd4
10 changed files with 131 additions and 128 deletions

View File

@ -2,6 +2,7 @@ TOP=..
include $(TOP)/configure/CONFIG include $(TOP)/configure/CONFIG
USR_CPPFLAGS += -I$(TOP)/src/utils
USR_CPPFLAGS += -I$(TOP)/src/remote USR_CPPFLAGS += -I$(TOP)/src/remote
PROD_HOST += pvget PROD_HOST += pvget

View File

@ -228,7 +228,8 @@ bool discoverServers(double timeOut)
int broadcastPort = configuration->getPropertyAsInteger("EPICS_PVA_BROADCAST_PORT", PVA_BROADCAST_PORT); int broadcastPort = configuration->getPropertyAsInteger("EPICS_PVA_BROADCAST_PORT", PVA_BROADCAST_PORT);
// quary broadcast addresses of all IFs // quary broadcast addresses of all IFs
auto_ptr<InetAddrVector> broadcastAddresses(getBroadcastAddresses(socket, broadcastPort)); InetAddrVector broadcastAddresses;
getBroadcastAddresses(broadcastAddresses, socket, broadcastPort);
// set broadcast address list // set broadcast address list
if (!addressList.empty()) if (!addressList.empty())
@ -236,18 +237,19 @@ bool discoverServers(double timeOut)
// if auto is true, add it to specified list // if auto is true, add it to specified list
InetAddrVector* appendList = 0; InetAddrVector* appendList = 0;
if (autoAddressList) if (autoAddressList)
appendList = broadcastAddresses.get(); appendList = &broadcastAddresses;
auto_ptr<InetAddrVector> list(getSocketAddressList(addressList, broadcastPort, appendList)); InetAddrVector list;
if (list.get() && list->size()) { getSocketAddressList(list, addressList, broadcastPort, appendList);
if (!list.empty()) {
// delete old list and take ownership of a new one // delete old list and take ownership of a new one
broadcastAddresses = list; broadcastAddresses = list;
} }
} }
for (size_t i = 0; broadcastAddresses.get() && i < broadcastAddresses->size(); i++) for (size_t i = 0; i < broadcastAddresses.size(); i++)
LOG(logLevelDebug, LOG(logLevelDebug,
"Broadcast address #%d: %s.", i, inetAddressToString((*broadcastAddresses)[i]).c_str()); "Broadcast address #%d: %s.", i, inetAddressToString(broadcastAddresses[i]).c_str());
// --- // ---
@ -330,11 +332,11 @@ bool discoverServers(double timeOut)
sendBuffer.putShort((int16_t)0); // count sendBuffer.putShort((int16_t)0); // count
bool oneOK = false; bool oneOK = false;
for (size_t i = 0; i < broadcastAddresses->size(); i++) for (size_t i = 0; i < broadcastAddresses.size(); i++)
{ {
// send the packet // send the packet
status = ::sendto(socket, sendBuffer.getArray(), sendBuffer.getPosition(), 0, status = ::sendto(socket, sendBuffer.getArray(), sendBuffer.getPosition(), 0,
&((*broadcastAddresses)[i].sa), sizeof(sockaddr)); &broadcastAddresses[i].sa, sizeof(sockaddr));
if (status < 0) if (status < 0)
{ {
char errStr[64]; char errStr[64];
@ -409,11 +411,11 @@ bool discoverServers(double timeOut)
{ {
// TODO duplicate code // TODO duplicate code
bool oneOK = false; bool oneOK = false;
for (size_t i = 0; i < broadcastAddresses->size(); i++) for (size_t i = 0; i < broadcastAddresses.size(); i++)
{ {
// send the packet // send the packet
status = ::sendto(socket, sendBuffer.getArray(), sendBuffer.getPosition(), 0, status = ::sendto(socket, sendBuffer.getArray(), sendBuffer.getPosition(), 0,
&((*broadcastAddresses)[i].sa), sizeof(sockaddr)); &broadcastAddresses[i].sa, sizeof(sockaddr));
if (status < 0) if (status < 0)
{ {
char errStr[64]; char errStr[64];

View File

@ -619,10 +619,11 @@ void initializeUDPTransports(bool serverFlag,
if (!autoAddressList) if (!autoAddressList)
autoBCastAddr.clear(); autoBCastAddr.clear();
auto_ptr<InetAddrVector> list(getSocketAddressList(addressList, sendPort, &autoBCastAddr)); InetAddrVector list;
if (list.get() && list->size()) getSocketAddressList(list, addressList, sendPort, &autoBCastAddr);
if (!list.empty())
{ {
sendTransport->setSendAddresses(*list); sendTransport->setSendAddresses(list);
} }
/* /*
else else
@ -667,9 +668,8 @@ void initializeUDPTransports(bool serverFlag,
// //
// set ignore address list // set ignore address list
// //
auto_ptr<InetAddrVector> ignoreAddressVector; InetAddrVector ignoreAddressVector;
if (!ignoreAddressList.empty()) getSocketAddressList(ignoreAddressVector, ignoreAddressList, 0, 0);
ignoreAddressVector.reset(getSocketAddressList(ignoreAddressList, 0, 0));
// //
// Setup UDP trasport(s) (per interface) // Setup UDP trasport(s) (per interface)
@ -700,8 +700,7 @@ void initializeUDPTransports(bool serverFlag,
continue; continue;
listenLocalAddress = *transport->getRemoteAddress(); listenLocalAddress = *transport->getRemoteAddress();
if (ignoreAddressVector.get() && ignoreAddressVector->size()) transport->setIgnoredAddresses(ignoreAddressVector);
transport->setIgnoredAddresses(*ignoreAddressVector);
tappedNIF.push_back(listenLocalAddress); tappedNIF.push_back(listenLocalAddress);
@ -740,8 +739,7 @@ void initializeUDPTransports(bool serverFlag,
*/ */
// NOTE: search responses all always send from sendTransport // NOTE: search responses all always send from sendTransport
if (ignoreAddressVector.get() && ignoreAddressVector->size()) transport2->setIgnoredAddresses(ignoreAddressVector);
transport2->setIgnoredAddresses(*ignoreAddressVector);
tappedNIF.push_back(bcastAddress); tappedNIF.push_back(bcastAddress);
} }

View File

@ -303,12 +303,11 @@ public:
return &_bindAddress; return &_bindAddress;
} }
bool isBroadcastAddress(const osiSockAddr* address, InetAddrVector *broadcastAddresses) bool isBroadcastAddress(const osiSockAddr* address, const InetAddrVector& broadcastAddresses)
{ {
if (broadcastAddresses) for (size_t i = 0; i < broadcastAddresses.size(); i++)
for (size_t i = 0; i < broadcastAddresses->size(); i++) if (broadcastAddresses[i].ia.sin_addr.s_addr == address->ia.sin_addr.s_addr)
if ((*broadcastAddresses)[i].ia.sin_addr.s_addr == address->ia.sin_addr.s_addr) return true;
return true;
return false; return false;
} }
@ -318,9 +317,10 @@ public:
*/ */
void setSendAddresses(const InetAddrVector& addresses) { void setSendAddresses(const InetAddrVector& addresses) {
std::vector<bool> isuni(addresses.size(), false); std::vector<bool> isuni(addresses.size(), false);
std::auto_ptr<InetAddrVector> broadcastAddresses(getBroadcastAddresses(_channel, 0)); InetAddrVector broadcastAddresses;
getBroadcastAddresses(broadcastAddresses, _channel, 0);
for(size_t i=0, N=addresses.size(); i<N; i++) for(size_t i=0, N=addresses.size(); i<N; i++)
isuni[i] = !isBroadcastAddress(&addresses[i], broadcastAddresses.get()) isuni[i] = !isBroadcastAddress(&addresses[i], broadcastAddresses)
&& !isMulticastAddress(&addresses[i]); && !isMulticastAddress(&addresses[i]);
_sendAddresses = addresses; _sendAddresses = addresses;
_isSendAddressUnicast.swap(isuni); _isSendAddressUnicast.swap(isuni);

View File

@ -3129,13 +3129,8 @@ public:
short priority, short priority,
std::string const & addressesStr) OVERRIDE FINAL std::string const & addressesStr) OVERRIDE FINAL
{ {
auto_ptr<InetAddrVector> addresses; InetAddrVector addresses;
if (!addressesStr.empty()) getSocketAddressList(addresses, addressesStr, PVA_SERVER_PORT);
{
addresses.reset(getSocketAddressList(addressesStr, PVA_SERVER_PORT));
if (addresses->empty())
addresses.reset();
}
Channel::shared_pointer channel = createChannelInternal(channelName, channelRequester, priority, addresses); Channel::shared_pointer channel = createChannelInternal(channelName, channelRequester, priority, addresses);
if (channel.get()) if (channel.get())
@ -3200,7 +3195,7 @@ public:
/** /**
* List of fixed addresses, if <code<0</code> name resolution will be used. * List of fixed addresses, if <code<0</code> name resolution will be used.
*/ */
auto_ptr<InetAddrVector> m_addresses; InetAddrVector m_addresses;
/** /**
* @brief m_addressIndex Index of currently used address (rollover pointer in a list). * @brief m_addressIndex Index of currently used address (rollover pointer in a list).
@ -3279,7 +3274,7 @@ private:
string const & name, string const & name,
ChannelRequester::shared_pointer const & requester, ChannelRequester::shared_pointer const & requester,
short priority, short priority,
auto_ptr<InetAddrVector>& addresses) : const InetAddrVector& addresses) :
m_context(context), m_context(context),
m_channelID(channelID), m_channelID(channelID),
m_name(name), m_name(name),
@ -3315,7 +3310,7 @@ private:
string const & name, string const & name,
ChannelRequester::shared_pointer requester, ChannelRequester::shared_pointer requester,
short priority, short priority,
auto_ptr<InetAddrVector>& addresses) const InetAddrVector& addresses)
{ {
std::tr1::shared_ptr<InternalChannelImpl> internal( std::tr1::shared_ptr<InternalChannelImpl> internal(
new InternalChannelImpl(context, channelID, name, requester, priority, addresses)), new InternalChannelImpl(context, channelID, name, requester, priority, addresses)),
@ -3680,14 +3675,14 @@ public:
m_allowCreation = true; m_allowCreation = true;
if (!m_addresses.get()) if (m_addresses.empty())
{ {
m_context->getChannelSearchManager()->registerSearchInstance(internal_from_this(), penalize); m_context->getChannelSearchManager()->registerSearchInstance(internal_from_this(), penalize);
} }
else if (!m_addresses->empty()) else
{ {
m_context->getTimer()->scheduleAfterDelay(internal_from_this(), m_context->getTimer()->scheduleAfterDelay(internal_from_this(),
(m_addressIndex / m_addresses->size())*STATIC_SEARCH_BASE_DELAY_SEC); (m_addressIndex / m_addresses.size())*STATIC_SEARCH_BASE_DELAY_SEC);
} }
} }
@ -3695,14 +3690,15 @@ public:
// TODO cancellaction?! // TODO cancellaction?!
// TODO not in this timer thread !!! // TODO not in this timer thread !!!
// TODO boost when a server (from address list) is started!!! IP vs address !!! // TODO boost when a server (from address list) is started!!! IP vs address !!!
int ix = m_addressIndex % m_addresses->size(); int ix = m_addressIndex % m_addresses.size();
m_addressIndex++; m_addressIndex++;
if (m_addressIndex >= static_cast<int>(m_addresses->size()*(STATIC_SEARCH_MAX_MULTIPLIER+1))) if (m_addressIndex >= static_cast<int>(m_addresses.size()*(STATIC_SEARCH_MAX_MULTIPLIER+1)))
m_addressIndex = m_addresses->size()*STATIC_SEARCH_MAX_MULTIPLIER; m_addressIndex = m_addresses.size()*STATIC_SEARCH_MAX_MULTIPLIER;
// NOTE: calls channelConnectFailed() on failure // NOTE: calls channelConnectFailed() on failure
static ServerGUID guid = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; static ServerGUID guid = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
searchResponse(guid, PVA_PROTOCOL_REVISION, &((*m_addresses)[ix])); // m_addresses[ix] is modified by the following
searchResponse(guid, PVA_PROTOCOL_REVISION, &m_addresses[ix]);
} }
virtual void timerStopped() OVERRIDE FINAL { virtual void timerStopped() OVERRIDE FINAL {
@ -4521,7 +4517,7 @@ private:
// TODO no minor version with the addresses // TODO no minor version with the addresses
// TODO what if there is an channel with the same name, but on different host! // TODO what if there is an channel with the same name, but on different host!
ChannelImpl::shared_pointer createChannelInternal(std::string const & name, ChannelRequester::shared_pointer const & requester, short priority, ChannelImpl::shared_pointer createChannelInternal(std::string const & name, ChannelRequester::shared_pointer const & requester, short priority,
auto_ptr<InetAddrVector>& addresses) OVERRIDE FINAL { // TODO addresses const InetAddrVector& addresses) OVERRIDE FINAL { // TODO addresses
checkState(); checkState();
checkChannelName(name); checkChannelName(name);

View File

@ -103,7 +103,7 @@ public:
virtual ChannelImpl::shared_pointer createChannelInternal(std::string const &name, virtual ChannelImpl::shared_pointer createChannelInternal(std::string const &name,
ChannelRequester::shared_pointer const & requester, ChannelRequester::shared_pointer const & requester,
short priority, short priority,
std::auto_ptr<InetAddrVector>& addresses) = 0; const InetAddrVector& addresses) = 0;
virtual ResponseRequest::shared_pointer getResponseRequest(pvAccessID ioid) = 0; virtual ResponseRequest::shared_pointer getResponseRequest(pvAccessID ioid) = 0;
virtual pvAccessID registerResponseRequest(ResponseRequest::shared_pointer const & request) = 0; virtual pvAccessID registerResponseRequest(ResponseRequest::shared_pointer const & request) = 0;

View File

@ -34,8 +34,10 @@ void addDefaultBroadcastAddress(InetAddrVector* v, unsigned short p) {
v->push_back(pNewNode); v->push_back(pNewNode);
} }
InetAddrVector* getBroadcastAddresses(SOCKET sock, void getBroadcastAddresses(InetAddrVector& ret,
unsigned short defaultPort) { SOCKET sock,
unsigned short defaultPort) {
ret.clear();
ELLLIST as; ELLLIST as;
ellInit(&as); ellInit(&as);
osiSockAddr serverAddr; osiSockAddr serverAddr;
@ -47,13 +49,12 @@ InetAddrVector* getBroadcastAddresses(SOCKET sock,
osiSockAddrNode * sn = (osiSockAddrNode *)n; osiSockAddrNode * sn = (osiSockAddrNode *)n;
sn->addr.ia.sin_port = htons(defaultPort); sn->addr.ia.sin_port = htons(defaultPort);
// TODO discover possible duplicates // TODO discover possible duplicates
v->push_back(sn->addr); ret.push_back(sn->addr);
} }
ellFree(&as); ellFree(&as);
// add fallback address // add fallback address
if (!v->size()) if (!ret.size())
addDefaultBroadcastAddress(v, defaultPort); addDefaultBroadcastAddress(v, defaultPort);
return v;
} }
void encodeAsIPv6Address(ByteBuffer* buffer, const osiSockAddr* address) { void encodeAsIPv6Address(ByteBuffer* buffer, const osiSockAddr* address) {
@ -101,13 +102,10 @@ bool isMulticastAddress(const osiSockAddr* address) {
return msB >= 224 && msB <= 239; return msB >= 224 && msB <= 239;
} }
osiSockAddr* intToIPv4Address(int32 addr) { void intToIPv4Address(osiSockAddr& ret, int32 addr) {
osiSockAddr* ret = new osiSockAddr; ret.ia.sin_family = AF_INET;
ret->ia.sin_family = AF_INET; ret.ia.sin_addr.s_addr = htonl(addr);
ret->ia.sin_addr.s_addr = htonl(addr); ret.ia.sin_port = 0;
ret->ia.sin_port = 0;
return ret;
} }
int32 ipv4AddressToInt(const osiSockAddr& addr) { int32 ipv4AddressToInt(const osiSockAddr& addr) {
@ -148,9 +146,10 @@ int32 parseInetAddress(const string & addr) {
return htonl(retAddr); return htonl(retAddr);
} }
InetAddrVector* getSocketAddressList(const std::string & list, int defaultPort, void getSocketAddressList(InetAddrVector& ret,
const std::string & list, int defaultPort,
const InetAddrVector* appendList) { const InetAddrVector* appendList) {
InetAddrVector* iav = new InetAddrVector(); ret.clear();
// skip leading spaces // skip leading spaces
size_t len = list.length(); size_t len = list.length();
@ -164,21 +163,20 @@ InetAddrVector* getSocketAddressList(const std::string & list, int defaultPort,
string address = list.substr(subStart, (subEnd-subStart)); string address = list.substr(subStart, (subEnd-subStart));
osiSockAddr addr; osiSockAddr addr;
if (aToIPAddr(address.c_str(), defaultPort, &addr.ia) == 0) if (aToIPAddr(address.c_str(), defaultPort, &addr.ia) == 0)
iav->push_back(addr); ret.push_back(addr);
subStart = list.find_first_not_of(" \t\r\n\v", subEnd); subStart = list.find_first_not_of(" \t\r\n\v", subEnd);
} }
if(subStart!=std::string::npos && subStart<len) { if(subStart!=std::string::npos && subStart<len) {
osiSockAddr addr; osiSockAddr addr;
if (aToIPAddr(list.substr(subStart).c_str(), defaultPort, &addr.ia) == 0) if (aToIPAddr(list.substr(subStart).c_str(), defaultPort, &addr.ia) == 0)
iav->push_back(addr); ret.push_back(addr);
} }
if(appendList!=NULL) { if(appendList!=NULL) {
for(size_t i = 0; i<appendList->size(); i++) for(size_t i = 0; i<appendList->size(); i++)
iav->push_back((*appendList)[i]); ret.push_back((*appendList)[i]);
} }
return iav;
} }
string inetAddressToString(const osiSockAddr &addr, string inetAddressToString(const osiSockAddr &addr,

View File

@ -24,12 +24,12 @@ namespace pvAccess {
typedef std::vector<osiSockAddr> InetAddrVector; typedef std::vector<osiSockAddr> InetAddrVector;
/** /**
* Returns a vector containing all the IPv4 broadcast addresses on this machine. * Populate a vector containing all the IPv4 broadcast addresses on this machine.
* IPv6 doesn't have a local broadcast address. * IPv6 doesn't have a local broadcast address.
* Conversion of the defaultPort to network byte order performed by * Conversion of the defaultPort to network byte order performed by
* the function. * the function.
*/ */
epicsShareFunc InetAddrVector* getBroadcastAddresses(SOCKET sock, unsigned short defaultPort); epicsShareFunc void getBroadcastAddresses(InetAddrVector& ret, SOCKET sock, unsigned short defaultPort);
struct ifaceNode { struct ifaceNode {
osiSockAddr ifaceAddr, ifaceBCast; osiSockAddr ifaceAddr, ifaceBCast;
@ -66,10 +66,10 @@ epicsShareFunc bool isMulticastAddress(const osiSockAddr* address);
/** /**
* Convert an integer into an IPv4 INET address. * Convert an integer into an IPv4 INET address.
* @param ret address stored here
* @param addr integer representation of a given address. * @param addr integer representation of a given address.
* @return IPv4 INET address.
*/ */
epicsShareFunc osiSockAddr* intToIPv4Address(epics::pvData::int32 addr); epicsShareFunc void intToIPv4Address(osiSockAddr& ret, epics::pvData::int32 addr);
/** /**
* Convert an IPv4 INET address to an integer. * Convert an IPv4 INET address to an integer.
@ -79,14 +79,15 @@ epicsShareFunc osiSockAddr* intToIPv4Address(epics::pvData::int32 addr);
epicsShareFunc epics::pvData::int32 ipv4AddressToInt(const osiSockAddr& addr); epicsShareFunc epics::pvData::int32 ipv4AddressToInt(const osiSockAddr& addr);
/** /**
* Parse space delimited addresss[:port] string and return array of <code>InetSocketAddress</code>. * Parse space delimited addresss[:port] string and populate array of <code>InetSocketAddress</code>.
* @param ret results stored hre
* @param list space delimited addresss[:port] string. * @param list space delimited addresss[:port] string.
* @param defaultPort port take if not specified. * @param defaultPort port take if not specified.
* @param appendList list to be appended. * @param appendList list to be appended.
* @return array of <code>InetSocketAddress</code>. * @return array of <code>InetSocketAddress</code>.
*/ */
epicsShareFunc InetAddrVector* getSocketAddressList(const std::string & list, int defaultPort, epicsShareFunc void getSocketAddressList(InetAddrVector& ret, const std::string & list, int defaultPort,
const InetAddrVector* appendList = NULL); const InetAddrVector* appendList = NULL);
epicsShareFunc std::string inetAddressToString(const osiSockAddr &addr, epicsShareFunc std::string inetAddressToString(const osiSockAddr &addr,
bool displayPort = true, bool displayHex = false); bool displayPort = true, bool displayHex = false);

View File

@ -3,6 +3,7 @@
TOP = .. TOP = ..
include $(TOP)/configure/CONFIG include $(TOP)/configure/CONFIG
USR_CPPFLAGS += -I$(TOP)/src/utils
USR_CPPFLAGS += -I$(TOP)/src/server USR_CPPFLAGS += -I$(TOP)/src/server
USR_CPPFLAGS += -I$(TOP)/src/remote USR_CPPFLAGS += -I$(TOP)/src/remote
USR_CPPFLAGS += -I$(TOP)/src/remoteClient USR_CPPFLAGS += -I$(TOP)/src/remoteClient

View File

@ -21,24 +21,25 @@ void test_getSocketAddressList()
{ {
testDiag("Test getSocketAddressList()"); testDiag("Test getSocketAddressList()");
auto_ptr<InetAddrVector> vec(getSocketAddressList("127.0.0.1 10.10.12.11:1234 192.168.3.4", 555)); InetAddrVector vec;
getSocketAddressList(vec, "127.0.0.1 10.10.12.11:1234 192.168.3.4", 555);
testOk1(static_cast<size_t>(3) == vec->size()); testOk1(static_cast<size_t>(3) == vec.size());
osiSockAddr addr; osiSockAddr addr;
addr = vec->at(0); addr = vec.at(0);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(555) == addr.ia.sin_port); testOk1(htons(555) == addr.ia.sin_port);
testOk1(htonl(0x7F000001) == addr.ia.sin_addr.s_addr); testOk1(htonl(0x7F000001) == addr.ia.sin_addr.s_addr);
testOk1("127.0.0.1:555" == inetAddressToString(addr)); testOk1("127.0.0.1:555" == inetAddressToString(addr));
addr = vec->at(1); addr = vec.at(1);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(1234) == addr.ia.sin_port); testOk1(htons(1234) == addr.ia.sin_port);
testOk1(htonl(0x0A0A0C0B) == addr.ia.sin_addr.s_addr); testOk1(htonl(0x0A0A0C0B) == addr.ia.sin_addr.s_addr);
testOk1("10.10.12.11:1234" == inetAddressToString(addr)); testOk1("10.10.12.11:1234" == inetAddressToString(addr));
addr = vec->at(2); addr = vec.at(2);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(555) == addr.ia.sin_port); testOk1(htons(555) == addr.ia.sin_port);
testOk1(htonl(0xC0A80304) == addr.ia.sin_addr.s_addr); testOk1(htonl(0xC0A80304) == addr.ia.sin_addr.s_addr);
@ -47,29 +48,30 @@ void test_getSocketAddressList()
auto_ptr<InetAddrVector> vec1(getSocketAddressList("172.16.55.160", 6789, vec.get())); InetAddrVector vec1;
getSocketAddressList(vec1, "172.16.55.160", 6789, &vec);
testOk1(static_cast<size_t>(4) == vec1->size()); testOk1(static_cast<size_t>(4) == vec1.size());
addr = vec1->at(0); addr = vec1.at(0);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(6789) == addr.ia.sin_port); testOk1(htons(6789) == addr.ia.sin_port);
testOk1(htonl(0xAC1037A0) == addr.ia.sin_addr.s_addr); testOk1(htonl(0xAC1037A0) == addr.ia.sin_addr.s_addr);
testOk1("172.16.55.160:6789" == inetAddressToString(addr)); testOk1("172.16.55.160:6789" == inetAddressToString(addr));
addr = vec1->at(1); addr = vec1.at(1);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(555) == addr.ia.sin_port); testOk1(htons(555) == addr.ia.sin_port);
testOk1(htonl(0x7F000001) == addr.ia.sin_addr.s_addr); testOk1(htonl(0x7F000001) == addr.ia.sin_addr.s_addr);
testOk1("127.0.0.1:555" == inetAddressToString(addr)); testOk1("127.0.0.1:555" == inetAddressToString(addr));
addr = vec1->at(2); addr = vec1.at(2);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(1234) == addr.ia.sin_port); testOk1(htons(1234) == addr.ia.sin_port);
testOk1(htonl(0x0A0A0C0B) == addr.ia.sin_addr.s_addr); testOk1(htonl(0x0A0A0C0B) == addr.ia.sin_addr.s_addr);
testOk1("10.10.12.11:1234" == inetAddressToString(addr)); testOk1("10.10.12.11:1234" == inetAddressToString(addr));
addr = vec1->at(3); addr = vec1.at(3);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(555) == addr.ia.sin_port); testOk1(htons(555) == addr.ia.sin_port);
testOk1(htonl(0xC0A80304) == addr.ia.sin_addr.s_addr); testOk1(htonl(0xC0A80304) == addr.ia.sin_addr.s_addr);
@ -77,31 +79,34 @@ void test_getSocketAddressList()
// empty // empty
auto_ptr<InetAddrVector> vec2(getSocketAddressList("", 1111)); InetAddrVector vec2;
testOk1(static_cast<size_t>(0) == vec2->size()); getSocketAddressList(vec2, "", 1111);
testOk1(static_cast<size_t>(0) == vec2.size());
// just spaces // just spaces
auto_ptr<InetAddrVector> vec3(getSocketAddressList(" ", 1111)); InetAddrVector vec3;
testOk1(static_cast<size_t>(0) == vec3->size()); getSocketAddressList(vec3, " ", 1111);
testOk1(static_cast<size_t>(0) == vec3.size());
// leading spaces // leading spaces
auto_ptr<InetAddrVector> vec4(getSocketAddressList(" 127.0.0.1 10.10.12.11:1234 192.168.3.4", 555)); InetAddrVector vec4;
getSocketAddressList(vec4, " 127.0.0.1 10.10.12.11:1234 192.168.3.4", 555);
testOk1(static_cast<size_t>(3) == vec4->size()); testOk1(static_cast<size_t>(3) == vec4.size());
addr = vec4->at(0); addr = vec4.at(0);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(555) == addr.ia.sin_port); testOk1(htons(555) == addr.ia.sin_port);
testOk1(htonl(0x7F000001) == addr.ia.sin_addr.s_addr); testOk1(htonl(0x7F000001) == addr.ia.sin_addr.s_addr);
testOk1("127.0.0.1:555" == inetAddressToString(addr)); testOk1("127.0.0.1:555" == inetAddressToString(addr));
addr = vec4->at(1); addr = vec4.at(1);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(1234) == addr.ia.sin_port); testOk1(htons(1234) == addr.ia.sin_port);
testOk1(htonl(0x0A0A0C0B) == addr.ia.sin_addr.s_addr); testOk1(htonl(0x0A0A0C0B) == addr.ia.sin_addr.s_addr);
testOk1("10.10.12.11:1234" == inetAddressToString(addr)); testOk1("10.10.12.11:1234" == inetAddressToString(addr));
addr = vec4->at(2); addr = vec4.at(2);
testOk1(AF_INET == addr.ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1(htons(555) == addr.ia.sin_port); testOk1(htons(555) == addr.ia.sin_port);
testOk1(htonl(0xC0A80304) == addr.ia.sin_addr.s_addr); testOk1(htonl(0xC0A80304) == addr.ia.sin_addr.s_addr);
@ -112,28 +117,28 @@ void test_ipv4AddressToInt()
{ {
testDiag("Test ipv4AddressToInt()"); testDiag("Test ipv4AddressToInt()");
auto_ptr<InetAddrVector> vec(getSocketAddressList("127.0.0.1 10.10.12.11:1234 192.168.3.4", 555)); InetAddrVector vec;
getSocketAddressList(vec, "127.0.0.1 10.10.12.11:1234 192.168.3.4", 555);
testOk1(static_cast<size_t>(3) == vec->size()); testOk1(static_cast<size_t>(3) == vec.size());
testOk1((int32)0x7F000001 == ipv4AddressToInt((vec->at(0)))); testOk1((int32)0x7F000001 == ipv4AddressToInt((vec.at(0))));
testOk1((int32)0x0A0A0C0B == ipv4AddressToInt((vec->at(1)))); testOk1((int32)0x0A0A0C0B == ipv4AddressToInt((vec.at(1))));
testOk1((int32)0xC0A80304 == ipv4AddressToInt((vec->at(2)))); testOk1((int32)0xC0A80304 == ipv4AddressToInt((vec.at(2))));
} }
void test_intToIPv4Address() void test_intToIPv4Address()
{ {
testDiag("Test intToIPv4Address()"); testDiag("Test intToIPv4Address()");
auto_ptr<osiSockAddr> paddr(intToIPv4Address(0x7F000001)); osiSockAddr addr;
testOk1((uintptr_t)0 != (uintptr_t)paddr.get()); intToIPv4Address(addr, 0x7F000001);
testOk1(AF_INET == paddr->ia.sin_family); testOk1(AF_INET == addr.ia.sin_family);
testOk1("127.0.0.1:0" == inetAddressToString(*paddr.get())); testOk1("127.0.0.1:0" == inetAddressToString(addr));
paddr.reset(intToIPv4Address(0x0A0A0C0B)); intToIPv4Address(addr, 0x0A0A0C0B);
testOk1((uintptr_t)0 != (uintptr_t)paddr.get()); testOk1(AF_INET == addr.ia.sin_family);
testOk1(AF_INET == paddr->ia.sin_family); testOk1("10.10.12.11:0" == inetAddressToString(addr));
testOk1("10.10.12.11:0" == inetAddressToString(*paddr.get()));
} }
void test_encodeAsIPv6Address() void test_encodeAsIPv6Address()
@ -147,9 +152,8 @@ void test_encodeAsIPv6Address()
(char)0x0A, (char)0x0A, (char)0x0C, (char)0x0B (char)0x0A, (char)0x0A, (char)0x0C, (char)0x0B
}; };
auto_ptr<osiSockAddr> paddr(intToIPv4Address(0x0A0A0C0B)); osiSockAddr addr;
testOk1((uintptr_t)0 != (uintptr_t)paddr.get()); intToIPv4Address(addr, 0x0A0A0C0B);
osiSockAddr addr = *paddr;
encodeAsIPv6Address(buff.get(), &addr); encodeAsIPv6Address(buff.get(), &addr);
testOk1(static_cast<size_t>(16) == buff->getPosition()); testOk1(static_cast<size_t>(16) == buff->getPosition());
@ -161,16 +165,17 @@ void test_isMulticastAddress()
{ {
testDiag("Test test_isMulticastAddress()"); testDiag("Test test_isMulticastAddress()");
auto_ptr<InetAddrVector> vec(getSocketAddressList("127.0.0.1 255.255.255.255 0.0.0.0 224.0.0.0 239.255.255.255 235.3.6.3", 0)); InetAddrVector vec;
getSocketAddressList(vec, "127.0.0.1 255.255.255.255 0.0.0.0 224.0.0.0 239.255.255.255 235.3.6.3", 0);
testOk1(static_cast<size_t>(6) == vec->size()); testOk1(static_cast<size_t>(6) == vec.size());
testOk1(!isMulticastAddress(&vec->at(0))); testOk1(!isMulticastAddress(&vec.at(0)));
testOk1(!isMulticastAddress(&vec->at(1))); testOk1(!isMulticastAddress(&vec.at(1)));
testOk1(!isMulticastAddress(&vec->at(2))); testOk1(!isMulticastAddress(&vec.at(2)));
testOk1(isMulticastAddress(&vec->at(3))); testOk1(isMulticastAddress(&vec.at(3)));
testOk1(isMulticastAddress(&vec->at(4))); testOk1(isMulticastAddress(&vec.at(4)));
testOk1(isMulticastAddress(&vec->at(5))); testOk1(isMulticastAddress(&vec.at(5)));
} }
void test_getBroadcastAddresses() void test_getBroadcastAddresses()
@ -180,15 +185,16 @@ void test_getBroadcastAddresses()
osiSockAttach(); osiSockAttach();
SOCKET socket = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP); SOCKET socket = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP);
auto_ptr<InetAddrVector> broadcasts(getBroadcastAddresses(socket, 6678)); InetAddrVector broadcasts;
getBroadcastAddresses(broadcasts, socket, 6678);
// at least one is expected, in case of no network connection a fallback address is returned // at least one is expected, in case of no network connection a fallback address is returned
testOk1(static_cast<size_t>(0) < broadcasts->size()); testOk1(static_cast<size_t>(0) < broadcasts.size());
//testDiag("getBroadcastAddresses() returned %zu entry/-ies.", broadcasts->size()); //testDiag("getBroadcastAddresses() returned %zu entry/-ies.", broadcasts->size());
epicsSocketDestroy(socket); epicsSocketDestroy(socket);
// debug // debug
for(size_t i = 0; i<broadcasts->size(); i++) { for(size_t i = 0; i<broadcasts.size(); i++) {
testDiag("%s", inetAddressToString(broadcasts->at(i)).c_str()); testDiag("%s", inetAddressToString(broadcasts[i]).c_str());
} }
} }
@ -229,7 +235,7 @@ void test_multicastLoopback()
SOCKET socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, IPPROTO_UDP); SOCKET socket = epicsSocketCreate(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
testOk1(socket != INVALID_SOCKET); testOk1(socket != INVALID_SOCKET);
if (socket == INVALID_SOCKET) if (socket == INVALID_SOCKET)
return; testAbort("Can't allocate socket");
unsigned short port = 5555; unsigned short port = 5555;
@ -246,7 +252,7 @@ void test_multicastLoopback()
{ {
char errStr[64]; char errStr[64];
epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
fprintf(stderr, "Failed to bind: %s\n", errStr); testFail("Failed to bind: %s\n", errStr);
epicsSocketDestroy(socket); epicsSocketDestroy(socket);
return; return;
} }
@ -270,7 +276,7 @@ void test_multicastLoopback()
{ {
char errStr[64]; char errStr[64];
epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
fprintf(stderr, "Error setting IP_ADD_MEMBERSHIP: %s\n", errStr); testFail("Error setting IP_ADD_MEMBERSHIP: %s\n", errStr);
} }
testOk(status == 0, "IP_ADD_MEMBERSHIP set"); testOk(status == 0, "IP_ADD_MEMBERSHIP set");
@ -288,7 +294,7 @@ void test_multicastLoopback()
{ {
char errStr[64]; char errStr[64];
epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
fprintf(stderr, "Error setting IP_MULTICAST_IF: %s\n", errStr); testFail("Error setting IP_MULTICAST_IF: %s\n", errStr);
} }
testOk(status == 0, "IP_MULTICAST_IF set"); testOk(status == 0, "IP_MULTICAST_IF set");
@ -300,7 +306,7 @@ void test_multicastLoopback()
{ {
char errStr[64]; char errStr[64];
epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
fprintf(stderr, "Error setting IP_MULTICAST_LOOP: %s\n", errStr); testFail("Error setting IP_MULTICAST_LOOP: %s\n", errStr);
} }
testOk(status == 0, "IP_MULTICAST_LOOP set"); testOk(status == 0, "IP_MULTICAST_LOOP set");
@ -317,7 +323,7 @@ void test_multicastLoopback()
{ {
char errStr[64]; char errStr[64];
epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
fprintf(stderr, "Multicast send error: %s\n", errStr); testFail("Multicast send error: %s\n", errStr);
} }
testOk((size_t)status == len, "Multicast send"); testOk((size_t)status == len, "Multicast send");
@ -334,7 +340,7 @@ void test_multicastLoopback()
{ {
char errStr[64]; char errStr[64];
epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
fprintf(stderr, "Error setting SO_RCVTIMEO: %s\n", errStr); testFail("Error setting SO_RCVTIMEO: %s\n", errStr);
} }
testOk(status == 0, "SO_RCVTIMEO set"); testOk(status == 0, "SO_RCVTIMEO set");
@ -350,7 +356,7 @@ void test_multicastLoopback()
{ {
char errStr[64]; char errStr[64];
epicsSocketConvertErrnoToString(errStr, sizeof(errStr)); epicsSocketConvertErrnoToString(errStr, sizeof(errStr));
fprintf(stderr, "Multicast recv error: %s\n", errStr); testFail("Multicast recv error: %s\n", errStr);
} }
testOk((size_t)status == len, "Multicast recv"); testOk((size_t)status == len, "Multicast recv");
testOk(strncmp(rxbuff, txbuff, len) == 0, "Multicast content matches"); testOk(strncmp(rxbuff, txbuff, len) == 0, "Multicast content matches");
@ -362,7 +368,7 @@ void test_multicastLoopback()
MAIN(testInetAddressUtils) MAIN(testInetAddressUtils)
{ {
testPlan(83); testPlan(80);
testDiag("Tests for InetAddress utils"); testDiag("Tests for InetAddress utils");
test_getSocketAddressList(); test_getSocketAddressList();