P2P-File-Sharing / Registry / server.c
server.c
Raw
#include "server.h"

int process_request(char *buf, struct peer_entry **peers, int socket_descriptor) {
    switch(buf[0]) {
        case '\0':  // JOIN
            return parse_join(buf, peers[find_peer(peers, socket_descriptor)]);
        case '\1':  // PUBLISH
            return parse_publish(buf, peers[find_peer(peers, socket_descriptor)]);
        case '\2':  // SEARCH
            return parse_search(buf, peers, socket_descriptor);
        default:    // FALLBACK
            perror("ERROR] Peer sent invalid action id\n");
    }
    return -1;
}

int parse_join(char *buf, struct peer_entry *peer) {
    peer->id = ntohl(*((uint32_t*)(buf + sizeof(char))));
    printf("TEST] JOIN %u\n", peer->id);
    return 0;
}

int parse_publish(char *buf, struct peer_entry *peer) {
    uint32_t count = ntohl(*((uint32_t*)(buf + sizeof(char))));
    printf("TEST] PUBLISH %u", count);
    int current_index = sizeof(char) + sizeof(uint32_t);
    // Decrements Count until all entries are added to array
    // Added in reverse order but who cares
    while (count > 0) {
        int length = strlen(buf + current_index);
        printf(" %s", buf + current_index);
        memcpy(peer->files[count - 1], buf + current_index, length);
        current_index += length + 1;
        count--;
    }
    printf("\n");
    return 0;
}

// Search may fail unless all values in char arrays are set to null because
// of string functions used. Kinda annoying
// Could possibly fix by settings two indices in front of entries written in to null
int parse_search(char *buf, struct peer_entry **peers, int sender_fd) {
    printf("TEST] SEARCH %s", (buf + sizeof(char)));
    int found = 0;
    for (int i = 0; i < MAX_PEERS; i++) {
        if (peers[i] == NULL) continue;
        for (int j = 0; j < MAX_FILES; j++) {
            if (peers[i]->files[j][0] == '\0') break;
            if (strcmp(buf + sizeof(char), peers[i]->files[j]) == 0 && peers[i]->socket_descriptor != sender_fd) {
                // Building Search Reply
                *((uint32_t*)buf) = htonl(peers[i]->id);
                *((uint32_t*)(buf + sizeof(uint32_t))) = peers[i]->address.sin_addr.s_addr;
                *((uint32_t*)(buf + sizeof(uint32_t) + sizeof(uint32_t))) = peers[i]->address.sin_port;
                // Prints {ID IP:PORT}
                printf(" %u %u.%u.%u.%u:%u\n", peers[i]->id,
                       ((char*)&peers[i]->address.sin_addr)[0], ((char*)&peers[i]->address.sin_addr)[1],
                       ((char*)&peers[i]->address.sin_addr)[2], ((char*)&peers[i]->address.sin_addr)[3],
                       ntohs(peers[i]->address.sin_port));
                found = 1;
            }
        }
    }
    if (found == 0) memset(buf, '\0', sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t));
    return (2 * sizeof(uint32_t)) + sizeof(uint16_t);
}

// Searches Peers array for an open entry | Open when Socket_descriptor == -1
int find_peer(struct peer_entry **peers, int file_descriptor) {
    for(int i = 0; i < MAX_PEERS; i++) {
        if (peers[i] == NULL) continue;
        if (peers[i]->socket_descriptor == file_descriptor) return i;
    }
    perror("CATASTROPHIC ERROR] JOIN REQ FROM NON-EXISTENT SOCKET DESCRIPTOR -- YOU WILL PROBABLY SEGFAULT SOON");
    return -1;
}

// Returns the index of the first open peer
int find_open_peer(struct peer_entry **peers) {
    for (int i = 0; i < MAX_PEERS; i++) {
        if (peers[i] == NULL) {
            peers[i] = (struct peer_entry*) malloc(sizeof(struct peer_entry));
            memset(peers[i], '\0', sizeof(struct peer_entry));
            return i;
        }
    }
    return -1;
}