/*
 * Copyright (C) 2014 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 <set>
#include "VirtualNetwork.h"

#include "SockDiag.h"
#include "RouteController.h"

#define LOG_TAG "Netd"
#include "log/log.h"

VirtualNetwork::VirtualNetwork(unsigned netId, bool hasDns, bool secure) :
        Network(netId), mHasDns(hasDns), mSecure(secure) {
}

VirtualNetwork::~VirtualNetwork() {
}

bool VirtualNetwork::getHasDns() const {
    return mHasDns;
}

bool VirtualNetwork::isSecure() const {
    return mSecure;
}

bool VirtualNetwork::appliesToUser(uid_t uid) const {
    return mUidRanges.hasUid(uid);
}


int VirtualNetwork::maybeCloseSockets(bool add, const UidRanges& uidRanges,
                                      const std::set<uid_t>& protectableUsers) {
    if (!mSecure) {
        return 0;
    }

    SockDiag sd;
    if (!sd.open()) {
        return -EBADFD;
    }

    if (int ret = sd.destroySockets(uidRanges, protectableUsers)) {
        ALOGE("Failed to close sockets while %s %s to network %d: %s",
              add ? "adding" : "removing", uidRanges.toString().c_str(), mNetId, strerror(-ret));
        return ret;
    }

    return 0;
}

int VirtualNetwork::addUsers(const UidRanges& uidRanges, const std::set<uid_t>& protectableUsers) {
    maybeCloseSockets(true, uidRanges, protectableUsers);

    for (const std::string& interface : mInterfaces) {
        if (int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure,
                                                                uidRanges)) {
            ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
            return ret;
        }
    }
    mUidRanges.add(uidRanges);
    return 0;
}

int VirtualNetwork::removeUsers(const UidRanges& uidRanges,
                                const std::set<uid_t>& protectableUsers) {
    maybeCloseSockets(false, uidRanges, protectableUsers);

    for (const std::string& interface : mInterfaces) {
        if (int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(),
                                                                     mSecure, uidRanges)) {
            ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
            return ret;
        }
    }
    mUidRanges.remove(uidRanges);
    return 0;
}

Network::Type VirtualNetwork::getType() const {
    return VIRTUAL;
}

int VirtualNetwork::addInterface(const std::string& interface) {
    if (hasInterface(interface)) {
        return 0;
    }
    if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure,
                                                                mUidRanges)) {
        ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId);
        return ret;
    }
    mInterfaces.insert(interface);
    return 0;
}

int VirtualNetwork::removeInterface(const std::string& interface) {
    if (!hasInterface(interface)) {
        return 0;
    }
    if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(),
                                                                     mSecure, mUidRanges)) {
        ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId);
        return ret;
    }
    mInterfaces.erase(interface);
    return 0;
}
