diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index ac3bafc..533402e 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -8,7 +8,8 @@ set(HEADER_FILES include/chiaki/log.h include/chiaki/ctrl.h include/chiaki/rpcrypt.h - include/chiaki/takion.h) + include/chiaki/takion.h + include/chiaki/senkusha.h) set(SOURCE_FILES src/common.c @@ -19,7 +20,9 @@ set(SOURCE_FILES src/log.c src/ctrl.c src/rpcrypt.c - src/takion.c) + src/takion.c + src/senkusha.c + src/utils.h) add_library(chiaki-lib ${HEADER_FILES} ${SOURCE_FILES}) diff --git a/lib/include/chiaki/senkusha.h b/lib/include/chiaki/senkusha.h new file mode 100644 index 0000000..b633e65 --- /dev/null +++ b/lib/include/chiaki/senkusha.h @@ -0,0 +1,36 @@ +/* + * This file is part of Chiaki. + * + * Chiaki is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Chiaki is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chiaki. If not, see . + */ + +#ifndef CHIAKI_SENKUSHA_H +#define CHIAKI_SENKUSHA_H + +#include "takion.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct chiaki_session_t; + + +CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(struct chiaki_session_t *session); + +#ifdef __cplusplus +} +#endif + +#endif // CHIAKI_SENKUSHA_H diff --git a/lib/include/chiaki/session.h b/lib/include/chiaki/session.h index d761a79..3e3e131 100644 --- a/lib/include/chiaki/session.h +++ b/lib/include/chiaki/session.h @@ -109,8 +109,6 @@ typedef struct chiaki_session_t ChiakiMutex ctrl_cond_mutex; bool ctrl_session_id_received; - ChiakiTakion takion; - ChiakiLog log; } ChiakiSession; diff --git a/lib/include/chiaki/takion.h b/lib/include/chiaki/takion.h index e664b31..c5738d5 100644 --- a/lib/include/chiaki/takion.h +++ b/lib/include/chiaki/takion.h @@ -30,9 +30,24 @@ extern "C" { #endif +typedef void (*ChiakiTakionDataCallback)(uint8_t *buf, size_t buf_size, void *user); + + +typedef struct chiaki_takion_connect_info_t +{ + ChiakiLog *log; + struct sockaddr *sa; + socklen_t sa_len; + ChiakiTakionDataCallback data_cb; + void *data_cb_user; +} ChiakiTakionConnectInfo; + + typedef struct chiaki_takion_t { ChiakiLog *log; + ChiakiTakionDataCallback data_cb; + void *data_cb_user; int sock; ChiakiThread thread; int stop_pipe[2]; @@ -40,12 +55,12 @@ typedef struct chiaki_takion_t int send_retries; uint32_t tag_local; uint32_t tag_remote; + uint32_t seq_num_local; } ChiakiTakion; -CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, ChiakiLog *log, struct sockaddr *sa, socklen_t sa_len); +CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, ChiakiTakionConnectInfo *info); CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion); -CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *buf, size_t buf_size); - +CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, uint8_t *buf, size_t buf_size); #ifdef __cplusplus } diff --git a/lib/src/senkusha.c b/lib/src/senkusha.c new file mode 100644 index 0000000..abeea4a --- /dev/null +++ b/lib/src/senkusha.c @@ -0,0 +1,80 @@ +/* + * This file is part of Chiaki. + * + * Chiaki is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Chiaki is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chiaki. If not, see . + */ + +#include +#include + +#include +#include + +// TODO: remove +#include + +#include "utils.h" + + +#define SENKUSHA_SOCKET 9297 + + +typedef struct senkusha_t +{ + ChiakiLog *log; + ChiakiTakion takion; +} Senkusha; + + +void senkusha_takion_data(uint8_t *buf, size_t buf_size, void *user); + +CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSession *session) +{ + Senkusha senkusha; + senkusha.log = &session->log; + + ChiakiTakionConnectInfo takion_info; + takion_info.log = senkusha.log; + takion_info.sa_len = session->connect_info.host_addrinfo_selected->ai_addrlen; + takion_info.sa = malloc(takion_info.sa_len); + if(!takion_info.sa) + return CHIAKI_ERR_MEMORY; + memcpy(takion_info.sa, session->connect_info.host_addrinfo_selected->ai_addr, takion_info.sa_len); + ChiakiErrorCode err = set_port(takion_info.sa, htons(SENKUSHA_SOCKET)); + assert(err == CHIAKI_ERR_SUCCESS); + + takion_info.data_cb = senkusha_takion_data; + takion_info.data_cb_user = &senkusha; + + err = chiaki_takion_connect(&senkusha.takion, &takion_info); + free(takion_info.sa); + if(err != CHIAKI_ERR_SUCCESS) + { + CHIAKI_LOGE(&session->log, "Senkusha connect failed\n"); + return err; + } + + while(true) + sleep(1); + + return CHIAKI_ERR_SUCCESS; +} + +void senkusha_takion_data(uint8_t *buf, size_t buf_size, void *user) +{ + Senkusha *senkusha = user; + + CHIAKI_LOGD(senkusha->log, "Senkusha received data:\n"); + chiaki_log_hexdump(senkusha->log, CHIAKI_LOG_DEBUG, buf, buf_size); +} \ No newline at end of file diff --git a/lib/src/session.c b/lib/src/session.c index 69aa5b0..fe27f00 100644 --- a/lib/src/session.c +++ b/lib/src/session.c @@ -15,6 +15,7 @@ * along with Chiaki. If not, see . */ +#include #include #include #include @@ -25,10 +26,13 @@ #include #include #include +#include #include #include +#include "utils.h" + #define SESSION_PORT 9295 @@ -153,23 +157,15 @@ static void *session_thread_func(void *arg) CHIAKI_LOGI(&session->log, "Starting Senkusha\n"); - // just testing... - struct sockaddr *sa = malloc(session->connect_info.host_addrinfo_selected->ai_addrlen); - memcpy(sa, session->connect_info.host_addrinfo_selected->ai_addr, session->connect_info.host_addrinfo_selected->ai_addrlen); - if(sa->sa_family == AF_INET) - ((struct sockaddr_in *)sa)->sin_port = htons(9297); - else if(sa->sa_family == AF_INET6) - ((struct sockaddr_in6 *)sa)->sin6_port = htons(9297); - else - CHIAKI_LOGE(&session->log, "wtf\n"); - err = chiaki_takion_connect(&session->takion, &session->log, sa, session->connect_info.host_addrinfo_selected->ai_addrlen); + err = chiaki_senkusha_run(session); if(err != CHIAKI_ERR_SUCCESS) { - CHIAKI_LOGE(&session->log, "Senkusha connect failed\n"); + CHIAKI_LOGE(&session->log, "Senkusha failed\n"); + } + else + { + CHIAKI_LOGE(&session->log, "Senkusha completed successfully\n"); } - free(sa); - - CHIAKI_LOGI(&session->log, "Senkusha started\n"); quit_ctrl: chiaki_ctrl_join(&session->ctrl); @@ -233,16 +229,14 @@ static bool session_thread_request_session(ChiakiSession *session) continue; memcpy(sa, ai->ai_addr, ai->ai_addrlen); - if(sa->sa_family == AF_INET) - ((struct sockaddr_in *)sa)->sin_port = htons(SESSION_PORT); - else if(sa->sa_family == AF_INET6) - ((struct sockaddr_in6 *)sa)->sin6_port = htons(SESSION_PORT); - else + if(sa->sa_family != AF_INET && sa->sa_family != AF_INET6) { free(sa); continue; } + set_port(sa, htons(SESSION_PORT)); + int r = getnameinfo(sa, ai->ai_addrlen, session->connect_info.hostname, sizeof(session->connect_info.hostname), NULL, 0, 0); if(r != 0) { diff --git a/lib/src/takion.c b/lib/src/takion.c index 637283c..fa71dc3 100644 --- a/lib/src/takion.c +++ b/lib/src/takion.c @@ -84,13 +84,14 @@ static ChiakiErrorCode takion_recv(ChiakiTakion *takion, uint8_t *buf, size_t *b static ChiakiErrorCode takion_recv_message_init_ack(ChiakiTakion *takion, TakionMessagePayloadInitAck *payload); static ChiakiErrorCode takion_recv_message_cookie_ack(ChiakiTakion *takion); -CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, ChiakiLog *log, struct sockaddr *sa, socklen_t sa_len) +CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, ChiakiTakionConnectInfo *info) { ChiakiErrorCode ret; - takion->log = log; + takion->log = info->log; takion->tag_local = 0x4823; // "random" tag + takion->seq_num_local = takion->tag_local; takion->tag_remote = 0; takion->recv_timeout.tv_sec = 2; takion->recv_timeout.tv_usec = 0; @@ -101,26 +102,30 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, Chiaki int r = pipe(takion->stop_pipe); if(r < 0) { + CHIAKI_LOGE(takion->log, "Takion failed to create pipe\n"); return CHIAKI_ERR_UNKNOWN; } r = fcntl(takion->stop_pipe[0], F_SETFL, O_NONBLOCK); if(r == -1) { + CHIAKI_LOGE(takion->log, "Takion failed to fcntl pipe\n"); ret = CHIAKI_ERR_UNKNOWN; goto error_pipe; } - takion->sock = socket(sa->sa_family, SOCK_DGRAM, IPPROTO_UDP); + takion->sock = socket(info->sa->sa_family, SOCK_DGRAM, IPPROTO_UDP); if(takion->sock < 0) { + CHIAKI_LOGE(takion->log, "Takion failed to create socket\n"); ret = CHIAKI_ERR_NETWORK; goto error_pipe; } - r = connect(takion->sock, sa, sa_len); + r = connect(takion->sock, info->sa, info->sa_len); if(r < 0) { + CHIAKI_LOGE(takion->log, "Takion failed to connect: %s\n", strerror(errno)); ret = CHIAKI_ERR_NETWORK; goto error_sock; } @@ -233,7 +238,7 @@ CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion) close(takion->stop_pipe[0]); } -CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *buf, size_t buf_size) +CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_raw(ChiakiTakion *takion, uint8_t *buf, size_t buf_size) { CHIAKI_LOGD(takion->log, "Takion send:\n"); chiaki_log_hexdump(takion->log, CHIAKI_LOG_DEBUG, buf, buf_size); @@ -246,7 +251,6 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t * - static void *takion_thread_func(void *user) { ChiakiTakion *takion = user; @@ -408,7 +412,7 @@ static ChiakiErrorCode takion_send_message_init(ChiakiTakion *takion, TakionMess *((uint16_t *)(pl + 0xa)) = htons(payload->max); *((uint32_t *)(pl + 0xc)) = htonl(payload->tag1); - return chiaki_takion_send(takion, message, sizeof(message)); + return chiaki_takion_send_raw(takion, message, sizeof(message)); } @@ -419,7 +423,7 @@ static ChiakiErrorCode takion_send_message_cookie(ChiakiTakion *takion, uint8_t message[0] = TAKION_PACKET_TYPE_MESSAGE; takion_write_message_header(message + 1, takion->tag_remote, 0, 0xa, 0, TAKION_COOKIE_SIZE); memcpy(message + 1 + MESSAGE_HEADER_SIZE, cookie, TAKION_COOKIE_SIZE); - return chiaki_takion_send(takion, message, sizeof(message)); + return chiaki_takion_send_raw(takion, message, sizeof(message)); } diff --git a/lib/src/utils.h b/lib/src/utils.h new file mode 100644 index 0000000..6d4a191 --- /dev/null +++ b/lib/src/utils.h @@ -0,0 +1,35 @@ +/* + * This file is part of Chiaki. + * + * Chiaki is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Chiaki is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chiaki. If not, see . + */ + +#ifndef CHIAKI_UTILS_H +#define CHIAKI_UTILS_H + +#include +#include + +static inline ChiakiErrorCode set_port(struct sockaddr *sa, in_port_t port) +{ + if(sa->sa_family == AF_INET) + ((struct sockaddr_in *)sa)->sin_port = port; + else if(sa->sa_family == AF_INET6) + ((struct sockaddr_in6 *)sa)->sin6_port = port; + else + return CHIAKI_ERR_INVALID_DATA; + return CHIAKI_ERR_SUCCESS; +} + +#endif // CHIAKI_UTILS_H