/*
 * Copyright 2017, The Android Open Source Project
 *
 * 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.
 */

#include "dhcpclient.h"
#include "dhcp.h"
#include "interface.h"
#include "log.h"

#include <arpa/inet.h>
#include <errno.h>
#include <linux/if_ether.h>
#include <poll.h>
#include <unistd.h>

#include <cutils/properties.h>

#include <inttypes.h>

// The initial retry timeout for DHCP is 4000 milliseconds
static const uint32_t kInitialTimeout = 4000;
// The maximum retry timeout for DHCP is 64000 milliseconds
static const uint32_t kMaxTimeout = 64000;
// A specific value that indicates that no timeout should happen and that
// the state machine should immediately transition to the next state
static const uint32_t kNoTimeout = 0;

// Enable debug messages
static const bool kDebug = false;

// The number of milliseconds that the timeout should vary (up or down) from the
// base timeout. DHCP requires a -1 to +1 second variation in timeouts.
static const int kTimeoutSpan = 1000;

static std::string addrToStr(in_addr_t address) {
    struct in_addr addr = { address };
    char buffer[64];
    return inet_ntop(AF_INET, &addr, buffer, sizeof(buffer));
}

DhcpClient::DhcpClient(uint32_t options)
    : mOptions(options),
      mRandomEngine(std::random_device()()),
      mRandomDistribution(-kTimeoutSpan, kTimeoutSpan),
      mState(State::Init),
      mNextTimeout(kInitialTimeout),
      mFuzzNextTimeout(true) {
}

Result DhcpClient::init(const char* interfaceName) {
    Result res = mInterface.init(interfaceName);
    if (!res) {
        return res;
    }

    res = mRouter.init();
    if (!res) {
        return res;
    }

    res = mSocket.open(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
    if (!res) {
        return res;
    }

    res = mSocket.bindRaw(mInterface.getIndex());
    if (!res) {
        return res;
    }
    return Result::success();
}

Result DhcpClient::run() {
    // Block all signals while we're running. This way we don't have to deal
    // with things like EINTR. waitAndReceive then uses ppoll to set the
    // original mask while polling. This way polling can be interrupted but
    // socket writing, reading and ioctl remain interrupt free. If a signal
    // arrives while we're blocking it it will be placed in the signal queue
    // and handled once ppoll sets the original mask. This way no signals are
    // lost.
    sigset_t blockMask, originalMask;
    int status = ::sigfillset(&blockMask);
    if (status != 0) {
        return Result::error("Unable to fill signal set: %s", strerror(errno));
    }
    status = ::sigprocmask(SIG_SETMASK, &blockMask, &originalMask);
    if (status != 0) {
        return Result::error("Unable to set signal mask: %s", strerror(errno));
    }

    for (;;) {
        // Before waiting, polling or receiving we check the current state and
        // see what we should do next. This may result in polling but could
        // also lead to instant state changes without any polling. The new state
        // will then be evaluated instead, most likely leading to polling.
        switch (mState) {
            case State::Init:
                // The starting state. This is the state the client is in when
                // it first starts. It's also the state that the client returns
                // to when things go wrong in other states.
                setNextState(State::Selecting);
                break;
            case State::Selecting:
                // In the selecting state the client attempts to find DHCP
                // servers on the network. The client remains in this state
                // until a suitable server responds.
                sendDhcpDiscover();
                increaseTimeout();
                break;
            case State::Requesting:
                // In the requesting state the client has found a suitable
                // server. The next step is to send a request directly to that
                // server.
                if (mNextTimeout >= kMaxTimeout) {
                    // We've tried to request a bunch of times, start over
                    setNextState(State::Init);
                } else {
                    sendDhcpRequest(mServerAddress);
                    increaseTimeout();
                }
                break;
            case State::Bound:
                // The client enters the bound state when the server has
                // accepted and acknowledged a request and given us a lease. At
                // this point the client will wait until the lease is close to
                // expiring and then it will try to renew the lease.
                if (mT1.expired()) {
                    // Lease expired, renew lease
                    setNextState(State::Renewing);
                } else {
                    // Spurious wake-up, continue waiting. Do not fuzz the
                    // timeout with a random offset. Doing so can cause wakeups
                    // before the timer has expired causing unnecessary
                    // processing. Even worse it can cause the timer to expire
                    // after the lease has ended.
                    mNextTimeout = mT1.remainingMillis();
                    mFuzzNextTimeout = false;
                }
                break;
            case State::Renewing:
                // In the renewing state the client is sending a request for the
                // same address it had was previously bound to. If the second
                // timer expires when in this state the client will attempt to
                // do a full rebind.
                if (mT2.expired()) {
                    // Timeout while renewing, move to rebinding
                    setNextState(State::Rebinding);
                } else {
                    sendDhcpRequest(mServerAddress);
                    increaseTimeout();
                }
                break;
            case State::Rebinding:
                // The client was unable to renew the lease and moved to the
                // rebinding state. In this state the client sends a request for
                // the same address it had before to the broadcast address. This
                // means that any DHCP server on the network is free to respond.
                // After attempting this a few times the client will give up and
                // move to the Init state to try to find a new DHCP server.
                if (mNextTimeout >= kMaxTimeout) {
                    // We've tried to rebind a bunch of times, start over
                    setNextState(State::Init);
                } else {
                    // Broadcast a request
                    sendDhcpRequest(INADDR_BROADCAST);
                    increaseTimeout();
                }
                break;
            default:
                break;
        }
        // The proper action for the current state has been taken, perform any
        // polling and/or waiting needed.
        waitAndReceive(originalMask);
    }

    return Result::error("Client terminated unexpectedly");
}

const char* DhcpClient::stateToStr(State state) {
    switch (state) {
        case State::Init:
            return "Init";
        case State::Selecting:
            return "Selecting";
        case State::Requesting:
            return "Requesting";
        case State::Bound:
            return "Bound";
        case State::Renewing:
            return "Renewing";
        case State::Rebinding:
            return "Rebinding";
    }
    return "<unknown>";
}

void DhcpClient::waitAndReceive(const sigset_t& pollSignalMask) {
    if (mNextTimeout == kNoTimeout) {
        // If there is no timeout the state machine has indicated that it wants
        // an immediate transition to another state. Do nothing.
        return;
    }

    struct pollfd fds;
    fds.fd = mSocket.get();
    fds.events = POLLIN;

    uint32_t timeout = calculateTimeoutMillis();
    for (;;) {
        uint64_t startedAt = now();

        struct timespec ts;
        ts.tv_sec = timeout / 1000;
        ts.tv_nsec = (timeout - ts.tv_sec * 1000) * 1000000;

        // Poll for any incoming traffic with the calculated timeout. While
        // polling the original signal mask is set so that the polling can be
        // interrupted.
        int res = ::ppoll(&fds, 1, &ts, &pollSignalMask);
        if (res == 0) {
            // Timeout, return to let the caller evaluate
            return;
        } else if (res > 0) {
            // Something to read
            Message msg;
            if (receiveDhcpMessage(&msg)) {
                // We received a DHCP message, check if it's of interest
                uint8_t msgType = msg.type();
                switch (mState) {
                    case State::Selecting:
                        if (msgType == DHCPOFFER) {
                            // Received an offer, move to the Requesting state
                            // to request it.
                            mServerAddress = msg.serverId();
                            mRequestAddress = msg.dhcpData.yiaddr;
                            setNextState(State::Requesting);
                            return;
                        }
                        break;
                    case State::Requesting:
                    case State::Renewing:
                    case State::Rebinding:
                        // All of these states have sent a DHCP request and are
                        // now waiting for an ACK so the behavior is the same.
                        if (msgType == DHCPACK) {
                            // Request approved
                            if (configureDhcp(msg)) {
                                // Successfully configured DHCP, move to Bound
                                setNextState(State::Bound);
                                return;
                            }
                            // Unable to configure DHCP, keep sending requests.
                            // This may not fix the issue but eventually it will
                            // allow for a full timeout which will lead to a
                            // move to the Init state. This might still not fix
                            // the issue but at least the client keeps trying.
                        } else if (msgType == DHCPNAK) {
                            // Request denied, halt network and start over
                            haltNetwork();
                            setNextState(State::Init);
                            return;
                        } 
                        break;
                    default:
                        // For the other states the client is not expecting any
                        // network messages so we ignore those messages.
                        break;
                }
            }
        } else {
            // An error occurred in polling, don't do anything here. The client
            // should keep going anyway to try to acquire a lease in the future
            // if things start working again.
        }
        // If we reach this point we received something that's not a DHCP,
        // message, we timed out, or an error occurred. Go again with whatever
        // time remains.
        uint64_t currentTime = now();
        uint64_t end = startedAt + timeout;
        if (currentTime >= end) {
            // We're done anyway, return and let caller evaluate
            return;
        }
        // Wait whatever the remaining time is
        timeout = end - currentTime;
    }
}

bool DhcpClient::configureDhcp(const Message& msg) {
    uint8_t optLength = 0;

    size_t optsSize = msg.optionsSize();
    if (optsSize < 4) {
        // Message is too small
        if (kDebug) ALOGD("Opts size too small %d", static_cast<int>(optsSize));
        return false;
    }

    const uint8_t* options = msg.dhcpData.options;

    memset(&mDhcpInfo, 0, sizeof(mDhcpInfo));

    // Inspect all options in the message to try to find the ones we want
    for (size_t i = 4; i + 1 < optsSize; ) {
        uint8_t optCode = options[i];
        uint8_t optLength = options[i + 1];
        if (optCode == OPT_END) {
            break;
        }

        if (options + optLength + i >= msg.end()) {
            // Invalid option length, drop it
            if (kDebug) ALOGD("Invalid opt length %d for opt %d",
                              static_cast<int>(optLength),
                              static_cast<int>(optCode));
            return false;
        }
        const uint8_t* opt = options + i + 2;
        switch (optCode) {
            case OPT_LEASE_TIME:
                if (optLength == 4) {
                    mDhcpInfo.leaseTime =
                        ntohl(*reinterpret_cast<const uint32_t*>(opt));
                }
                break;
            case OPT_T1:
                if (optLength == 4) {
                    mDhcpInfo.t1 =
                        ntohl(*reinterpret_cast<const uint32_t*>(opt));
                }
                break;
            case OPT_T2:
                if (optLength == 4) {
                    mDhcpInfo.t2 =
                        ntohl(*reinterpret_cast<const uint32_t*>(opt));
                }
                break;
            case OPT_SUBNET_MASK:
                if (optLength == 4) {
                    mDhcpInfo.subnetMask =
                        *reinterpret_cast<const in_addr_t*>(opt);
                }
                break;
            case OPT_GATEWAY:
                if (optLength >= 4) {
                    mDhcpInfo.gateway =
                        *reinterpret_cast<const in_addr_t*>(opt);
                }
                break;
            case OPT_MTU:
                if (optLength == 2) {
                    mDhcpInfo.mtu =
                        ntohs(*reinterpret_cast<const uint16_t*>(opt));
                }
                break;
            case OPT_DNS:
                if (optLength >= 4) {
                    mDhcpInfo.dns[0] =
                        *reinterpret_cast<const in_addr_t*>(opt);
                }
                if (optLength >= 8) {
                    mDhcpInfo.dns[1] =
                        *reinterpret_cast<const in_addr_t*>(opt + 4);
                }
                if (optLength >= 12) {
                    mDhcpInfo.dns[2] =
                        *reinterpret_cast<const in_addr_t*>(opt + 8);
                }
                if (optLength >= 16) {
                    mDhcpInfo.dns[3] =
                        *reinterpret_cast<const in_addr_t*>(opt + 12);
                }
            case OPT_SERVER_ID:
                if (optLength == 4) {
                    mDhcpInfo.serverId =
                        *reinterpret_cast<const in_addr_t*>(opt);
                }
            default:
                break;
        }
        i += 2 + optLength;
    }
    mDhcpInfo.offeredAddress = msg.dhcpData.yiaddr;

    if (mDhcpInfo.leaseTime == 0) {
        // We didn't get a lease time, ignore this offer
        return false;
    }
    // If there is no T1 or T2 timer given then we create an estimate as
    // suggested for servers in RFC 2131.
    uint32_t t1 = mDhcpInfo.t1, t2 = mDhcpInfo.t2;
    mT1.expireSeconds(t1 > 0 ? t1 : (mDhcpInfo.leaseTime / 2));
    mT2.expireSeconds(t2 > 0 ? t2 : ((mDhcpInfo.leaseTime * 7) / 8));

    Result res = mInterface.bringUp();
    if (!res) {
        ALOGE("Could not configure DHCP: %s", res.c_str());
        return false;
    }

    if (mDhcpInfo.mtu != 0) {
        res = mInterface.setMtu(mDhcpInfo.mtu);
        if (!res) {
            // Consider this non-fatal, the system will not perform at its best
            // but should still work.
            ALOGE("Could not configure DHCP: %s", res.c_str());
        }
    }

    char propName[64];
    snprintf(propName, sizeof(propName), "net.%s.gw",
             mInterface.getName().c_str());
    if (property_set(propName, addrToStr(mDhcpInfo.gateway).c_str()) != 0) {
        ALOGE("Failed to set %s: %s", propName, strerror(errno));
    }

    int numDnsEntries = sizeof(mDhcpInfo.dns) / sizeof(mDhcpInfo.dns[0]);
    for (int i = 0; i < numDnsEntries; ++i) {
        snprintf(propName, sizeof(propName), "net.%s.dns%d",
                 mInterface.getName().c_str(), i + 1);
        if (mDhcpInfo.dns[i] != 0) {
            if (property_set(propName,
                             addrToStr(mDhcpInfo.dns[i]).c_str()) != 0) {
                ALOGE("Failed to set %s: %s", propName, strerror(errno));
            }
        } else {
            // Clear out any previous value here in case it was set
            if (property_set(propName, "") != 0) {
                ALOGE("Failed to clear %s: %s", propName, strerror(errno));
            }
        }
    }

    res = mInterface.setAddress(mDhcpInfo.offeredAddress,
                                mDhcpInfo.subnetMask);
    if (!res) {
        ALOGE("Could not configure DHCP: %s", res.c_str());
        return false;
    }

    if ((mOptions & static_cast<uint32_t>(ClientOption::NoGateway)) == 0) {
        res = mRouter.setDefaultGateway(mDhcpInfo.gateway,
                                        mInterface.getIndex());
        if (!res) {
            ALOGE("Could not configure DHCP: %s", res.c_str());
            return false;
        }
    }
    return true;
}

void DhcpClient::haltNetwork() {
    Result res = mInterface.setAddress(0, 0);
    if (!res) {
        ALOGE("Could not halt network: %s", res.c_str());
    }
    res = mInterface.bringDown();
    if (!res) {
        ALOGE("Could not halt network: %s", res.c_str());
    }
}

bool DhcpClient::receiveDhcpMessage(Message* msg) {
    bool isValid = false;
    Result res = mSocket.receiveRawUdp(PORT_BOOTP_CLIENT, msg, &isValid);
    if (!res) {
        if (kDebug) ALOGD("Discarding message: %s", res.c_str());
        return false;
    }

    return isValid &&
           msg->isValidDhcpMessage(OP_BOOTREPLY, mLastMsg.dhcpData.xid);
}

uint32_t DhcpClient::calculateTimeoutMillis() {
    if (!mFuzzNextTimeout) {
        return mNextTimeout;
    }
    int adjustment = mRandomDistribution(mRandomEngine);
    if (adjustment < 0 && static_cast<uint32_t>(-adjustment) > mNextTimeout) {
        // Underflow, return a timeout of zero milliseconds
        return 0;
    }
    return mNextTimeout + adjustment;
}

void DhcpClient::increaseTimeout() {
    if (mNextTimeout == kNoTimeout) {
        mNextTimeout = kInitialTimeout;
    } else {
        if (mNextTimeout < kMaxTimeout) {
            mNextTimeout *= 2;
        }
        if (mNextTimeout > kMaxTimeout) {
            mNextTimeout = kMaxTimeout;
        }
    }
}

void DhcpClient::setNextState(State state) {
    if (kDebug) ALOGD("Moving from state %s to %s",
                      stateToStr(mState), stateToStr(state));
    mState = state;
    mNextTimeout = kNoTimeout;
    mFuzzNextTimeout = true;
}

void DhcpClient::sendDhcpRequest(in_addr_t destination) {
    if (kDebug) ALOGD("Sending DHCPREQUEST");
    mLastMsg = Message::request(mInterface.getMacAddress(),
                                mRequestAddress,
                                destination);
    sendMessage(mLastMsg);
}

void DhcpClient::sendDhcpDiscover() {
    if (kDebug) ALOGD("Sending DHCPDISCOVER");
    mLastMsg = Message::discover(mInterface.getMacAddress());
    sendMessage(mLastMsg);
}

void DhcpClient::sendMessage(const Message& message) {
    Result res = mSocket.sendRawUdp(INADDR_ANY,
                                    PORT_BOOTP_CLIENT,
                                    INADDR_BROADCAST,
                                    PORT_BOOTP_SERVER,
                                    mInterface.getIndex(),
                                    message);
    if (!res) {
        ALOGE("Unable to send message: %s", res.c_str());
    }
}

