/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file implements UDP/IPv6 sockets.
 */

#include "udp6.hpp"

#include <stdio.h>

#include <openthread/platform/udp.h>

#include "common/code_utils.hpp"
#include "common/encoding.hpp"
#include "common/instance.hpp"
#include "net/ip6.hpp"

using ot::Encoding::BigEndian::HostSwap16;

namespace ot {
namespace Ip6 {

#if OPENTHREAD_ENABLE_PLATFORM_UDP
static bool IsMle(Instance &aInstance, uint16_t aPort)
{
#if OPENTHREAD_FTD
    return aPort == ot::Mle::kUdpPort || aPort == aInstance.Get<MeshCoP::JoinerRouter>().GetJoinerUdpPort();
#else
    return aPort == ot::Mle::kUdpPort;
#endif
}
#endif

UdpSocket::UdpSocket(Udp &aUdp)
    : InstanceLocator(aUdp.GetInstance())
{
    mHandle = NULL;
}

Udp &UdpSocket::GetUdp(void)
{
    return GetInstance().GetIp6().GetUdp();
}

Message *UdpSocket::NewMessage(uint16_t aReserved, uint8_t aPriority)
{
    return GetUdp().NewMessage(aReserved, aPriority);
}

otError UdpSocket::Open(otUdpReceive aHandler, void *aContext)
{
    otError error;

    memset(&mSockName, 0, sizeof(mSockName));
    memset(&mPeerName, 0, sizeof(mPeerName));
    mHandler = aHandler;
    mContext = aContext;

#if OPENTHREAD_ENABLE_PLATFORM_UDP
    SuccessOrExit(error = otPlatUdpSocket(this));
#endif
    SuccessOrExit(error = GetUdp().AddSocket(*this));

exit:
    return error;
}

otError UdpSocket::Bind(const SockAddr &aSockAddr)
{
    otError error = OT_ERROR_NONE;

    mSockName = aSockAddr;

    if (mSockName.mPort == 0)
    {
        do
        {
            mSockName.mPort = GetUdp().GetEphemeralPort();
#if OPENTHREAD_ENABLE_PLATFORM_UDP
            error = otPlatUdpBind(this);
#endif
        } while (error != OT_ERROR_NONE);
    }
#if OPENTHREAD_ENABLE_PLATFORM_UDP
    else if (!IsMle(GetInstance(), mSockName.mPort))
    {
        error = otPlatUdpBind(this);
    }
#endif

    return error;
}

otError UdpSocket::Connect(const SockAddr &aSockAddr)
{
    otError error = OT_ERROR_NONE;

    mPeerName = aSockAddr;

#if OPENTHREAD_ENABLE_PLATFORM_UDP
    if (!IsMle(GetInstance(), mSockName.mPort))
    {
        error = otPlatUdpConnect(this);
    }
#endif
    return error;
}

otError UdpSocket::Close(void)
{
    otError error = OT_ERROR_NONE;

#if OPENTHREAD_ENABLE_PLATFORM_UDP
    SuccessOrExit(error = otPlatUdpClose(this));
#endif
    SuccessOrExit(error = GetUdp().RemoveSocket(*this));
    memset(&mSockName, 0, sizeof(mSockName));
    memset(&mPeerName, 0, sizeof(mPeerName));

exit:
    return error;
}

otError UdpSocket::SendTo(Message &aMessage, const MessageInfo &aMessageInfo)
{
    otError     error = OT_ERROR_NONE;
    MessageInfo messageInfoLocal;

    messageInfoLocal = aMessageInfo;

    if (messageInfoLocal.GetPeerAddr().IsUnspecified())
    {
        VerifyOrExit(!GetPeerName().GetAddress().IsUnspecified(), error = OT_ERROR_INVALID_ARGS);

        messageInfoLocal.SetPeerAddr(GetPeerName().GetAddress());
    }

    if (messageInfoLocal.mPeerPort == 0)
    {
        VerifyOrExit(GetPeerName().mPort != 0, error = OT_ERROR_INVALID_ARGS);
        messageInfoLocal.mPeerPort = GetPeerName().mPort;
    }

    if (messageInfoLocal.GetSockAddr().IsUnspecified())
    {
        messageInfoLocal.SetSockAddr(GetSockName().GetAddress());
    }

    if (GetSockName().mPort == 0)
    {
        SuccessOrExit(error = Bind(GetSockName()));
    }
    messageInfoLocal.SetSockPort(GetSockName().mPort);

#if OPENTHREAD_ENABLE_PLATFORM_UDP
    if (!IsMle(GetInstance(), mSockName.mPort) &&
        !(mSockName.mPort == ot::kCoapUdpPort && aMessage.GetSubType() == Message::kSubTypeJoinerEntrust))
    {
        SuccessOrExit(error = otPlatUdpSend(this, &aMessage, &messageInfoLocal));
    }
    else
#endif
    {
        SuccessOrExit(error = GetUdp().SendDatagram(aMessage, messageInfoLocal, kProtoUdp));
    }

exit:
    return error;
}

Udp::Udp(Instance &aInstance)
    : InstanceLocator(aInstance)
    , mEphemeralPort(kDynamicPortMin)
    , mReceivers(NULL)
    , mSockets(NULL)
{
}

otError Udp::AddReceiver(UdpReceiver &aReceiver)
{
    for (UdpReceiver *cur = mReceivers; cur; cur = cur->GetNext())
    {
        if (cur == &aReceiver)
        {
            ExitNow();
        }
    }

    aReceiver.SetNext(mReceivers);
    mReceivers = &aReceiver;

exit:
    return OT_ERROR_NONE;
}

otError Udp::RemoveReceiver(UdpReceiver &aReceiver)
{
    if (mReceivers == &aReceiver)
    {
        mReceivers = mReceivers->GetNext();
    }
    else
    {
        for (UdpReceiver *handler = mReceivers; handler; handler = handler->GetNext())
        {
            if (handler->GetNext() == &aReceiver)
            {
                handler->SetNext(aReceiver.GetNext());
                break;
            }
        }
    }

    aReceiver.SetNext(NULL);

    return OT_ERROR_NONE;
}

otError Udp::AddSocket(UdpSocket &aSocket)
{
    for (UdpSocket *cur = mSockets; cur; cur = cur->GetNext())
    {
        if (cur == &aSocket)
        {
            ExitNow();
        }
    }

    aSocket.SetNext(mSockets);
    mSockets = &aSocket;

exit:
    return OT_ERROR_NONE;
}

otError Udp::RemoveSocket(UdpSocket &aSocket)
{
    if (mSockets == &aSocket)
    {
        mSockets = mSockets->GetNext();
    }
    else
    {
        for (UdpSocket *socket = mSockets; socket; socket = socket->GetNext())
        {
            if (socket->GetNext() == &aSocket)
            {
                socket->SetNext(aSocket.GetNext());
                break;
            }
        }
    }

    aSocket.SetNext(NULL);

    return OT_ERROR_NONE;
}

uint16_t Udp::GetEphemeralPort(void)
{
    uint16_t rval = mEphemeralPort;

    if (mEphemeralPort < kDynamicPortMax)
    {
        mEphemeralPort++;
    }
    else
    {
        mEphemeralPort = kDynamicPortMin;
    }

    return rval;
}

Message *Udp::NewMessage(uint16_t aReserved, uint8_t aPriority)
{
    return GetIp6().NewMessage(sizeof(UdpHeader) + aReserved, aPriority);
}

otError Udp::SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, IpProto aIpProto)
{
    otError error = OT_ERROR_NONE;

#if OPENTHREAD_ENABLE_UDP_PROXY
    if (aMessageInfo.GetInterfaceId() == OT_NETIF_INTERFACE_ID_HOST)
    {
        VerifyOrExit(mProxySender != NULL, error = OT_ERROR_NO_ROUTE);
        mProxySender(&aMessage, aMessageInfo.mPeerPort, &aMessageInfo.GetPeerAddr(), aMessageInfo.mSockPort,
                     mProxySenderContext);
        // message is consumed by the callback
    }
    else
#endif
    {
        UdpHeader udpHeader;

        udpHeader.SetSourcePort(aMessageInfo.mSockPort);
        udpHeader.SetDestinationPort(aMessageInfo.mPeerPort);
        udpHeader.SetLength(sizeof(udpHeader) + aMessage.GetLength());
        udpHeader.SetChecksum(0);

        SuccessOrExit(error = aMessage.Prepend(&udpHeader, sizeof(udpHeader)));
        aMessage.SetOffset(0);

        error = GetIp6().SendDatagram(aMessage, aMessageInfo, aIpProto);
    }

exit:
    return error;
}

otError Udp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo)
{
    otError   error = OT_ERROR_NONE;
    UdpHeader udpHeader;
    uint16_t  payloadLength;
    uint16_t  checksum;

    payloadLength = aMessage.GetLength() - aMessage.GetOffset();

    // check length
    VerifyOrExit(payloadLength >= sizeof(UdpHeader), error = OT_ERROR_PARSE);

    // verify checksum
    checksum = Ip6::ComputePseudoheaderChecksum(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(), payloadLength,
                                                kProtoUdp);
    checksum = aMessage.UpdateChecksum(checksum, aMessage.GetOffset(), payloadLength);

#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
    VerifyOrExit(checksum == 0xffff, error = OT_ERROR_DROP);
#endif

    VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(udpHeader), &udpHeader) == sizeof(udpHeader),
                 error = OT_ERROR_PARSE);
    aMessage.MoveOffset(sizeof(udpHeader));
    aMessageInfo.mPeerPort = udpHeader.GetSourcePort();
    aMessageInfo.mSockPort = udpHeader.GetDestinationPort();

#if OPENTHREAD_ENABLE_PLATFORM_UDP
    VerifyOrExit(IsMle(GetInstance(), aMessageInfo.mSockPort));
#endif

    for (UdpReceiver *receiver = mReceivers; receiver; receiver = receiver->GetNext())
    {
        VerifyOrExit(!receiver->HandleMessage(aMessage, aMessageInfo));
    }

    HandlePayload(aMessage, aMessageInfo);

exit:
    return error;
}

void Udp::HandlePayload(Message &aMessage, MessageInfo &aMessageInfo)
{
    // find socket
    for (UdpSocket *socket = mSockets; socket; socket = socket->GetNext())
    {
        if (socket->GetSockName().mPort != aMessageInfo.GetSockPort())
        {
            continue;
        }

        if (socket->GetSockName().mScopeId != 0 && socket->GetSockName().mScopeId != aMessageInfo.mInterfaceId)
        {
            continue;
        }

        if (!aMessageInfo.GetSockAddr().IsMulticast() && !socket->GetSockName().GetAddress().IsUnspecified() &&
            socket->GetSockName().GetAddress() != aMessageInfo.GetSockAddr())
        {
            continue;
        }

        // verify source if connected socket
        if (socket->GetPeerName().mPort != 0)
        {
            if (socket->GetPeerName().mPort != aMessageInfo.GetPeerPort())
            {
                continue;
            }

            if (!socket->GetPeerName().GetAddress().IsUnspecified() &&
                socket->GetPeerName().GetAddress() != aMessageInfo.GetPeerAddr())
            {
                continue;
            }
        }

        socket->HandleUdpReceive(aMessage, aMessageInfo);
    }
}

otError Udp::UpdateChecksum(Message &aMessage, uint16_t aChecksum)
{
    aChecksum = aMessage.UpdateChecksum(aChecksum, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset());

    if (aChecksum != 0xffff)
    {
        aChecksum = ~aChecksum;
    }

    aChecksum = HostSwap16(aChecksum);
    aMessage.Write(aMessage.GetOffset() + UdpHeader::GetChecksumOffset(), sizeof(aChecksum), &aChecksum);
    return OT_ERROR_NONE;
}

} // namespace Ip6
} // namespace ot
