/* libcutils/qtaguid.c
**
** Copyright 2011, 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.
*/

// #define LOG_NDEBUG 0

#define LOG_TAG "qtaguid"

#include <cutils/qtaguid.h>
#include <cutils/log.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

static const char* CTRL_PROCPATH = "/proc/net/xt_qtaguid/ctrl";
static const int CTRL_MAX_INPUT_LEN = 128;
static const char *GLOBAL_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/passive";
static const char *TAG_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/tag_tracking_passive";

/*
 * One per proccess.
 * Once the device is open, this process will have its socket tags tracked.
 * And on exit or untimely death, all socket tags will be removed.
 * A process can only open /dev/xt_qtaguid once.
 * It should not close it unless it is really done with all the socket tags.
 * Failure to open it will be visible when socket tagging will be attempted.
 */
static int resTrackFd = -1;
pthread_once_t resTrackInitDone = PTHREAD_ONCE_INIT;

/* Only call once per process. */
void qtaguid_resTrack(void) {
    resTrackFd = TEMP_FAILURE_RETRY(open("/dev/xt_qtaguid", O_RDONLY));
    if (resTrackFd >=0) {
        TEMP_FAILURE_RETRY(fcntl(resTrackFd, F_SETFD, FD_CLOEXEC));
    }
}

/*
 * Returns:
 *   0 on success.
 *   -errno on failure.
 */
static int write_ctrl(const char *cmd) {
    int fd, res, savedErrno;

    LOGV("write_ctrl(%s)", cmd);

    fd = TEMP_FAILURE_RETRY(open(CTRL_PROCPATH, O_WRONLY));
    if (fd < 0) {
        return -errno;
    }

    res = TEMP_FAILURE_RETRY(write(fd, cmd, strlen(cmd)));
    if (res < 0) {
        savedErrno = errno;
    } else {
        savedErrno = 0;
    }
    if (res < 0) {
        LOGI("Failed write_ctrl(%s) res=%d errno=%d", cmd, res, savedErrno);
    }
    close(fd);
    return -savedErrno;
}

static int write_param(const char *param_path, const char *value) {
    int param_fd;
    int res;

    param_fd = TEMP_FAILURE_RETRY(open(param_path, O_WRONLY));
    if (param_fd < 0) {
        return -errno;
    }
    res = TEMP_FAILURE_RETRY(write(param_fd, value, strlen(value)));
    if (res < 0) {
        return -errno;
    }
    close(param_fd);
    return 0;
}

int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
    char lineBuf[CTRL_MAX_INPUT_LEN];
    int res;
    /* Doing java-land a favor, enforcing "long" */
    uint64_t kTag = ((uint64_t)tag << 32) & ~(1LLU<<63);


    pthread_once(&resTrackInitDone, qtaguid_resTrack);

    snprintf(lineBuf, sizeof(lineBuf), "t %d %llu %d", sockfd, kTag, uid);

    LOGV("Tagging socket %d with tag %llx{%u,0} for uid %d", sockfd, kTag, tag, uid);

    res = write_ctrl(lineBuf);
    if (res < 0) {
        LOGI("Tagging socket %d with tag %llx(%d) for uid %d failed errno=%d",
             sockfd, kTag, tag, uid, res);
    }

    return res;
}

int qtaguid_untagSocket(int sockfd) {
    char lineBuf[CTRL_MAX_INPUT_LEN];
    int res;

    LOGV("Untagging socket %d", sockfd);

    snprintf(lineBuf, sizeof(lineBuf), "u %d", sockfd);
    res = write_ctrl(lineBuf);
    if (res < 0) {
        LOGI("Untagging socket %d failed errno=%d", sockfd, res);
    }

    return res;
}

int qtaguid_setCounterSet(int counterSetNum, uid_t uid) {
    char lineBuf[CTRL_MAX_INPUT_LEN];
    int res;

    LOGV("Setting counters to set %d for uid %d", counterSetNum, uid);

    snprintf(lineBuf, sizeof(lineBuf), "s %d %d", counterSetNum, uid);
    res = write_ctrl(lineBuf);
    return res;
}

int qtaguid_deleteTagData(int tag, uid_t uid) {
    char lineBuf[CTRL_MAX_INPUT_LEN];
    int fd, cnt = 0, res = 0;
    uint64_t kTag = (uint64_t)tag << 32;

    LOGV("Deleting tag data with tag %llx{%d,0} for uid %d", kTag, tag, uid);

    pthread_once(&resTrackInitDone, qtaguid_resTrack);

    snprintf(lineBuf, sizeof(lineBuf), "d %llu %d", kTag, uid);
    res = write_ctrl(lineBuf);
    if (res < 0) {
        LOGI("Deleteing tag data with tag %llx/%d for uid %d failed with cnt=%d errno=%d",
             kTag, tag, uid, cnt, errno);
    }

    return res;
}

int qtaguid_setPacifier(int on) {
    int param_fd;
    int res;
    const char *value;

    value = on ? "Y" : "N";
    if (write_param(GLOBAL_PACIFIER_PARAM, value) < 0) {
        return -errno;
    }
    if (write_param(TAG_PACIFIER_PARAM, value) < 0) {
        return -errno;
    }
    return 0;
}
