mirror of
https://github.com/Kiritow/wg-ops.git
synced 2024-03-22 13:11:37 +08:00
WIP: Add W2U LoadBalancer
This commit is contained in:
parent
fb0840d606
commit
b87f956b25
|
@ -24,7 +24,8 @@ if op_mode not in ("c", "s", "m"):
|
||||||
|
|
||||||
udp2raw_config = {
|
udp2raw_config = {
|
||||||
"server": [],
|
"server": [],
|
||||||
"client": []
|
"client": [],
|
||||||
|
"demuxer": [], # w2u
|
||||||
}
|
}
|
||||||
|
|
||||||
if op_mode in ("s", "m"):
|
if op_mode in ("s", "m"):
|
||||||
|
@ -113,12 +114,37 @@ if op_mode in ("c", "m"):
|
||||||
"enable": False
|
"enable": False
|
||||||
}
|
}
|
||||||
|
|
||||||
udp2raw_config["client"].append({
|
is_enable_balance = input("Enable Load Balance? [y/N]: ").strip()
|
||||||
"remote": udp_server_address,
|
if is_enable_balance and is_enable_balance.lower() in ('y', 'yes'):
|
||||||
"password": udp_server_password,
|
balance_count = input("Enter Balance Underlay Connection counts (default to 10): ").strip() or "10"
|
||||||
"port": 29100 + len(udp2raw_config["client"]),
|
balance_count = int(balance_count)
|
||||||
"speeder": speeder_info
|
|
||||||
})
|
default_balancer_port = 29000 + len(udp2raw_config["demuxer"])
|
||||||
|
balancer_port = input("Enter Balancer Listen Port (default to {}): ".format(default_balancer_port)).strip() or default_balancer_port
|
||||||
|
balancer_port = int(balancer_port)
|
||||||
|
|
||||||
|
udp2raw_config["demuxer"].append({
|
||||||
|
"port": balancer_port,
|
||||||
|
"forward": 29100 + len(udp2raw_config["client"]),
|
||||||
|
"size": balance_count
|
||||||
|
})
|
||||||
|
|
||||||
|
for i in range(balance_count):
|
||||||
|
udp2raw_config["client"].append({
|
||||||
|
"remote": udp_server_address,
|
||||||
|
"password": udp_server_password,
|
||||||
|
"port": 29100 + len(udp2raw_config["client"]),
|
||||||
|
"speeder": speeder_info,
|
||||||
|
"balanced": True
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
udp2raw_config["client"].append({
|
||||||
|
"remote": udp_server_address,
|
||||||
|
"password": udp_server_password,
|
||||||
|
"port": 29100 + len(udp2raw_config["client"]),
|
||||||
|
"speeder": speeder_info,
|
||||||
|
"balanced": False
|
||||||
|
})
|
||||||
|
|
||||||
if not input("Add more udp2raw client? (Keep empty to finish)").strip():
|
if not input("Add more udp2raw client? (Keep empty to finish)").strip():
|
||||||
break
|
break
|
||||||
|
|
|
@ -36,6 +36,7 @@ if "version" not in config or int(config["version"]) < 1:
|
||||||
op_mode = config["mode"]
|
op_mode = config["mode"]
|
||||||
udp_clients = config["udp2raw"]["client"]
|
udp_clients = config["udp2raw"]["client"]
|
||||||
udp_servers = config["udp2raw"]["server"]
|
udp_servers = config["udp2raw"]["server"]
|
||||||
|
udp_demuxer = config["udp2raw"]["demuxer"]
|
||||||
|
|
||||||
|
|
||||||
logger.info("Generating WireGuard config...")
|
logger.info("Generating WireGuard config...")
|
||||||
|
@ -59,31 +60,35 @@ PostUp=sysctl net.ipv4.tcp_congestion_control=bbr
|
||||||
current_dir = os.getcwd()
|
current_dir = os.getcwd()
|
||||||
path_tunnel = os.path.join(current_dir, "bin", "udp2raw_amd64")
|
path_tunnel = os.path.join(current_dir, "bin", "udp2raw_amd64")
|
||||||
path_speeder = os.path.join(current_dir, "bin", "speederv2_amd64")
|
path_speeder = os.path.join(current_dir, "bin", "speederv2_amd64")
|
||||||
|
path_demuxer = os.path.join(current_dir, "bin", "w2u")
|
||||||
|
|
||||||
for info in udp_clients:
|
for info in udp_clients:
|
||||||
if info["speeder"]["enable"]:
|
if info["speeder"]["enable"]:
|
||||||
# WG --> Speeder --> RawTunnel
|
# WG --> Speeder --> RawTunnel
|
||||||
speeder = info["speeder"]
|
speeder = info["speeder"]
|
||||||
f.write('''PostUp={} new-window -t tunnel -d '{} -c -l127.0.0.1:{} -r 127.0.0.1:{} -f{} --mode 0' \n'''.format(tmux_path, path_speeder, speeder["port"], info["port"], speeder["ratio"]))
|
f.write('''PostUp={} new-window -t tunnel -d '{} -c -l127.0.0.1:{} -r 127.0.0.1:{} -f{} --mode 0'; sleep 2 \n'''.format(tmux_path, path_speeder, speeder["port"], info["port"], speeder["ratio"]))
|
||||||
|
|
||||||
filename = write_tunnel_config("c", "127.0.0.1:{}".format(info["port"]), info["remote"], info["password"])
|
filename = write_tunnel_config("c", "127.0.0.1:{}".format(info["port"]), info["remote"], info["password"])
|
||||||
filepath = os.path.join(current_dir, "local", "tunnel", filename)
|
filepath = os.path.join(current_dir, "local", "tunnel", filename)
|
||||||
f.write('''PostUp={} new-window -t tunnel -d '{} --conf-file {}' \n'''.format(tmux_path, path_tunnel, filepath))
|
f.write('''PostUp={} new-window -t tunnel -d '{} --conf-file {}'; sleep 2 \n'''.format(tmux_path, path_tunnel, filepath))
|
||||||
|
|
||||||
|
for info in udp_demuxer:
|
||||||
|
f.write('''PostUp={} new-window -t tunnel -d '{} -f {} -l {} -t {} -s {}' \n'''.format(tmux_path, path_demuxer, config["listen"], info["port"], info["forward"], info["size"]))
|
||||||
|
|
||||||
for info in udp_servers:
|
for info in udp_servers:
|
||||||
if info["speeder"]["enable"]:
|
if info["speeder"]["enable"]:
|
||||||
# RawTunnel --> Speeder --> WG
|
# RawTunnel --> Speeder --> WG
|
||||||
speeder = info["speeder"]
|
speeder = info["speeder"]
|
||||||
f.write('''PostUp={} new-window -t tunnel -d '{} -s -l127.0.0.1:{} -r 127.0.0.1:{} -f{} --mode 0' \n'''.format(tmux_path, path_speeder, speeder["port"], config["listen"], speeder["ratio"]))
|
f.write('''PostUp={} new-window -t tunnel -d '{} -s -l127.0.0.1:{} -r 127.0.0.1:{} -f{} --mode 0'; sleep 2 \n'''.format(tmux_path, path_speeder, speeder["port"], config["listen"], speeder["ratio"]))
|
||||||
|
|
||||||
filename = write_tunnel_config("s", "0.0.0.0:{}".format(info["port"]), "127.0.0.1:{}".format(speeder["port"]), info["password"])
|
filename = write_tunnel_config("s", "0.0.0.0:{}".format(info["port"]), "127.0.0.1:{}".format(speeder["port"]), info["password"])
|
||||||
filepath = os.path.join(current_dir, "local", "tunnel", filename)
|
filepath = os.path.join(current_dir, "local", "tunnel", filename)
|
||||||
f.write('''PostUp={} new-window -t tunnel -d '{} --conf-file {}' \n'''.format(tmux_path, path_tunnel, filepath))
|
f.write('''PostUp={} new-window -t tunnel -d '{} --conf-file {}'; sleep 2 \n'''.format(tmux_path, path_tunnel, filepath))
|
||||||
else:
|
else:
|
||||||
# RawTunnel --> WG
|
# RawTunnel --> WG
|
||||||
filename = write_tunnel_config("s", "0.0.0.0:{}".format(info["port"]), "127.0.0.1:{}".format(config["listen"]), info["password"])
|
filename = write_tunnel_config("s", "0.0.0.0:{}".format(info["port"]), "127.0.0.1:{}".format(config["listen"]), info["password"])
|
||||||
filepath = os.path.join(current_dir, "local", "tunnel", filename)
|
filepath = os.path.join(current_dir, "local", "tunnel", filename)
|
||||||
f.write('''PostUp={} new-window -t tunnel -d '{} --conf-file {}' \n'''.format(tmux_path, path_tunnel, filepath))
|
f.write('''PostUp={} new-window -t tunnel -d '{} --conf-file {}'; sleep 2 \n'''.format(tmux_path, path_tunnel, filepath))
|
||||||
|
|
||||||
# Generate PostDown
|
# Generate PostDown
|
||||||
f.write("PostDown={} kill-session -t tunnel\n".format(tmux_path))
|
f.write("PostDown={} kill-session -t tunnel\n".format(tmux_path))
|
||||||
|
|
145
w2u.c
Normal file
145
w2u.c
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
// WireGuard ---> W2U --> Internet
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int ret, flags;
|
||||||
|
int listener, sender, ep;
|
||||||
|
int PORT_WG=51820, PORT_ENDP=29000, PORT_UR_BEGIN=29100, PORT_UR_SIZE=10;
|
||||||
|
|
||||||
|
while((ret = getopt(argc, argv, "hf:l:t:s:")) != -1)
|
||||||
|
{
|
||||||
|
switch(ret)
|
||||||
|
{
|
||||||
|
case 'f':
|
||||||
|
PORT_WG=atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
PORT_ENDP=atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
PORT_UR_BEGIN=atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
PORT_UR_SIZE=atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Usage: %s -f WGPort -l ListenPort -t TargetPort -s TargetRange\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "listening on %d, receiving from %d and sending to [%d,%d)\n", PORT_ENDP, PORT_WG, PORT_UR_BEGIN, PORT_UR_BEGIN+PORT_UR_SIZE);
|
||||||
|
|
||||||
|
listener = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
struct sockaddr_in saddr;
|
||||||
|
memset(&saddr, 0, sizeof(saddr));
|
||||||
|
saddr.sin_family = AF_INET;
|
||||||
|
saddr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
saddr.sin_port = htons(PORT_ENDP);
|
||||||
|
ret = bind(listener, (const struct sockaddr*)&saddr, sizeof(saddr));
|
||||||
|
if (ret < 0) {
|
||||||
|
perror("bind");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sender = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
// Set to non-blocking
|
||||||
|
flags = fcntl(listener, F_GETFL, 0);
|
||||||
|
if (flags < 0)
|
||||||
|
{
|
||||||
|
perror("fcntl");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
fcntl(listener, F_SETFL, flags);
|
||||||
|
|
||||||
|
flags = fcntl(sender, F_GETFL, 0);
|
||||||
|
if (flags < 0)
|
||||||
|
{
|
||||||
|
perror("fcntl");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
fcntl(sender, F_SETFL, flags);
|
||||||
|
|
||||||
|
ep = epoll_create(1024);
|
||||||
|
|
||||||
|
struct epoll_event ev1;
|
||||||
|
ev1.events = EPOLLIN;
|
||||||
|
ev1.data.fd = listener;
|
||||||
|
|
||||||
|
struct epoll_event ev2;
|
||||||
|
ev2.events = EPOLLIN;
|
||||||
|
ev2.data.fd = sender;
|
||||||
|
|
||||||
|
epoll_ctl(ep, EPOLL_CTL_ADD, listener, &ev1);
|
||||||
|
epoll_ctl(ep, EPOLL_CTL_ADD, sender, &ev2);
|
||||||
|
|
||||||
|
struct epoll_event events[1024];
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int nfds = epoll_wait(ep, events, 1024, -1);
|
||||||
|
|
||||||
|
if (nfds < 0) {
|
||||||
|
perror("epoll_wait");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0;i<nfds; i++)
|
||||||
|
{
|
||||||
|
if (events[i].data.fd == listener)
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
socklen_t alen = sizeof(addr);
|
||||||
|
|
||||||
|
char buffer[2048];
|
||||||
|
int nsize = recvfrom(listener, &buffer, 2048, 0, (struct sockaddr*)&addr, &alen);
|
||||||
|
|
||||||
|
if (nsize < 0) {
|
||||||
|
perror("recvfrom");
|
||||||
|
} else {
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
|
||||||
|
int randPort = PORT_UR_BEGIN + rand()%PORT_UR_SIZE;
|
||||||
|
addr.sin_port = htons(randPort);
|
||||||
|
sendto(sender, buffer, nsize, 0, (const struct sockaddr*)&addr, sizeof(addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (events[i].data.fd == sender)
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
socklen_t alen = sizeof(addr);
|
||||||
|
|
||||||
|
char buffer[2048];
|
||||||
|
int nsize = recvfrom(sender, &buffer, 2048, 0, (struct sockaddr*)&addr, &alen);
|
||||||
|
|
||||||
|
if (nsize < 0)
|
||||||
|
{
|
||||||
|
perror("recvfrom");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
|
||||||
|
addr.sin_port = htons(PORT_WG);
|
||||||
|
sendto(listener, buffer, nsize, 0, (const struct sockaddr*)&addr, sizeof(addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user