Commit 6d7457f0 authored by Simon Wüllhorst's avatar Simon Wüllhorst

First 'working' solution

parent 20c187f0
......@@ -145,6 +145,15 @@ int Close(int fd)
return n;
}
int Getsockname(int sockfd, struct sockaddr* addr, socklen_t* addrlen)
{
int n;
if ((n = getsockname(sockfd, addr, addrlen)) < 0) {
perror("getsockname");
exit(-1);
}
return n;
}
int Setsockopt(int sockfd, int level, int optname, const void* optval, socklen_t optlen)
{
int n;
......@@ -159,7 +168,7 @@ int Pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_
{
int n;
if ((n = pthread_create(thread, attr, start_routine, arg)) < 0) {
perror("getsockopt");
perror("pthread_create");
exit(-1);
}
return n;
......
......@@ -59,6 +59,7 @@ int Shutdown(int sockfd, int how);
int Listen(int sockfd, int backlog);
int Accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
int Close(int fd);
int Getsockname(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
int Setsockopt(int sockfd, int level, int optname, const void* optval, socklen_t optlen);
int Pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine)(void*), void* arg);
int Pthread_detach(pthread_t thread);
......
......@@ -26,8 +26,8 @@
#define MSG_HEARTBEAT_ACK 7
#define MSG_UNKNOWN_MSG_TYPE 8
#define LOCAL_START 0
#define REMOTE_START 1
#define LOCAL_START 1
#define REMOTE_START 0
#define LOCAL_PLAYER -1
#define REMOTE_PLAYER 1
......@@ -129,6 +129,7 @@ struct game_peers_info_t {
struct addrinfo* remote;
int start_flag;
int net_fd;
int server_fd;
struct game_state_t state;
struct game_timer_t timer;
struct message_buffer_t message;
......
......@@ -31,7 +31,7 @@ int parse_remote_server(char** argv, game_peers_info* peers_info)
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);
peers_info->credentials.pass = malloc(peers_info->credentials.pass_len);
memcpy(peers_info->credentials.pass, argv[6], peers_info->credentials.pass_len);
return MODE_SERVER;
......@@ -95,6 +95,7 @@ void send_primitive_message(game_peers_info* peers_info, uint16_t type)
struct msg_meta_t a_meta_msg;
a_meta_msg.length = htons(0);
a_meta_msg.type = htons(type);
//printf("Type: %d\n", type);
Send(peers_info->net_fd, &a_meta_msg, sizeof(a_meta_msg), 0);
}
void handle_hb_timer(game_peers_info* peers_info)
......@@ -188,6 +189,64 @@ int handle_msg_ack(game_peers_info* peers_info, msg_move_ack* a_move_ack)
return 0;
}
void finalize_game_server(game_peers_info* peers_info)
{
char buf[BUFFER_SIZE];
stop_timer(peers_info->timer.hb_timer);
delete_timer(peers_info->timer.hb_timer);
peers_info->timer.hb_timeout_ms = TIMEOUT_HB_MIN_MS;
deregister_fd_callback(peers_info->net_fd);
Shutdown(peers_info->net_fd, SHUT_WR);
while (Recv(peers_info->net_fd, (void*)buf, (size_t)BUFFER_SIZE, 0) != 0) {
}
peers_info->state.current_mode = MODE_DIRECT;
//Close(peers_info->net_fd);
peers_info->server_fd = peers_info->net_fd;
peers_info->net_fd = -1;
}
void handle_msg_peer_info(game_peers_info* peers_info, struct msg_meta_t* meta_data)
{
ssize_t name_len;
msg_peer_info* a_peer_info_msg;
char *a_msg, *a_name;
char net_addr[16], net_port[6];
struct addrinfo hints;
struct sockaddr_in ip_addr;
//struct sockaddr_in a_game_peer;
a_msg = (char*)meta_data;
a_peer_info_msg = (msg_peer_info*)meta_data;
//Note leaf net_addr and net_port in network byte order
a_peer_info_msg->start_flag = ntohs(a_peer_info_msg->start_flag);
name_len = a_peer_info_msg->length - (sizeof(msg_peer_info) - sizeof(struct msg_meta_t));
a_name = calloc(1, name_len + 1);
memcpy(a_name, a_msg + sizeof(msg_peer_info), name_len);
printf("Foreign game peer is: %s\n", a_name);
finalize_game_server(peers_info);
freeaddrinfo(peers_info->remote);
memset(&hints, 0, sizeof(hints));
memset(&ip_addr, 0, sizeof(ip_addr));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
ip_addr.sin_addr.s_addr = a_peer_info_msg->net_addr;
ip_addr.sin_family = AF_INET;
ip_addr.sin_port = a_peer_info_msg->net_port;
//printf("port: %d\n", ntohs(a_peer_info_msg->net_port));
Getnameinfo((struct sockaddr*)&ip_addr, sizeof(struct sockaddr_in), net_addr, sizeof(net_addr), net_port, sizeof(net_port), NI_NUMERICHOST);
printf("Net-Addr: %s, Net-Port: %s\n", net_addr, net_port);
Getaddrinfo(net_addr, net_port, &hints, &peers_info->remote);
if (a_peer_info_msg->start_flag == 0) {
peers_info->start_flag = REMOTE_START;
} else {
peers_info->start_flag = LOCAL_START;
}
}
void handle_rec_msg(game_peers_info* peers_info, struct msg_meta_t* meta_data)
{
......@@ -215,6 +274,7 @@ void handle_rec_msg(game_peers_info* peers_info, struct msg_meta_t* meta_data)
return;
case MSG_PEER_INFO:
printf("Got Peer Info\n");
handle_msg_peer_info(peers_info, meta_data);
return;
};
} else {
......@@ -240,6 +300,7 @@ void handle_rec_udp(game_peers_info* peers_info)
//printf("GOT MESSAGE\n");
//printf("net_fd: %d\n", peers_info->net_fd);
n = Recv(peers_info->net_fd, (void*)peers_info->message.buf, BUFFER_SIZE, 0);
if (n <= 0) {
finalize(peers_info, -1, "Connection closed.\nLeaving the game.\n");
......@@ -278,6 +339,12 @@ ssize_t packet_sequenzer(game_peers_info* peers_info, ssize_t n)
return len;
handle_rec_msg(peers_info, a_msg);
if (peers_info->net_fd == -1) {
//tcp session has been finalized
init_4gw(peers_info);
Close(peers_info->server_fd);
return 0;
}
memmove(peers_info->message.buf, peers_info->message.buf + msg_len, len - msg_len);
return packet_sequenzer(peers_info, n - msg_len);
......@@ -364,6 +431,8 @@ void send_reg_msg(game_peers_info* peers_info)
{
char *a_msg, *a_name, *a_pass;
ssize_t s, name_padd, pass_padd;
struct sockaddr_in local_addr;
socklen_t addr_len = sizeof(local_addr);
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;
......@@ -377,8 +446,13 @@ void send_reg_msg(game_peers_info* peers_info)
//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_addr = ((struct sockaddr_in*)peers_info->local->ai_addr)->sin_addr.s_addr;
//Determine own addr by getting informations about current connection
Getsockname(peers_info->net_fd, (struct sockaddr*)&local_addr, &addr_len);
//Note: sockaddr / sockaddr_in is always in network byte order
a_reg_msg->net_addr = local_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);
......@@ -394,7 +468,7 @@ void send_reg_msg(game_peers_info* peers_info)
int init_gs_4gw(game_peers_info* peers_info)
{
peers_info->net_fd = Socket(peers_info->remote->ai_family, peers_info->remote->ai_socktype, peers_info->remote->ai_protocol);
peers_info->net_fd = Socket(peers_info->remote->ai_family, peers_info->remote->ai_socktype, 0);
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);
......
......@@ -98,8 +98,9 @@ void send_peer_info(client_info* a_client, client_info* a_clients_peer, uint16_t
a_peer_info = (msg_peer_info*)a_msg;
a_peer_info->type = htons(MSG_PEER_INFO);
a_peer_info->length = htons(s - name_padding);
a_peer_info->net_addr = htonl(a_clients_peer->net_addr);
a_peer_info->net_port = htons(a_clients_peer->net_port);
// Note: net_addr and net_port are still in network byte order
a_peer_info->net_addr = a_clients_peer->net_addr;
a_peer_info->net_port = a_clients_peer->net_port;
a_peer_info->start_flag = htons(start_flag);
a_name = a_msg + sizeof(msg_peer_info);
......@@ -136,8 +137,6 @@ void handle_peer_reg(client_info* a_client, struct msg_meta_t* a_msg)
//printf("Got a peer_reg message\n");
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;
......@@ -152,18 +151,18 @@ void handle_peer_reg(client_info* a_client, struct msg_meta_t* a_msg)
memcpy(a_client->credentials.name, a_name, a_client->credentials.name_len);
memcpy(a_client->credentials.pass, a_pass, a_client->credentials.pass_len);
//Leafe it in network byte order
a_client->net_addr = a_reg_msg->net_addr;
a_client->net_port = a_reg_msg->net_port;
// 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
//TODO: do further validation
printf("Entered password is valid.\n");
send_primitive_message(a_client, MSG_REG_ACK);
a_client->client_state = CLIENT_STATE_WAIT_FOR_PEER;
find_game_peers(a_client->server_info);
} else {
//TODO: send peer_reg_nack
printf("Entered password is invalid.\n");
send_primitive_message(a_client, MSG_REG_NACK);
}
......@@ -176,6 +175,8 @@ void handle_client_message(client_info* a_client, struct msg_meta_t* a_msg)
handle_peer_reg(a_client, a_msg);
break;
case MSG_PEER_INFO_ACK:
printf("Got MSG_PEER_INFO_ACK\n");
finalize_client(a_client);
break;
case MSG_HEARTBEAT_ACK:
a_client->hb_timeout_ms = TIMEOUT_HB_MIN_MS;
......
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