mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-20 13:33:13 -07:00
Support Broadcast in Regist
This commit is contained in:
parent
cda4d1cefc
commit
cbf51a7f82
6 changed files with 109 additions and 46 deletions
|
@ -29,6 +29,7 @@ class Settings;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class QPlainTextEdit;
|
class QPlainTextEdit;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
|
class QCheckBox;
|
||||||
|
|
||||||
class RegistDialog : public QDialog
|
class RegistDialog : public QDialog
|
||||||
{
|
{
|
||||||
|
@ -38,6 +39,7 @@ class RegistDialog : public QDialog
|
||||||
Settings *settings;
|
Settings *settings;
|
||||||
|
|
||||||
QLineEdit *host_edit;
|
QLineEdit *host_edit;
|
||||||
|
QCheckBox *broadcast_check_box;
|
||||||
QLineEdit *psn_id_edit;
|
QLineEdit *psn_id_edit;
|
||||||
QLineEdit *pin_edit;
|
QLineEdit *pin_edit;
|
||||||
QDialogButtonBox *button_box;
|
QDialogButtonBox *button_box;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ChiakiLogLevel)
|
Q_DECLARE_METATYPE(ChiakiLogLevel)
|
||||||
|
|
||||||
|
@ -52,6 +53,10 @@ RegistDialog::RegistDialog(Settings *settings, const QString &host, QWidget *par
|
||||||
else
|
else
|
||||||
host_edit->setText(host);
|
host_edit->setText(host);
|
||||||
|
|
||||||
|
broadcast_check_box = new QCheckBox(this);
|
||||||
|
form_layout->addRow(tr("Broadcast:"), broadcast_check_box);
|
||||||
|
broadcast_check_box->setChecked(host.isEmpty());
|
||||||
|
|
||||||
psn_id_edit = new QLineEdit(this);
|
psn_id_edit = new QLineEdit(this);
|
||||||
form_layout->addRow(tr("PSN ID (username):"), psn_id_edit);
|
form_layout->addRow(tr("PSN ID (username):"), psn_id_edit);
|
||||||
|
|
||||||
|
@ -90,6 +95,7 @@ void RegistDialog::accept()
|
||||||
QByteArray host = host_edit->text().trimmed().toUtf8();
|
QByteArray host = host_edit->text().trimmed().toUtf8();
|
||||||
info.psn_id = psn_id.data();
|
info.psn_id = psn_id.data();
|
||||||
info.host = host.data();
|
info.host = host.data();
|
||||||
|
info.broadcast = broadcast_check_box->isChecked();
|
||||||
info.pin = (uint32_t)pin_edit->text().toULong();
|
info.pin = (uint32_t)pin_edit->text().toULong();
|
||||||
|
|
||||||
RegistExecuteDialog execute_dialog(settings, info, this);
|
RegistExecuteDialog execute_dialog(settings, info, this);
|
||||||
|
|
|
@ -32,6 +32,7 @@ extern "C" {
|
||||||
typedef struct chiaki_regist_info_t
|
typedef struct chiaki_regist_info_t
|
||||||
{
|
{
|
||||||
char *host;
|
char *host;
|
||||||
|
bool broadcast;
|
||||||
char *psn_id;
|
char *psn_id;
|
||||||
uint32_t pin;
|
uint32_t pin;
|
||||||
} ChiakiRegistInfo;
|
} ChiakiRegistInfo;
|
||||||
|
@ -50,7 +51,6 @@ typedef struct chiaki_registered_host_t
|
||||||
} ChiakiRegisteredHost;
|
} ChiakiRegisteredHost;
|
||||||
|
|
||||||
typedef enum chiaki_regist_event_type_t {
|
typedef enum chiaki_regist_event_type_t {
|
||||||
CHIAKI_REGIST_EVENT_TYPE_CONNECTED,
|
|
||||||
CHIAKI_REGIST_EVENT_TYPE_FINISHED_CANCELED,
|
CHIAKI_REGIST_EVENT_TYPE_FINISHED_CANCELED,
|
||||||
CHIAKI_REGIST_EVENT_TYPE_FINISHED_FAILED,
|
CHIAKI_REGIST_EVENT_TYPE_FINISHED_FAILED,
|
||||||
CHIAKI_REGIST_EVENT_TYPE_FINISHED_SUCCESS
|
CHIAKI_REGIST_EVENT_TYPE_FINISHED_SUCCESS
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <chiaki/discovery.h>
|
#include <chiaki/discovery.h>
|
||||||
#include <chiaki/http.h>
|
#include <chiaki/http.h>
|
||||||
#include <chiaki/log.h>
|
#include <chiaki/log.h>
|
||||||
|
@ -61,21 +63,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_srch_response_parse(ChiakiDiscove
|
||||||
|
|
||||||
memset(response, 0, sizeof(*response));
|
memset(response, 0, sizeof(*response));
|
||||||
|
|
||||||
void *addr_src;
|
response->host_addr = sockaddr_str(addr, addr_buf, addr_buf_size);
|
||||||
switch(addr->sa_family)
|
|
||||||
{
|
|
||||||
case AF_INET:
|
|
||||||
addr_src = &((struct sockaddr_in *)addr)->sin_addr;
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
addr_src = &((struct sockaddr_in6 *)addr)->sin6_addr;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
addr_src = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(addr_src)
|
|
||||||
response->host_addr = inet_ntop(addr->sa_family, addr_src, addr_buf, addr_buf_size);
|
|
||||||
|
|
||||||
switch(http_response.code)
|
switch(http_response.code)
|
||||||
{
|
{
|
||||||
|
|
100
lib/src/regist.c
100
lib/src/regist.c
|
@ -36,8 +36,9 @@
|
||||||
#define REGIST_REPONSE_TIMEOUT_MS 3000
|
#define REGIST_REPONSE_TIMEOUT_MS 3000
|
||||||
|
|
||||||
static void *regist_thread_func(void *user);
|
static void *regist_thread_func(void *user);
|
||||||
static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addrinfos);
|
static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addrinfos, struct sockaddr *recv_addr, socklen_t *recv_addr_size);
|
||||||
static int regist_connect(ChiakiRegist *regist, struct addrinfo *addrinfos, int protocol);
|
static int regist_search_connect(ChiakiRegist *regist, struct addrinfo *addrinfos, struct sockaddr *send_addr, socklen_t *send_addr_len);
|
||||||
|
static int regist_request_connect(ChiakiRegist *regist, const struct sockaddr *addr, size_t addr_len);
|
||||||
static ChiakiErrorCode regist_recv_response(ChiakiRegist *regist, ChiakiRegisteredHost *host, int sock, ChiakiRPCrypt *rpcrypt);
|
static ChiakiErrorCode regist_recv_response(ChiakiRegist *regist, ChiakiRegisteredHost *host, int sock, ChiakiRPCrypt *rpcrypt);
|
||||||
static ChiakiErrorCode regist_parse_response_payload(ChiakiRegist *regist, ChiakiRegisteredHost *host, char *buf, size_t buf_size);
|
static ChiakiErrorCode regist_parse_response_payload(ChiakiRegist *regist, ChiakiRegisteredHost *host, char *buf, size_t buf_size);
|
||||||
|
|
||||||
|
@ -163,7 +164,10 @@ static void *regist_thread_func(void *user)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = regist_search(regist, addrinfos); // TODO: get addr from response
|
struct sockaddr recv_addr = {};
|
||||||
|
socklen_t recv_addr_size;
|
||||||
|
recv_addr_size = sizeof(recv_addr);
|
||||||
|
err = regist_search(regist, addrinfos, &recv_addr, &recv_addr_size);
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
{
|
{
|
||||||
if(err == CHIAKI_ERR_CANCELED)
|
if(err == CHIAKI_ERR_CANCELED)
|
||||||
|
@ -180,7 +184,7 @@ static void *regist_thread_func(void *user)
|
||||||
goto fail_addrinfos;
|
goto fail_addrinfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sock = regist_connect(regist, addrinfos, IPPROTO_TCP);
|
int sock = regist_request_connect(regist, &recv_addr, recv_addr_size);
|
||||||
if(sock < 0)
|
if(sock < 0)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(regist->log, "Regist eventually failed to connect for request");
|
CHIAKI_LOGE(regist->log, "Regist eventually failed to connect for request");
|
||||||
|
@ -242,10 +246,12 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addrinfos)
|
static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addrinfos, struct sockaddr *recv_addr, socklen_t *recv_addr_size)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGI(regist->log, "Regist starting search");
|
CHIAKI_LOGI(regist->log, "Regist starting search");
|
||||||
int sock = regist_connect(regist, addrinfos, IPPROTO_UDP);
|
struct sockaddr send_addr;
|
||||||
|
socklen_t send_addr_len = sizeof(send_addr);
|
||||||
|
int sock = regist_search_connect(regist, addrinfos, &send_addr, &send_addr_len);
|
||||||
if(sock < 0)
|
if(sock < 0)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(regist->log, "Regist eventually failed to connect for search");
|
CHIAKI_LOGE(regist->log, "Regist eventually failed to connect for search");
|
||||||
|
@ -255,10 +261,11 @@ static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addr
|
||||||
ChiakiErrorCode err = CHIAKI_ERR_SUCCESS;
|
ChiakiErrorCode err = CHIAKI_ERR_SUCCESS;
|
||||||
|
|
||||||
CHIAKI_LOGI(regist->log, "Regist sending search packet");
|
CHIAKI_LOGI(regist->log, "Regist sending search packet");
|
||||||
int r = send(sock, "SRC2", 4, 0);
|
int r = sendto(sock, "SRC2", 4, 0, &send_addr, send_addr_len);
|
||||||
if(r < 0)
|
if(r < 0)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(regist->log, "Regist failed to send search: %s", strerror(errno));
|
CHIAKI_LOGE(regist->log, "Regist failed to send search: %s", strerror(errno));
|
||||||
|
err = CHIAKI_ERR_NETWORK;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,10 +285,7 @@ static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addr
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t buf[0x100];
|
uint8_t buf[0x100];
|
||||||
struct sockaddr recv_addr;
|
ssize_t n = recvfrom(sock, buf, sizeof(buf) - 1, 0, recv_addr, recv_addr_size);
|
||||||
socklen_t recv_addr_size;
|
|
||||||
recv_addr_size = sizeof(recv_addr);
|
|
||||||
ssize_t n = recvfrom(sock, buf, sizeof(buf) - 1, 0, &recv_addr, &recv_addr_size);
|
|
||||||
if(n <= 0)
|
if(n <= 0)
|
||||||
{
|
{
|
||||||
if(n < 0)
|
if(n < 0)
|
||||||
|
@ -297,7 +301,9 @@ static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addr
|
||||||
|
|
||||||
if(n >= 4 && memcmp(buf, "RES2", 4) == 0)
|
if(n >= 4 && memcmp(buf, "RES2", 4) == 0)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGI(regist->log, "Regist received search response"); // TODO: print from <addr>
|
char addr[64];
|
||||||
|
const char *addr_str = sockaddr_str(recv_addr, addr, sizeof(addr));
|
||||||
|
CHIAKI_LOGI(regist->log, "Regist received search response from %s", addr_str ? addr_str : "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,42 +313,82 @@ done:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regist_connect(ChiakiRegist *regist, struct addrinfo *addrinfos, int protocol)
|
static int regist_search_connect(ChiakiRegist *regist, struct addrinfo *addrinfos, struct sockaddr *send_addr, socklen_t *send_addr_len)
|
||||||
{
|
{
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
for(struct addrinfo *ai=addrinfos; ai; ai=ai->ai_next)
|
for(struct addrinfo *ai=addrinfos; ai; ai=ai->ai_next)
|
||||||
{
|
{
|
||||||
if(ai->ai_protocol != protocol)
|
if(ai->ai_protocol != IPPROTO_UDP)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(ai->ai_addr->sa_family != AF_INET) // TODO: support IPv6
|
if(ai->ai_addr->sa_family != AF_INET) // TODO: support IPv6
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
struct sockaddr *sa = malloc(ai->ai_addrlen);
|
if(ai->ai_addrlen > *send_addr_len)
|
||||||
if(!sa)
|
|
||||||
continue;
|
continue;
|
||||||
memcpy(sa, ai->ai_addr, ai->ai_addrlen);
|
memcpy(send_addr, ai->ai_addr, ai->ai_addrlen);
|
||||||
|
*send_addr_len = ai->ai_addrlen;
|
||||||
|
|
||||||
set_port(sa, htons(REGIST_PORT));
|
set_port(send_addr, htons(REGIST_PORT));
|
||||||
|
|
||||||
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
if(sock < 0)
|
if(sock < 0)
|
||||||
{
|
|
||||||
free(sa);
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(regist->info.broadcast)
|
||||||
|
{
|
||||||
|
const int broadcast = 1;
|
||||||
|
int r = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
|
||||||
|
if(r < 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(regist->log, "Regist failed to setsockopt SO_BROADCAST");
|
||||||
|
goto connect_fail;
|
||||||
}
|
}
|
||||||
int r = connect(sock, sa, ai->ai_addrlen);
|
|
||||||
|
in_addr_t ip = ((struct sockaddr_in *)send_addr)->sin_addr.s_addr;
|
||||||
|
((struct sockaddr_in *)send_addr)->sin_addr.s_addr = INADDR_ANY;
|
||||||
|
r = bind(sock, send_addr, *send_addr_len);
|
||||||
|
((struct sockaddr_in *)send_addr)->sin_addr.s_addr = ip;
|
||||||
|
if(r < 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(regist->log, "Regist failed to bind socket");
|
||||||
|
goto connect_fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int r = connect(sock, send_addr, *send_addr_len);
|
||||||
|
if(r < 0)
|
||||||
|
{
|
||||||
|
int errsv = errno;
|
||||||
|
CHIAKI_LOGE(regist->log, "Regist connect failed: %s", strerror(errsv));
|
||||||
|
goto connect_fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
connect_fail:
|
||||||
|
close(sock);
|
||||||
|
sock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regist_request_connect(ChiakiRegist *regist, const struct sockaddr *addr, size_t addr_len)
|
||||||
|
{
|
||||||
|
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if(sock < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int r = connect(sock, addr, addr_len);
|
||||||
if(r < 0)
|
if(r < 0)
|
||||||
{
|
{
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
CHIAKI_LOGE(regist->log, "Regist connect failed: %s", strerror(errsv));
|
CHIAKI_LOGE(regist->log, "Regist connect failed: %s", strerror(errsv));
|
||||||
close(sock);
|
close(sock);
|
||||||
sock = -1;
|
|
||||||
free(sa);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
free(sa);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sock;
|
return sock;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <chiaki/common.h>
|
#include <chiaki/common.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
static inline ChiakiErrorCode set_port(struct sockaddr *sa, in_port_t port)
|
static inline ChiakiErrorCode set_port(struct sockaddr *sa, in_port_t port)
|
||||||
{
|
{
|
||||||
|
@ -32,6 +33,26 @@ static inline ChiakiErrorCode set_port(struct sockaddr *sa, in_port_t port)
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return CHIAKI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char *sockaddr_str(struct sockaddr *addr, char *addr_buf, size_t addr_buf_size)
|
||||||
|
{
|
||||||
|
void *addr_src;
|
||||||
|
switch(addr->sa_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
addr_src = &((struct sockaddr_in *)addr)->sin_addr;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
addr_src = &((struct sockaddr_in6 *)addr)->sin6_addr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
addr_src = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(addr_src)
|
||||||
|
return inet_ntop(addr->sa_family, addr_src, addr_buf, addr_buf_size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void xor_bytes(uint8_t *dst, uint8_t *src, size_t sz)
|
static inline void xor_bytes(uint8_t *dst, uint8_t *src, size_t sz)
|
||||||
{
|
{
|
||||||
while(sz > 0)
|
while(sz > 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue