1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 16:57:16 +01:00
SqMod/vendor/POCO/Net/src/ICMPSocket.cpp
Sandu Liviu Catalin 4a6bfc086c Major plugin refactor and cleanup.
Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
2021-01-30 08:51:39 +02:00

148 lines
2.8 KiB
C++

//
// ICMPSocket.cpp
//
// Library: Net
// Package: ICMP
// Module: ICMPSocket
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Net/ICMPSocket.h"
#include "Poco/Net/ICMPSocketImpl.h"
#include "Poco/Exception.h"
#include "Poco/Net/NetException.h"
using Poco::InvalidArgumentException;
namespace Poco {
namespace Net {
ICMPSocket::ICMPSocket(IPAddress::Family family, int dataSize, int ttl, int timeout):
Socket(new ICMPSocketImpl(family, dataSize, ttl, timeout))
{
}
ICMPSocket::ICMPSocket(const Socket& socket):
Socket(socket)
{
if (!dynamic_cast<ICMPSocketImpl*>(impl()))
throw InvalidArgumentException("Cannot assign incompatible socket");
}
ICMPSocket::ICMPSocket(SocketImpl* pImpl):
Socket(pImpl)
{
if (!dynamic_cast<ICMPSocketImpl*>(impl()))
throw InvalidArgumentException("Cannot assign incompatible socket");
}
ICMPSocket::~ICMPSocket()
{
}
ICMPSocket& ICMPSocket::operator = (const Socket& socket)
{
if (dynamic_cast<ICMPSocketImpl*>(socket.impl()))
Socket::operator = (socket);
else
throw InvalidArgumentException("Cannot assign incompatible socket");
return *this;
}
int ICMPSocket::sendTo(const SocketAddress& address, int flags)
{
return impl()->sendTo(0, 0, address, flags);
}
int ICMPSocket::receiveFrom(SocketAddress& address, int flags)
{
return impl()->receiveFrom(0, 0, address, flags);
}
int ICMPSocket::dataSize() const
{
return static_cast<ICMPSocketImpl*>(impl())->dataSize();
}
int ICMPSocket::packetSize() const
{
return static_cast<ICMPSocketImpl*>(impl())->packetSize();
}
int ICMPSocket::ttl() const
{
return static_cast<ICMPSocketImpl*>(impl())->ttl();
}
int ICMPSocket::timeout() const
{
return static_cast<ICMPSocketImpl*>(impl())->timeout();
}
Poco::UInt16 ICMPSocket::mtu(const SocketAddress& address, Poco::UInt16 sz)
{
if (address.family() != IPAddress::IPv4) return 0;
SocketAddress returnAddress(address);
for (; sz >= 68 /*RFC791*/; --sz)
{
ICMPSocket icmpSocket(address.family(), sz);
#ifdef IP_DONTFRAGMENT
icmpSocket.setOption(IPPROTO_IP, IP_DONTFRAGMENT, 1);
#elif defined(IP_MTU_DISCOVER)
icmpSocket.setOption(IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DO);
#elif defined(IP_DONTFRAG)
icmpSocket.setOption(IPPROTO_IP, IP_DONTFRAG, 1);
#else
throw NotImplementedException("ICMPSocket::mtu()");
#endif
try
{
icmpSocket.sendTo(address);
icmpSocket.receiveFrom(returnAddress);
poco_assert_dbg (returnAddress == address);
return sz;
}
catch (ICMPFragmentationException&)
{
// PMTU fragmentation, continue discovery
continue;
}
catch (NetException& ex)
{
// local MTU limit, continue discovery
if (ex.code() == POCO_EMSGSIZE)
continue;
}
catch (Exception&)
{
return 0;
}
}
return 0;
}
} } // namespace Poco::Net