/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file defines classes for abstracting access to and
 *      interactions with a platform- and system-specific Internet
 *      Protocol stack which, as of this implementation, may be either
 *      BSD/POSIX Sockets or LwIP.
 *
 *      Major abstractions provided are:
 *
 *        * Timers
 *        * Domain Name System (DNS) resolution
 *        * TCP network transport
 *        * UDP network transport
 *        * Raw network transport
 *
 *      For BSD/POSIX Sockets, event readiness notification is handled
 *      via file descriptors and a traditional poll / select
 *      implementation on the platform adaptation.
 *
 *      For LwIP, event readiness notification is handle via events /
 *      messages and platform- and system-specific hooks for the event
 *      / message system.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include "InetLayer.h"

#include "InetFaultInjection.h"

#include <system/SystemTimer.h>

#include <support/CodeUtils.h>
#include <support/logging/CHIPLogging.h>

#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <utility>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/netif.h>
#include <lwip/sys.h>
#else // !CHIP_SYSTEM_CONFIG_USE_LWIP
#include <fcntl.h>
#include <net/if.h>
#include <unistd.h>
#ifdef __ANDROID__
#include <ifaddrs-android.h>
#elif CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
#include <ifaddrs.h>
#endif
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
#include <net/net_if.h>
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

namespace chip {
namespace Inet {

void InetLayer::UpdateSnapshot(chip::System::Stats::Snapshot & aSnapshot)
{
#if INET_CONFIG_ENABLE_DNS_RESOLVER
    DNSResolver::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumDNSResolvers],
                                     aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumDNSResolvers]);
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    TCPEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumTCPEps],
                                     aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumTCPEps]);
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
#if INET_CONFIG_ENABLE_UDP_ENDPOINT
    UDPEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumUDPEps],
                                     aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumUDPEps]);
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
#if INET_CONFIG_ENABLE_RAW_ENDPOINT
    RawEndPoint::sPool.GetStatistics(aSnapshot.mResourcesInUse[chip::System::Stats::kInetLayer_NumRawEps],
                                     aSnapshot.mHighWatermarks[chip::System::Stats::kInetLayer_NumRawEps]);
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT
}

/**
 *  This is the InetLayer default constructor.
 *
 *  It performs some basic data member initialization; however, since
 *  InetLayer follows an explicit initializer design pattern, the InetLayer::Init
 *  method must be called successfully prior to using the object.
 *
 */
InetLayer::InetLayer()
{
    State = kState_NotInitialized;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    if (!sInetEventHandlerDelegate.IsInitialized())
        sInetEventHandlerDelegate.Init(HandleInetLayerEvent);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
}

#if CHIP_SYSTEM_CONFIG_USE_LWIP
chip::System::LwIPEventHandlerDelegate InetLayer::sInetEventHandlerDelegate;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if INET_CONFIG_MAX_DROPPABLE_EVENTS && CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_NO_LOCKING

INET_ERROR InetLayer::InitQueueLimiter(void)
{
    mDroppableEvents = 0;
    return INET_NO_ERROR;
}

bool InetLayer::CanEnqueueDroppableEvent(void)
{
    if (__sync_add_and_fetch(&mDroppableEvents, 1) <= INET_CONFIG_MAX_DROPPABLE_EVENTS)
    {
        return true;
    }
    else
    {
        __sync_add_and_fetch(&mDroppableEvents, -1);
        return false;
    }
}

void InetLayer::DroppableEventDequeued(void)
{
    __sync_add_and_fetch(&mDroppableEvents, -1);
}

#elif CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING

INET_ERROR InetLayer::InitQueueLimiter(void)
{
    const unsigned portBASE_TYPE maximum = INET_CONFIG_MAX_DROPPABLE_EVENTS;
    const unsigned portBASE_TYPE initial = INET_CONFIG_MAX_DROPPABLE_EVENTS;

#if (configSUPPORT_STATIC_ALLOCATION == 1)
    mDroppableEvents                     = xSemaphoreCreateCountingStatic(maximum, initial, &mDroppableEventsObj);
#else
    mDroppableEvents = xSemaphoreCreateCounting(maximum, initial);
#endif

    if (mDroppableEvents != NULL)
        return INET_NO_ERROR;
    else
        return INET_ERROR_NO_MEMORY;
}

bool InetLayer::CanEnqueueDroppableEvent(void)
{
    if (xSemaphoreTake(mDroppableEvents, 0) != pdTRUE)
    {
        return false;
    }
    return true;
}

void InetLayer::DroppableEventDequeued(void)
{
    xSemaphoreGive(mDroppableEvents);
}

#else // !CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING

INET_ERROR InetLayer::InitQueueLimiter(void)
{
    if (sem_init(&mDroppableEvents, 0, INET_CONFIG_MAX_DROPPABLE_EVENTS) != 0)
    {
        return chip::System::MapErrorPOSIX(errno);
    }
    return INET_NO_ERROR;
}

bool InetLayer::CanEnqueueDroppableEvent(void)
{
    // Striclty speaking, we should check for EAGAIN.  But, other
    // errno values probably should signal that that we should drop
    // the packet: EINVAL means that the semaphore is not valid (we
    // failed initialization), and EINTR should probably also lead to
    // dropping a packet.

    if (sem_trywait(&mDroppableEvents) != 0)
    {
        return false;
    }
    return true;
}

void InetLayer::DroppableEventDequeued(void)
{
    sem_post(&mDroppableEvents);
}

#endif // !CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
#endif // INET_CONFIG_MAX_DROPPABLE_EVENTS && CHIP_SYSTEM_CONFIG_USE_LWIP

/**
 *  This is the InetLayer explicit initializer. This must be called
 *  and complete successfully before the InetLayer may be used.
 *
 *  The caller may provide an optional context argument which will be
 *  passed back via any platform-specific hook functions. For
 *  LwIP-based adaptations, this will typically be a pointer to the
 *  event queue associated with the InetLayer instance.
 *
 *  Platforms may choose to assert
 *  #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS in their
 *  platform-specific configuration header and enable the
 *  Platform::InetLayer::WillInit and Platform::InetLayer::DidInit
 *  hooks to effect platform-specific customizations or data extensions
 *  to InetLayer.
 *
 *  @param[in]  aSystemLayer  A required instance of the chip System Layer
 *                            already successfully initialized.
 *
 *  @param[in]  aContext  An optional context argument which will be passed
 *                        back to the caller via any platform-specific hook
 *                        functions.
 *
 *  @retval   #INET_ERROR_INCORRECT_STATE        If the InetLayer is in an
 *                                               incorrect state.
 *  @retval   #INET_ERROR_NO_MEMORY              If the InetLayer runs out
 *                                               of resource for this
 *                                               request for a new timer.
 *  @retval   other Platform-specific errors indicating the reason for
 *            initialization failure.
 *  @retval   #INET_NO_ERROR                     On success.
 *
 */
INET_ERROR InetLayer::Init(chip::System::Layer & aSystemLayer, void * aContext)
{
    INET_ERROR err = INET_NO_ERROR;

    Inet::RegisterLayerErrorFormatter();

    if (State != kState_NotInitialized)
        return INET_ERROR_INCORRECT_STATE;

    // Platform-specific initialization may elect to set this data
    // member. Ensure it is set to a sane default value before
    // invoking platform-specific initialization.

    mPlatformData = nullptr;

    err = Platform::InetLayer::WillInit(this, aContext);
    SuccessOrExit(err);

    mSystemLayer = &aSystemLayer;
    mContext     = aContext;

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    err = InitQueueLimiter();
    SuccessOrExit(err);

    mSystemLayer->AddEventHandlerDelegate(sInetEventHandlerDelegate);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    State = kState_Initialized;

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
#if INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

    err = mAsyncDNSResolver.Init(this);
    SuccessOrExit(err);

#endif // INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

exit:
    Platform::InetLayer::DidInit(this, mContext, err);
    return err;
}

/**
 *  This is the InetLayer explicit deinitializer and should be called
 *  prior to disposing of an instantiated InetLayer instance.
 *
 *  Platforms may choose to assert
 *  #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS in their
 *  platform-specific configuration header and enable the
 *  Platform::InetLayer::WillShutdown and
 *  Platform::InetLayer::DidShutdown hooks to effect clean-up of
 *  platform-specific customizations or data extensions to InetLayer.
 *
 *  @return #INET_NO_ERROR on success; otherwise, a specific error indicating
 *          the reason for shutdown failure.
 *
 */
INET_ERROR InetLayer::Shutdown()
{
    INET_ERROR err;

    err = Platform::InetLayer::WillShutdown(this, mContext);
    SuccessOrExit(err);

    if (State == kState_Initialized)
    {
#if INET_CONFIG_ENABLE_DNS_RESOLVER
        // Cancel all DNS resolution requests owned by this instance.
        for (size_t i = 0; i < DNSResolver::sPool.Size(); i++)
        {
            DNSResolver * lResolver = DNSResolver::sPool.Get(*mSystemLayer, i);
            if ((lResolver != nullptr) && lResolver->IsCreatedByInetLayer(*this))
            {
                lResolver->Cancel();
            }
        }

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

        err = mAsyncDNSResolver.Shutdown();

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER

#if INET_CONFIG_ENABLE_RAW_ENDPOINT
        // Close all raw endpoints owned by this Inet layer instance.
        for (size_t i = 0; i < RawEndPoint::sPool.Size(); i++)
        {
            RawEndPoint * lEndPoint = RawEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->Close();
            }
        }
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
        // Abort all TCP endpoints owned by this instance.
        for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
        {
            TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->Abort();
            }
        }
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
        // Close all UDP endpoints owned by this instance.
        for (size_t i = 0; i < UDPEndPoint::sPool.Size(); i++)
        {
            UDPEndPoint * lEndPoint = UDPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->Close();
            }
        }
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
    }

    State = kState_NotInitialized;

exit:
    Platform::InetLayer::DidShutdown(this, mContext, err);

    return err;
}

/**
 * This returns any client-specific platform data assigned to the
 * instance, if it has been previously set.
 *
 * @return Client-specific platform data, if is has been previously set;
 *         otherwise, NULL.
 *
 */
void * InetLayer::GetPlatformData()
{
    return mPlatformData;
}

/**
 * This sets the specified client-specific platform data to the
 * instance for later retrieval by the client platform.
 *
 * @param[in]  aPlatformData  The client-specific platform data to set.
 *
 */
void InetLayer::SetPlatformData(void * aPlatformData)
{
    mPlatformData = aPlatformData;
}

#if INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
bool InetLayer::IsIdleTimerRunning()
{
    bool timerRunning = false;

    // see if there are any TCP connections with the idle timer check in use.
    for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
    {
        TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);

        if ((lEndPoint != nullptr) && (lEndPoint->mIdleTimeout != 0))
        {
            timerRunning = true;
            break;
        }
    }

    return timerRunning;
}
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0

/**
 *  Get the link local IPv6 address for a specified link or interface.
 *
 *  @param[in]    link    The interface for which the link local IPv6
 *                        address is being sought.
 *
 *  @param[out]   llAddr  The link local IPv6 address for the link.
 *
 *  @retval    #INET_ERROR_NOT_IMPLEMENTED      If IPv6 is not supported.
 *  @retval    #INET_ERROR_BAD_ARGS             If the link local address
 *                                              is NULL.
 *  @retval    #INET_ERROR_ADDRESS_NOT_FOUND    If the link does not have
 *                                              any address configured.
 *  @retval    #INET_NO_ERROR                   On success.
 *
 */
INET_ERROR InetLayer::GetLinkLocalAddr(InterfaceId link, IPAddress * llAddr)
{
    INET_ERROR err = INET_NO_ERROR;
#if CHIP_SYSTEM_CONFIG_USE_LWIP
#if !LWIP_IPV6
    err = INET_ERROR_NOT_IMPLEMENTED;
    goto exit;
#endif //! LWIP_IPV6
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    if (llAddr == nullptr)
    {
        err = INET_ERROR_BAD_ARGS;
        goto exit;
    }

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    for (struct netif * intf = netif_list; intf != NULL; intf = intf->next)
    {
        if ((link != NULL) && (link != intf))
            continue;
        int j;
        for (j = 0; j < LWIP_IPV6_NUM_ADDRESSES; ++j)
        {
            if (ip6_addr_isvalid(netif_ip6_addr_state(intf, j)) && ip6_addr_islinklocal(netif_ip6_addr(intf, j)))
            {
                (*llAddr) = IPAddress::FromIPv6(*netif_ip6_addr(intf, j));
                goto exit;
            }
        }
        if (link != NULL)
        {
            err = INET_ERROR_ADDRESS_NOT_FOUND;
            break;
        }
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    struct ifaddrs * ifaddr;
    int rv;
    rv = getifaddrs(&ifaddr);
    if (rv != -1)
    {
        struct ifaddrs * ifaddr_iter = ifaddr;
        while (ifaddr_iter != nullptr)
        {

            if (ifaddr_iter->ifa_addr != nullptr)
            {
                if ((ifaddr_iter->ifa_addr->sa_family == AF_INET6) &&
                    ((link == INET_NULL_INTERFACEID) || (if_nametoindex(ifaddr_iter->ifa_name) == link)))
                {
                    struct in6_addr * sin6_addr = &(reinterpret_cast<struct sockaddr_in6 *>(ifaddr_iter->ifa_addr))->sin6_addr;
                    if (sin6_addr->s6_addr[0] == 0xfe && (sin6_addr->s6_addr[1] & 0xc0) == 0x80) // Link Local Address
                    {
                        (*llAddr) =
                            IPAddress::FromIPv6((reinterpret_cast<struct sockaddr_in6 *>(ifaddr_iter->ifa_addr))->sin6_addr);
                        break;
                    }
                }
            }
            ifaddr_iter = ifaddr_iter->ifa_next;
        }
        freeifaddrs(ifaddr);
    }
    else
    {
        err = INET_ERROR_ADDRESS_NOT_FOUND;
    }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    net_if * iface;
    in6_addr * ip6_addr;

    iface = (link == INET_NULL_INTERFACEID) ? net_if_get_default() : net_if_get_by_index(link);
    VerifyOrExit(iface != nullptr, err = INET_ERROR_ADDRESS_NOT_FOUND);

    ip6_addr = net_if_ipv6_get_ll(iface, NET_ADDR_PREFERRED);
    VerifyOrExit(ip6_addr != nullptr, err = INET_ERROR_ADDRESS_NOT_FOUND);

    *llAddr = IPAddress::FromIPv6(*ip6_addr);
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

exit:
    return err;
}

#if INET_CONFIG_ENABLE_RAW_ENDPOINT
/**
 *  Creates a new RawEndPoint object for a specific IP version and protocol.
 *
 *  @note
 *    This function gets a free RawEndPoint object from a pre-allocated pool
 *    and also calls the explicit initializer on the new object.
 *
 *  @param[in]      ipVer          IPv4 or IPv6.
 *
 *  @param[in]      ipProto        A protocol within the IP family (e.g., ICMPv4 or ICMPv6).
 *
 *  @param[in,out]  retEndPoint    A pointer to a pointer of the RawEndPoint object that is
 *                                 a return parameter upon completion of the object creation.
 *                                 *retEndPoint is NULL if creation fails.
 *
 *  @retval  #INET_ERROR_INCORRECT_STATE  If the InetLayer object is not initialized.
 *  @retval  #INET_ERROR_NO_ENDPOINTS     If the InetLayer RawEndPoint pool is full and no new
 *                                        endpoints can be created.
 *  @retval  #INET_NO_ERROR               On success.
 *
 */
INET_ERROR InetLayer::NewRawEndPoint(IPVersion ipVer, IPProtocol ipProto, RawEndPoint ** retEndPoint)
{
    INET_ERROR err = INET_NO_ERROR;
    *retEndPoint   = nullptr;

    VerifyOrExit(State == kState_Initialized, err = INET_ERROR_INCORRECT_STATE);

    *retEndPoint = RawEndPoint::sPool.TryCreate(*mSystemLayer);
    if (*retEndPoint != nullptr)
    {
        (*retEndPoint)->Inet::RawEndPoint::Init(this, ipVer, ipProto);
        SYSTEM_STATS_INCREMENT(chip::System::Stats::kInetLayer_NumRawEps);
    }
    else
    {
        ChipLogError(Inet, "%s endpoint pool FULL", "Raw");
        err = INET_ERROR_NO_ENDPOINTS;
    }

exit:
    return err;
}
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
/**
 *  Creates a new TCPEndPoint object.
 *
 *  @note
 *    This function gets a free TCPEndPoint object from a pre-allocated pool
 *    and also calls the explicit initializer on the new object.
 *
 *  @param[in,out]  retEndPoint    A pointer to a pointer of the TCPEndPoint object that is
 *                                 a return parameter upon completion of the object creation.
 *                                 *retEndPoint is NULL if creation fails.
 *
 *  @retval  #INET_ERROR_INCORRECT_STATE  If the InetLayer object is not initialized.
 *  @retval  #INET_ERROR_NO_ENDPOINTS     If the InetLayer TCPEndPoint pool is full and no new
 *                                        endpoints can be created.
 *  @retval  #INET_NO_ERROR               On success.
 *
 */
INET_ERROR InetLayer::NewTCPEndPoint(TCPEndPoint ** retEndPoint)
{
    INET_ERROR err = INET_NO_ERROR;
    *retEndPoint   = nullptr;

    VerifyOrExit(State == kState_Initialized, err = INET_ERROR_INCORRECT_STATE);

    *retEndPoint = TCPEndPoint::sPool.TryCreate(*mSystemLayer);
    if (*retEndPoint != nullptr)
    {
        (*retEndPoint)->Init(this);
        SYSTEM_STATS_INCREMENT(chip::System::Stats::kInetLayer_NumTCPEps);
    }
    else
    {
        ChipLogError(Inet, "%s endpoint pool FULL", "TCP");
        err = INET_ERROR_NO_ENDPOINTS;
    }

exit:
    return err;
}
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
/**
 *  Creates a new UDPEndPoint object.
 *
 *  @note
 *    This function gets a free UDPEndPoint object from a pre-allocated pool
 *    and also calls the explicit initializer on the new object.
 *
 *  @param[in,out]  retEndPoint    A pointer to a pointer of the UDPEndPoint object that is
 *                                 a return parameter upon completion of the object creation.
 *                                 *retEndPoint is NULL if creation fails.
 *
 *  @retval  #INET_ERROR_INCORRECT_STATE  If the InetLayer object is not initialized.
 *  @retval  #INET_ERROR_NO_ENDPOINTS     If the InetLayer UDPEndPoint pool is full and no new
 *                                        endpoints can be created.
 *  @retval  #INET_NO_ERROR               On success.
 *
 */
INET_ERROR InetLayer::NewUDPEndPoint(UDPEndPoint ** retEndPoint)
{
    INET_ERROR err = INET_NO_ERROR;
    *retEndPoint   = nullptr;

    VerifyOrExit(State == kState_Initialized, err = INET_ERROR_INCORRECT_STATE);

    *retEndPoint = UDPEndPoint::sPool.TryCreate(*mSystemLayer);
    if (*retEndPoint != nullptr)
    {
        (*retEndPoint)->Init(this);
        SYSTEM_STATS_INCREMENT(chip::System::Stats::kInetLayer_NumUDPEps);
    }
    else
    {
        ChipLogError(Inet, "%s endpoint pool FULL", "UDP");
        err = INET_ERROR_NO_ENDPOINTS;
    }

exit:
    return err;
}
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT

#if INET_CONFIG_ENABLE_DNS_RESOLVER
/**
 *  Perform an IP address resolution of a specified hostname.
 *
 *  @note
 *    This is an asynchronous operation and the result will be communicated back
 *    via the OnComplete() callback.
 *
 *  @param[in]  hostName    A pointer to a NULL-terminated C string representing
 *                          the host name to be queried.
 *
 *  @param[in]  maxAddrs    The maximum number of addresses to store in the DNS
 *                          table.
 *
 *  @param[in]  addrArray   A pointer to the DNS table.
 *
 *  @param[in]  onComplete  A pointer to the callback function when a DNS
 *                          request is complete.
 *
 *  @param[in]  appState    A pointer to the application state to be passed to
 *                          onComplete when a DNS request is complete.
 *
 *  @retval #INET_NO_ERROR                   if a DNS request is handled
 *                                           successfully.
 *  @retval #INET_ERROR_NO_MEMORY            if the Inet layer resolver pool
 *                                           is full.
 *  @retval #INET_ERROR_HOST_NAME_TOO_LONG   if a requested host name is too
 *                                           long.
 *  @retval #INET_ERROR_HOST_NOT_FOUND       if a request host name could not be
 *                                           resolved to an address.
 *  @retval #INET_ERROR_DNS_TRY_AGAIN        if a name server returned a
 *                                           temporary failure indication;
 *                                           try again later.
 *  @retval #INET_ERROR_DNS_NO_RECOVERY      if a name server returned an
 *                                           unrecoverable error.
 *  @retval #INET_ERROR_NOT_IMPLEMENTED      if DNS resolution is not enabled on
 *                                           the underlying platform.
 *  @retval other POSIX network or OS error returned by the underlying DNS
 *          resolver implementation.
 *
 */
INET_ERROR InetLayer::ResolveHostAddress(const char * hostName, uint8_t maxAddrs, IPAddress * addrArray,
                                         DNSResolveCompleteFunct onComplete, void * appState)
{
    size_t hostNameLength = strlen(hostName);
    if (hostNameLength > UINT16_MAX)
    {
        return INET_ERROR_HOST_NAME_TOO_LONG;
    }
    return ResolveHostAddress(hostName, static_cast<uint16_t>(hostNameLength), maxAddrs, addrArray, onComplete, appState);
}

/**
 *  Perform an IP address resolution of a specified hostname.
 *
 *  @param[in]  hostName    A pointer to a non NULL-terminated C string representing the host name
 *                          to be queried.
 *
 *  @param[in]  hostNameLen The string length of host name.
 *
 *  @param[in]  maxAddrs    The maximum number of addresses to store in the DNS
 *                          table.
 *
 *  @param[in]  addrArray   A pointer to the DNS table.
 *
 *  @param[in]  onComplete  A pointer to the callback function when a DNS
 *                          request is complete.
 *
 *  @param[in]  appState    A pointer to the application state to be passed to
 *                          onComplete when a DNS request is complete.
 *
 *  @retval #INET_NO_ERROR                   if a DNS request is handled
 *                                           successfully.
 *  @retval #INET_ERROR_NO_MEMORY            if the Inet layer resolver pool
 *                                           is full.
 *  @retval #INET_ERROR_HOST_NAME_TOO_LONG   if a requested host name is too
 *                                           long.
 *  @retval #INET_ERROR_HOST_NOT_FOUND       if a request host name could not be
 *                                           resolved to an address.
 *  @retval #INET_ERROR_DNS_TRY_AGAIN        if a name server returned a
 *                                           temporary failure indication;
 *                                           try again later.
 *  @retval #INET_ERROR_DNS_NO_RECOVERY      if a name server returned an
 *                                           unrecoverable error.
 *  @retval #INET_ERROR_NOT_IMPLEMENTED      if DNS resolution is not enabled on
 *                                           the underlying platform.
 *  @retval other POSIX network or OS error returned by the underlying DNS
 *          resolver implementation.
 *
 */
INET_ERROR InetLayer::ResolveHostAddress(const char * hostName, uint16_t hostNameLen, uint8_t maxAddrs, IPAddress * addrArray,
                                         DNSResolveCompleteFunct onComplete, void * appState)
{
    return ResolveHostAddress(hostName, hostNameLen, kDNSOption_Default, maxAddrs, addrArray, onComplete, appState);
}

/**
 *  Perform an IP address resolution of a specified hostname.
 *
 *  @param[in]  hostName    A pointer to a non NULL-terminated C string representing the host name
 *                          to be queried.
 *
 *  @param[in]  hostNameLen The string length of host name.
 *
 *  @param[in]  options     An integer value controlling how host name resolution is performed.
 *
 *                          Value should be one of the address family values from the
 *                          #DNSOptions enumeration:
 *
 *                          #kDNSOption_AddrFamily_Any
 *                          #kDNSOption_AddrFamily_IPv4Only
 *                          #kDNSOption_AddrFamily_IPv6Only
 *                          #kDNSOption_AddrFamily_IPv4Preferred
 *                          #kDNSOption_AddrFamily_IPv6Preferred
 *
 *  @param[in]  maxAddrs    The maximum number of addresses to store in the DNS
 *                          table.
 *
 *  @param[in]  addrArray   A pointer to the DNS table.
 *
 *  @param[in]  onComplete  A pointer to the callback function when a DNS
 *                          request is complete.
 *
 *  @param[in]  appState    A pointer to the application state to be passed to
 *                          onComplete when a DNS request is complete.
 *
 *  @retval #INET_NO_ERROR                   if a DNS request is handled
 *                                           successfully.
 *  @retval #INET_ERROR_NO_MEMORY            if the Inet layer resolver pool
 *                                           is full.
 *  @retval #INET_ERROR_HOST_NAME_TOO_LONG   if a requested host name is too
 *                                           long.
 *  @retval #INET_ERROR_HOST_NOT_FOUND       if a request host name could not be
 *                                           resolved to an address.
 *  @retval #INET_ERROR_DNS_TRY_AGAIN        if a name server returned a
 *                                           temporary failure indication;
 *                                           try again later.
 *  @retval #INET_ERROR_DNS_NO_RECOVERY      if a name server returned an
 *                                           unrecoverable error.
 *  @retval #INET_ERROR_NOT_IMPLEMENTED      if DNS resolution is not enabled on
 *                                           the underlying platform.
 *  @retval other POSIX network or OS error returned by the underlying DNS
 *          resolver implementation.
 *
 */
INET_ERROR InetLayer::ResolveHostAddress(const char * hostName, uint16_t hostNameLen, uint8_t options, uint8_t maxAddrs,
                                         IPAddress * addrArray, DNSResolveCompleteFunct onComplete, void * appState)
{
    INET_ERROR err         = INET_NO_ERROR;
    DNSResolver * resolver = nullptr;

    VerifyOrExit(State == kState_Initialized, err = INET_ERROR_INCORRECT_STATE);

    INET_FAULT_INJECT(FaultInjection::kFault_DNSResolverNew, return INET_ERROR_NO_MEMORY);

    // Store context information and set the resolver state.
    VerifyOrExit(hostNameLen <= NL_DNS_HOSTNAME_MAX_LEN, err = INET_ERROR_HOST_NAME_TOO_LONG);
    VerifyOrExit(maxAddrs > 0, err = INET_ERROR_NO_MEMORY);

    resolver = DNSResolver::sPool.TryCreate(*mSystemLayer);
    if (resolver != nullptr)
    {
        resolver->InitInetLayerBasis(*this);
    }
    else
    {
        ChipLogError(Inet, "%s resolver pool FULL", "DNS");
        ExitNow(err = INET_ERROR_NO_MEMORY);
    }

    // Short-circuit full address resolution if the supplied host name is a text-form
    // IP address...
    if (IPAddress::FromString(hostName, hostNameLen, *addrArray))
    {
        uint8_t addrTypeOption = (options & kDNSOption_AddrFamily_Mask);
        IPAddressType addrType = addrArray->Type();

        if ((addrTypeOption == kDNSOption_AddrFamily_IPv6Only && addrType != kIPAddressType_IPv6)
#if INET_CONFIG_ENABLE_IPV4
            || (addrTypeOption == kDNSOption_AddrFamily_IPv4Only && addrType != kIPAddressType_IPv4)
#endif
        )
        {
            err = INET_ERROR_INCOMPATIBLE_IP_ADDRESS_TYPE;
        }

        if (onComplete)
        {
            onComplete(appState, err, (err == INET_NO_ERROR) ? 1 : 0, addrArray);
        }

        resolver->Release();
        resolver = nullptr;

        ExitNow(err = INET_NO_ERROR);
    }

    // After this point, the resolver will be released by:
    // - mAsyncDNSResolver (in case of ASYNC_DNS_SOCKETS)
    // - resolver->Resolve() (in case of synchronous resolving)
    // - the event handlers (in case of LwIP)

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

    err =
        mAsyncDNSResolver.PrepareDNSResolver(*resolver, hostName, hostNameLen, options, maxAddrs, addrArray, onComplete, appState);
    SuccessOrExit(err);

    mAsyncDNSResolver.EnqueueRequest(*resolver);

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

#if !INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
    err = resolver->Resolve(hostName, hostNameLen, options, maxAddrs, addrArray, onComplete, appState);
#endif // !INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
exit:

    return err;
}

/**
 *  Cancel any outstanding DNS query (for a matching completion callback and
 *  application state) that may still be active.
 *
 *  @note
 *    This situation can arise if the application initiates a connection
 *    to a peer using a hostname and then aborts/closes the connection
 *    before the hostname resolution completes.
 *
 *  @param[in]    onComplete   A pointer to the callback function when a DNS
 *                             request is complete.
 *
 *  @param[in]    appState     A pointer to an application state object to be passed
 *                             to the callback function as argument.
 *
 */
void InetLayer::CancelResolveHostAddress(DNSResolveCompleteFunct onComplete, void * appState)
{
    if (State != kState_Initialized)
        return;

    for (size_t i = 0; i < DNSResolver::sPool.Size(); i++)
    {
        DNSResolver * lResolver = DNSResolver::sPool.Get(*mSystemLayer, i);

        if (lResolver == nullptr)
        {
            continue;
        }

        if (!lResolver->IsCreatedByInetLayer(*this))
        {
            continue;
        }

        if (lResolver->OnComplete != onComplete)
        {
            continue;
        }

        if (lResolver->AppState != appState)
        {
            continue;
        }

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS
        if (lResolver->mState == DNSResolver::kState_Canceled)
        {
            continue;
        }
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS

        lResolver->Cancel();
        break;
    }
}

#endif // INET_CONFIG_ENABLE_DNS_RESOLVER

/**
 *  Get the interface identifier for the specified IP address. If the
 *  interface identifier cannot be derived it is set to the
 *  #INET_NULL_INTERFACEID.
 *
 *  @note
 *    This function fetches the first interface (from the configured list
 *    of interfaces) that matches the specified IP address.
 *
 *  @param[in]    addr      A reference to the IPAddress object.
 *
 *  @param[out]   intfId    A reference to the InterfaceId object.
 *
 *  @return  #INET_NO_ERROR unconditionally.
 *
 */
INET_ERROR InetLayer::GetInterfaceFromAddr(const IPAddress & addr, InterfaceId & intfId)
{
    InterfaceAddressIterator addrIter;

    for (; addrIter.HasCurrent(); addrIter.Next())
    {
        IPAddress curAddr = addrIter.GetAddress();
        if (addr == curAddr)
        {
            intfId = addrIter.GetInterface();
            return INET_NO_ERROR;
        }
    }

    intfId = INET_NULL_INTERFACEID;

    return INET_NO_ERROR;
}

/**
 *  Check if there is a prefix match between the specified IPv6 address and any of
 *  the locally configured IPv6 addresses.
 *
 *  @param[in]    addr    The IPv6 address to check for the prefix-match.
 *
 *  @return true if a successful match is found, otherwise false.
 *
 */
bool InetLayer::MatchLocalIPv6Subnet(const IPAddress & addr)
{
    if (addr.IsIPv6LinkLocal())
        return true;

    InterfaceAddressIterator ifAddrIter;
    for (; ifAddrIter.HasCurrent(); ifAddrIter.Next())
    {
        IPPrefix addrPrefix;
        addrPrefix.IPAddr = ifAddrIter.GetAddress();
#if INET_CONFIG_ENABLE_IPV4
        if (addrPrefix.IPAddr.IsIPv4())
            continue;
#endif // INET_CONFIG_ENABLE_IPV4
        if (addrPrefix.IPAddr.IsIPv6LinkLocal())
            continue;
        addrPrefix.Length = ifAddrIter.GetIPv6PrefixLength();
        if (addrPrefix.MatchAddress(addr))
            return true;
    }

    return false;
}

#if INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0
void InetLayer::HandleTCPInactivityTimer(chip::System::Layer * aSystemLayer, void * aAppState, chip::System::Error aError)
{
    InetLayer & lInetLayer = *reinterpret_cast<InetLayer *>(aAppState);
    bool lTimerRequired    = lInetLayer.IsIdleTimerRunning();

    for (size_t i = 0; i < INET_CONFIG_NUM_TCP_ENDPOINTS; i++)
    {
        TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*aSystemLayer, i);

        if (lEndPoint == nullptr)
            continue;
        if (!lEndPoint->IsCreatedByInetLayer(lInetLayer))
            continue;
        if (!lEndPoint->IsConnected())
            continue;
        if (lEndPoint->mIdleTimeout == 0)
            continue;

        if (lEndPoint->mRemainingIdleTime == 0)
        {
            lEndPoint->DoClose(INET_ERROR_IDLE_TIMEOUT, false);
        }
        else
        {
            --lEndPoint->mRemainingIdleTime;
        }
    }

    if (lTimerRequired)
    {
        aSystemLayer->StartTimer(INET_TCP_IDLE_CHECK_INTERVAL, HandleTCPInactivityTimer, &lInetLayer);
    }
}
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT && INET_TCP_IDLE_CHECK_INTERVAL > 0

#if CHIP_SYSTEM_CONFIG_USE_LWIP
chip::System::Error InetLayer::HandleInetLayerEvent(chip::System::Object & aTarget, chip::System::EventType aEventType,
                                                    uintptr_t aArgument)
{
    chip::System::Error lReturn = CHIP_SYSTEM_NO_ERROR;
    InetLayerBasis & lBasis     = static_cast<InetLayerBasis &>(aTarget);

    VerifyOrExit(INET_IsInetEvent(aEventType), lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT);

    // Dispatch the event according to its type.
    switch (aEventType)
    {
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    case kInetEvent_TCPConnectComplete:
        static_cast<TCPEndPoint &>(aTarget).HandleConnectComplete(static_cast<INET_ERROR>(aArgument));
        break;

    case kInetEvent_TCPConnectionReceived:
        static_cast<TCPEndPoint &>(aTarget).HandleIncomingConnection(reinterpret_cast<TCPEndPoint *>(aArgument));
        break;

    case kInetEvent_TCPDataReceived:
        static_cast<TCPEndPoint &>(aTarget).HandleDataReceived(
            System::PacketBufferHandle::Adopt(reinterpret_cast<chip::System::PacketBuffer *>(aArgument)));
        break;

    case kInetEvent_TCPDataSent:
        static_cast<TCPEndPoint &>(aTarget).HandleDataSent(static_cast<uint16_t>(aArgument));
        break;

    case kInetEvent_TCPError:
        static_cast<TCPEndPoint &>(aTarget).HandleError(static_cast<INET_ERROR>(aArgument));
        break;
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_RAW_ENDPOINT
    case kInetEvent_RawDataReceived:
        static_cast<RawEndPoint &>(aTarget).HandleDataReceived(
            System::PacketBufferHandle::Adopt(reinterpret_cast<chip::System::PacketBuffer *>(aArgument)));
        break;
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
    case kInetEvent_UDPDataReceived:
        static_cast<UDPEndPoint &>(aTarget).HandleDataReceived(
            System::PacketBufferHandle::Adopt(reinterpret_cast<chip::System::PacketBuffer *>(aArgument)));
        break;
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT

#if INET_CONFIG_ENABLE_DNS_RESOLVER
    case kInetEvent_DNSResolveComplete:
        static_cast<DNSResolver &>(aTarget).HandleResolveComplete();
        break;
#endif // INET_CONFIG_ENABLE_DNS_RESOLVER

    default:
        lReturn = CHIP_SYSTEM_ERROR_UNEXPECTED_EVENT;
        ExitNow();
    }

    // If the event was droppable, record the fact that it has been dequeued.
    if (IsDroppableEvent(aEventType))
    {
        InetLayer & lInetLayer = lBasis.Layer();

        lInetLayer.DroppableEventDequeued();
    }

exit:
    return lReturn;
}

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
/**
 *  Prepare the sets of file descriptors for @p select() to work with.
 *
 *  @param[out]    nfds       The range of file descriptors in the file
 *                            descriptor set.
 *
 *  @param[in]     readfds    A pointer to the set of readable file descriptors.
 *
 *  @param[in]     writefds   A pointer to the set of writable file descriptors.
 *
 *  @param[in]     exceptfds  A pointer to the set of file descriptors with errors.
 *
 * @param[in]      sleepTimeTV A pointer to a structure specifying how long the select should sleep
 *
 */
void InetLayer::PrepareSelect(int & nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval & sleepTimeTV)
{
    if (State != kState_Initialized)
        return;

#if INET_CONFIG_ENABLE_RAW_ENDPOINT
    for (size_t i = 0; i < RawEndPoint::sPool.Size(); i++)
    {
        RawEndPoint * lEndPoint = RawEndPoint::sPool.Get(*mSystemLayer, i);
        if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            lEndPoint->PrepareIO().SetFDs(lEndPoint->mSocket, nfds, readfds, writefds, exceptfds);
    }
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
    for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
    {
        TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);
        if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            lEndPoint->PrepareIO().SetFDs(lEndPoint->mSocket, nfds, readfds, writefds, exceptfds);
    }
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
    for (size_t i = 0; i < UDPEndPoint::sPool.Size(); i++)
    {
        UDPEndPoint * lEndPoint = UDPEndPoint::sPool.Get(*mSystemLayer, i);
        if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            lEndPoint->PrepareIO().SetFDs(lEndPoint->mSocket, nfds, readfds, writefds, exceptfds);
    }
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
}

/**
 *  Handle I/O from a select call. This method registers the pending I/O
 *  event in each active endpoint and then invokes the respective I/O
 *  handling functions for those endpoints.
 *
 *  @note
 *    It is important to set the pending I/O fields for all endpoints
 *    *before* making any callbacks. This avoids the case where an
 *    endpoint is closed and then re-opened within the callback for
 *    another endpoint. When this happens the new endpoint is likely
 *    to be assigned the same file descriptor as the old endpoint.
 *    However, any pending I/O for that file descriptor number represents
 *    I/O related to the old incarnation of the endpoint, not the current
 *    one. Saving the pending I/O state in each endpoint before acting
 *    on it allows the endpoint code to clear the I/O flags in the event
 *    of a close, thus avoiding any confusion.
 *
 *  @param[in]    selectRes    The return value of the select call.
 *
 *  @param[in]    readfds      A pointer to the set of read file descriptors.
 *
 *  @param[in]    writefds     A pointer to the set of write file descriptors.
 *
 *  @param[in]    exceptfds    A pointer to the set of file descriptors with
 *                             errors.
 *
 */
void InetLayer::HandleSelectResult(int selectRes, fd_set * readfds, fd_set * writefds, fd_set * exceptfds)
{
    if (State != kState_Initialized)
        return;

    if (selectRes < 0)
        return;

    if (selectRes > 0)
    {
        // Set the pending I/O field for each active endpoint based on the value returned by select.
#if INET_CONFIG_ENABLE_RAW_ENDPOINT
        for (size_t i = 0; i < RawEndPoint::sPool.Size(); i++)
        {
            RawEndPoint * lEndPoint = RawEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->mPendingIO = SocketEvents::FromFDs(lEndPoint->mSocket, readfds, writefds, exceptfds);
            }
        }
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
        for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
        {
            TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->mPendingIO = SocketEvents::FromFDs(lEndPoint->mSocket, readfds, writefds, exceptfds);
            }
        }
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
        for (size_t i = 0; i < UDPEndPoint::sPool.Size(); i++)
        {
            UDPEndPoint * lEndPoint = UDPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->mPendingIO = SocketEvents::FromFDs(lEndPoint->mSocket, readfds, writefds, exceptfds);
            }
        }
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT

        // Now call each active endpoint to handle its pending I/O.
#if INET_CONFIG_ENABLE_RAW_ENDPOINT
        for (size_t i = 0; i < RawEndPoint::sPool.Size(); i++)
        {
            RawEndPoint * lEndPoint = RawEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->HandlePendingIO();
            }
        }
#endif // INET_CONFIG_ENABLE_RAW_ENDPOINT

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
        for (size_t i = 0; i < TCPEndPoint::sPool.Size(); i++)
        {
            TCPEndPoint * lEndPoint = TCPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->HandlePendingIO();
            }
        }
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

#if INET_CONFIG_ENABLE_UDP_ENDPOINT
        for (size_t i = 0; i < UDPEndPoint::sPool.Size(); i++)
        {
            UDPEndPoint * lEndPoint = UDPEndPoint::sPool.Get(*mSystemLayer, i);
            if ((lEndPoint != nullptr) && lEndPoint->IsCreatedByInetLayer(*this))
            {
                lEndPoint->HandlePendingIO();
            }
        }
#endif // INET_CONFIG_ENABLE_UDP_ENDPOINT
    }
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS

/**
 *  Reset the members of the IPPacketInfo object.
 *
 */
void IPPacketInfo::Clear()
{
    SrcAddress  = IPAddress::Any;
    DestAddress = IPAddress::Any;
    Interface   = INET_NULL_INTERFACEID;
    SrcPort     = 0;
    DestPort    = 0;
}

#if !INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS

// MARK: InetLayer platform- and system-specific functions for InetLayer
//       construction and destruction.

namespace Platform {
namespace InetLayer {

/**
 * This is a platform-specific InetLayer pre-initialization hook. This
 * may be overridden by assserting the preprocessor definition,
 * #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS.
 *
 * @param[in,out] aLayer    A pointer to the InetLayer instance being
 *                          initialized.
 *
 * @param[in,out] aContext  Platform-specific context data passed to
 *                          the layer initialization method, \::Init.
 *
 * @return #INET_NO_ERROR on success; otherwise, a specific error indicating
 *         the reason for initialization failure. Returning non-successful
 *         status will abort initialization.
 *
 */
DLL_EXPORT INET_ERROR WillInit(Inet::InetLayer * aLayer, void * aContext)
{
    (void) aLayer;
    (void) aContext;

    return INET_NO_ERROR;
}

/**
 * This is a platform-specific InetLayer post-initialization hook. This
 * may be overridden by assserting the preprocessor definition,
 * #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS.
 *
 * @param[in,out] aLayer    A pointer to the InetLayer instance being
 *                          initialized.
 *
 * @param[in,out] aContext  Platform-specific context data passed to
 *                          the layer initialization method, \::Init.
 *
 * @param[in]     anError   The overall status being returned via the
 *                          InetLayer \::Init method.
 *
 */
DLL_EXPORT void DidInit(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError)
{
    (void) aLayer;
    (void) aContext;
    (void) anError;
}

/**
 * This is a platform-specific InetLayer pre-shutdown hook. This
 * may be overridden by assserting the preprocessor definition,
 * #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS.
 *
 * @param[in,out] aLayer    A pointer to the InetLayer instance being
 *                          shutdown.
 *
 * @param[in,out] aContext  Platform-specific context data passed to
 *                          the layer initialization method, \::Init.
 *
 * @return #INET_NO_ERROR on success; otherwise, a specific error indicating
 *         the reason for shutdown failure. Returning non-successful
 *         status will abort shutdown.
 *
 */
DLL_EXPORT INET_ERROR WillShutdown(Inet::InetLayer * aLayer, void * aContext)
{
    (void) aLayer;
    (void) aContext;

    return INET_NO_ERROR;
}

/**
 * This is a platform-specific InetLayer post-shutdown hook. This
 * may be overridden by assserting the preprocessor definition,
 * #INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS.
 *
 * @param[in,out] aLayer    A pointer to the InetLayer instance being
 *                          shutdown.
 *
 * @param[in,out] aContext  Platform-specific context data passed to
 *                          the layer initialization method, \::Init.
 *
 * @param[in]     anError   The overall status being returned via the
 *                          InetLayer \::Shutdown method.
 *
 */
DLL_EXPORT void DidShutdown(Inet::InetLayer * aLayer, void * aContext, INET_ERROR anError)
{
    (void) aLayer;
    (void) aContext;
    (void) anError;
}

} // namespace InetLayer
} // namespace Platform

#endif // !INET_CONFIG_WILL_OVERRIDE_PLATFORM_XTOR_FUNCS

} // namespace Inet
} // namespace chip
