#define _POSIX_C_SOURCE 200809L
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>

static double now_ms(void) {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (double)ts.tv_sec * 1000.0 + (double)ts.tv_nsec / 1e6;
}

static int probe_tcp(const char *ip, int port, int timeout_ms, double *rtt_ms) {
    int fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
    if (fd < 0) return -1;

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons((uint16_t)port);
    if (inet_pton(AF_INET, ip, &addr.sin_addr) != 1) {
        close(fd);
        return -1;
    }

    double t0 = now_ms();
    int rc = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
    if (rc < 0 && errno != EINPROGRESS) {
        close(fd);
        return -1;
    }

    struct pollfd pfd = { .fd = fd, .events = POLLOUT };
    rc = poll(&pfd, 1, timeout_ms);
    if (rc <= 0) {
        close(fd);
        return -1;
    }

    int err = 0;
    socklen_t len = sizeof(err);
    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0 || err != 0) {
        close(fd);
        return -1;
    }

    *rtt_ms = now_ms() - t0;
    close(fd);
    return 0;
}

int main(int argc, char **argv) {
    const char *target = (argc > 1) ? argv[1] : "1.1.1.1";
    int port = (argc > 2) ? atoi(argv[2]) : 443;
    double rtt = 0.0;
    if (probe_tcp(target, port, 3000, &rtt) == 0) {
        printf("ok target=%s port=%d rtt_ms=%.2f\n", target, port, rtt);
        return 0;
    }
    fprintf(stderr, "fail target=%s port=%d\n", target, port);
    return 1;
}
