Skip to content

Commit

Permalink
ipv6 support wip
Browse files Browse the repository at this point in the history
  • Loading branch information
mariotaku committed Jan 6, 2024
1 parent 28a44b4 commit 0205c84
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 40 deletions.
15 changes: 10 additions & 5 deletions core/libgamestream/src/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -919,17 +919,22 @@ static bool construct_url(GS_CLIENT hnd, char *url, size_t ulen, bool secure, co
port = secure ? 47984 : 47989;
}
char *const proto = secure ? "https" : "http";
size_t w_len = snprintf(url, ulen, "%s://", proto);
bool is_ipv6 = strchr(address, ':') != NULL;
if (is_ipv6) {
w_len += snprintf(url + w_len, ulen - w_len, "[%s]", address);
} else {
w_len += snprintf(url + w_len, ulen - w_len, "%s", address);
}
w_len += snprintf(url + w_len, ulen - w_len, ":%u/%s?uniqueid=%s&uuid=%.*s", port, action, hnd->unique_id, 36,
uuid.data);
if (fmt) {
char params[4096];
va_list ap;
va_start(ap, fmt);
vsnprintf(params, 4096, fmt, ap);
va_end(ap);
snprintf(url, ulen, "%s://%s:%u/%s?uniqueid=%s&uuid=%.*s&%s", proto, address, port, action,
hnd->unique_id, 36, uuid.data, params);
} else {
snprintf(url, ulen, "%s://%s:%u/%s?uniqueid=%s&uuid=%.*s", proto, address, port,
action, hnd->unique_id, 36, uuid.data);
snprintf(url + w_len, ulen - w_len, "&%s", params);
}
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/app/backend/pcmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "libgamestream/client.h"
#include "uuidstr.h"
#include "sockaddr.h"

typedef struct app_t app_t;
typedef struct pcmanager_t pcmanager_t;
Expand Down Expand Up @@ -76,7 +77,7 @@ void pcmanager_unregister_listener(pcmanager_t *manager, const pcmanager_listene
* @param userdata
* @return
*/
bool pcmanager_manual_add(pcmanager_t *manager, const char *address, pcmanager_callback_t callback, void *userdata);
bool pcmanager_manual_add(pcmanager_t *manager, sockaddr_t *address, pcmanager_callback_t callback, void *userdata);

/**
* @brief Generates a PIN code, and start pairing process.
Expand Down
10 changes: 8 additions & 2 deletions src/app/backend/pcmanager/discovery/discovery_libmicrodns.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,18 @@ static void discovery_callback(discovery_task_t *task, int status, const struct
switch (cur->type) {
case RR_A: {
if (addr->sa_family != AF_UNSPEC) { continue; }
sockaddr_set_address(addr, AF_INET, &cur->data.A.addr);
sockaddr_set_ip(addr, AF_INET, &cur->data.A.addr);
break;
}
case RR_SRV:
case RR_AAAA: {
if (addr->sa_family != AF_UNSPEC) { continue; }
sockaddr_set_ip(addr, AF_INET6, &cur->data.AAAA.addr);
break;
}
case RR_SRV: {
sockaddr_set_port(addr, cur->data.SRV.port);
break;
}
}
}
if (addr->sa_family == AF_UNSPEC) {
Expand Down
39 changes: 24 additions & 15 deletions src/app/backend/pcmanager/known_hosts.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "util/ini_ext.h"
#include "util/path.h"
#include "app_settings.h"
#include "sockaddr.h"

#define LINKEDLIST_IMPL
#define LINKEDLIST_MODIFIER static
Expand All @@ -34,19 +35,22 @@ void pcmanager_load_known_hosts(pcmanager_t *manager) {

bool selected_set = false;
for (known_host_t *cur = hosts; cur; cur = cur->next) {
const char *mac = cur->mac, *hostname = cur->hostname, *address = cur->address;
const char *mac = cur->mac, *hostname = cur->hostname;
const struct sockaddr *address = cur->address;
char address_buf[64] = {0};
sockaddr_get_ip_str(address, address_buf, sizeof(address_buf));
if (!mac || !hostname || !address) {
commons_log_warn("PCManager", "Unknown host entry: mac=%s, hostname=%s, address=%s", mac, hostname,
address);
address_buf);
continue;
}

PSERVER_DATA server = serverdata_new();
server->uuid = uuidstr_tostr(&cur->uuid);
server->mac = mac;
server->hostname = hostname;
server->serverInfo.address = address;
server->extPort = cur->port;
server->serverInfo.address = strdup(address_buf);
server->extPort = sockaddr_get_port(address);

pclist_t *node = pclist_insert_known(manager, &cur->uuid, server);

Expand Down Expand Up @@ -76,16 +80,24 @@ void pcmanager_save_known_hosts(pcmanager_t *manager) {
if (!cur->server || !cur->known) {
continue;
}
char address_buf[64] = {0};
const SERVER_DATA *server = cur->server;
ini_write_section(fp, server->uuid);

ini_write_string(fp, "mac", server->mac);
ini_write_string(fp, "hostname", server->hostname);
if (server->extPort && server->extPort != 47989) {
ini_write_stringf(fp, "address", "%s:%d", server->serverInfo.address, server->extPort);
} else {
ini_write_string(fp, "address", server->serverInfo.address);

struct sockaddr *address = sockaddr_new();
if (sockaddr_set_ip_str(address, strchr(server->serverInfo.address, ':') ? AF_INET6 : AF_INET,
server->serverInfo.address) != 0) {
free(address);
continue;
}
sockaddr_set_port(address, server->extPort);
sockaddr_to_string(address, address_buf, sizeof(address_buf));
ini_write_string(fp, "address", address_buf);
free(address);

if (!selected_set && cur->selected) {
ini_write_bool(fp, "selected", true);
selected_set = true;
Expand Down Expand Up @@ -119,13 +131,7 @@ static int known_hosts_handle(known_host_t **list, const char *section, const ch
} else if (INI_NAME_MATCH("hostname")) {
host->hostname = SDL_strdup(value);
} else if (INI_NAME_MATCH("address")) {
char *address = SDL_strdup(value);
char *port_colon = SDL_strrchr(address, ':');
host->address = address;
if (port_colon) {
port_colon[0] = '\0';
host->port = SDL_atoi(port_colon + 1);
}
host->address = sockaddr_parse(value);
} else if (INI_NAME_MATCH("selected")) {
host->selected = INI_IS_TRUE(value);
} else if (INI_NAME_MATCH("favorite")) {
Expand All @@ -145,6 +151,9 @@ static int known_hosts_find_uuid(known_host_t *node, void *v) {
}

void known_hosts_node_free(known_host_t *node) {
if (node->address) {
free(node->address);
}
if (node->favs) {
appid_list_free(node->favs, (appid_list_nodefree_fn) free);
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/backend/pcmanager/known_hosts.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@

#include "backend/types.h"
#include "uuidstr.h"
#include "sockaddr.h"

typedef struct known_host_t {
uuidstr_t uuid;
char *mac;
char *hostname;
char *address;
uint16_t port;
struct sockaddr *address;
bool selected;
appid_list_t *favs;
appid_list_t *hidden;
Expand Down
9 changes: 6 additions & 3 deletions src/app/backend/pcmanager/pairing.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ bool pcmanager_pair(pcmanager_t *manager, const uuidstr_t *uuid, char *pin, pcma
return false;
}
SERVER_DATA *server = node->server;
if (server->paired) return false;
if (server->paired) { return false; }
if (server->currentGame) {
commons_log_info("PCManager", "The server %s is in game", server->hostname);
}
Expand All @@ -28,9 +28,12 @@ bool pcmanager_pair(pcmanager_t *manager, const uuidstr_t *uuid, char *pin, pcma
return true;
}

bool pcmanager_manual_add(pcmanager_t *manager, const char *address, pcmanager_callback_t callback, void *userdata) {
bool pcmanager_manual_add(pcmanager_t *manager, sockaddr_t *address, pcmanager_callback_t callback, void *userdata) {
if (address == NULL) {
return false;
}
worker_context_t *ctx = worker_context_new(manager, NULL, callback, userdata);
ctx->arg1 = strdup(address);
ctx->arg1 = address;
pcmanager_worker_queue(manager, worker_add_by_ip, ctx);
return true;
}
Expand Down
14 changes: 10 additions & 4 deletions src/app/backend/pcmanager/worker/manual_add.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@
#include "errors.h"
#include "sockaddr.h"

static int updated_by_addr(worker_context_t *context, bool force);

int worker_add_by_ip(worker_context_t *context) {
return pcmanager_update_by_ip(context, context->arg1, 0, true);
return updated_by_addr(context, true);
}

int worker_host_discovered(worker_context_t *context) {
return updated_by_addr(context, false);
}

int updated_by_addr(worker_context_t *context, bool force) {
struct sockaddr *addr = context->arg1;
char ip[64];
if (sockaddr_address_to_string(addr, ip, sizeof(ip)) != 0) {
if (sockaddr_get_ip_str(addr, ip, sizeof(ip)) != 0) {
return GS_FAILED;
}
uint16_t port = sockaddr_get_port(addr);
return pcmanager_update_by_ip(context, ip, port, false);
}
return pcmanager_update_by_ip(context, ip, port, force);
}
21 changes: 13 additions & 8 deletions src/app/ui/launcher/add.dialog.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ static lv_obj_t *create_dialog(lv_fragment_t *self, lv_obj_t *parent) {
lv_obj_set_style_pad_all(content, lv_dpx(8), 0);
lv_obj_set_style_pad_gap(content, lv_dpx(8), 0);
lv_obj_set_layout(content, LV_LAYOUT_GRID);
lv_obj_clear_flag(content, LV_OBJ_FLAG_SCROLLABLE);
static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_CONTENT, 1, LV_GRID_TEMPLATE_LAST};
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
col_dsc[2] = LV_DPX(10);
Expand All @@ -58,9 +59,9 @@ static lv_obj_t *create_dialog(lv_fragment_t *self, lv_obj_t *parent) {

lv_obj_t *ip_input = lv_textarea_create(content);
lv_obj_set_grid_cell(ip_input, LV_GRID_ALIGN_STRETCH, 0, 3, LV_GRID_ALIGN_STRETCH, 1, 1);
lv_textarea_set_placeholder_text(ip_input, locstr("IPv4 address only"));
lv_textarea_set_placeholder_text(ip_input, locstr("IPv4 or IPv6 address"));
lv_textarea_set_one_line(ip_input, true);
lv_textarea_set_accepted_chars(ip_input, ".-_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
lv_textarea_set_accepted_chars(ip_input, ".-_:[]0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
lv_obj_add_event_cb(ip_input, input_changed_cb, LV_EVENT_VALUE_CHANGED, controller);
lv_obj_add_event_cb(ip_input, input_key_cb, LV_EVENT_KEY, controller);
lv_obj_add_event_cb(ip_input, input_cancel_cb, LV_EVENT_CANCEL, controller);
Expand All @@ -74,7 +75,7 @@ static lv_obj_t *create_dialog(lv_fragment_t *self, lv_obj_t *parent) {

lv_obj_t *add_error = lv_label_create(content);
lv_obj_add_flag(add_error, LV_OBJ_FLAG_HIDDEN);
lv_obj_set_height(add_error, LV_SIZE_CONTENT);
lv_obj_set_size(add_error, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_grid_cell(add_error, LV_GRID_ALIGN_START, 0, 3, LV_GRID_ALIGN_STRETCH, 2, 1);
lv_label_set_long_mode(add_error, LV_LABEL_LONG_WRAP);
lv_label_set_text_static(add_error, locstr("Failed to add computer."));
Expand All @@ -93,11 +94,15 @@ static lv_obj_t *create_dialog(lv_fragment_t *self, lv_obj_t *parent) {
static void dialog_cb(lv_event_t *event) {
add_dialog_controller_t *controller = lv_event_get_user_data(event);
lv_obj_t *dialog = lv_event_get_current_target(event);
if (dialog != controller->base.obj) return;
if (dialog != controller->base.obj) {
return;
}
uint16_t btn = lv_msgbox_get_active_btn(dialog);
if (btn == 1) {
const char *address = lv_textarea_get_text(controller->input);
if (!address || !address[0])return;
sockaddr_t *address = sockaddr_parse(lv_textarea_get_text(controller->input));
if (!address) {
return;
}
lv_obj_add_state(controller->btns, LV_STATE_DISABLED);
lv_obj_add_state(controller->input, LV_STATE_DISABLED);
lv_obj_clear_flag(controller->progress, LV_OBJ_FLAG_HIDDEN);
Expand All @@ -110,8 +115,8 @@ static void dialog_cb(lv_event_t *event) {

static void input_changed_cb(lv_event_t *event) {
add_dialog_controller_t *controller = lv_event_get_user_data(event);
const char *address = lv_textarea_get_text(controller->input);
if (address && address[0]) {
sockaddr_t *address = sockaddr_parse(lv_textarea_get_text(controller->input));
if (address) {
lv_btnmatrix_clear_btn_ctrl(controller->btns, 1, LV_BTNMATRIX_CTRL_DISABLED);
} else {
lv_btnmatrix_set_btn_ctrl(controller->btns, 1, LV_BTNMATRIX_CTRL_DISABLED);
Expand Down

0 comments on commit 0205c84

Please sign in to comment.