diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 884d48b..652a4e8 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -11,7 +11,6 @@ set(HEADER_FILES
include/chiaki/takion.h
include/chiaki/senkusha.h
include/chiaki/streamconnection.h
- include/chiaki/mirai.h
include/chiaki/ecdh.h
include/chiaki/launchspec.h
include/chiaki/random.h
@@ -48,7 +47,6 @@ set(SOURCE_FILES
src/utils.h
src/pb_utils.h
src/streamconnection.c
- src/mirai.c
src/ecdh.c
src/launchspec.c
src/random.c
diff --git a/lib/include/chiaki/mirai.h b/lib/include/chiaki/mirai.h
deleted file mode 100644
index e4db2c2..0000000
--- a/lib/include/chiaki/mirai.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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_MIRAI_H
-#define CHIAKI_MIRAI_H
-
-#include "thread.h"
-
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct chiaki_mirai_t
-{
- int request;
- int response;
- ChiakiMutex mutex;
- ChiakiCond cond;
-} ChiakiMirai;
-
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_init(ChiakiMirai *mirai);
-CHIAKI_EXPORT void chiaki_mirai_fini(ChiakiMirai *mirai);
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_signal(ChiakiMirai *mirai, int response);
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_request_begin(ChiakiMirai *mirai, int request, bool first);
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_request_wait(ChiakiMirai *mirai, uint64_t timeout_ms, bool keep_locked);
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_request_unlock(ChiakiMirai *mirai);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // CHIAKI_MIRAI_H
diff --git a/lib/include/chiaki/senkusha.h b/lib/include/chiaki/senkusha.h
index b633e65..0e3e5ec 100644
--- a/lib/include/chiaki/senkusha.h
+++ b/lib/include/chiaki/senkusha.h
@@ -24,10 +24,33 @@
extern "C" {
#endif
-struct chiaki_session_t;
+typedef struct chiaki_session_t ChiakiSession;
+typedef struct senkusha_t
+{
+ ChiakiSession *session;
+ ChiakiLog *log;
+ ChiakiTakion takion;
-CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(struct chiaki_session_t *session);
+ int state;
+ bool state_finished;
+ bool state_failed;
+ bool should_stop;
+
+ /**
+ * signaled on change of state_finished or should_stop
+ */
+ ChiakiCond state_cond;
+
+ /**
+ * protects state, state_finished, state_failed and should_stop
+ */
+ ChiakiMutex state_mutex;
+} ChiakiSenkusha;
+
+CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_init(ChiakiSenkusha *senkusha, ChiakiSession *session);
+CHIAKI_EXPORT void chiaki_senkusha_fini(ChiakiSenkusha *senkusha);
+CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSenkusha *senkusha);
#ifdef __cplusplus
}
diff --git a/lib/src/mirai.c b/lib/src/mirai.c
deleted file mode 100644
index 548243c..0000000
--- a/lib/src/mirai.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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
-
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_init(ChiakiMirai *mirai)
-{
- mirai->request = -1;
- mirai->response = -1;
- ChiakiErrorCode err = chiaki_mutex_init(&mirai->mutex, false);
- if(err != CHIAKI_ERR_SUCCESS)
- return err;
- err = chiaki_cond_init(&mirai->cond);
- if(err != CHIAKI_ERR_SUCCESS)
- {
- chiaki_mutex_fini(&mirai->mutex);
- return err;
- }
- return CHIAKI_ERR_SUCCESS;
-}
-
-CHIAKI_EXPORT void chiaki_mirai_fini(ChiakiMirai *mirai)
-{
- chiaki_mutex_fini(&mirai->mutex);
- chiaki_cond_fini(&mirai->cond);
-}
-
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_signal(ChiakiMirai *mirai, int response)
-{
- ChiakiErrorCode err = chiaki_mutex_lock(&mirai->mutex);
- if(err != CHIAKI_ERR_SUCCESS)
- return err;
- mirai->response = response;
- err = chiaki_cond_signal(&mirai->cond);
- if(err != CHIAKI_ERR_SUCCESS)
- return err;
- return chiaki_mutex_unlock(&mirai->mutex);
-}
-
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_request_begin(ChiakiMirai *mirai, int request, bool first)
-{
- ChiakiErrorCode err = first ? chiaki_mutex_lock(&mirai->mutex) : CHIAKI_ERR_SUCCESS;
- mirai->request = request;
- return err;
-}
-
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_request_wait(ChiakiMirai *mirai, uint64_t timeout_ms, bool keep_locked)
-{
- ChiakiErrorCode err = chiaki_cond_timedwait(&mirai->cond, &mirai->mutex, timeout_ms);
- mirai->request = -1;
- if(!keep_locked)
- {
- ChiakiErrorCode err2 = chiaki_mutex_unlock(&mirai->mutex);
- if(err2 != CHIAKI_ERR_SUCCESS)
- return err2;
- }
- return err;
-}
-
-CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_request_unlock(ChiakiMirai *mirai)
-{
- return chiaki_mutex_unlock(&mirai->mutex);
-}
\ No newline at end of file
diff --git a/lib/src/senkusha.c b/lib/src/senkusha.c
index c5bd5e5..fa8ab4b 100644
--- a/lib/src/senkusha.c
+++ b/lib/src/senkusha.c
@@ -17,7 +17,6 @@
#include
#include
-#include
#include
#include
@@ -33,43 +32,86 @@
#define SENKUSHA_PORT 9297
-#define BIG_TIMEOUT_MS 5000
-
-
-typedef struct senkusha_t
-{
- ChiakiLog *log;
- ChiakiTakion takion;
-
- ChiakiMirai bang_mirai;
-} Senkusha;
-
-#define MIRAI_REQUEST_CONNECT 1
-#define MIRAI_REQUEST_BANG 2
+#define EXPECT_TIMEOUT_MS 5000
+typedef enum {
+ STATE_IDLE,
+ STATE_TAKION_CONNECT,
+ STATE_EXPECT_BANG
+} SenkushaState;
static void senkusha_takion_cb(ChiakiTakionEvent *event, void *user);
-static void senkusha_takion_data(Senkusha *senkusha, ChiakiTakionMessageDataType data_type, uint8_t *buf, size_t buf_size);
-static ChiakiErrorCode senkusha_send_big(Senkusha *senkusha);
-static ChiakiErrorCode senkusha_send_disconnect(Senkusha *senkusha);
+static void senkusha_takion_data(ChiakiSenkusha *senkusha, ChiakiTakionMessageDataType data_type, uint8_t *buf, size_t buf_size);
+static ChiakiErrorCode senkusha_send_big(ChiakiSenkusha *senkusha);
+static ChiakiErrorCode senkusha_send_disconnect(ChiakiSenkusha *senkusha);
-CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSession *session)
+CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_init(ChiakiSenkusha *senkusha, ChiakiSession *session)
{
- Senkusha senkusha;
- senkusha.log = &session->log;
- ChiakiErrorCode err = chiaki_mirai_init(&senkusha.bang_mirai);
+ senkusha->session = session;
+ senkusha->log = &session->log;
+
+ ChiakiErrorCode err = chiaki_mutex_init(&senkusha->state_mutex, false);
if(err != CHIAKI_ERR_SUCCESS)
- goto error_bang_mirai;
+ goto error;
+
+ err = chiaki_cond_init(&senkusha->state_cond);
+ if(err != CHIAKI_ERR_SUCCESS)
+ goto error_state_mutex;
+
+ senkusha->state = STATE_IDLE;
+ senkusha->state_finished = false;
+ senkusha->state_failed = false;
+ senkusha->should_stop = false;
+
+ return CHIAKI_ERR_SUCCESS;
+
+error_state_mutex:
+ chiaki_mutex_fini(&senkusha->state_mutex);
+error:
+ return err;
+}
+
+CHIAKI_EXPORT void chiaki_senkusha_fini(ChiakiSenkusha *senkusha)
+{
+ chiaki_cond_fini(&senkusha->state_cond);
+ chiaki_mutex_fini(&senkusha->state_mutex);
+}
+
+static bool state_finished_cond_check(void *user)
+{
+ ChiakiSenkusha *senkusha = user;
+ return senkusha->state_finished || senkusha->should_stop;
+}
+
+CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSenkusha *senkusha)
+{
+ ChiakiSession *session = senkusha->session;
+ ChiakiErrorCode err;
+
+ err = chiaki_mutex_lock(&senkusha->state_mutex);
+ assert(err == CHIAKI_ERR_SUCCESS);
+
+#define QUIT(quit_label) do { \
+ chiaki_mutex_unlock(&senkusha->state_mutex); \
+ goto quit_label; \
+ } while(0)
+
+ if(senkusha->should_stop)
+ {
+ err = CHIAKI_ERR_CANCELED;
+ goto quit;
+ }
ChiakiTakionConnectInfo takion_info;
- takion_info.log = senkusha.log;
+ 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)
{
err = CHIAKI_ERR_MEMORY;
- goto error_bang_mirai;
+ QUIT(quit);
}
+
memcpy(takion_info.sa, session->connect_info.host_addrinfo_selected->ai_addr, takion_info.sa_len);
err = set_port(takion_info.sa, htons(SENKUSHA_PORT));
assert(err == CHIAKI_ERR_SUCCESS);
@@ -77,83 +119,96 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_senkusha_run(ChiakiSession *session)
takion_info.enable_crypt = false;
takion_info.cb = senkusha_takion_cb;
- takion_info.cb_user = &senkusha;
+ takion_info.cb_user = senkusha;
- err = chiaki_mirai_request_begin(&senkusha.bang_mirai, MIRAI_REQUEST_CONNECT, true);
- assert(err == CHIAKI_ERR_SUCCESS);
+ senkusha->state = STATE_TAKION_CONNECT;
+ senkusha->state_finished = false;
+ senkusha->state_failed = false;
- err = chiaki_takion_connect(&senkusha.takion, &takion_info);
+ err = chiaki_takion_connect(&senkusha->takion, &takion_info);
free(takion_info.sa);
if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(&session->log, "Senkusha connect failed");
- goto error_bang_mirai;
+ QUIT(quit);
}
- err = chiaki_mirai_request_wait(&senkusha.bang_mirai, BIG_TIMEOUT_MS, false);
+ err = chiaki_cond_timedwait_pred(&senkusha->state_cond, &senkusha->state_mutex, EXPECT_TIMEOUT_MS, state_finished_cond_check, senkusha);
assert(err == CHIAKI_ERR_SUCCESS || err == CHIAKI_ERR_TIMEOUT);
-
- if(!senkusha.bang_mirai.response)
+ if(!senkusha->state_finished)
{
if(err == CHIAKI_ERR_TIMEOUT)
CHIAKI_LOGE(&session->log, "Senkusha connect timeout");
- CHIAKI_LOGE(&session->log, "Senkusha Takion connect failed");
- err = CHIAKI_ERR_UNKNOWN;
- goto error_takion;
+ if(senkusha->should_stop)
+ err = CHIAKI_ERR_CANCELED;
+ else
+ CHIAKI_LOGE(&session->log, "Senkusha Takion connect failed");
+
+ QUIT(quit_takion);
}
CHIAKI_LOGI(&session->log, "Senkusha sending big");
- err = chiaki_mirai_request_begin(&senkusha.bang_mirai, MIRAI_REQUEST_BANG, true);
- assert(err == CHIAKI_ERR_SUCCESS);
-
- err = senkusha_send_big(&senkusha);
+ senkusha->state = STATE_EXPECT_BANG;
+ senkusha->state_finished = false;
+ senkusha->state_failed = false;
+ err = senkusha_send_big(senkusha);
if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(&session->log, "Senkusha failed to send big");
- goto error_takion;
+ QUIT(quit_takion);
}
- err = chiaki_mirai_request_wait(&senkusha.bang_mirai, BIG_TIMEOUT_MS, false);
+ err = chiaki_cond_timedwait_pred(&senkusha->state_cond, &senkusha->state_mutex, EXPECT_TIMEOUT_MS, state_finished_cond_check, senkusha);
assert(err == CHIAKI_ERR_SUCCESS || err == CHIAKI_ERR_TIMEOUT);
- if(!senkusha.bang_mirai.response)
+ if(!senkusha->state_finished)
{
if(err == CHIAKI_ERR_TIMEOUT)
CHIAKI_LOGE(&session->log, "Senkusha bang receive timeout");
- CHIAKI_LOGE(&session->log, "Senkusha didn't receive bang");
- err = CHIAKI_ERR_UNKNOWN;
- goto error_takion;
+ if(senkusha->should_stop)
+ err = CHIAKI_ERR_CANCELED;
+ else
+ CHIAKI_LOGE(&session->log, "Senkusha didn't receive bang");
+
+ QUIT(quit_takion);
}
CHIAKI_LOGI(&session->log, "Senkusha successfully received bang");
+ // TODO: Do the actual tests
+
CHIAKI_LOGI(&session->log, "Senkusha is disconnecting");
- senkusha_send_disconnect(&senkusha);
+ senkusha_send_disconnect(senkusha);
+ chiaki_mutex_unlock(&senkusha->state_mutex);
err = CHIAKI_ERR_SUCCESS;
-error_takion:
- chiaki_takion_close(&senkusha.takion);
+quit_takion:
+ chiaki_takion_close(&senkusha->takion);
CHIAKI_LOGI(&session->log, "Senkusha closed takion");
-error_bang_mirai:
- chiaki_mirai_fini(&senkusha.bang_mirai);
+quit:
return err;
}
static void senkusha_takion_cb(ChiakiTakionEvent *event, void *user)
{
- Senkusha *senkusha = user;
+ ChiakiSenkusha *senkusha = user;
switch(event->type)
{
case CHIAKI_TAKION_EVENT_TYPE_CONNECTED:
case CHIAKI_TAKION_EVENT_TYPE_DISCONNECT:
- if(senkusha->bang_mirai.request == MIRAI_REQUEST_CONNECT)
+ chiaki_mutex_lock(&senkusha->state_mutex);
+ if(senkusha->state == STATE_TAKION_CONNECT)
{
- chiaki_mirai_signal(&senkusha->bang_mirai, event->type == CHIAKI_TAKION_EVENT_TYPE_CONNECTED);
+ senkusha->state_finished = event->type == CHIAKI_TAKION_EVENT_TYPE_CONNECTED;
+ senkusha->state_failed = event->type == CHIAKI_TAKION_EVENT_TYPE_DISCONNECT;
+ chiaki_cond_signal(&senkusha->state_cond);
}
+ chiaki_mutex_unlock(&senkusha->state_mutex);
+ break;
case CHIAKI_TAKION_EVENT_TYPE_DATA:
senkusha_takion_data(senkusha, event->data.data_type, event->data.buf, event->data.buf_size);
break;
@@ -162,7 +217,7 @@ static void senkusha_takion_cb(ChiakiTakionEvent *event, void *user)
}
}
-static void senkusha_takion_data(Senkusha *senkusha, ChiakiTakionMessageDataType data_type, uint8_t *buf, size_t buf_size)
+static void senkusha_takion_data(ChiakiSenkusha *senkusha, ChiakiTakionMessageDataType data_type, uint8_t *buf, size_t buf_size)
{
if(data_type != CHIAKI_TAKION_MESSAGE_DATA_TYPE_PROTOBUF)
return;
@@ -178,18 +233,23 @@ static void senkusha_takion_data(Senkusha *senkusha, ChiakiTakionMessageDataType
return;
}
- if(senkusha->bang_mirai.request == MIRAI_REQUEST_BANG)
+ chiaki_mutex_lock(&senkusha->state_mutex);
+ if(senkusha->state == STATE_EXPECT_BANG)
{
if(msg.type != tkproto_TakionMessage_PayloadType_BANG || !msg.has_bang_payload)
{
CHIAKI_LOGE(senkusha->log, "Senkusha expected bang payload but received something else");
- return;
}
- chiaki_mirai_signal(&senkusha->bang_mirai, 1);
+ else
+ {
+ senkusha->state_finished = true;
+ chiaki_cond_signal(&senkusha->state_cond);
+ }
}
+ chiaki_mutex_unlock(&senkusha->state_mutex);
}
-static ChiakiErrorCode senkusha_send_big(Senkusha *senkusha)
+static ChiakiErrorCode senkusha_send_big(ChiakiSenkusha *senkusha)
{
tkproto_TakionMessage msg;
memset(&msg, 0, sizeof(msg));
@@ -221,7 +281,7 @@ static ChiakiErrorCode senkusha_send_big(Senkusha *senkusha)
return err;
}
-static ChiakiErrorCode senkusha_send_disconnect(Senkusha *senkusha)
+static ChiakiErrorCode senkusha_send_disconnect(ChiakiSenkusha *senkusha)
{
tkproto_TakionMessage msg;
memset(&msg, 0, sizeof(msg));
diff --git a/lib/src/session.c b/lib/src/session.c
index 6ce494f..3f070e5 100644
--- a/lib/src/session.c
+++ b/lib/src/session.c
@@ -166,6 +166,8 @@ static bool session_check_state_pred(void *user)
|| session->ctrl_session_id_received;
}
+//#define ENABLE_SENKUSHA
+
static void *session_thread_func(void *arg)
{
ChiakiSession *session = arg;
@@ -217,21 +219,30 @@ static void *session_thread_func(void *arg)
QUIT(quit_ctrl);
}
- //CHIAKI_LOGI(&session->log, "Starting Senkusha");
+#ifdef ENABLE_SENKUSHA
+ CHIAKI_LOGI(&session->log, "Starting Senkusha");
+
+ ChiakiSenkusha senkusha;
+ err = chiaki_senkusha_init(&senkusha, session);
+ if(err != CHIAKI_ERR_SUCCESS)
+ QUIT(quit_ctrl);
+
+ err = chiaki_senkusha_run(&senkusha);
+ chiaki_senkusha_fini(&senkusha);
- /* TODO err = chiaki_senkusha_run(session);
if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(&session->log, "Senkusha failed");
- goto quit_ctrl;
- }*/
+ QUIT(quit_ctrl);
+ }
+
+ CHIAKI_LOGI(&session->log, "Senkusha completed successfully");
+#endif
// TODO: Senkusha should set that
session->mtu = 1454;
session->rtt = 12;
- //CHIAKI_LOGI(&session->log, "Senkusha completed successfully");
-
err = chiaki_random_bytes(session->handshake_key, sizeof(session->handshake_key));
if(err != CHIAKI_ERR_SUCCESS)
{
diff --git a/lib/src/streamconnection.c b/lib/src/streamconnection.c
index 09c8582..de714d7 100644
--- a/lib/src/streamconnection.c
+++ b/lib/src/streamconnection.c
@@ -113,7 +113,7 @@ CHIAKI_EXPORT void chiaki_stream_connection_fini(ChiakiStreamConnection *stream_
}
-bool state_finished_cond_check(void *user)
+static bool state_finished_cond_check(void *user)
{
ChiakiStreamConnection *stream_connection = user;
return stream_connection->state_finished || stream_connection->should_stop;
@@ -150,11 +150,14 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_run(ChiakiStreamConnectio
if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(&session->log, "StreamConnection connect failed");
+ chiaki_mutex_unlock(&stream_connection->state_mutex);
return err;
}
+ // TODO: timeout?
err = chiaki_cond_wait_pred(&stream_connection->state_cond, &stream_connection->state_mutex, state_finished_cond_check, stream_connection);
assert(err == CHIAKI_ERR_SUCCESS || err == CHIAKI_ERR_TIMEOUT);
+ // TODO: check stop
if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(&session->log, "StreamConnection Takion connect failed");
@@ -181,6 +184,8 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_run(ChiakiStreamConnectio
if(err == CHIAKI_ERR_TIMEOUT)
CHIAKI_LOGE(&session->log, "StreamConnection bang receive timeout");
+ // TODO: check canceled and don't report error
+
CHIAKI_LOGE(&session->log, "StreamConnection didn't receive bang or failed to handle it");
err = CHIAKI_ERR_UNKNOWN;
goto disconnect;