static int dlinfoack(int fd, char *bufp, char *ebuf) { return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL)); }
static int dlbindack(int fd, char *bufp, char *ebuf, int *uerror) { return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf, uerror)); }
static int dlokack(int fd, const char *what, char *bufp, char *ebuf) { return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, NULL)); }
/** * void process_dgram(char *dgram, struct sockaddr_in *addr) * * Processes accepted datagram. Checks if sequential ID is correct, if it's lower, * we resend the ACK packet and dont bother with that datagram anymore, because * it was already processed before. */ void process_dgram(char *dgram, struct sockaddr_in *addr) { /* Protocol token */ char *token; /* Token length */ int token_len; /* Command */ char *type; /* Generic char buffer */ char *generic_chbuff; /* Sequential ID of received packet */ int packet_seq_id; /* Client which we receive from */ client_t *client; /* Generic unsigned int var */ unsigned int generic_uint; /* String representation of address */ char addr_str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &addr->sin_addr, addr_str, INET_ADDRSTRLEN); /* Log */ sprintf(log_buffer, "DATA_IN: %s <--- %s:%d", dgram, addr_str, htons(addr->sin_port) ); log_line(log_buffer, LOG_DEBUG); token = strtok(dgram, ";"); token_len = strlen(token); generic_chbuff = strtok(NULL, ";"); packet_seq_id = (int) strtol(generic_chbuff, NULL, 0); /* Check if datagram belongs to us */ if( (token_len == strlen(STRINGIFY(APP_TOKEN))) && strncmp(token, STRINGIFY(APP_TOKEN), strlen(STRINGIFY(APP_TOKEN))) == 0 && packet_seq_id > 0) { type = strtok(NULL, ";"); /* New client connection */ if(strncmp(type, "CONNECT", 7) == 0) { add_client(addr); client = get_client_by_addr(addr); if(client) { send_ack(client, 1, 0); send_reconnect_code(client); /* Release client */ release_client(client); } } /* Reconnect */ else if(strncmp(type, "RECONNECT", 9) == 0) { client = get_client_by_index(get_client_index_by_rcode(strtok(NULL, ";"))); if(client) { /* Sends ACK aswell after resetting clients SEQ_ID */ reconnect_client(client, addr); /* Release client */ release_client(client); } } /* Client should already exist */ else { client = get_client_by_addr(addr); if(client != NULL) { /* Check if expected seq ID matches */ if(packet_seq_id == client->pkt_recv_seq_id) { /* Get command */ if(strncmp(type, "CREATE_GAME", 11) == 0) { /* ACK client */ send_ack(client, packet_seq_id, 0); create_game(client); } /* Receive ACK packet */ else if(strncmp(type, "ACK", 3) == 0) { recv_ack(client, (int) strtoul(strtok(NULL, ";"), NULL, 10)); update_client_timestamp(client); } /* Close client connection */ else if(strncmp(type, "CLOSE", 5) == 0) { /* ACK client */ send_ack(client, packet_seq_id, 0); leave_game(client); remove_client(&client); } /* Keepalive loop */ else if(strncmp(type, "KEEPALIVE", 9) == 0) { /* ACK client */ send_ack(client, packet_seq_id, 0); } /* Join existing game */ else if(strncmp(type, "JOIN_GAME", 9) == 0) { /* ACK client */ send_ack(client, packet_seq_id, 0); join_game(client, strtok(NULL, ";")); } /* Leave existing game */ else if(strncmp(type, "LEAVE_GAME", 10) == 0) { /* ACK client */ send_ack(client, packet_seq_id, 0); leave_game(client); } /* Start game */ else if(strncmp(type, "START_GAME", 10) == 0) { /* ACK client */ send_ack(client, packet_seq_id, 0); start_game(client); } /* Rolling die */ else if(strncmp(type, "DIE_ROLL", 8) == 0) { /* ACK client */ send_ack(client, packet_seq_id, 0); roll_die(client); } /* Moving figure */ else if(strncmp(type, "FIGURE_MOVE", 11) == 0) { /* ACK client */ send_ack(client, packet_seq_id, 0); /* Parse figure id */ generic_chbuff = strtok(NULL, ";"); generic_uint = (unsigned int) strtoul(generic_chbuff, NULL, 10); move_figure(client, generic_uint); } else if(strncmp(type, "MESSAGE", 7) == 0) { /* ACK client */ send_ack(client, packet_seq_id, 0); broadcast_message(client, strtok(NULL, ";")); } } /* Packet was already processed */ else if(packet_seq_id < client->pkt_recv_seq_id && strncmp(type, "ACK", 3) != 0) { send_ack(client, packet_seq_id, 1); } /* If client didnt close conection */ if(client != NULL) { /* Release client */ release_client(client); } } } } }