#include "socks.hpp"
#include <arpa/inet.h>


typedef struct __attribute__((packed)) {
    uint8_t vn; // protocol version number and should be 4
    uint8_t cd; // command code and should be 1 for CONNECT
    uint16_t dstport;
    uint32_t dstip;
    uint8_t null; // no auth
} socks_req_t;

typedef struct __attribute__((packed)) {
    uint8_t vn; // version of the reply code and should be 0
    uint8_t cd; // result code: 90: request granted, 91: request rejected or failed
    uint16_t dstport; // ignored
    uint32_t dstip; // ignored
} socks_rep_t;


bool socks_req(int fd, sockaddr_in* addr) {
    socks_req_t req;
    if (read(fd, &req, sizeof(req)) != sizeof(req)) {
        return false;
    }
    if (req.vn != 4 || req.cd != 1 || req.null) {
        return false;
    }

    memset(addr, 0, sizeof(*addr));
    addr->sin_family = AF_INET;
    addr->sin_addr.s_addr = req.dstip;
    addr->sin_port = req.dstport;
    LOG("got request to %s:%d", inet_ntoa(addr->sin_addr), htons(req.dstport));
    return true;
}


bool socks_rep(int fd, bool success) {
    socks_rep_t rep = {};
    rep.cd = success? 90: 91;
    return write(fd, &rep, sizeof(rep)) == sizeof(rep);
}