mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-19 21:13:12 -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 QPlainTextEdit;
|
||||
class QDialogButtonBox;
|
||||
class QCheckBox;
|
||||
|
||||
class RegistDialog : public QDialog
|
||||
{
|
||||
|
@ -38,6 +39,7 @@ class RegistDialog : public QDialog
|
|||
Settings *settings;
|
||||
|
||||
QLineEdit *host_edit;
|
||||
QCheckBox *broadcast_check_box;
|
||||
QLineEdit *psn_id_edit;
|
||||
QLineEdit *pin_edit;
|
||||
QDialogButtonBox *button_box;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QPlainTextEdit>
|
||||
#include <QScrollBar>
|
||||
#include <QMessageBox>
|
||||
#include <QCheckBox>
|
||||
|
||||
Q_DECLARE_METATYPE(ChiakiLogLevel)
|
||||
|
||||
|
@ -52,6 +53,10 @@ RegistDialog::RegistDialog(Settings *settings, const QString &host, QWidget *par
|
|||
else
|
||||
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);
|
||||
form_layout->addRow(tr("PSN ID (username):"), psn_id_edit);
|
||||
|
||||
|
@ -90,6 +95,7 @@ void RegistDialog::accept()
|
|||
QByteArray host = host_edit->text().trimmed().toUtf8();
|
||||
info.psn_id = psn_id.data();
|
||||
info.host = host.data();
|
||||
info.broadcast = broadcast_check_box->isChecked();
|
||||
info.pin = (uint32_t)pin_edit->text().toULong();
|
||||
|
||||
RegistExecuteDialog execute_dialog(settings, info, this);
|
||||
|
|
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
typedef struct chiaki_regist_info_t
|
||||
{
|
||||
char *host;
|
||||
bool broadcast;
|
||||
char *psn_id;
|
||||
uint32_t pin;
|
||||
} ChiakiRegistInfo;
|
||||
|
@ -50,7 +51,6 @@ typedef struct chiaki_registered_host_t
|
|||
} ChiakiRegisteredHost;
|
||||
|
||||
typedef enum chiaki_regist_event_type_t {
|
||||
CHIAKI_REGIST_EVENT_TYPE_CONNECTED,
|
||||
CHIAKI_REGIST_EVENT_TYPE_FINISHED_CANCELED,
|
||||
CHIAKI_REGIST_EVENT_TYPE_FINISHED_FAILED,
|
||||
CHIAKI_REGIST_EVENT_TYPE_FINISHED_SUCCESS
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <chiaki/discovery.h>
|
||||
#include <chiaki/http.h>
|
||||
#include <chiaki/log.h>
|
||||
|
@ -61,21 +63,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_discovery_srch_response_parse(ChiakiDiscove
|
|||
|
||||
memset(response, 0, sizeof(*response));
|
||||
|
||||
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)
|
||||
response->host_addr = inet_ntop(addr->sa_family, addr_src, addr_buf, addr_buf_size);
|
||||
response->host_addr = sockaddr_str(addr, addr_buf, addr_buf_size);
|
||||
|
||||
switch(http_response.code)
|
||||
{
|
||||
|
|
106
lib/src/regist.c
106
lib/src/regist.c
|
@ -36,8 +36,9 @@
|
|||
#define REGIST_REPONSE_TIMEOUT_MS 3000
|
||||
|
||||
static void *regist_thread_func(void *user);
|
||||
static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addrinfos);
|
||||
static int regist_connect(ChiakiRegist *regist, struct addrinfo *addrinfos, int protocol);
|
||||
static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addrinfos, struct sockaddr *recv_addr, socklen_t *recv_addr_size);
|
||||
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_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;
|
||||
}
|
||||
|
||||
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_CANCELED)
|
||||
|
@ -180,7 +184,7 @@ static void *regist_thread_func(void *user)
|
|||
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)
|
||||
{
|
||||
CHIAKI_LOGE(regist->log, "Regist eventually failed to connect for request");
|
||||
|
@ -242,10 +246,12 @@ fail:
|
|||
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");
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
CHIAKI_LOGE(regist->log, "Regist failed to send search: %s", strerror(errno));
|
||||
err = CHIAKI_ERR_NETWORK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -278,10 +285,7 @@ static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addr
|
|||
}
|
||||
|
||||
uint8_t buf[0x100];
|
||||
struct sockaddr recv_addr;
|
||||
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);
|
||||
ssize_t n = recvfrom(sock, buf, sizeof(buf) - 1, 0, recv_addr, recv_addr_size);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -307,42 +313,82 @@ done:
|
|||
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;
|
||||
for(struct addrinfo *ai=addrinfos; ai; ai=ai->ai_next)
|
||||
{
|
||||
if(ai->ai_protocol != protocol)
|
||||
if(ai->ai_protocol != IPPROTO_UDP)
|
||||
continue;
|
||||
|
||||
if(ai->ai_addr->sa_family != AF_INET) // TODO: support IPv6
|
||||
continue;
|
||||
|
||||
struct sockaddr *sa = malloc(ai->ai_addrlen);
|
||||
if(!sa)
|
||||
if(ai->ai_addrlen > *send_addr_len)
|
||||
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);
|
||||
if(sock < 0)
|
||||
{
|
||||
free(sa);
|
||||
continue;
|
||||
}
|
||||
int r = connect(sock, sa, ai->ai_addrlen);
|
||||
if(r < 0)
|
||||
|
||||
if(regist->info.broadcast)
|
||||
{
|
||||
int errsv = errno;
|
||||
CHIAKI_LOGE(regist->log, "Regist connect failed: %s", strerror(errsv));
|
||||
close(sock);
|
||||
sock = -1;
|
||||
free(sa);
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
free(sa);
|
||||
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)
|
||||
{
|
||||
int errsv = errno;
|
||||
CHIAKI_LOGE(regist->log, "Regist connect failed: %s", strerror(errsv));
|
||||
close(sock);
|
||||
}
|
||||
|
||||
return sock;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <chiaki/common.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
while(sz > 0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue