diff --git a/lib/include/chiaki/ctrl.h b/lib/include/chiaki/ctrl.h index a5e6449..29021a1 100644 --- a/lib/include/chiaki/ctrl.h +++ b/lib/include/chiaki/ctrl.h @@ -21,6 +21,8 @@ #include "common.h" #include "thread.h" +#include + #ifdef __cplusplus extern "C" { #endif @@ -30,6 +32,8 @@ typedef struct chiaki_ctrl_t struct chiaki_session_t *session; ChiakiThread thread; int sock; + uint8_t recv_buf[512]; + size_t recv_buf_size; } ChiakiCtrl; CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_start(ChiakiCtrl *ctrl, struct chiaki_session_t *session); diff --git a/lib/src/ctrl.c b/lib/src/ctrl.c index 7a224a4..eb5a0e8 100644 --- a/lib/src/ctrl.c +++ b/lib/src/ctrl.c @@ -44,25 +44,76 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_join(ChiakiCtrl *ctrl) } -static ChiakiErrorCode ctrl_thread_connect(ChiakiCtrl *ctrl); +static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl); +static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *payload, size_t payload_size); static void *ctrl_thread_func(void *user) { ChiakiCtrl *ctrl = user; - ChiakiErrorCode err = ctrl_thread_connect(ctrl); + ChiakiErrorCode err = ctrl_connect(ctrl); if(err != CHIAKI_ERR_SUCCESS) { chiaki_session_set_quit_reason(ctrl->session, CHIAKI_QUIT_REASON_CTRL_UNKNOWN); return NULL; } - // ... + CHIAKI_LOGI(&ctrl->session->log, "Ctrl connected\n"); + + while(true) + { + bool overflow = false; + while(ctrl->recv_buf_size >= 8) + { + uint32_t payload_size = *((uint32_t *)ctrl->recv_buf); + payload_size = ntohl(payload_size); + + if(ctrl->recv_buf_size < 8 + payload_size) + { + if(8 + payload_size > sizeof(ctrl->recv_buf)) + { + CHIAKI_LOGE(&ctrl->session->log, "Ctrl buffer overflow!\n"); + overflow = true; + } + break; + } + + uint16_t msg_type = *((uint16_t *)(ctrl->recv_buf + 4)); + msg_type = ntohs(msg_type); + + ctrl_message_received(ctrl, msg_type, ctrl->recv_buf + 8, (size_t)payload_size); + ctrl->recv_buf_size -= 8 + payload_size; + if(ctrl->recv_buf_size > 0) + memmove(ctrl->recv_buf, ctrl->recv_buf + 8 + payload_size, ctrl->recv_buf_size); + } + + if(overflow) + { + chiaki_session_set_quit_reason(ctrl->session, CHIAKI_QUIT_REASON_CTRL_UNKNOWN); + break; + } + + ssize_t received = recv(ctrl->sock, ctrl->recv_buf + ctrl->recv_buf_size, sizeof(ctrl->recv_buf) - ctrl->recv_buf_size, 0); + if(received <= 0) + { + if(received < 0) + chiaki_session_set_quit_reason(ctrl->session, CHIAKI_QUIT_REASON_CTRL_UNKNOWN); + break; + } + + ctrl->recv_buf_size += received; + } return NULL; } +static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *payload, size_t payload_size) +{ + CHIAKI_LOGI(&ctrl->session->log, "Received Ctrl Message Type %#x\n", msg_type); +} + + typedef struct ctrl_response_t { bool server_type_valid; @@ -93,7 +144,7 @@ static void parse_ctrl_response(CtrlResponse *response, ChiakiHttpResponse *http } } -static ChiakiErrorCode ctrl_thread_connect(ChiakiCtrl *ctrl) +static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl) { ChiakiSession *session = ctrl->session; struct addrinfo *addr = session->connect_info.host_addrinfo_selected; @@ -196,15 +247,13 @@ static ChiakiErrorCode ctrl_thread_connect(ChiakiCtrl *ctrl) size_t header_size; size_t received_size; - err = chiaki_recv_http_header(sock, buf, sizeof(buf)-1, &header_size, &received_size); + err = chiaki_recv_http_header(sock, buf, sizeof(buf), &header_size, &received_size); if(err != CHIAKI_ERR_SUCCESS) { CHIAKI_LOGE(&session->log, "Failed to receive ctrl request response\n"); goto error; } - buf[received_size] = '\0'; - ChiakiHttpResponse http_response; err = chiaki_http_response_parse(&http_response, buf, header_size); if(err != CHIAKI_ERR_SUCCESS) @@ -233,7 +282,12 @@ static ChiakiErrorCode ctrl_thread_connect(ChiakiCtrl *ctrl) CHIAKI_LOGE(&session->log, "No valid Server Type in ctrl response\n"); ctrl->sock = sock; - close(sock); // TODO: remove + + // if we already got more data than the header, put the rest in the buffer. + ctrl->recv_buf_size = received_size - header_size; + if(ctrl->recv_buf_size > 0) + memcpy(ctrl->recv_buf, buf + header_size, ctrl->recv_buf_size); + return CHIAKI_ERR_SUCCESS; error: diff --git a/lib/src/http.c b/lib/src/http.c index 42320bc..bff6093 100644 --- a/lib/src/http.c +++ b/lib/src/http.c @@ -166,7 +166,10 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_recv_http_header(int sock, char *buf, size_ break; } if(nl_state == 4) + { + received--; break; + } } if(nl_state == 4) diff --git a/lib/src/session.c b/lib/src/session.c index 191b116..bd15058 100644 --- a/lib/src/session.c +++ b/lib/src/session.c @@ -117,7 +117,7 @@ static void *session_thread_func(void *arg) chiaki_rpcrypt_init(&session->rpcrypt, session->nonce, session->connect_info.morning); - usleep(10000); + usleep(5000); CHIAKI_LOGI(&session->log, "Starting ctrl\n"); @@ -273,7 +273,7 @@ static bool session_thread_request_session(ChiakiSession *session) size_t header_size; size_t received_size; - ChiakiErrorCode err = chiaki_recv_http_header(session_sock, buf, sizeof(buf)-1, &header_size, &received_size); + ChiakiErrorCode err = chiaki_recv_http_header(session_sock, buf, sizeof(buf), &header_size, &received_size); if(err != CHIAKI_ERR_SUCCESS) { CHIAKI_LOGE(&session->log, "Failed to receive session request response\n"); @@ -282,8 +282,6 @@ static bool session_thread_request_session(ChiakiSession *session) return false; } - buf[received_size] = '\0'; - ChiakiHttpResponse http_response; err = chiaki_http_response_parse(&http_response, buf, header_size); if(err != CHIAKI_ERR_SUCCESS)