Commit fb65eaac authored by Simon Wüllhorst's avatar Simon Wüllhorst

Implemented msg_reg, msg_reg_ack, msg_reg_nack, ...

- On both, server and client.
- ...
parent adc3eb9f
......@@ -66,8 +66,8 @@ struct msg_reg_t {
uint32_t net_addr;
uint16_t net_port;
uint16_t name_len;
char* name;
char* password;
// char* name;
// char* password;
} __attribute__((packed));
typedef struct msg_reg_t msg_reg;
......@@ -96,6 +96,7 @@ struct msg_move_ack_t {
typedef struct msg_move_ack_t msg_move_ack;
struct game_state_t {
uint16_t current_mode;
uint16_t current_state;
uint32_t my_latest_move;
int16_t sec_my;
......@@ -116,6 +117,12 @@ struct message_buffer_t {
ssize_t buf_offset;
char buf[BUFFER_SIZE];
};
struct credentials_t {
char* name;
uint32_t name_len;
char* pass;
uint32_t pass_len;
};
struct game_peers_info_t {
struct addrinfo* local;
......@@ -125,6 +132,7 @@ struct game_peers_info_t {
struct game_state_t state;
struct game_timer_t timer;
struct message_buffer_t message;
struct credentials_t credentials;
};
typedef struct game_peers_info_t game_peers_info;
......@@ -134,6 +142,7 @@ struct client_info_t {
int client_fd;
struct timer* hb_timer;
unsigned int hb_timeout_ms;
struct credentials_t credentials;
struct message_buffer_t message;
};
typedef struct client_info_t client_info;
......@@ -141,6 +150,7 @@ struct game_server_info_t {
struct addrinfo* server;
int server_fd;
struct client_info_t client_queue;
struct credentials_t credentials;
};
typedef struct game_server_info_t game_server_info;
......
......@@ -26,13 +26,21 @@ int parse_remote_server(int argc, char** argv, game_peers_info* peers_info)
hints.ai_socktype = SOCK_STREAM;
Getaddrinfo(argv[3], argv[4], &hints, &peers_info->remote);
/* Note: These "strings" are not zero-terminated anymore, so we handle it as char array rather than strings */
peers_info->credentials.name_len = strlen(argv[5]);
peers_info->credentials.name = malloc(peers_info->credentials.name_len);
memcpy(peers_info->credentials.name, argv[5], peers_info->credentials.name_len);
peers_info->credentials.pass_len = strlen(argv[6]);
peers_info->credentials.pass = malloc(peers_info->credentials.name_len);
memcpy(peers_info->credentials.pass, argv[6], peers_info->credentials.pass_len);
return MODE_SERVER;
}
int parse_args(int argc, char** argv, game_peers_info* peers_info)
{
char fmt_string[] = "Wrong amount of parameters. Propper usage:\n %s LOCAL_PORT {(-c REMOTE_CLIENT_ADDRESS REMOTE_CLIENT_PORT) | (-s REMOTE_SERVER_ADDRESS REMOTE_SERVER_PORT)}\n";
char fmt_string[] = "Wrong amount of parameters. Propper usage:\n %s LOCAL_PORT {(-c REMOTE_CLIENT_ADDRESS REMOTE_CLIENT_PORT) | (-s REMOTE_SERVER_ADDRESS REMOTE_SERVER_PORT USERNAME PASSWORD)}\n";
struct addrinfo hints;
if (argc < 5) {
if (argc < 6) {
printf(fmt_string, argv[0]);
return -1;
}
......@@ -53,7 +61,7 @@ int parse_args(int argc, char** argv, game_peers_info* peers_info)
}
return parse_remote_client(argc, argv, peers_info);
} else if (argv[2][1] == 's') {
if (argc != 5) {
if (argc != 7) {
printf(fmt_string, argv[0]);
return -1;
}
......@@ -205,24 +213,39 @@ void handle_rec_msg(game_peers_info* peers_info, struct msg_meta_t* meta_data)
switch (meta_data->type) {
case MSG_HEARTBEAT:
send_hb_ack(peers_info);
break;
return;
case MSG_HEARTBEAT_ACK:
peers_info->timer.hb_timeout_ms = TIMEOUT_HB_MIN_MS;
break;
case MSG_MOVE:
handle_foreign_move(peers_info, (msg_move*)peers_info->message.buf);
break;
case MSG_MOVE_ACK:
handle_msg_ack(peers_info, (msg_move_ack*)peers_info->message.buf);
break;
return;
case MSG_UNKNOWN_MSG_TYPE:
finalize(peers_info, -1, "Sended unknown message.\n");
break;
default:
printf("Received unknown message, msg_type-ID: %d\n", meta_data->type);
send_unknown_packet(peers_info);
break;
};
return;
}
if (peers_info->state.current_mode == MODE_SERVER) {
switch (meta_data->type) {
case MSG_REG_ACK:
printf("Yaay, got a msg_reg_ack. Now waiting for a foreign player. *_____*\n");
return;
case MSG_REG_NACK:
finalize(peers_info, -1, "Damn it, got a msg_reg_nack, going to die!\n");
return;
case MSG_PEER_INFO:
return;
};
} else {
switch (meta_data->type) {
case MSG_MOVE:
handle_foreign_move(peers_info, (msg_move*)peers_info->message.buf);
return;
case MSG_MOVE_ACK:
handle_msg_ack(peers_info, (msg_move_ack*)peers_info->message.buf);
return;
};
}
// DEFAULT
printf("Received unknown message, msg_type-ID: %d\n", meta_data->type);
send_unknown_packet(peers_info);
}
/* for udp */
......@@ -348,20 +371,47 @@ void handle_stdin(game_peers_info* peers_info)
return;
}
void send_reg_msg(game_peers_info* peers_info)
{
char *a_msg, *a_name, *a_pass;
ssize_t s, name_padd, pass_padd;
msg_reg* a_reg_msg;
name_padd = (4 - peers_info->credentials.name_len % 4) % 4;
pass_padd = (4 - peers_info->credentials.pass_len % 4) % 4;
//printf("pass_len: %d, pass: %.*s\n", peers_info->credentials.pass_len, peers_info->credentials.pass_len, peers_info->credentials.pass);
s = sizeof(msg_reg) + peers_info->credentials.name_len + name_padd + peers_info->credentials.pass_len + pass_padd;
a_msg = calloc(s, sizeof(char));
a_reg_msg = (msg_reg*)a_msg;
a_reg_msg->type = htons(MSG_REG);
a_reg_msg->length = htons(s - (sizeof(struct msg_meta_t) + pass_padd));
//NOTE: Can't use this, because we are binding on a wildcard address.
//TODO: Provide a cli argument for address || determine address on server-side.
a_reg_msg->net_addr = ((struct sockaddr_in*)peers_info->local->ai_addr)->sin_addr.s_addr;
a_reg_msg->net_port = ((struct sockaddr_in*)peers_info->local->ai_addr)->sin_port;
a_reg_msg->name_len = htons(peers_info->credentials.name_len);
a_name = a_msg + sizeof(msg_reg);
a_pass = a_name + peers_info->credentials.name_len + name_padd;
memcpy(a_name, peers_info->credentials.name, peers_info->credentials.name_len);
memcpy(a_pass, peers_info->credentials.pass, peers_info->credentials.pass_len);
Send(peers_info->net_fd, a_msg, s, 0);
free(a_msg);
}
int init_gs_4gw(game_peers_info* peers_info)
{
msg_heartbeat hb;
peers_info->net_fd = Socket(peers_info->remote->ai_family, peers_info->remote->ai_socktype, peers_info->remote->ai_protocol);
Connect(peers_info->net_fd, peers_info->remote->ai_addr, peers_info->remote->ai_addrlen);
register_fd_callback(peers_info->net_fd, (void (*)(void*)) & handle_rec_tcp, peers_info);
peers_info->timer.hb_timer = create_timer((void (*)(void*)) & handle_hb_timer, peers_info, "HB_TIMER");
start_timer(peers_info->timer.hb_timer, 200);
peers_info->timer.hb_timeout_ms = TIMEOUT_HB_MIN_MS;
hb.length = htons(0);
hb.type = htons(MSG_HEARTBEAT);
Send(peers_info->net_fd, (const void*)&hb, sizeof(hb), 0);
send_reg_msg(peers_info);
//Close(peers_info->net_fd);
peers_info->state.current_state = STATE_INIT;
return 0;
......@@ -409,7 +459,8 @@ int main(int argc, char** argv)
game_peers_info peers_info;
init_4clib();
init_cblib();
switch (parse_args(argc, argv, &peers_info)) {
peers_info.state.current_mode = parse_args(argc, argv, &peers_info);
switch (peers_info.state.current_mode) {
case MODE_DIRECT:
init_4gw(&peers_info);
break;
......
......@@ -20,8 +20,8 @@ void client_list_remove(client_info* list, client_info* a_client)
int parse_args(int argc, char** argv, game_server_info* server_info)
{
struct addrinfo hints;
if (argc != 2) {
printf("Wrong amount of parameters. Propper usage:\n ./%s LOCAL_PORT\n", argv[0]);
if (argc != 3) {
printf("Wrong amount of parameters. Propper usage:\n ./%s LOCAL_PORT PASSWORD\n", argv[0]);
return -1;
}
memset(&hints, 0, sizeof(hints));
......@@ -29,7 +29,10 @@ int parse_args(int argc, char** argv, game_server_info* server_info)
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
Getaddrinfo(NULL, argv[1], &hints, &server_info->server);
/* Note: These "strings" are not zero-terminated anymore, so we handle it as char array rather than strings */
server_info->credentials.pass_len = strlen(argv[2]);
server_info->credentials.pass = malloc(server_info->credentials.pass_len);
memcpy(server_info->credentials.pass, argv[2], server_info->credentials.pass_len);
return 0;
}
void finalize_client(client_info* a_client)
......@@ -43,6 +46,8 @@ void finalize_client(client_info* a_client)
}
Close(a_client->client_fd);
client_list_remove(&a_client->server_info->client_queue, a_client);
free(a_client->credentials.name);
free(a_client->credentials.pass);
free(a_client);
return;
}
......@@ -78,7 +83,7 @@ int send_unknown_packet(client_info* a_client)
}
void handle_client_hb_timer(client_info* a_client)
{
printf("handle_client_hb_timer\n");
//printf("handle_client_hb_timer\n");
msg_heartbeat a_hb;
a_hb.length = htons(0);
a_hb.type = htons(MSG_HEARTBEAT);
......@@ -91,9 +96,65 @@ void handle_client_hb_timer(client_info* a_client)
start_timer(a_client->hb_timer, a_client->hb_timeout_ms);
return;
}
void send_reg_ack(client_info* a_client)
{
msg_reg_ack a_reg_ack;
a_reg_ack.length = htons(0);
a_reg_ack.type = htons(MSG_REG_ACK);
Send(a_client->client_fd, &a_reg_ack, sizeof(a_reg_ack), 0);
}
void send_reg_nack(client_info* a_client)
{
msg_reg_ack a_reg_ack;
a_reg_ack.length = htons(0);
a_reg_ack.type = htons(MSG_REG_NACK);
Send(a_client->client_fd, &a_reg_ack, sizeof(a_reg_ack), 0);
}
void handle_peer_reg(client_info* a_client, struct msg_meta_t* a_msg)
{
ssize_t name_padd, pass_len;
char *a_name, *a_pass;
msg_reg* a_reg_msg;
a_reg_msg = (msg_reg*)a_msg;
a_reg_msg->net_addr = ntohl(a_reg_msg->net_addr);
a_reg_msg->net_port = ntohs(a_reg_msg->net_port);
a_reg_msg->name_len = ntohs(a_reg_msg->name_len);
name_padd = (4 - a_reg_msg->name_len % 4) % 4;
a_name = (char*)a_msg + sizeof(msg_reg);
a_pass = a_name + a_reg_msg->name_len + name_padd;
pass_len = a_reg_msg->length - ((sizeof(msg_reg) - sizeof(struct msg_meta_t)) + a_reg_msg->name_len + name_padd);
a_client->credentials.name_len = a_reg_msg->name_len;
a_client->credentials.name = malloc(a_client->credentials.name_len);
a_client->credentials.pass_len = pass_len;
a_client->credentials.pass = malloc(a_client->credentials.pass_len);
memcpy(a_client->credentials.name, a_name, a_client->credentials.name_len);
memcpy(a_client->credentials.pass, a_pass, a_client->credentials.pass_len);
// printf("s_len: %d, c_len: %d\n", a_client->server_info->credentials.pass_len, a_client->credentials.pass_len);
// printf("s: %.*s, p: %.*s\n", a_client->server_info->credentials.pass_len, a_client->server_info->credentials.pass, a_client->credentials.pass_len, a_client->credentials.pass);
if (a_client->server_info->credentials.pass_len == a_client->credentials.pass_len && memcmp(a_client->server_info->credentials.pass, a_client->credentials.pass, a_client->credentials.pass_len) == 0) {
//TODO: send peer_reg_ack, TODO: do further validation
printf("Entered password is valid.\n");
send_reg_ack(a_client);
} else {
//TODO: send peer_reg_nack
printf("Entered password is invalid.\n");
send_reg_nack(a_client);
}
printf("Got a peer_reg message\n");
}
void handle_client_message(client_info* a_client, struct msg_meta_t* a_msg)
{
switch (a_msg->type) {
case MSG_REG:
handle_peer_reg(a_client, a_msg);
break;
case MSG_PEER_INFO_ACK:
break;
case MSG_HEARTBEAT_ACK:
a_client->hb_timeout_ms = TIMEOUT_HB_MIN_MS;
break;
......@@ -135,13 +196,12 @@ ssize_t packet_sequenzer(client_info* a_client, ssize_t n)
void handle_client_rec(client_info* a_client)
{
printf("handle_client_rec\n");
ssize_t n;
if ((n = Recv(a_client->client_fd, (void*)(a_client->message.buf + a_client->message.buf_offset), BUFFER_SIZE - a_client->message.buf_offset, 0)) == 0) {
finalize_client(a_client);
return;
}
printf("Received %zd bytes, buf offset: %zd \n", n, a_client->message.buf_offset);
//printf("Received %zd bytes, buf offset: %zd \n", n, a_client->message.buf_offset);
a_client->message.buf_offset = packet_sequenzer(a_client, n);
}
client_info* initialize_client(game_server_info* server_info, int a_client_fd)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment