/* handle received packets for not yet established crypto connections. */ static void receive_crypto(void) { uint32_t i; for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) { uint8_t temp_data[MAX_DATA_SIZE]; uint8_t secret_nonce[crypto_box_NONCEBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t session_key[crypto_box_PUBLICKEYBYTES]; uint16_t len; if (id_packet(crypto_connections[i].number) == 1) /* if the packet is a friend request drop it (because we are already friends) */ len = read_packet(crypto_connections[i].number, temp_data); if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ len = read_packet(crypto_connections[i].number, temp_data); if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); increment_nonce(crypto_connections[i].sent_nonce); uint32_t zero = 0; encrypt_precompute(crypto_connections[i].peersessionpublic_key, crypto_connections[i].sessionsecret_key, crypto_connections[i].shared_key); crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ } } } else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does crypto_kill(crypto_connections[i].number); } if (crypto_connections[i].status == CONN_NOT_CONFIRMED) { if (id_packet(crypto_connections[i].number) == 3) { uint8_t temp_data[MAX_DATA_SIZE]; uint8_t data[MAX_DATA_SIZE]; int length = read_packet(crypto_connections[i].number, temp_data); int len = decrypt_data(crypto_connections[i].peersessionpublic_key, crypto_connections[i].sessionsecret_key, crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); uint32_t zero = 0; if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { increment_nonce(crypto_connections[i].recv_nonce); encrypt_precompute(crypto_connections[i].peersessionpublic_key, crypto_connections[i].sessionsecret_key, crypto_connections[i].shared_key); crypto_connections[i].status = CONN_ESTABLISHED; /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ kill_connection_in(crypto_connections[i].number, 3000000); } else crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does } else if(id_packet(crypto_connections[i].number) != -1) /* This should not happen kill the connection if it does */ crypto_kill(crypto_connections[i].number); } } }
int main(int argc, char *argv[]) { if (argc < 2) { printf("usage: %s filename\n", argv[0]); exit(0); } uint8_t buffer[512]; int read; FILE *file = fopen(argv[1], "wb"); if (file == NULL) return 1; //initialize networking //bind to ip 0.0.0.0:PORT IP ip; ip.i = 0; init_networking(ip, PORT); perror("Initialization"); int connection; uint64_t timer = current_time(); while (1) { Lossless_UDP(); connection = incoming_connection(); if(connection != -1) { if(is_connected(connection) == 2) { printf("Recieved the connection.\n"); } break; } c_sleep(1); } timer = current_time(); while (1) { //printconnection(0); Lossless_UDP(); if (is_connected(connection) >= 2) { kill_connection_in(connection, 3000000); read = read_packet(connection, buffer); if (read != 0) { // printf("Recieved data.\n"); if (!fwrite(buffer, read, 1, file)) printf("file write error\n"); } } if(is_connected(connection) == 4) { printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer)); fclose(file); return 1; } c_sleep(1); } return 0; }
/* Handle received packets for not yet established crypto connections. */ static void receive_crypto(Net_Crypto *c) { uint32_t i; for (i = 0; i < c->crypto_connections_length; ++i) { if (c->crypto_connections[i].status == CONN_HANDSHAKE_SENT) { uint8_t temp_data[MAX_DATA_SIZE]; uint8_t secret_nonce[crypto_box_NONCEBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t session_key[crypto_box_PUBLICKEYBYTES]; uint16_t len; if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 2) { /* Handle handshake packet. */ len = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); if (handle_cryptohandshake(c, public_key, secret_nonce, session_key, temp_data, len)) { if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { memcpy(c->crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); memcpy(c->crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); increment_nonce(c->crypto_connections[i].sent_nonce); uint32_t zero = 0; encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, c->crypto_connections[i].sessionsecret_key, c->crypto_connections[i].shared_key); c->crypto_connections[i].status = CONN_ESTABLISHED; /* Connection status needs to be 3 for write_cryptpacket() to work. */ write_cryptpacket(c, i, ((uint8_t *)&zero), sizeof(zero)); c->crypto_connections[i].status = CONN_NOT_CONFIRMED; /* Set it to its proper value right after. */ } } } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != -1) { // This should not happen, kill the connection if it does. crypto_kill(c, i); return; } } if (c->crypto_connections[i].status == CONN_NOT_CONFIRMED) { if (id_packet(c->lossless_udp, c->crypto_connections[i].number) == 3) { uint8_t temp_data[MAX_DATA_SIZE]; uint8_t data[MAX_DATA_SIZE]; int length = read_packet(c->lossless_udp, c->crypto_connections[i].number, temp_data); int len = decrypt_data(c->crypto_connections[i].peersessionpublic_key, c->crypto_connections[i].sessionsecret_key, c->crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); uint32_t zero = 0; if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { increment_nonce(c->crypto_connections[i].recv_nonce); encrypt_precompute(c->crypto_connections[i].peersessionpublic_key, c->crypto_connections[i].sessionsecret_key, c->crypto_connections[i].shared_key); c->crypto_connections[i].status = CONN_ESTABLISHED; /* Connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ kill_connection_in(c->lossless_udp, c->crypto_connections[i].number, 3000000); } else { /* This should not happen, kill the connection if it does. */ crypto_kill(c, i); return; } } else if (id_packet(c->lossless_udp, c->crypto_connections[i].number) != -1) /* This should not happen, kill the connection if it does. */ crypto_kill(c, i); return; } } }