static int cmp_one(void *binary, int index) { uint64_t *t,*b = (uint64_t *) binary; copy_hash_back(); t = (uint64_t *)ghash; if (b[3] != t[hash_addr(0, index)]) return 0; return 1; }
static int cmp_one(void *binary, int index) { uint64_t *b = (uint64_t *) binary; uint64_t *t = (uint64_t *) ghash; cuda_xsha512_cpy_hash(ghash); if (b[3] != t[hash_addr(0, index)]) return 0; return 1; }
static int cmp_all(void *binary, int count) { uint32_t i; uint32_t b = ((uint32_t *) binary)[0]; uint32_t *out = outbuffer; for (i = 0; i < count; i++) if (b == out[hash_addr(0, i)]) return 1; return 0; }
static int cmp_one(void *binary, int index) { int i; uint32_t *t = (uint32_t *) binary; uint32_t *out = outbuffer; for (i = 0; i < 8; i++) if (t[i] != out[hash_addr(i, index)]) return 0; return 1; }
hash_item_t *hash_get(hash_t *table, directed_node_t *node) { int addr; hash_item_t *head = NULL; addr = hash_addr(table, node); head = table->buckets[addr]; while(head) { if(head->node == node) return head; head = head->next; } return NULL; }
void hash_insert(hash_t *table, directed_node_t *node, heap_item_t *item) { int addr; hash_item_t *hashitem; hash_item_t *head; //printf("making item\n"); hashitem = make_hash_item(node,item); // find the bucket addr = hash_addr(table, node); //printf("getting addr %d\n",addr); // insert at head //printf("inserting at head\n"); head = table->buckets[addr]; table->buckets[addr] = hashitem; hashitem->next = head; }
static int get_hash_6(int index) { copy_hash_back(); return ((uint64_t*)ghash)[hash_addr(0, index)] & 0x7FFFFFF; }
static int get_hash_6(int index) { uint32_t *out = outbuffer; return out[hash_addr(0, index)] & 0x7ffffff; }
/** calculate infra hash for a key */ static hashvalue_t hash_infra(struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name) { return dname_query_hash(name, hash_addr(addr, addrlen)); }
static int get_hash_6(int index) { cuda_xsha512_cpy_hash(ghash); return ((uint64_t *) ghash)[hash_addr(0, index)] & 0x7FFFFFF; }
int main(int argc, char **argv) { if (argc != 5) { die("give host and server port and address as argument"); } char *host_address = argv[1]; char *host_port = argv[2]; char *server_address = argv[3]; char *server_port = argv[4]; int status = 0; int running = 1; // Connection state int acks_received = 0; int left = -1; // left neighbour socket int right = -1; // right neighbour socket struct tcp_addr left_addr; struct tcp_addr right_addr; sha1_t host_key; sha1_t serv_key; fd_set rfds; fd_set wfds; int cmdsock = fileno(stdin); // TODO Connect this to GUI int servsock = -1; int listensock = create_listen_socket(host_port); // Buffers for sending and receiving byte *sendbuf = malloc(MAX_PACKET_SIZE); byte *recvbuf = malloc(MAX_PACKET_SIZE); memset(sendbuf, 0, MAX_PACKET_SIZE); memset(recvbuf, 0, MAX_PACKET_SIZE); int packetlen = 0; // Structs for connection info struct addrinfo servhints, hosthints, *servinfo, *hostinfo; memset(&servhints, 0, sizeof(struct addrinfo)); memset(&hosthints, 0, sizeof(struct addrinfo)); servhints.ai_family = AF_INET; // AF_UNSPEC, AF_INET or AF_INET6 servhints.ai_socktype = SOCK_STREAM; hosthints.ai_family = AF_INET; hosthints.ai_socktype = SOCK_STREAM; hosthints.ai_flags = AI_PASSIVE; // Connect to server if ((status = getaddrinfo(host_address, host_port, &hosthints, &hostinfo)) != 0) { die(gai_strerror(status)); } if ((status = getaddrinfo(server_address, server_port, &servhints, &servinfo)) != 0) { die(gai_strerror(status)); } servsock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); if (connect(servsock, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { die("connection refused (is server running?)"); } // Handshake with server sleep(1); // Server doesn't accept handshake if sent immediately init_hs(servsock); // Create keys and address structs struct sockaddr_in *sa = (struct sockaddr_in *) hostinfo->ai_addr; char host_ip4[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(sa->sin_addr), host_ip4, INET_ADDRSTRLEN); struct tcp_addr host_addr; strcpy(host_addr.addr, host_ip4); strcpy(host_addr.port, host_port); struct sockaddr_in *sb = (struct sockaddr_in *) servinfo->ai_addr; char serv_ip4[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(sb->sin_addr), serv_ip4, INET_ADDRSTRLEN); struct tcp_addr serv_addr; strcpy(serv_addr.addr, serv_ip4); strcpy(serv_addr.port, server_port); hash_addr(&host_addr, host_key); hash_addr(&serv_addr, serv_key); freeaddrinfo(hostinfo); freeaddrinfo(servinfo); // Send DHT_REGISTER_BEGIN to server uint16_t port = htons(atoi(host_addr.port)); byte *pl = malloc(sizeof(uint16_t) + strlen(host_addr.addr) + 1); memcpy(pl, &port, sizeof(uint16_t)); memcpy(pl+sizeof(uint16_t), host_addr.addr, strlen(host_addr.addr) + 1); packetlen = pack(sendbuf, MAX_PACKET_SIZE, serv_key, host_key, DHT_REGISTER_BEGIN, pl, sizeof(uint16_t) + strlen(host_addr.addr) + 1); sendall(servsock, sendbuf, packetlen, 0); free(pl); // Start main loop (connection sequence isn't actually // finished at this point) while(running) { // Add sockets to listening pool FD_ZERO(&rfds); FD_SET(listensock, &rfds); FD_SET(servsock, &rfds); FD_SET(cmdsock, &rfds); if (left != -1) { FD_SET(left, &rfds); } if (right != -1) { FD_SET(right, &rfds); } // Reset buffers memset(sendbuf, 0, MAX_PACKET_SIZE); memset(recvbuf, 0, MAX_PACKET_SIZE); // Let's hope 10 is high enough for numfds... status = select(10, &rfds, NULL, NULL, NULL); if (status == -1) { die("select failed"); } else if (FD_ISSET(cmdsock, &rfds)) { // Currently program terminates if it receives q from stdin. read(cmdsock, recvbuf, MAX_PACKET_SIZE); if (recvbuf[0] == 'q') { DEBUG("Disconnecting...\n"); packetlen = pack(sendbuf, MAX_PACKET_SIZE, host_key, host_key, DHT_DEREGISTER_BEGIN, NULL, 0); sendall(servsock, sendbuf, packetlen, 0); } } else if (FD_ISSET(left, &rfds) || FD_ISSET(right, &rfds)) { int tempfd = -1; if (FD_ISSET(left, &rfds)) { tempfd = left; left = -1; } else if (FD_ISSET(right, &rfds)) { tempfd = right; right = -1; } packetlen = recvall(tempfd, recvbuf, MAX_PACKET_SIZE, 0); struct packet *packet = unpack(recvbuf, packetlen); switch (packet->type) { case DHT_TRANSFER_DATA: // TODO: Implement data structure and insert data there break; case DHT_REGISTER_ACK: // Received all data from neighbour, send DONE to server if // ACK received from both neighbours acks_received++; close(tempfd); if (acks_received == 2) { packetlen = pack(sendbuf, MAX_PACKET_SIZE, host_key, host_key, DHT_REGISTER_DONE, NULL, 0); sendall(servsock, sendbuf, packetlen, 0); } break; case DHT_DEREGISTER_ACK: // Received all data from leaving neighbour, acknowledge this to server close(tempfd); packetlen = pack(sendbuf, MAX_PACKET_SIZE, packet->sender, host_key, DHT_DEREGISTER_DONE, NULL, 0); sendall(servsock, sendbuf, packetlen, 0); break; default: die("invalid header"); } free(packet->payload); free(packet); } else if (FD_ISSET(servsock, &rfds)) { packetlen = recvall(servsock, recvbuf, MAX_PACKET_SIZE, 0); struct packet *packet = unpack(recvbuf, packetlen); switch (packet->type) { case DHT_REGISTER_FAKE_ACK: // First node in network packetlen = pack(sendbuf, MAX_PACKET_SIZE, host_key, host_key, DHT_REGISTER_DONE, NULL, 0); sendall(servsock, sendbuf, packetlen, 0); break; case DHT_REGISTER_BEGIN: // New node is trying to join, connect and send data ; // Complier throws error without this semicolon int tempfd; struct tcp_addr nb_addr; struct addrinfo nb_hints, *nb_info; build_tcp_addr(packet->payload, &nb_addr, NULL); memset(&nb_hints, 0, sizeof(struct addrinfo)); nb_hints.ai_family = AF_INET; nb_hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(nb_addr.addr, nb_addr.port, &nb_hints, &nb_info)) != 0) { die(gai_strerror(status)); } if ((tempfd = socket(nb_info->ai_family, nb_info->ai_socktype, nb_info->ai_protocol)) == -1) { die("Socket creation failed\n"); } if ((status = connect(tempfd, nb_info->ai_addr, nb_info->ai_addrlen)) == -1) { die("Connecting failed\n"); close(tempfd); } // Handshake with new node sha1_t nb_key; hash_addr(&nb_addr, nb_key); init_hs(tempfd); // TODO Send data // Send ACK to new node to inform that all data is sent packetlen = pack(sendbuf, MAX_PACKET_SIZE, nb_key, nb_key, DHT_REGISTER_ACK, NULL, 0); sendall(tempfd, sendbuf, packetlen, 0); close(tempfd); freeaddrinfo(nb_info); break; case DHT_REGISTER_DONE: // TODO Forget data sent to new neighbour break; case DHT_DEREGISTER_BEGIN: // A node leaves abnormally packetlen = pack(sendbuf, MAX_PACKET_SIZE, packet->sender, host_key, DHT_DEREGISTER_DONE, NULL, 0); sendall(servsock, sendbuf, packetlen, 0); break; case DHT_DEREGISTER_ACK: // Server has responded to our attempt to leave, create connections to both neighbours build_tcp_addr(packet->payload, &left_addr, &right_addr); // Connect to left neighbour struct addrinfo left_hints, *left_info; memset(&left_hints, 0, sizeof(struct addrinfo)); left_hints.ai_family = AF_INET; left_hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(left_addr.addr, left_addr.port, &left_hints, &left_info)) != 0) { die(gai_strerror(status)); } if ((left = socket(left_info->ai_family, left_info->ai_socktype, left_info->ai_protocol)) == -1) { die(strerror(errno)); } if ((status = connect(left, left_info->ai_addr, left_info->ai_addrlen)) == -1) { die(strerror(errno)); } // Handshake with left init_hs(left); // Connect to right neighbour struct addrinfo right_hints, *right_info; memset(&right_hints, 0, sizeof(struct addrinfo)); right_hints.ai_family = AF_INET; right_hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(right_addr.addr, right_addr.port, &right_hints, &right_info)) != 0) { die(gai_strerror(status)); } if ((right = socket(right_info->ai_family, right_info->ai_socktype, right_info->ai_protocol)) == -1) { die(strerror(errno)); } if ((status = connect(right, right_info->ai_addr, right_info->ai_addrlen)) == -1) { die(strerror(errno)); } // Handshake with right init_hs(right); // Cleanup freeaddrinfo(left_info); freeaddrinfo(right_info); running = 0; break; case DHT_DEREGISTER_DENY: // Disconnection attempt denied fprintf(stderr, "Disconnecting denied\n"); break; default: // Invalid packet type, dump packet if debugging and die DEBUG("PACKET DUMP\n"); for (int i = 0; i < packetlen; ++i) { DEBUG("%x ", recvbuf[i]); } DEBUG("\n"); die("invalid packet type"); } free(packet->payload); free(packet); } else if (FD_ISSET(listensock, &rfds)) { // Another node tries to connect struct sockaddr_in tempaddr; int tempfd; unsigned int addrlen = 0; if ((tempfd = accept(listensock, (struct sockaddr *)&tempaddr, &addrlen)) == -1) { die(strerror(errno)); } else if (left == -1) { left = tempfd; } else if (left != -1 && right == -1) { right = tempfd; } else { die("error accepting new connection"); } wait_hs(tempfd); } } // Server accepted our leaving attempt and connections // to both neighbours have been established. Send data to // neighbours and wait confirmation from server. int disconnecting = 1; int deregs_received = 0; while (disconnecting) { FD_ZERO(&rfds); FD_ZERO(&wfds); FD_SET(servsock, &rfds); if (left != -1) { FD_SET(left, &wfds); } if (right != -1) { FD_SET(right, &wfds); } memset(sendbuf, 0, MAX_PACKET_SIZE); memset(recvbuf, 0, MAX_PACKET_SIZE); status = select(10, &rfds, &wfds, NULL, NULL); if (status == -1) { die("select failed"); } else if (FD_ISSET(servsock, &rfds)) { packetlen = recvall(servsock, recvbuf, MAX_PACKET_SIZE, 0); struct packet *packet = unpack(recvbuf, packetlen); switch (packet->type) { case DHT_DEREGISTER_DONE: // Simply leave after receiving confirmations from // both neighbours deregs_received++; if (deregs_received == 2) { disconnecting = 0; } free(packet->payload); free(packet); break; default: die("invalid packet type"); } } else if (FD_ISSET(left, &wfds) || FD_ISSET(right, &wfds)) { if (FD_ISSET(left, &wfds)) { // Send data to left neighbour sha1_t left_key; hash_addr(&left_addr, left_key); packetlen = pack(sendbuf, MAX_PACKET_SIZE, left_key, host_key, DHT_DEREGISTER_ACK, NULL, 0); sendall(left, sendbuf, packetlen, 0); close(left); left = -1; } else if (FD_ISSET(right, &wfds)) { // Send data to right neighbour sha1_t right_key; hash_addr(&right_addr, right_key); packetlen = pack(sendbuf, MAX_PACKET_SIZE, right_key, host_key, DHT_DEREGISTER_ACK, NULL, 0); sendall(right, sendbuf, packetlen, 0); close(right); right = -1; } } } // Cleanup close(listensock); close(servsock); free(sendbuf); free(recvbuf); return 0; }