mirror of
https://github.com/holdmysocks/ps5-tailscale.git
synced 2026-10-06 07:00:22 +02:00
The status page can now be protected with a password and edits the settings itself, so the config file no longer has to be changed by hand. - Password for everything on the status page that shows or changes something. The console's own browser is exempt. Connections to the page from the tailnet are served directly so they are not taken for local. - Settings form: name, ports, forwards, proxy, priority, update checks. Most take effect at once; the page says which need a restart. - Game streaming: several Sunshine hosts, each with its own port. - The HTTP proxy is off by default. - The page says when a newer release exists. - Uninstall removes the home screen icon. - Priority setting for streams that stutter under a demanding game. - After the console's network is reconfigured, Tailscale is asked to rebind. Seen working across a short stay in rest mode. - Favicon, and the device list can be collapsed.
103 lines
2.8 KiB
C
103 lines
2.8 KiB
C
/* Exercise the daemon's local forwards from the console: an HTTP GET through
|
|
* the TCP forward on 127.0.0.1:47989, and a UDP round trip through the
|
|
* forward on 127.0.0.1:47998. Build with -DHTTP_PATH="/serverinfo" etc. */
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <arpa/inet.h>
|
|
#include <netinet/in.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/time.h>
|
|
|
|
#ifndef HTTP_PATH
|
|
#define HTTP_PATH "/hello.txt"
|
|
#endif
|
|
/* Sunshine's "port" setting on the host under test; its HTTP port is this
|
|
* and its video (UDP) port is this plus 9. */
|
|
#ifndef BASE_PORT
|
|
#define BASE_PORT 47989
|
|
#endif
|
|
|
|
static struct sockaddr_in
|
|
local(int port) {
|
|
struct sockaddr_in addr = {0};
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_port = htons(port);
|
|
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
return addr;
|
|
}
|
|
|
|
static double
|
|
now(void) {
|
|
struct timeval tv;
|
|
gettimeofday(&tv, 0);
|
|
return tv.tv_sec + tv.tv_usec / 1e6;
|
|
}
|
|
|
|
int
|
|
main(void) {
|
|
struct timeval tv = {10, 0};
|
|
struct sockaddr_in addr;
|
|
char buf[2048];
|
|
ssize_t n;
|
|
int fd;
|
|
|
|
setvbuf(stdout, 0, _IONBF, 0);
|
|
|
|
/* TCP */
|
|
addr = local(BASE_PORT);
|
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
|
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
|
double t0 = now();
|
|
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr))) {
|
|
printf("tcp 127.0.0.1:%d: cannot connect (no forward listening)\n", BASE_PORT);
|
|
} else {
|
|
const char *req = "GET " HTTP_PATH " HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n";
|
|
size_t total = 0;
|
|
write(fd, req, strlen(req));
|
|
while (total < sizeof(buf) - 1 && (n = read(fd, buf + total, sizeof(buf) - 1 - total)) > 0) {
|
|
total += n;
|
|
}
|
|
buf[total] = 0;
|
|
char *body = strstr(buf, "\r\n\r\n");
|
|
char *eol = strstr(buf, "\r\n");
|
|
if (!total) {
|
|
printf("tcp 127.0.0.1:%d: connected but no response\n", BASE_PORT);
|
|
} else {
|
|
printf("tcp 127.0.0.1:%d: %.*s (%.0f ms)\n", BASE_PORT, eol ? (int)(eol - buf) : 60, buf, (now() - t0) * 1000);
|
|
if (body) {
|
|
printf(" body: %.400s\n", body + 4);
|
|
}
|
|
}
|
|
}
|
|
close(fd);
|
|
|
|
#ifndef SKIP_UDP
|
|
/* UDP */
|
|
addr = local(BASE_PORT + 9);
|
|
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
|
int ok = 0;
|
|
double worst = 0;
|
|
for (int i = 0; i < 20; i++) {
|
|
char msg[1300];
|
|
memset(msg, 'a' + i, sizeof(msg));
|
|
t0 = now();
|
|
sendto(fd, msg, sizeof(msg), 0, (struct sockaddr *)&addr, sizeof(addr));
|
|
n = recv(fd, buf, sizeof(buf), 0);
|
|
double ms = (now() - t0) * 1000;
|
|
if (n == sizeof(msg) && !memcmp(buf, msg, sizeof(msg))) {
|
|
ok++;
|
|
if (ms > worst) {
|
|
worst = ms;
|
|
}
|
|
}
|
|
}
|
|
printf("udp 127.0.0.1:%d: %d/20 datagrams of 1300 bytes echoed, worst round trip %.1f ms\n", BASE_PORT + 9, ok, worst);
|
|
close(fd);
|
|
#endif
|
|
return 0;
|
|
}
|