Passed everything through astyle.

This commit is contained in:
irungentoo 2013-08-16 13:11:09 -04:00
parent c5af8f44a9
commit 88ff81d9de
46 changed files with 3107 additions and 2471 deletions

View File

@ -10,8 +10,8 @@
void rand_bytes(uint8_t *b, size_t blen) void rand_bytes(uint8_t *b, size_t blen)
{ {
size_t i; size_t i;
for (i = 0; i < blen; i++)
{ for (i = 0; i < blen; i++) {
b[i] = rand(); b[i] = rand();
} }
} }
@ -19,65 +19,65 @@ void rand_bytes(uint8_t *b, size_t blen)
// These test vectors are from libsodium's test suite // These test vectors are from libsodium's test suite
unsigned char alicesk[32] = { unsigned char alicesk[32] = {
0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d, 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d,
0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45, 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45,
0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a,
0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a
}; };
unsigned char bobpk[32] = { unsigned char bobpk[32] = {
0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4, 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4,
0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37, 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37,
0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d,
0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f
}; };
unsigned char nonce[24] = { unsigned char nonce[24] = {
0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73, 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73,
0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6, 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6,
0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37
}; };
unsigned char test_m[131] = { unsigned char test_m[131] = {
0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5, 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5,
0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b, 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b,
0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4, 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4,
0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc, 0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc,
0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a, 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a,
0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29, 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29,
0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4, 0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4,
0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31, 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31,
0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d, 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d,
0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57, 0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57,
0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a, 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a,
0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde, 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde,
0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd, 0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd,
0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52, 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52,
0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40, 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40,
0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64, 0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64,
0x5e,0x07,0x05 0x5e, 0x07, 0x05
}; };
unsigned char test_c[147] = { unsigned char test_c[147] = {
0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5, 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9, 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9,
0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73, 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce, 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4, 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a, 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b, 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72, 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2, 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38, 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a, 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae, 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea, 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda, 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde, 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3, 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6, 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74, 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
0xe3,0x55,0xa5 0xe3, 0x55, 0xa5
}; };
START_TEST(test_known) START_TEST(test_known)
@ -86,19 +86,20 @@ START_TEST(test_known)
unsigned char m[131]; unsigned char m[131];
int clen, mlen; int clen, mlen;
ck_assert_msg(sizeof(c) == sizeof(m) + ENCRYPTION_PADDING * sizeof(unsigned char), "cyphertext should be ENCRYPTION_PADDING bytes longer than plaintext"); ck_assert_msg(sizeof(c) == sizeof(m) + ENCRYPTION_PADDING * sizeof(unsigned char),
"cyphertext should be ENCRYPTION_PADDING bytes longer than plaintext");
ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
clen = encrypt_data(bobpk, alicesk, nonce, test_m, sizeof(test_m)/sizeof(unsigned char), c); clen = encrypt_data(bobpk, alicesk, nonce, test_m, sizeof(test_m) / sizeof(unsigned char), c);
ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector");
ck_assert_msg(clen == sizeof(c)/sizeof(unsigned char), "wrong ciphertext length"); ck_assert_msg(clen == sizeof(c) / sizeof(unsigned char), "wrong ciphertext length");
mlen = decrypt_data(bobpk, alicesk, nonce, test_c, sizeof(test_c)/sizeof(unsigned char), m); mlen = decrypt_data(bobpk, alicesk, nonce, test_c, sizeof(test_c) / sizeof(unsigned char), m);
ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector");
ck_assert_msg(mlen == sizeof(m)/sizeof(unsigned char), "wrong plaintext length"); ck_assert_msg(mlen == sizeof(m) / sizeof(unsigned char), "wrong plaintext length");
} }
END_TEST END_TEST
@ -111,20 +112,21 @@ START_TEST(test_fast_known)
encrypt_precompute(bobpk, alicesk, k); encrypt_precompute(bobpk, alicesk, k);
ck_assert_msg(sizeof(c) == sizeof(m) + ENCRYPTION_PADDING * sizeof(unsigned char), "cyphertext should be ENCRYPTION_PADDING bytes longer than plaintext"); ck_assert_msg(sizeof(c) == sizeof(m) + ENCRYPTION_PADDING * sizeof(unsigned char),
"cyphertext should be ENCRYPTION_PADDING bytes longer than plaintext");
ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
clen = encrypt_data_fast(k, nonce, test_m, sizeof(test_m)/sizeof(unsigned char), c); clen = encrypt_data_fast(k, nonce, test_m, sizeof(test_m) / sizeof(unsigned char), c);
ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector");
ck_assert_msg(clen == sizeof(c)/sizeof(unsigned char), "wrong ciphertext length"); ck_assert_msg(clen == sizeof(c) / sizeof(unsigned char), "wrong ciphertext length");
mlen = decrypt_data_fast(k, nonce, test_c, sizeof(test_c)/sizeof(unsigned char), m); mlen = decrypt_data_fast(k, nonce, test_c, sizeof(test_c) / sizeof(unsigned char), m);
ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector");
ck_assert_msg(mlen == sizeof(m)/sizeof(unsigned char), "wrong plaintext length"); ck_assert_msg(mlen == sizeof(m) / sizeof(unsigned char), "wrong plaintext length");
} }
END_TEST END_TEST
@ -156,23 +158,22 @@ START_TEST(test_endtoend)
int testno; int testno;
// Test 100 random messages and keypairs // Test 100 random messages and keypairs
for (testno = 0; testno < 100; testno++) for (testno = 0; testno < 100; testno++) {
{
//Generate random message (random length from 100 to 500) //Generate random message (random length from 100 to 500)
mlen = (rand() % 400) + 100; mlen = (rand() % 400) + 100;
rand_bytes(m, mlen); rand_bytes(m, mlen);
rand_bytes(n, crypto_box_NONCEBYTES); rand_bytes(n, crypto_box_NONCEBYTES);
//Generate keypairs //Generate keypairs
crypto_box_keypair(pk1,sk1); crypto_box_keypair(pk1, sk1);
crypto_box_keypair(pk2,sk2); crypto_box_keypair(pk2, sk2);
//Precompute shared keys //Precompute shared keys
encrypt_precompute(pk2, sk1, k1); encrypt_precompute(pk2, sk1, k1);
encrypt_precompute(pk1, sk2, k2); encrypt_precompute(pk1, sk2, k2);
ck_assert_msg(memcmp(k1, k2, crypto_box_BEFORENMBYTES) == 0, "encrypt_precompute: bad"); ck_assert_msg(memcmp(k1, k2, crypto_box_BEFORENMBYTES) == 0, "encrypt_precompute: bad");
//Encrypt all four ways //Encrypt all four ways
c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); c1len = encrypt_data(pk2, sk1, n, m, mlen, c1);
c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); c2len = encrypt_data(pk1, sk2, n, m, mlen, c2);
@ -181,7 +182,8 @@ START_TEST(test_endtoend)
ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ");
ck_assert_msg(c1len == mlen + ENCRYPTION_PADDING, "wrong cyphertext length"); ck_assert_msg(c1len == mlen + ENCRYPTION_PADDING, "wrong cyphertext length");
ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0
&& memcmp(c1, c4, c1len) == 0, "crypertexts differ");
//Decrypt all four ways //Decrypt all four ways
m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1);
@ -191,7 +193,8 @@ START_TEST(test_endtoend)
ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ");
ck_assert_msg(m1len == mlen, "wrong decrypted text length"); ck_assert_msg(m1len == mlen, "wrong decrypted text length");
ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0 && memcmp(m1, m4, mlen) == 0, "decrypted texts differ"); ck_assert_msg(memcmp(m1, m2, mlen) == 0 && memcmp(m1, m3, mlen) == 0
&& memcmp(m1, m4, mlen) == 0, "decrypted texts differ");
ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text"); ck_assert_msg(memcmp(m1, m, mlen) == 0, "wrong decrypted text");
} }
} }
@ -217,18 +220,18 @@ START_TEST(test_large_data)
rand_bytes(m1, sizeof(m1)); rand_bytes(m1, sizeof(m1));
rand_bytes(m2, sizeof(m2)); rand_bytes(m2, sizeof(m2));
rand_bytes(n, crypto_box_NONCEBYTES); rand_bytes(n, crypto_box_NONCEBYTES);
//Generate key //Generate key
rand_bytes(k, crypto_box_BEFORENMBYTES); rand_bytes(k, crypto_box_BEFORENMBYTES);
c1len = encrypt_data_fast(k, n, m1, sizeof(m1), c1); c1len = encrypt_data_fast(k, n, m1, sizeof(m1), c1);
c2len = encrypt_data_fast(k, n, m2, sizeof(m2), c2); c2len = encrypt_data_fast(k, n, m2, sizeof(m2), c2);
ck_assert_msg(c1len == sizeof(m1) + ENCRYPTION_PADDING, "Could not encrypt max size"); ck_assert_msg(c1len == sizeof(m1) + ENCRYPTION_PADDING, "Could not encrypt max size");
ck_assert_msg(c2len == -1, "incorrectly succeeded encrypting massive size"); ck_assert_msg(c2len == -1, "incorrectly succeeded encrypting massive size");
m1plen = decrypt_data_fast(k, n, c1, c1len, m1prime); m1plen = decrypt_data_fast(k, n, c1, c1len, m1prime);
ck_assert_msg(m1plen == sizeof(m1), "decrypted text lengths differ"); ck_assert_msg(m1plen == sizeof(m1), "decrypted text lengths differ");
ck_assert_msg(memcmp(m1prime, m1, sizeof(m1)) == 0, "decrypted texts differ"); ck_assert_msg(memcmp(m1prime, m1, sizeof(m1)) == 0, "decrypted texts differ");
} }
@ -239,7 +242,7 @@ END_TEST
tcase_add_test(NAME, test_##NAME); \ tcase_add_test(NAME, test_##NAME); \
suite_add_tcase(s, NAME); suite_add_tcase(s, NAME);
Suite* crypto_suite(void) Suite *crypto_suite(void)
{ {
Suite *s = suite_create("Crypto"); Suite *s = suite_create("Crypto");
@ -251,7 +254,7 @@ Suite* crypto_suite(void)
return s; return s;
} }
int main(int argc, char* argv[]) int main(int argc, char *argv[])
{ {
srand((unsigned int) time(NULL)); srand((unsigned int) time(NULL));

47
auto_tests/friends_test.c Executable file → Normal file
View File

@ -56,22 +56,22 @@ void do_tox(void)
{ {
static int dht_on = 0; static int dht_on = 0;
if(!dht_on && DHT_isconnected()) { if (!dht_on && DHT_isconnected()) {
dht_on = 1; dht_on = 1;
} else if(dht_on && !DHT_isconnected()) { } else if (dht_on && !DHT_isconnected()) {
dht_on = 0; dht_on = 0;
} }
doMessenger(m); doMessenger(m);
} }
void parent_confirm_message(Messenger *m, int num, uint8_t *data, uint16_t length, void* userdata) void parent_confirm_message(Messenger *m, int num, uint8_t *data, uint16_t length, void *userdata)
{ {
puts("OK"); puts("OK");
request_flags |= SECOND_FLAG; request_flags |= SECOND_FLAG;
} }
void parent_confirm_status(Messenger *m, int num, uint8_t *data, uint16_t length, void* userdata) void parent_confirm_status(Messenger *m, int num, uint8_t *data, uint16_t length, void *userdata)
{ {
puts("OK"); puts("OK");
request_flags |= FIRST_FLAG; request_flags |= FIRST_FLAG;
@ -89,16 +89,18 @@ int parent_friend_request(void)
m_addfriend(m, child_id, (uint8_t *)message, len); m_addfriend(m, child_id, (uint8_t *)message, len);
/* wait on the status change */ /* wait on the status change */
for(i = 0; i < WAIT_COUNT; i++) { for (i = 0; i < WAIT_COUNT; i++) {
do_tox(); do_tox();
if(request_flags & FIRST_FLAG)
if (request_flags & FIRST_FLAG)
break; break;
fputs(".", stdout); fputs(".", stdout);
fflush(stdout); fflush(stdout);
c_sleep(WAIT_TIME); c_sleep(WAIT_TIME);
} }
if(!(request_flags & FIRST_FLAG)) { if (!(request_flags & FIRST_FLAG)) {
fputs("\nfriends_test: The child took to long to respond!\n" fputs("\nfriends_test: The child took to long to respond!\n"
"Friend requests may be broken, failing build!\n", stderr); "Friend requests may be broken, failing build!\n", stderr);
kill(child_pid, SIGKILL); kill(child_pid, SIGKILL);
@ -108,7 +110,7 @@ int parent_friend_request(void)
return 0; return 0;
} }
void child_got_request(uint8_t *public_key, uint8_t *data, uint16_t length, void* userdata) void child_got_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
{ {
fputs("OK\nsending status to parent", stdout); fputs("OK\nsending status to parent", stdout);
fflush(stdout); fflush(stdout);
@ -116,7 +118,7 @@ void child_got_request(uint8_t *public_key, uint8_t *data, uint16_t length, void
request_flags |= FIRST_FLAG; request_flags |= FIRST_FLAG;
} }
void child_got_statuschange(Messenger *m, int friend_num, uint8_t *string, uint16_t length, void* userdata) void child_got_statuschange(Messenger *m, int friend_num, uint8_t *string, uint16_t length, void *userdata)
{ {
request_flags |= SECOND_FLAG; request_flags |= SECOND_FLAG;
} }
@ -128,16 +130,18 @@ int parent_wait_for_message(void)
fputs("Parent waiting for message.", stdout); fputs("Parent waiting for message.", stdout);
fflush(stdout); fflush(stdout);
for(i = 0; i < WAIT_COUNT; i++) { for (i = 0; i < WAIT_COUNT; i++) {
do_tox(); do_tox();
if(request_flags & SECOND_FLAG)
if (request_flags & SECOND_FLAG)
break; break;
fputs(".", stdout); fputs(".", stdout);
fflush(stdout); fflush(stdout);
c_sleep(WAIT_TIME); c_sleep(WAIT_TIME);
} }
if(!(request_flags & SECOND_FLAG)) { if (!(request_flags & SECOND_FLAG)) {
fputs("\nParent hasn't received the message yet!\n" fputs("\nParent hasn't received the message yet!\n"
"Messaging may be broken, failing the build!\n", stderr); "Messaging may be broken, failing the build!\n", stderr);
kill(child_pid, SIGKILL); kill(child_pid, SIGKILL);
@ -160,12 +164,13 @@ int main(int argc, char *argv[])
/* set up the global memory */ /* set up the global memory */
parent_id = mmap(NULL, crypto_box_PUBLICKEYBYTES, PROT_READ | PROT_WRITE, parent_id = mmap(NULL, crypto_box_PUBLICKEYBYTES, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0); MAP_SHARED | MAP_ANONYMOUS, -1, 0);
child_id = mmap(NULL, crypto_box_PUBLICKEYBYTES, PROT_READ | PROT_WRITE, child_id = mmap(NULL, crypto_box_PUBLICKEYBYTES, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0); MAP_SHARED | MAP_ANONYMOUS, -1, 0);
fputs("friends_test: Starting test...\n", stdout); fputs("friends_test: Starting test...\n", stdout);
if((child_pid = fork()) == 0) {
if ((child_pid = fork()) == 0) {
/* child */ /* child */
int i = 0; int i = 0;
char *message = "Y-yes Mr. Watson?"; char *message = "Y-yes Mr. Watson?";
@ -179,14 +184,14 @@ int main(int argc, char *argv[])
m_callback_statusmessage(m, child_got_statuschange, NULL); m_callback_statusmessage(m, child_got_statuschange, NULL);
/* wait on the friend request */ /* wait on the friend request */
while(!(request_flags & FIRST_FLAG)) while (!(request_flags & FIRST_FLAG))
do_tox(); do_tox();
/* wait for the status change */ /* wait for the status change */
while(!(request_flags & SECOND_FLAG)) while (!(request_flags & SECOND_FLAG))
do_tox(); do_tox();
for(i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
/* send the message six times, just to be sure */ /* send the message six times, just to be sure */
m_sendmessage(m, 0, (uint8_t *)message, strlen(message)); m_sendmessage(m, 0, (uint8_t *)message, strlen(message));
do_tox(); do_tox();
@ -198,7 +203,7 @@ int main(int argc, char *argv[])
} }
/* parent */ /* parent */
if(atexit(cleanup) != 0) { if (atexit(cleanup) != 0) {
fputs("friends_test: atexit() failed!\nFailing build...\n", stderr); fputs("friends_test: atexit() failed!\nFailing build...\n", stderr);
kill(child_pid, SIGKILL); kill(child_pid, SIGKILL);
return -1; return -1;
@ -215,10 +220,10 @@ int main(int argc, char *argv[])
Messenger_save(m, parent_id); Messenger_save(m, parent_id);
if(parent_friend_request() == -1) if (parent_friend_request() == -1)
return -1; return -1;
if(parent_wait_for_message() == -1) if (parent_wait_for_message() == -1)
return -1; return -1;
wait(NULL); wait(NULL);

View File

@ -36,14 +36,16 @@ int friend_id_num = 0;
Messenger *m; Messenger *m;
unsigned char * hex_string_to_bin(char hex_string[]) unsigned char *hex_string_to_bin(char hex_string[])
{ {
size_t len = strlen(hex_string); size_t len = strlen(hex_string);
unsigned char *val = calloc(1, len); unsigned char *val = calloc(1, len);
char *pos = hex_string; char *pos = hex_string;
int i = 0; int i = 0;
for(i = 0; i < len; ++i, pos+=2)
sscanf(pos,"%2hhx",&val[i]); for (i = 0; i < len; ++i, pos += 2)
sscanf(pos, "%2hhx", &val[i]);
return val; return val;
} }
@ -65,17 +67,17 @@ START_TEST(test_m_get_userstatus_size)
{ {
int rc = 0; int rc = 0;
ck_assert_msg((m_get_statusmessage_size(m, -1) == -1), ck_assert_msg((m_get_statusmessage_size(m, -1) == -1),
"m_get_statusmessage_size did NOT catch an argument of -1"); "m_get_statusmessage_size did NOT catch an argument of -1");
ck_assert_msg((m_get_statusmessage_size(m, REALLY_BIG_NUMBER) == -1), ck_assert_msg((m_get_statusmessage_size(m, REALLY_BIG_NUMBER) == -1),
"m_get_statusmessage_size did NOT catch the following argument: %d\n", "m_get_statusmessage_size did NOT catch the following argument: %d\n",
REALLY_BIG_NUMBER); REALLY_BIG_NUMBER);
rc = m_get_statusmessage_size(m, friend_id_num); rc = m_get_statusmessage_size(m, friend_id_num);
/* this WILL error if the original m_addfriend_norequest() failed */ /* this WILL error if the original m_addfriend_norequest() failed */
ck_assert_msg((rc > 0 && rc <= MAX_STATUSMESSAGE_LENGTH), ck_assert_msg((rc > 0 && rc <= MAX_STATUSMESSAGE_LENGTH),
"m_get_statusmessage_size is returning out of range values!\n" "m_get_statusmessage_size is returning out of range values!\n"
"(this can be caused by the error of m_addfriend_norequest" "(this can be caused by the error of m_addfriend_norequest"
" in the beginning of the suite)\n"); " in the beginning of the suite)\n");
} }
END_TEST END_TEST
@ -85,11 +87,11 @@ START_TEST(test_m_set_userstatus)
uint16_t good_length = strlen(status); uint16_t good_length = strlen(status);
uint16_t bad_length = REALLY_BIG_NUMBER; uint16_t bad_length = REALLY_BIG_NUMBER;
if(m_set_statusmessage(m, (uint8_t *)status, bad_length) != -1) if (m_set_statusmessage(m, (uint8_t *)status, bad_length) != -1)
ck_abort_msg("m_set_userstatus did NOT catch the following length: %d\n", ck_abort_msg("m_set_userstatus did NOT catch the following length: %d\n",
REALLY_BIG_NUMBER); REALLY_BIG_NUMBER);
if((m_set_statusmessage(m, (uint8_t *)status, good_length)) != 0) if ((m_set_statusmessage(m, (uint8_t *)status, good_length)) != 0)
ck_abort_msg("m_set_userstatus did NOT return 0 on the following length: %d\n" ck_abort_msg("m_set_userstatus did NOT return 0 on the following length: %d\n"
"MAX_STATUSMESSAGE_LENGTH: %d\n", good_length, MAX_STATUSMESSAGE_LENGTH); "MAX_STATUSMESSAGE_LENGTH: %d\n", good_length, MAX_STATUSMESSAGE_LENGTH);
} }
@ -98,20 +100,20 @@ END_TEST
START_TEST(test_m_friendstatus) START_TEST(test_m_friendstatus)
{ {
ck_assert_msg((m_friendstatus(m, -1) == NOFRIEND), ck_assert_msg((m_friendstatus(m, -1) == NOFRIEND),
"m_friendstatus did NOT catch an argument of -1.\n"); "m_friendstatus did NOT catch an argument of -1.\n");
ck_assert_msg((m_friendstatus(m, REALLY_BIG_NUMBER) == NOFRIEND), ck_assert_msg((m_friendstatus(m, REALLY_BIG_NUMBER) == NOFRIEND),
"m_friendstatus did NOT catch an argument of %d.\n", "m_friendstatus did NOT catch an argument of %d.\n",
REALLY_BIG_NUMBER); REALLY_BIG_NUMBER);
} }
END_TEST END_TEST
START_TEST(test_m_delfriend) START_TEST(test_m_delfriend)
{ {
ck_assert_msg((m_delfriend(m, -1) == -1), ck_assert_msg((m_delfriend(m, -1) == -1),
"m_delfriend did NOT catch an argument of -1\n"); "m_delfriend did NOT catch an argument of -1\n");
ck_assert_msg((m_delfriend(m, REALLY_BIG_NUMBER) == -1), ck_assert_msg((m_delfriend(m, REALLY_BIG_NUMBER) == -1),
"m_delfriend did NOT catch the following number: %d\n", "m_delfriend did NOT catch the following number: %d\n",
REALLY_BIG_NUMBER); REALLY_BIG_NUMBER);
} }
END_TEST END_TEST
/* /*
@ -124,12 +126,12 @@ START_TEST(test_m_addfriend)
int bad_len = strlen(bad_data); int bad_len = strlen(bad_data);
int really_bad_len = (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES int really_bad_len = (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
- crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
+ crypto_box_ZEROBYTES + 100); */ + crypto_box_ZEROBYTES + 100); */
/* TODO: Update this properly to latest master /* TODO: Update this properly to latest master
if(m_addfriend(m, (uint8_t *)friend_id, (uint8_t *)good_data, really_bad_len) != FAERR_TOOLONG) if(m_addfriend(m, (uint8_t *)friend_id, (uint8_t *)good_data, really_bad_len) != FAERR_TOOLONG)
ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", really_bad_len); ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", really_bad_len);
*/ */
/* this will error if the original m_addfriend_norequest() failed */ /* this will error if the original m_addfriend_norequest() failed */
/* if(m_addfriend(m, (uint8_t *)friend_id, (uint8_t *)good_data, good_len) != FAERR_ALREADYSENT) /* if(m_addfriend(m, (uint8_t *)friend_id, (uint8_t *)good_data, good_len) != FAERR_ALREADYSENT)
ck_abort_msg("m_addfriend did NOT catch adding a friend we already have.\n" ck_abort_msg("m_addfriend did NOT catch adding a friend we already have.\n"
"(this can be caused by the error of m_addfriend_norequest in" "(this can be caused by the error of m_addfriend_norequest in"
@ -138,13 +140,13 @@ START_TEST(test_m_addfriend)
if(m_addfriend(m, (uint8_t *)good_id_b, (uint8_t *)bad_data, bad_len) != FAERR_NOMESSAGE) if(m_addfriend(m, (uint8_t *)good_id_b, (uint8_t *)bad_data, bad_len) != FAERR_NOMESSAGE)
ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", bad_len); ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", bad_len);
*/ */
/* this should REALLY error */ /* this should REALLY error */
/* /*
* TODO: validate client_id in m_addfriend? * TODO: validate client_id in m_addfriend?
if(m_addfriend((uint8_t *)bad_id, (uint8_t *)good_data, good_len) >= 0) if(m_addfriend((uint8_t *)bad_id, (uint8_t *)good_data, good_len) >= 0)
ck_abort_msg("The following ID passed through " ck_abort_msg("The following ID passed through "
"m_addfriend without an error:\n'%s'\n", bad_id_str); "m_addfriend without an error:\n'%s'\n", bad_id_str);
} }
END_TEST */ END_TEST */
@ -154,10 +156,11 @@ START_TEST(test_setname)
int good_length = strlen(good_name); int good_length = strlen(good_name);
int bad_length = REALLY_BIG_NUMBER; int bad_length = REALLY_BIG_NUMBER;
if(setname(m, (uint8_t *)good_name, bad_length) != -1) if (setname(m, (uint8_t *)good_name, bad_length) != -1)
ck_abort_msg("setname() did NOT error on %d as a length argument!\n", ck_abort_msg("setname() did NOT error on %d as a length argument!\n",
bad_length); bad_length);
if(setname(m, (uint8_t *)good_name, good_length) != 0)
if (setname(m, (uint8_t *)good_name, good_length) != 0)
ck_abort_msg("setname() did NOT return 0 on good arguments!\n"); ck_abort_msg("setname() did NOT return 0 on good arguments!\n");
} }
END_TEST END_TEST
@ -172,8 +175,8 @@ START_TEST(test_getself_name)
getself_name(m, (uint8_t *)nick_check, len); getself_name(m, (uint8_t *)nick_check, len);
ck_assert_msg((!STRINGS_EQUAL(nickname, nick_check)), ck_assert_msg((!STRINGS_EQUAL(nickname, nick_check)),
"getself_name failed to return the known name!\n" "getself_name failed to return the known name!\n"
"known name: %s\nreturned: %s\n", nickname, nick_check); "known name: %s\nreturned: %s\n", nickname, nick_check);
} }
END_TEST END_TEST
@ -261,12 +264,12 @@ int main(int argc, char *argv[])
m = initMessenger(); m = initMessenger();
/* setup a default friend and friendnum */ /* setup a default friend and friendnum */
if(m_addfriend_norequest(m, (uint8_t *)friend_id) < 0) if (m_addfriend_norequest(m, (uint8_t *)friend_id) < 0)
fputs("m_addfriend_norequest() failed on a valid ID!\n" fputs("m_addfriend_norequest() failed on a valid ID!\n"
"this was CRITICAL to the test, and the build WILL fail.\n" "this was CRITICAL to the test, and the build WILL fail.\n"
"the tests will continue now...\n\n", stderr); "the tests will continue now...\n\n", stderr);
if((friend_id_num = getfriend_id(m, (uint8_t *)friend_id)) < 0) if ((friend_id_num = getfriend_id(m, (uint8_t *)friend_id)) < 0)
fputs("getfriend_id() failed on a valid ID!\n" fputs("getfriend_id() failed on a valid ID!\n"
"this was CRITICAL to the test, and the build WILL fail.\n" "this was CRITICAL to the test, and the build WILL fail.\n"
"the tests will continue now...\n\n", stderr); "the tests will continue now...\n\n", stderr);

File diff suppressed because it is too large Load Diff

View File

@ -39,13 +39,13 @@ typedef struct {
IP_Port ip_port; IP_Port ip_port;
uint64_t timestamp; uint64_t timestamp;
uint64_t last_pinged; uint64_t last_pinged;
/* Returned by this node. Either our friend or us */ /* Returned by this node. Either our friend or us */
IP_Port ret_ip_port; IP_Port ret_ip_port;
uint64_t ret_timestamp; uint64_t ret_timestamp;
} Client_data; } Client_data;
Client_data * DHT_get_close_list(void); Client_data *DHT_get_close_list(void);
/* Add a new friend to the friends list /* Add a new friend to the friends list
client_id must be CLIENT_ID_SIZE bytes long. client_id must be CLIENT_ID_SIZE bytes long.
@ -80,7 +80,7 @@ void DHT_bootstrap(IP_Port ip_port, uint8_t *public_key);
and are then removed from the list. and are then removed from the list.
if the list is full the nodes farthest from our client_id are replaced if the list is full the nodes farthest from our client_id are replaced
the purpose of this list is to enable quick integration of new nodes into the the purpose of this list is to enable quick integration of new nodes into the
network while preventing amplification attacks. network while preventing amplification attacks.
return 0 if node was added return 0 if node was added
return -1 if node was not added */ return -1 if node was not added */
int add_toping(uint8_t *client_id, IP_Port ip_port); int add_toping(uint8_t *client_id, IP_Port ip_port);
@ -123,7 +123,7 @@ int DHT_load(uint8_t *data, uint32_t size);
returns 1 if we are */ returns 1 if we are */
int DHT_isconnected(); int DHT_isconnected();
void addto_lists(IP_Port ip_port, uint8_t * client_id); void addto_lists(IP_Port ip_port, uint8_t *client_id);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -41,7 +41,7 @@ static uint32_t get_broadcast(void)
int i = 0; int i = 0;
/* configure ifconf for the ioctl call */ /* configure ifconf for the ioctl call */
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("[!] get_broadcast: socket() error"); perror("[!] get_broadcast: socket() error");
return 0; return 0;
} }
@ -51,15 +51,16 @@ static uint32_t get_broadcast(void)
ifconf.ifc_buf = (char *)i_faces; ifconf.ifc_buf = (char *)i_faces;
ifconf.ifc_len = sizeof(i_faces); ifconf.ifc_len = sizeof(i_faces);
count = ifconf.ifc_len / sizeof(struct ifreq); count = ifconf.ifc_len / sizeof(struct ifreq);
if(ioctl(sock, SIOCGIFCONF, &ifconf) < 0) {
if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0) {
perror("get_broadcast: ioctl() error"); perror("get_broadcast: ioctl() error");
return 0; return 0;
} }
for(i = 0; i < count; i++) { for (i = 0; i < count; i++) {
/* skip the loopback interface, as it's useless */ /* skip the loopback interface, as it's useless */
if(strcmp(i_faces[i].ifr_name, "lo") != 0) { if (strcmp(i_faces[i].ifr_name, "lo") != 0) {
if(ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) { if (ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) {
perror("[!] get_broadcast: ioctl error"); perror("[!] get_broadcast: ioctl error");
return 0; return 0;
} }
@ -69,8 +70,10 @@ static uint32_t get_broadcast(void)
break; break;
} }
} }
close(sock); close(sock);
if(sock_holder == NULL) {
if (sock_holder == NULL) {
perror("[!] no broadcast device found"); perror("[!] no broadcast device found");
return 0; return 0;
} }
@ -83,14 +86,16 @@ static uint32_t get_broadcast(void)
static IP broadcast_ip(void) static IP broadcast_ip(void)
{ {
IP ip; IP ip;
#ifdef __linux #ifdef __linux
ip.i = get_broadcast(); ip.i = get_broadcast();
if(ip.i == 0)
if (ip.i == 0)
/* error errored, but try anyway? */ /* error errored, but try anyway? */
ip.i = ~0; ip.i = ~0;
#else
#else
ip.i = ~0; ip.i = ~0;
#endif #endif
return ip; return ip;
} }
@ -100,14 +105,19 @@ static int LAN_ip(IP ip)
{ {
if (ip.c[0] == 127)/* Loopback */ if (ip.c[0] == 127)/* Loopback */
return 0; return 0;
if (ip.c[0] == 10)/* 10.0.0.0 to 10.255.255.255 range */ if (ip.c[0] == 10)/* 10.0.0.0 to 10.255.255.255 range */
return 0; return 0;
if (ip.c[0] == 172 && ip.c[1] >= 16 && ip.c[1] <= 31)/* 172.16.0.0 to 172.31.255.255 range */ if (ip.c[0] == 172 && ip.c[1] >= 16 && ip.c[1] <= 31)/* 172.16.0.0 to 172.31.255.255 range */
return 0; return 0;
if (ip.c[0] == 192 && ip.c[1] == 168) /* 192.168.0.0 to 192.168.255.255 range */ if (ip.c[0] == 192 && ip.c[1] == 168) /* 192.168.0.0 to 192.168.255.255 range */
return 0; return 0;
if (ip.c[0] == 169 && ip.c[1] == 254 && ip.c[2] != 0 && ip.c[2] != 255)/* 169.254.1.0 to 169.254.254.255 range */ if (ip.c[0] == 169 && ip.c[1] == 254 && ip.c[2] != 0 && ip.c[2] != 255)/* 169.254.1.0 to 169.254.254.255 range */
return 0; return 0;
return -1; return -1;
} }
@ -115,8 +125,10 @@ static int handle_LANdiscovery(IP_Port source, uint8_t *packet, uint32_t length)
{ {
if (LAN_ip(source.ip) == -1) if (LAN_ip(source.ip) == -1)
return 1; return 1;
if (length != crypto_box_PUBLICKEYBYTES + 1) if (length != crypto_box_PUBLICKEYBYTES + 1)
return 1; return 1;
DHT_bootstrap(source, packet + 1); DHT_bootstrap(source, packet + 1);
return 0; return 0;
} }

View File

@ -21,7 +21,7 @@
* *
*/ */
/* /*
* TODO: clean this file a bit. * TODO: clean this file a bit.
* There are a couple of useless variables to get rid of. * There are a couple of useless variables to get rid of.
*/ */
@ -59,9 +59,9 @@ typedef struct {
*/ */
uint8_t status; uint8_t status;
/* /*
* 1 or 2 if connection was initiated by someone else, 0 if not. * 1 or 2 if connection was initiated by someone else, 0 if not.
* 2 if incoming_connection() has not returned it yet, 1 if it has. * 2 if incoming_connection() has not returned it yet, 1 if it has.
*/ */
uint8_t inbound; uint8_t inbound;
@ -81,31 +81,31 @@ typedef struct {
uint32_t handshake_id2; uint32_t handshake_id2;
/* number of data packets received (also used as handshake_id1) */ /* number of data packets received (also used as handshake_id1) */
uint32_t recv_packetnum; uint32_t recv_packetnum;
/* number of packets received by the other peer */ /* number of packets received by the other peer */
uint32_t orecv_packetnum; uint32_t orecv_packetnum;
/* number of data packets sent */ /* number of data packets sent */
uint32_t sent_packetnum; uint32_t sent_packetnum;
/* number of packets sent by the other peer. */ /* number of packets sent by the other peer. */
uint32_t osent_packetnum; uint32_t osent_packetnum;
/* number of latest packet written onto the sendbuffer */ /* number of latest packet written onto the sendbuffer */
uint32_t sendbuff_packetnum; uint32_t sendbuff_packetnum;
/* we know all packets before that number were successfully sent */ /* we know all packets before that number were successfully sent */
uint32_t successful_sent; uint32_t successful_sent;
/* packet number of last packet read with the read_packet function */ /* packet number of last packet read with the read_packet function */
uint32_t successful_read; uint32_t successful_read;
/* list of currently requested packet numbers(by the other person) */ /* list of currently requested packet numbers(by the other person) */
uint32_t req_packets[BUFFER_PACKET_NUM]; uint32_t req_packets[BUFFER_PACKET_NUM];
/* total number of currently requested packets(by the other person) */ /* total number of currently requested packets(by the other person) */
uint16_t num_req_paquets; uint16_t num_req_paquets;
uint8_t recv_counter; uint8_t recv_counter;
uint8_t send_counter; uint8_t send_counter;
@ -113,7 +113,7 @@ typedef struct {
} Connection; } Connection;
static Connection * connections; static Connection *connections;
static uint32_t connections_length; /* Length of connections array */ static uint32_t connections_length; /* Length of connections array */
static uint32_t connections_number; /* Number of connections in connections array */ static uint32_t connections_number; /* Number of connections in connections array */
@ -122,7 +122,7 @@ static uint32_t connections_number; /* Number of connections in connections arra
/* Functions */ /* Functions */
/* /*
* Get connection id from IP_Port * Get connection id from IP_Port
* Return -1 if there are no connections like we are looking for * Return -1 if there are no connections like we are looking for
* Return id if it found it * Return id if it found it
@ -130,10 +130,11 @@ static uint32_t connections_number; /* Number of connections in connections arra
int getconnection_id(IP_Port ip_port) int getconnection_id(IP_Port ip_port)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].ip_port.ip.i == ip_port.ip.i && if (connections[i].ip_port.ip.i == ip_port.ip.i &&
connections[i].ip_port.port == ip_port.port && connections[i].ip_port.port == ip_port.port &&
connections[i].status > 0) connections[i].status > 0)
return i; return i;
} }
@ -143,7 +144,7 @@ int getconnection_id(IP_Port ip_port)
/* table of random numbers used below. */ /* table of random numbers used below. */
static uint32_t randtable[6][256]; static uint32_t randtable[6][256];
/* /*
* Generate a handshake_id which depends on the ip_port. * Generate a handshake_id which depends on the ip_port.
* This function will always give one unique handshake_id per ip_port. * This function will always give one unique handshake_id per ip_port.
* *
@ -152,18 +153,21 @@ static uint32_t randtable[6][256];
static uint32_t handshake_id(IP_Port source) static uint32_t handshake_id(IP_Port source)
{ {
uint32_t id = 0, i; uint32_t id = 0, i;
for (i = 0; i < 6; ++i) { for (i = 0; i < 6; ++i) {
if(randtable[i][((uint8_t *)&source)[i]] == 0) if (randtable[i][((uint8_t *)&source)[i]] == 0)
randtable[i][((uint8_t *)&source)[i]] = random_int(); randtable[i][((uint8_t *)&source)[i]] = random_int();
id ^= randtable[i][((uint8_t *)&source)[i]]; id ^= randtable[i][((uint8_t *)&source)[i]];
} }
if (id == 0) /* id can't be zero */ if (id == 0) /* id can't be zero */
id = 1; id = 1;
return id; return id;
} }
/* /*
* Change the hanshake id associated with that ip_port * Change the hanshake id associated with that ip_port
* *
* TODO: make this better * TODO: make this better
@ -174,7 +178,7 @@ static void change_handshake(IP_Port source)
randtable[rand][((uint8_t *)&source)[rand]] = random_int(); randtable[rand][((uint8_t *)&source)[rand]] = random_int();
} }
/* /*
* Initialize a new connection to ip_port * Initialize a new connection to ip_port
* Returns an integer corresponding to the connection idt * Returns an integer corresponding to the connection idt
* Return -1 if it could not initialize the connectiont * Return -1 if it could not initialize the connectiont
@ -183,53 +187,56 @@ static void change_handshake(IP_Port source)
int new_connection(IP_Port ip_port) int new_connection(IP_Port ip_port)
{ {
int connect = getconnection_id(ip_port); int connect = getconnection_id(ip_port);
if (connect != -1) if (connect != -1)
return connect; return connect;
if(connections_number == connections_length) { if (connections_number == connections_length) {
Connection * temp; Connection *temp;
temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
if(temp == NULL) if (temp == NULL)
return -1; return -1;
memset(&temp[connections_length], 0, sizeof(Connection)); memset(&temp[connections_length], 0, sizeof(Connection));
++connections_length; ++connections_length;
connections = temp; connections = temp;
} }
uint32_t i; uint32_t i;
for (i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if(connections[i].status == 0) { if (connections[i].status == 0) {
memset(&connections[i], 0, sizeof(Connection)); memset(&connections[i], 0, sizeof(Connection));
uint32_t handshake_id1 = handshake_id(ip_port); uint32_t handshake_id1 = handshake_id(ip_port);
connections[i] = (Connection) { connections[i] = (Connection) {
.ip_port = ip_port, .ip_port = ip_port,
.status = 1, .status = 1,
.inbound = 0, .inbound = 0,
.handshake_id1 = handshake_id1, .handshake_id1 = handshake_id1,
.sent_packetnum = handshake_id1, .sent_packetnum = handshake_id1,
.sendbuff_packetnum = handshake_id1, .sendbuff_packetnum = handshake_id1,
.successful_sent = handshake_id1, .successful_sent = handshake_id1,
.SYNC_rate = SYNC_RATE, .SYNC_rate = SYNC_RATE,
.data_rate = DATA_SYNC_RATE, .data_rate = DATA_SYNC_RATE,
.last_recvSYNC = current_time(), .last_recvSYNC = current_time(),
.last_sent = current_time(), .last_sent = current_time(),
.killat = ~0, .killat = ~0,
.send_counter = 0, .send_counter = 0,
/* add randomness to timeout to prevent connections getting stuck in a loop. */ /* add randomness to timeout to prevent connections getting stuck in a loop. */
.timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
}; };
++connections_number; ++connections_number;
return i; return i;
} }
} }
return -1; return -1;
} }
/* /*
* Initialize a new inbound connection from ip_port * Initialize a new inbound connection from ip_port
* Returns an integer corresponding to the connection id. * Returns an integer corresponding to the connection id.
* Return -1 if it could not initialize the connection. * Return -1 if it could not initialize the connection.
@ -238,55 +245,58 @@ static int new_inconnection(IP_Port ip_port)
{ {
if (getconnection_id(ip_port) != -1) if (getconnection_id(ip_port) != -1)
return -1; return -1;
if(connections_number == connections_length) { if (connections_number == connections_length) {
Connection * temp; Connection *temp;
temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
if(temp == NULL) if (temp == NULL)
return -1; return -1;
memset(&temp[connections_length], 0, sizeof(Connection)); memset(&temp[connections_length], 0, sizeof(Connection));
++connections_length; ++connections_length;
connections = temp; connections = temp;
} }
uint32_t i; uint32_t i;
for (i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].status == 0) { if (connections[i].status == 0) {
memset(&connections[i], 0, sizeof(Connection)); memset(&connections[i], 0, sizeof(Connection));
uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT;
connections[i] = (Connection){ connections[i] = (Connection) {
.ip_port = ip_port, .ip_port = ip_port,
.status = 2, .status = 2,
.inbound = 2, .inbound = 2,
.SYNC_rate = SYNC_RATE, .SYNC_rate = SYNC_RATE,
.data_rate = DATA_SYNC_RATE, .data_rate = DATA_SYNC_RATE,
.last_recvSYNC = current_time(), .last_recvSYNC = current_time(),
.last_sent = current_time(), .last_sent = current_time(),
.send_counter = 127, .send_counter = 127,
/* add randomness to timeout to prevent connections getting stuck in a loop. */ /* add randomness to timeout to prevent connections getting stuck in a loop. */
.timeout = timeout, .timeout = timeout,
/* if this connection isn't handled within the timeout kill it. */ /* if this connection isn't handled within the timeout kill it. */
.killat = current_time() + 1000000UL*timeout .killat = current_time() + 1000000UL * timeout
}; };
++connections_number; ++connections_number;
return i; return i;
} }
} }
return -1; return -1;
} }
/* /*
* Returns an integer corresponding to the next connection in our incoming connection list. * Returns an integer corresponding to the next connection in our incoming connection list.
* Return -1 if there are no new incoming connections in the list. * Return -1 if there are no new incoming connections in the list.
*/ */
int incoming_connection(void) int incoming_connection(void)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].inbound == 2) { if (connections[i].inbound == 2) {
connections[i].inbound = 1; connections[i].inbound = 1;
@ -301,23 +311,25 @@ int incoming_connection(void)
static void free_connections(void) static void free_connections(void)
{ {
uint32_t i; uint32_t i;
for(i = connections_length; i != 0; --i)
for (i = connections_length; i != 0; --i)
if (connections[i - 1].status != 0) if (connections[i - 1].status != 0)
break; break;
if(connections_length == i) if (connections_length == i)
return; return;
Connection * temp; Connection *temp;
temp = realloc(connections, sizeof(Connection) * i); temp = realloc(connections, sizeof(Connection) * i);
if(temp == NULL && i != 0)
if (temp == NULL && i != 0)
return; return;
connections = temp; connections = temp;
connections_length = i; connections_length = i;
} }
/* /*
* Return -1 if it could not kill the connection. * Return -1 if it could not kill the connection.
* Return 0 if killed successfully * Return 0 if killed successfully
*/ */
@ -332,10 +344,11 @@ int kill_connection(int connection_id)
return 0; return 0;
} }
} }
return -1; return -1;
} }
/* /*
* Kill connection in seconds. * Kill connection in seconds.
* Return -1 if it can not kill the connection. * Return -1 if it can not kill the connection.
* Return 0 if it will kill it. * Return 0 if it will kill it.
@ -344,14 +357,15 @@ int kill_connection_in(int connection_id, uint32_t seconds)
{ {
if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) {
if (connections[connection_id].status > 0) { if (connections[connection_id].status > 0) {
connections[connection_id].killat = current_time() + 1000000UL*seconds; connections[connection_id].killat = current_time() + 1000000UL * seconds;
return 0; return 0;
} }
} }
return -1; return -1;
} }
/* /*
* Check if connection is connected: * Check if connection is connected:
* Return 0 no. * Return 0 no.
* Return 1 if attempting handshake. * Return 1 if attempting handshake.
@ -363,6 +377,7 @@ int is_connected(int connection_id)
{ {
if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
return connections[connection_id].status; return connections[connection_id].status;
return 0; return 0;
} }
@ -371,6 +386,7 @@ IP_Port connection_ip(int connection_id)
{ {
if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
return connections[connection_id].ip_port; return connections[connection_id].ip_port;
IP_Port zero = {{{0}}, 0}; IP_Port zero = {{{0}}, 0};
return zero; return zero;
} }
@ -380,6 +396,7 @@ uint32_t sendqueue(int connection_id)
{ {
if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
return 0; return 0;
return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent; return connections[connection_id].sendbuff_packetnum - connections[connection_id].successful_sent;
} }
@ -388,6 +405,7 @@ uint32_t recvqueue(int connection_id)
{ {
if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
return 0; return 0;
return connections[connection_id].recv_packetnum - connections[connection_id].successful_read; return connections[connection_id].recv_packetnum - connections[connection_id].successful_read;
} }
@ -406,7 +424,7 @@ char id_packet(int connection_id)
/* return 0 if there is no received data in the buffer. /* return 0 if there is no received data in the buffer.
return length of received packet if successful */ return length of received packet if successful */
int read_packet(int connection_id, uint8_t * data) int read_packet(int connection_id, uint8_t *data)
{ {
if (recvqueue(connection_id) != 0) { if (recvqueue(connection_id) != 0) {
uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM;
@ -416,14 +434,15 @@ int read_packet(int connection_id, uint8_t * data)
connections[connection_id].recvbuffer[index].size = 0; connections[connection_id].recvbuffer[index].size = 0;
return size; return size;
} }
return 0; return 0;
} }
/* /*
* Return 0 if data could not be put in packet queue * Return 0 if data could not be put in packet queue
* Return 1 if data was put into the queue * Return 1 if data was put into the queue
*/ */
int write_packet(int connection_id, uint8_t * data, uint32_t length) int write_packet(int connection_id, uint8_t *data, uint32_t length)
{ {
if (length > MAX_DATA_SIZE || length == 0) if (length > MAX_DATA_SIZE || length == 0)
return 0; return 0;
@ -440,31 +459,31 @@ int write_packet(int connection_id, uint8_t * data, uint32_t length)
} }
/* put the packet numbers the we are missing in requested and return the number */ /* put the packet numbers the we are missing in requested and return the number */
uint32_t missing_packets(int connection_id, uint32_t * requested) uint32_t missing_packets(int connection_id, uint32_t *requested)
{ {
uint32_t number = 0; uint32_t number = 0;
uint32_t i; uint32_t i;
uint32_t temp; uint32_t temp;
/* don't request packets if the buffer is full. */ /* don't request packets if the buffer is full. */
if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1))
return 0; return 0;
for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) {
if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) {
temp = htonl(i); temp = htonl(i);
memcpy(requested + number, &temp, 4); memcpy(requested + number, &temp, 4);
++number; ++number;
} }
} }
if(number == 0) if (number == 0)
connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum;
return number; return number;
} }
/* /*
* BEGIN Packet sending functions * BEGIN Packet sending functions
* One per packet type. * One per packet type.
* see http://wiki.tox.im/index.php/Lossless_UDP for more information. * see http://wiki.tox.im/index.php/Lossless_UDP for more information.
@ -486,7 +505,7 @@ static int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t hand
static int send_SYNC(uint32_t connection_id) static int send_SYNC(uint32_t connection_id)
{ {
uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)];
uint16_t index = 0; uint16_t index = 0;
IP_Port ip_port = connections[connection_id].ip_port; IP_Port ip_port = connections[connection_id].ip_port;
@ -507,7 +526,7 @@ static int send_SYNC(uint32_t connection_id)
index += 4; index += 4;
memcpy(packet + index, requested, 4 * number); memcpy(packet + index, requested, 4 * number);
return sendpacket(ip_port, packet, (number*4 + 4 + 4 + 2)); return sendpacket(ip_port, packet, (number * 4 + 4 + 4 + 2));
} }
@ -530,6 +549,7 @@ static int send_DATA(uint32_t connection_id)
{ {
int ret; int ret;
uint32_t buffer[BUFFER_PACKET_NUM]; uint32_t buffer[BUFFER_PACKET_NUM];
if (connections[connection_id].num_req_paquets > 0) { if (connections[connection_id].num_req_paquets > 0) {
ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]);
connections[connection_id].num_req_paquets--; connections[connection_id].num_req_paquets--;
@ -537,15 +557,17 @@ static int send_DATA(uint32_t connection_id)
memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4); memcpy(connections[connection_id].req_packets, buffer, connections[connection_id].num_req_paquets * 4);
return ret; return ret;
} }
if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) { if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) {
ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum); ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum);
connections[connection_id].sent_packetnum++; connections[connection_id].sent_packetnum++;
return ret; return ret;
} }
return 0; return 0;
} }
/* /*
* END of packet sending functions * END of packet sending functions
* *
* *
@ -555,7 +577,7 @@ static int send_DATA(uint32_t connection_id)
/* Return 0 if handled correctly, 1 if packet is bad. */ /* Return 0 if handled correctly, 1 if packet is bad. */
static int handle_handshake(IP_Port source, uint8_t * packet, uint32_t length) static int handle_handshake(IP_Port source, uint8_t *packet, uint32_t length)
{ {
if (length != (1 + 4 + 4)) if (length != (1 + 4 + 4))
return 1; return 1;
@ -573,11 +595,12 @@ static int handle_handshake(IP_Port source, uint8_t * packet, uint32_t length)
send_handshake(source, handshake_id(source), handshake_id1); send_handshake(source, handshake_id(source), handshake_id1);
return 0; return 0;
} }
if (is_connected(connection) != 1) if (is_connected(connection) != 1)
return 1; return 1;
/* if handshake_id2 is what we sent previously as handshake_id1 */ /* if handshake_id2 is what we sent previously as handshake_id1 */
if (handshake_id2 == connections[connection].handshake_id1) { if (handshake_id2 == connections[connection].handshake_id1) {
connections[connection].status = 2; connections[connection].status = 2;
/* NOTE: is this necessary? /* NOTE: is this necessary?
connections[connection].handshake_id2 = handshake_id1; */ connections[connection].handshake_id2 = handshake_id1; */
@ -595,9 +618,11 @@ static int SYNC_valid(uint32_t length)
{ {
if (length < 4 + 4 + 2) if (length < 4 + 4 + 2)
return 0; return 0;
if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) ||
((length - 4 - 4 - 2) % 4) != 0) if (length > (BUFFER_PACKET_NUM * 4 + 4 + 4 + 2) ||
((length - 4 - 4 - 2) % 4) != 0)
return 0; return 0;
return 1; return 1;
} }
@ -606,6 +631,7 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p
{ {
if (handshake_id(source) == recv_packetnum) { if (handshake_id(source) == recv_packetnum) {
int x = new_inconnection(source); int x = new_inconnection(source);
if (x != -1) { if (x != -1) {
connections[x].orecv_packetnum = recv_packetnum; connections[x].orecv_packetnum = recv_packetnum;
connections[x].sent_packetnum = recv_packetnum; connections[x].sent_packetnum = recv_packetnum;
@ -618,6 +644,7 @@ static int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_p
return x; return x;
} }
} }
return -1; return -1;
} }
@ -632,11 +659,13 @@ static int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packet
send_SYNC(connection_id); send_SYNC(connection_id);
return 0; return 0;
} }
return 1; return 1;
} }
/* case 3 in handle_SYNC: */ /* case 3 in handle_SYNC: */
static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum,
uint16_t number) uint32_t *req_packets,
uint16_t number)
{ {
uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); uint8_t comp_counter = (counter - connections[connection_id].recv_counter );
uint32_t i, temp; uint32_t i, temp;
@ -646,9 +675,9 @@ static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packet
uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum);
/* packet valid */ /* packet valid */
if (comp_1 <= BUFFER_PACKET_NUM && if (comp_1 <= BUFFER_PACKET_NUM &&
comp_2 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM &&
comp_counter < 10 && comp_counter != 0) { comp_counter < 10 && comp_counter != 0) {
connections[connection_id].orecv_packetnum = recv_packetnum; connections[connection_id].orecv_packetnum = recv_packetnum;
connections[connection_id].osent_packetnum = sent_packetnum; connections[connection_id].osent_packetnum = sent_packetnum;
@ -666,6 +695,7 @@ static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packet
connections[connection_id].num_req_paquets = number; connections[connection_id].num_req_paquets = number;
return 0; return 0;
} }
return 1; return 1;
} }
@ -680,12 +710,12 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
uint32_t temp; uint32_t temp;
uint32_t recv_packetnum, sent_packetnum; uint32_t recv_packetnum, sent_packetnum;
uint32_t req_packets[BUFFER_PACKET_NUM]; uint32_t req_packets[BUFFER_PACKET_NUM];
uint16_t number = (length - 4 - 4 - 2)/ 4; uint16_t number = (length - 4 - 4 - 2) / 4;
memcpy(&counter, packet + 1, 1); memcpy(&counter, packet + 1, 1);
memcpy(&temp, packet + 2, 4); memcpy(&temp, packet + 2, 4);
recv_packetnum = ntohl(temp); recv_packetnum = ntohl(temp);
memcpy(&temp,packet + 6, 4); memcpy(&temp, packet + 6, 4);
sent_packetnum = ntohl(temp); sent_packetnum = ntohl(temp);
if (number != 0) if (number != 0)
@ -695,17 +725,18 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
return handle_SYNC1(source, recv_packetnum, sent_packetnum); return handle_SYNC1(source, recv_packetnum, sent_packetnum);
if (connections[connection].status == 2) if (connections[connection].status == 2)
return handle_SYNC2(connection, counter, return handle_SYNC2(connection, counter,
recv_packetnum, sent_packetnum); recv_packetnum, sent_packetnum);
if (connections[connection].status == 3) if (connections[connection].status == 3)
return handle_SYNC3(connection, counter, recv_packetnum, return handle_SYNC3(connection, counter, recv_packetnum,
sent_packetnum, req_packets, number); sent_packetnum, req_packets, number);
return 0; return 0;
} }
/* /*
* Add a packet to the received buffer and set the recv_packetnum of the * Add a packet to the received buffer and set the recv_packetnum of the
* connection to its proper value. Return 1 if data was too big, 0 if not. * connection to its proper value. Return 1 if data was too big, 0 if not.
*/ */
static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) static int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
@ -766,8 +797,8 @@ static int handle_data(IP_Port source, uint8_t *packet, uint32_t length)
return add_recv(connection, number, packet + 5, size); return add_recv(connection, number, packet + 5, size);
} }
/* /*
* END of packet handling functions * END of packet handling functions
*/ */
void LosslessUDP_init(void) void LosslessUDP_init(void)
@ -785,17 +816,18 @@ static void doNew(void)
{ {
uint32_t i; uint32_t i;
uint64_t temp_time = current_time(); uint64_t temp_time = current_time();
for (i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].status == 1) if (connections[i].status == 1)
if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { if ((connections[i].last_sent + (1000000UL / connections[i].SYNC_rate)) <= temp_time) {
send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0);
connections[i].last_sent = temp_time; connections[i].last_sent = temp_time;
} }
/* kill all timed out connections */ /* kill all timed out connections */
if (connections[i].status > 0 && if (connections[i].status > 0 &&
(connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
connections[i].status != 4) { connections[i].status != 4) {
connections[i].status = 4; connections[i].status = 4;
/* kill_connection(i); */ /* kill_connection(i); */
} }
@ -809,9 +841,10 @@ static void doSYNC(void)
{ {
uint32_t i; uint32_t i;
uint64_t temp_time = current_time(); uint64_t temp_time = current_time();
for (i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].status == 2 || connections[i].status == 3) if (connections[i].status == 2 || connections[i].status == 3)
if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { if ((connections[i].last_SYNC + (1000000UL / connections[i].SYNC_rate)) <= temp_time) {
send_SYNC(i); send_SYNC(i);
connections[i].last_SYNC = temp_time; connections[i].last_SYNC = temp_time;
} }
@ -823,18 +856,20 @@ static void doData(void)
uint32_t i; uint32_t i;
uint64_t j; uint64_t j;
uint64_t temp_time = current_time(); uint64_t temp_time = current_time();
for (i = 0; i < MAX_CONNECTIONS; ++i) for (i = 0; i < MAX_CONNECTIONS; ++i)
if (connections[i].status == 3 && sendqueue(i) != 0) if (connections[i].status == 3 && sendqueue(i) != 0)
if ((connections[i].last_sent + (1000000UL/connections[i].data_rate)) <= temp_time) { if ((connections[i].last_sent + (1000000UL / connections[i].data_rate)) <= temp_time) {
for (j = connections[i].last_sent; j < temp_time; j += (1000000UL/connections[i].data_rate)) for (j = connections[i].last_sent; j < temp_time; j += (1000000UL / connections[i].data_rate))
send_DATA(i); send_DATA(i);
connections[i].last_sent = temp_time; connections[i].last_sent = temp_time;
} }
} }
#define MAX_SYNC_RATE 10 #define MAX_SYNC_RATE 10
/* /*
* Automatically adjusts send rates of packets for optimal transmission. * Automatically adjusts send rates of packets for optimal transmission.
* *
* TODO: flow control. * TODO: flow control.
@ -843,9 +878,11 @@ static void adjustRates(void)
{ {
uint32_t i; uint32_t i;
uint64_t temp_time = current_time(); uint64_t temp_time = current_time();
for (i = 0; i < MAX_CONNECTIONS; ++i) { for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].status == 1 || connections[i].status == 2) if (connections[i].status == 1 || connections[i].status == 2)
connections[i].SYNC_rate = MAX_SYNC_RATE; connections[i].SYNC_rate = MAX_SYNC_RATE;
if (connections[i].status == 3) { if (connections[i].status == 3) {
if (sendqueue(i) != 0) { if (sendqueue(i) != 0) {
connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE;

View File

@ -33,7 +33,7 @@ extern "C" {
/* maximum length of the data in the data packets */ /* maximum length of the data in the data packets */
#define MAX_DATA_SIZE 1024 #define MAX_DATA_SIZE 1024
/* /*
* Initialize a new connection to ip_port * Initialize a new connection to ip_port
* Returns an integer corresponding to the connection id. * Returns an integer corresponding to the connection id.
* Return -1 if it could not initialize the connection. * Return -1 if it could not initialize the connection.
@ -41,51 +41,51 @@ extern "C" {
*/ */
int new_connection(IP_Port ip_port); int new_connection(IP_Port ip_port);
/* /*
* Get connection id from IP_Port. * Get connection id from IP_Port.
* Return -1 if there are no connections like we are looking for. * Return -1 if there are no connections like we are looking for.
* Return id if it found it . * Return id if it found it .
*/ */
int getconnection_id(IP_Port ip_port); int getconnection_id(IP_Port ip_port);
/* /*
* Returns an int corresponding to the next connection in our imcoming connection list * Returns an int corresponding to the next connection in our imcoming connection list
* Return -1 if there are no new incoming connections in the list. * Return -1 if there are no new incoming connections in the list.
*/ */
int incoming_connection(void); int incoming_connection(void);
/* /*
* Return -1 if it could not kill the connection. * Return -1 if it could not kill the connection.
* Return 0 if killed successfully * Return 0 if killed successfully
*/ */
int kill_connection(int connection_id); int kill_connection(int connection_id);
/* /*
* Kill connection in seconds seconds. * Kill connection in seconds seconds.
* Return -1 if it can not kill the connection. * Return -1 if it can not kill the connection.
* Return 0 if it will kill it * Return 0 if it will kill it
*/ */
int kill_connection_in(int connection_id, uint32_t seconds); int kill_connection_in(int connection_id, uint32_t seconds);
/* /*
* Returns the ip_port of the corresponding connection. * Returns the ip_port of the corresponding connection.
* Return 0 if there is no such connection. * Return 0 if there is no such connection.
*/ */
IP_Port connection_ip(int connection_id); IP_Port connection_ip(int connection_id);
/* /*
* Returns the id of the next packet in the queue * Returns the id of the next packet in the queue
* Return -1 if no packet in queue * Return -1 if no packet in queue
*/ */
char id_packet(int connection_id); char id_packet(int connection_id);
/* /*
* Return 0 if there is no received data in the buffer. * Return 0 if there is no received data in the buffer.
* Return length of received packet if successful * Return length of received packet if successful
*/ */
int read_packet(int connection_id, uint8_t *data); int read_packet(int connection_id, uint8_t *data);
/* /*
* Return 0 if data could not be put in packet queue * Return 0 if data could not be put in packet queue
* Return 1 if data was put into the queue * Return 1 if data was put into the queue
*/ */
@ -94,8 +94,8 @@ int write_packet(int connection_id, uint8_t *data, uint32_t length);
/* Returns the number of packets in the queue waiting to be successfully sent. */ /* Returns the number of packets in the queue waiting to be successfully sent. */
uint32_t sendqueue(int connection_id); uint32_t sendqueue(int connection_id);
/* /*
* returns the number of packets in the queue waiting to be successfully * returns the number of packets in the queue waiting to be successfully
* read with read_packet(...) * read with read_packet(...)
*/ */
uint32_t recvqueue(int connection_id); uint32_t recvqueue(int connection_id);
@ -112,7 +112,7 @@ int is_connected(int connection_id);
/* Call this function a couple times per second It's the main loop. */ /* Call this function a couple times per second It's the main loop. */
void doLossless_UDP(void); void doLossless_UDP(void);
/* /*
* This function sets up LosslessUDP packet handling. * This function sets up LosslessUDP packet handling.
*/ */
void LosslessUDP_init(void); void LosslessUDP_init(void);

View File

@ -35,11 +35,14 @@ static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_i
/* set the size of the friend list to numfriends /* set the size of the friend list to numfriends
return -1 if realloc fails */ return -1 if realloc fails */
int realloc_friendlist(Messenger *m, uint32_t num) { int realloc_friendlist(Messenger *m, uint32_t num)
Friend *newfriendlist = realloc(m->friendlist, num*sizeof(Friend)); {
Friend *newfriendlist = realloc(m->friendlist, num * sizeof(Friend));
if (newfriendlist == NULL) if (newfriendlist == NULL)
return -1; return -1;
memset(&newfriendlist[num-1], 0, sizeof(Friend));
memset(&newfriendlist[num - 1], 0, sizeof(Friend));
m->friendlist = newfriendlist; m->friendlist = newfriendlist;
return 0; return 0;
} }
@ -85,8 +88,10 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len)
uint8_t checksum[2] = {0}; uint8_t checksum[2] = {0};
uint16_t check; uint16_t check;
uint32_t i; uint32_t i;
for(i = 0; i < len; ++i)
for (i = 0; i < len; ++i)
checksum[i % 2] ^= address[i]; checksum[i % 2] ^= address[i];
memcpy(&check, checksum, sizeof(check)); memcpy(&check, checksum, sizeof(check));
return check; return check;
} }
@ -125,25 +130,33 @@ void getaddress(Messenger *m, uint8_t *address)
int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
{ {
if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
- crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
+ crypto_box_ZEROBYTES)) + crypto_box_ZEROBYTES))
return FAERR_TOOLONG; return FAERR_TOOLONG;
uint8_t client_id[crypto_box_PUBLICKEYBYTES]; uint8_t client_id[crypto_box_PUBLICKEYBYTES];
memcpy(client_id, address, crypto_box_PUBLICKEYBYTES); memcpy(client_id, address, crypto_box_PUBLICKEYBYTES);
uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check)); memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check));
if (check != checksum) if (check != checksum)
return FAERR_BADCHECKSUM; return FAERR_BADCHECKSUM;
if (length < 1) if (length < 1)
return FAERR_NOMESSAGE; return FAERR_NOMESSAGE;
if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
return FAERR_OWNKEY; return FAERR_OWNKEY;
int friend_id = getfriend_id(m, client_id); int friend_id = getfriend_id(m, client_id);
if (friend_id != -1) { if (friend_id != -1) {
uint32_t nospam; uint32_t nospam;
memcpy(&nospam, address + crypto_box_PUBLICKEYBYTES, sizeof(nospam)); memcpy(&nospam, address + crypto_box_PUBLICKEYBYTES, sizeof(nospam));
if(m->friendlist[friend_id].friendrequest_nospam == nospam)
if (m->friendlist[friend_id].friendrequest_nospam == nospam)
return FAERR_ALREADYSENT; return FAERR_ALREADYSENT;
m->friendlist[friend_id].friendrequest_nospam = nospam; m->friendlist[friend_id].friendrequest_nospam = nospam;
return FAERR_SETNEWNOSPAM; return FAERR_SETNEWNOSPAM;
} }
@ -153,6 +166,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
return FAERR_NOMEM; return FAERR_NOMEM;
uint32_t i; uint32_t i;
for (i = 0; i <= m->numfriends; ++i) { for (i = 0; i <= m->numfriends; ++i) {
if (m->friendlist[i].status == NOFRIEND) { if (m->friendlist[i].status == NOFRIEND) {
DHT_addfriend(client_id); DHT_addfriend(client_id);
@ -173,10 +187,11 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
return i; return i;
} }
} }
return FAERR_UNKNOWN; return FAERR_UNKNOWN;
} }
int m_addfriend_norequest(Messenger *m, uint8_t * client_id) int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
{ {
if (getfriend_id(m, client_id) != -1) if (getfriend_id(m, client_id) != -1)
return -1; return -1;
@ -186,8 +201,9 @@ int m_addfriend_norequest(Messenger *m, uint8_t * client_id)
return FAERR_NOMEM; return FAERR_NOMEM;
uint32_t i; uint32_t i;
for (i = 0; i <= m->numfriends; ++i) { for (i = 0; i <= m->numfriends; ++i) {
if(m->friendlist[i].status == NOFRIEND) { if (m->friendlist[i].status == NOFRIEND) {
DHT_addfriend(client_id); DHT_addfriend(client_id);
m->friendlist[i].status = FRIEND_REQUESTED; m->friendlist[i].status = FRIEND_REQUESTED;
m->friendlist[i].crypt_connection_id = -1; m->friendlist[i].crypt_connection_id = -1;
@ -202,6 +218,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t * client_id)
return i; return i;
} }
} }
return -1; return -1;
} }
@ -220,9 +237,10 @@ int m_delfriend(Messenger *m, int friendnumber)
uint32_t i; uint32_t i;
for (i = m->numfriends; i != 0; --i) { for (i = m->numfriends; i != 0; --i) {
if (m->friendlist[i-1].status != NOFRIEND) if (m->friendlist[i - 1].status != NOFRIEND)
break; break;
} }
m->numfriends = i; m->numfriends = i;
if (realloc_friendlist(m, m->numfriends + 1) != 0) if (realloc_friendlist(m, m->numfriends + 1) != 0)
@ -240,6 +258,7 @@ int m_friendstatus(Messenger *m, int friendnumber)
{ {
if (friendnumber < 0 || friendnumber >= m->numfriends) if (friendnumber < 0 || friendnumber >= m->numfriends)
return NOFRIEND; return NOFRIEND;
return m->friendlist[friendnumber].status; return m->friendlist[friendnumber].status;
} }
@ -250,10 +269,13 @@ uint32_t m_sendmessage(Messenger *m, int friendnumber, uint8_t *message, uint32_
{ {
if (friendnumber < 0 || friendnumber >= m->numfriends) if (friendnumber < 0 || friendnumber >= m->numfriends)
return 0; return 0;
uint32_t msgid = ++m->friendlist[friendnumber].message_id; uint32_t msgid = ++m->friendlist[friendnumber].message_id;
if (msgid == 0) if (msgid == 0)
msgid = 1; /* otherwise, false error */ msgid = 1; /* otherwise, false error */
if(m_sendmessage_withid(m, friendnumber, msgid, message, length)) {
if (m_sendmessage_withid(m, friendnumber, msgid, message, length)) {
return msgid; return msgid;
} }
@ -264,6 +286,7 @@ uint32_t m_sendmessage_withid(Messenger *m, int friendnumber, uint32_t theid, ui
{ {
if (length >= (MAX_DATA_SIZE - sizeof(theid))) if (length >= (MAX_DATA_SIZE - sizeof(theid)))
return 0; return 0;
uint8_t temp[MAX_DATA_SIZE]; uint8_t temp[MAX_DATA_SIZE];
theid = htonl(theid); theid = htonl(theid);
memcpy(temp, &theid, sizeof(theid)); memcpy(temp, &theid, sizeof(theid));
@ -281,20 +304,22 @@ int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t lengt
/* send a name packet to friendnumber /* send a name packet to friendnumber
length is the length with the NULL terminator*/ length is the length with the NULL terminator*/
static int m_sendname(Messenger *m, int friendnumber, uint8_t * name, uint16_t length) static int m_sendname(Messenger *m, int friendnumber, uint8_t *name, uint16_t length)
{ {
if(length > MAX_NAME_LENGTH || length == 0) if (length > MAX_NAME_LENGTH || length == 0)
return 0; return 0;
return write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length); return write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length);
} }
/* set the name of a friend /* set the name of a friend
return 0 if success return 0 if success
return -1 if failure */ return -1 if failure */
static int setfriendname(Messenger *m, int friendnumber, uint8_t * name) static int setfriendname(Messenger *m, int friendnumber, uint8_t *name)
{ {
if (friendnumber >= m->numfriends || friendnumber < 0) if (friendnumber >= m->numfriends || friendnumber < 0)
return -1; return -1;
memcpy(m->friendlist[friendnumber].name, name, MAX_NAME_LENGTH); memcpy(m->friendlist[friendnumber].name, name, MAX_NAME_LENGTH);
return 0; return 0;
} }
@ -305,15 +330,18 @@ static int setfriendname(Messenger *m, int friendnumber, uint8_t * name)
length is the length of name with the NULL terminator length is the length of name with the NULL terminator
return 0 if success return 0 if success
return -1 if failure */ return -1 if failure */
int setname(Messenger *m, uint8_t * name, uint16_t length) int setname(Messenger *m, uint8_t *name, uint16_t length)
{ {
if (length > MAX_NAME_LENGTH || length == 0) if (length > MAX_NAME_LENGTH || length == 0)
return -1; return -1;
memcpy(m->name, name, length); memcpy(m->name, name, length);
m->name_length = length; m->name_length = length;
uint32_t i; uint32_t i;
for (i = 0; i < m->numfriends; ++i) for (i = 0; i < m->numfriends; ++i)
m->friendlist[i].name_sent = 0; m->friendlist[i].name_sent = 0;
return 0; return 0;
} }
@ -340,10 +368,11 @@ uint16_t getself_name(Messenger *m, uint8_t *name, uint16_t nlen)
name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
return 0 if success return 0 if success
return -1 if failure */ return -1 if failure */
int getname(Messenger *m, int friendnumber, uint8_t * name) int getname(Messenger *m, int friendnumber, uint8_t *name)
{ {
if (friendnumber >= m->numfriends || friendnumber < 0) if (friendnumber >= m->numfriends || friendnumber < 0)
return -1; return -1;
memcpy(name, m->friendlist[friendnumber].name, MAX_NAME_LENGTH); memcpy(name, m->friendlist[friendnumber].name, MAX_NAME_LENGTH);
return 0; return 0;
} }
@ -352,12 +381,15 @@ int m_set_statusmessage(Messenger *m, uint8_t *status, uint16_t length)
{ {
if (length > MAX_STATUSMESSAGE_LENGTH) if (length > MAX_STATUSMESSAGE_LENGTH)
return -1; return -1;
memcpy(m->statusmessage, status, length); memcpy(m->statusmessage, status, length);
m->statusmessage_length = length; m->statusmessage_length = length;
uint32_t i; uint32_t i;
for (i = 0; i < m->numfriends; ++i) for (i = 0; i < m->numfriends; ++i)
m->friendlist[i].statusmessage_sent = 0; m->friendlist[i].statusmessage_sent = 0;
return 0; return 0;
} }
@ -366,10 +398,13 @@ int m_set_userstatus(Messenger *m, USERSTATUS status)
if (status >= USERSTATUS_INVALID) { if (status >= USERSTATUS_INVALID) {
return -1; return -1;
} }
m->userstatus = status; m->userstatus = status;
uint32_t i; uint32_t i;
for (i = 0; i < m->numfriends; ++i) for (i = 0; i < m->numfriends; ++i)
m->friendlist[i].userstatus_sent = 0; m->friendlist[i].userstatus_sent = 0;
return 0; return 0;
} }
@ -379,21 +414,23 @@ int m_get_statusmessage_size(Messenger *m, int friendnumber)
{ {
if (friendnumber >= m->numfriends || friendnumber < 0) if (friendnumber >= m->numfriends || friendnumber < 0)
return -1; return -1;
return m->friendlist[friendnumber].statusmessage_length; return m->friendlist[friendnumber].statusmessage_length;
} }
/* copy the user status of friendnumber into buf, truncating if needed to maxlen /* copy the user status of friendnumber into buf, truncating if needed to maxlen
bytes, use m_get_statusmessage_size to find out how much you need to allocate */ bytes, use m_get_statusmessage_size to find out how much you need to allocate */
int m_copy_statusmessage(Messenger *m, int friendnumber, uint8_t * buf, uint32_t maxlen) int m_copy_statusmessage(Messenger *m, int friendnumber, uint8_t *buf, uint32_t maxlen)
{ {
if (friendnumber >= m->numfriends || friendnumber < 0) if (friendnumber >= m->numfriends || friendnumber < 0)
return -1; return -1;
memset(buf, 0, maxlen); memset(buf, 0, maxlen);
memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
return 0; return 0;
} }
int m_copy_self_statusmessage(Messenger *m, uint8_t * buf, uint32_t maxlen) int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen)
{ {
memset(buf, 0, maxlen); memset(buf, 0, maxlen);
memcpy(buf, m->statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); memcpy(buf, m->statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
@ -404,10 +441,13 @@ USERSTATUS m_get_userstatus(Messenger *m, int friendnumber)
{ {
if (friendnumber >= m->numfriends || friendnumber < 0) if (friendnumber >= m->numfriends || friendnumber < 0)
return USERSTATUS_INVALID; return USERSTATUS_INVALID;
USERSTATUS status = m->friendlist[friendnumber].userstatus; USERSTATUS status = m->friendlist[friendnumber].userstatus;
if (status >= USERSTATUS_INVALID) { if (status >= USERSTATUS_INVALID) {
status = USERSTATUS_NONE; status = USERSTATUS_NONE;
} }
return status; return status;
} }
@ -416,7 +456,7 @@ USERSTATUS m_get_self_userstatus(Messenger *m)
return m->userstatus; return m->userstatus;
} }
static int send_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length) static int send_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length)
{ {
return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length); return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length);
} }
@ -427,10 +467,11 @@ static int send_userstatus(Messenger *m, int friendnumber, USERSTATUS status)
return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat)); return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat));
} }
static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length) static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length)
{ {
if (friendnumber >= m->numfriends || friendnumber < 0) if (friendnumber >= m->numfriends || friendnumber < 0)
return -1; return -1;
uint8_t *newstatus = calloc(length, 1); uint8_t *newstatus = calloc(length, 1);
memcpy(newstatus, status, length); memcpy(newstatus, status, length);
free(m->friendlist[friendnumber].statusmessage); free(m->friendlist[friendnumber].statusmessage);
@ -449,56 +490,61 @@ void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno)
{ {
if (yesno != 0 || yesno != 1) if (yesno != 0 || yesno != 1)
return; return;
if (friendnumber >= m->numfriends || friendnumber < 0) if (friendnumber >= m->numfriends || friendnumber < 0)
return; return;
m->friendlist[friendnumber].receives_read_receipts = yesno; m->friendlist[friendnumber].receives_read_receipts = yesno;
} }
/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */ /* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */
/* set the function that will be executed when a friend request is received. */ /* set the function that will be executed when a friend request is received. */
void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata) void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
{ {
callback_friendrequest(function, userdata); callback_friendrequest(function, userdata);
} }
/* set the function that will be executed when a message from a friend is received. */ /* set the function that will be executed when a message from a friend is received. */
void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
void *userdata)
{ {
m->friend_message = function; m->friend_message = function;
m->friend_message_userdata = userdata; m->friend_message_userdata = userdata;
} }
void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *), void *userdata)
{ {
m->friend_action = function; m->friend_action = function;
m->friend_action_userdata = userdata; m->friend_action_userdata = userdata;
} }
void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
void *userdata)
{ {
m->friend_namechange = function; m->friend_namechange = function;
m->friend_namechange_userdata = userdata; m->friend_namechange_userdata = userdata;
} }
void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
void *userdata)
{ {
m->friend_statusmessagechange = function; m->friend_statusmessagechange = function;
m->friend_statuschange_userdata = userdata; m->friend_statuschange_userdata = userdata;
} }
void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void*), void* userdata) void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void *), void *userdata)
{ {
m->friend_userstatuschange = function; m->friend_userstatuschange = function;
m->friend_userstatuschange_userdata = userdata; m->friend_userstatuschange_userdata = userdata;
} }
void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void*), void* userdata) void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void *), void *userdata)
{ {
m->read_receipt = function; m->read_receipt = function;
m->read_receipt_userdata = userdata; m->read_receipt_userdata = userdata;
} }
void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void*), void* userdata) void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void *), void *userdata)
{ {
m->friend_connectionstatuschange = function; m->friend_connectionstatuschange = function;
m->friend_connectionstatuschange_userdata = userdata; m->friend_connectionstatuschange_userdata = userdata;
@ -508,10 +554,13 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_
{ {
if (!m->friend_connectionstatuschange) if (!m->friend_connectionstatuschange)
return; return;
if (status == NOFRIEND) if (status == NOFRIEND)
return; return;
const uint8_t was_connected = m->friendlist[friendnumber].status == FRIEND_ONLINE; const uint8_t was_connected = m->friendlist[friendnumber].status == FRIEND_ONLINE;
const uint8_t is_connected = status == FRIEND_ONLINE; const uint8_t is_connected = status == FRIEND_ONLINE;
if (is_connected != was_connected) if (is_connected != was_connected)
m->friend_connectionstatuschange(m, friendnumber, is_connected, m->friend_connectionstatuschange_userdata); m->friend_connectionstatuschange(m, friendnumber, is_connected, m->friend_connectionstatuschange_userdata);
} }
@ -526,8 +575,10 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
{ {
if (friendnumber < 0 || friendnumber >= m->numfriends) if (friendnumber < 0 || friendnumber >= m->numfriends)
return 0; return 0;
if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE) if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
return 0; return 0;
uint8_t packet[length + 1]; uint8_t packet[length + 1];
packet[0] = packet_id; packet[0] = packet_id;
memcpy(packet + 1, data, length); memcpy(packet + 1, data, length);
@ -541,7 +592,7 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
#define PORT 33445 #define PORT 33445
/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
int LANdiscovery(timer* t, void* arg) int LANdiscovery(timer *t, void *arg)
{ {
send_LANdiscovery(htons(PORT)); send_LANdiscovery(htons(PORT));
timer_start(t, LAN_DISCOVERY_INTERVAL); timer_start(t, LAN_DISCOVERY_INTERVAL);
@ -549,19 +600,20 @@ int LANdiscovery(timer* t, void* arg)
} }
/* run this at startup */ /* run this at startup */
Messenger * initMessenger(void) Messenger *initMessenger(void)
{ {
Messenger *m = calloc(1, sizeof(Messenger)); Messenger *m = calloc(1, sizeof(Messenger));
if( ! m )
if ( ! m )
return 0; return 0;
new_keys(); new_keys();
m_set_statusmessage(m, (uint8_t*)"Online", sizeof("Online")); m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
initNetCrypto(); initNetCrypto();
IP ip; IP ip;
ip.i = 0; ip.i = 0;
if(init_networking(ip,PORT) == -1) if (init_networking(ip, PORT) == -1)
return 0; return 0;
DHT_init(); DHT_init();
@ -576,7 +628,8 @@ Messenger * initMessenger(void)
} }
/* run this before closing shop */ /* run this before closing shop */
void cleanupMessenger(Messenger *m){ void cleanupMessenger(Messenger *m)
{
/* FIXME TODO ideally cleanupMessenger will mirror initMessenger /* FIXME TODO ideally cleanupMessenger will mirror initMessenger
* this requires the other modules to expose cleanup functions * this requires the other modules to expose cleanup functions
*/ */
@ -591,117 +644,155 @@ void doFriends(Messenger *m)
uint32_t i; uint32_t i;
int len; int len;
uint8_t temp[MAX_DATA_SIZE]; uint8_t temp[MAX_DATA_SIZE];
for (i = 0; i < m->numfriends; ++i) { for (i = 0; i < m->numfriends; ++i) {
if (m->friendlist[i].status == FRIEND_ADDED) { if (m->friendlist[i].status == FRIEND_ADDED) {
int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, m->friendlist[i].info_size); int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info,
m->friendlist[i].info_size);
if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */ if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */
set_friend_status(m, i, FRIEND_REQUESTED); set_friend_status(m, i, FRIEND_REQUESTED);
else if (fr > 0) else if (fr > 0)
set_friend_status(m, i, FRIEND_REQUESTED); set_friend_status(m, i, FRIEND_REQUESTED);
} }
if (m->friendlist[i].status == FRIEND_REQUESTED || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */
if (m->friendlist[i].status == FRIEND_REQUESTED
|| m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */
if (m->friendlist[i].status == FRIEND_REQUESTED) { if (m->friendlist[i].status == FRIEND_REQUESTED) {
if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/ if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/
send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, m->friendlist[i].info_size); send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info,
m->friendlist[i].info_size);
m->friendlist[i].friend_request_id = unix_time(); m->friendlist[i].friend_request_id = unix_time();
} }
} }
IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id);
switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) { switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) {
case 0: case 0:
if (friendip.ip.i > 1) if (friendip.ip.i > 1)
m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip); m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip);
break;
case 3: /* Connection is established */ break;
set_friend_status(m, i, FRIEND_ONLINE);
m->friendlist[i].name_sent = 0; case 3: /* Connection is established */
m->friendlist[i].userstatus_sent = 0; set_friend_status(m, i, FRIEND_ONLINE);
m->friendlist[i].statusmessage_sent = 0; m->friendlist[i].name_sent = 0;
break; m->friendlist[i].userstatus_sent = 0;
case 4: m->friendlist[i].statusmessage_sent = 0;
crypto_kill(m->friendlist[i].crypt_connection_id); break;
m->friendlist[i].crypt_connection_id = -1;
break; case 4:
default: crypto_kill(m->friendlist[i].crypt_connection_id);
break; m->friendlist[i].crypt_connection_id = -1;
break;
default:
break;
} }
} }
while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online */ while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online */
if (m->friendlist[i].name_sent == 0) { if (m->friendlist[i].name_sent == 0) {
if (m_sendname(m, i, m->name, m->name_length)) if (m_sendname(m, i, m->name, m->name_length))
m->friendlist[i].name_sent = 1; m->friendlist[i].name_sent = 1;
} }
if (m->friendlist[i].statusmessage_sent == 0) { if (m->friendlist[i].statusmessage_sent == 0) {
if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length)) if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length))
m->friendlist[i].statusmessage_sent = 1; m->friendlist[i].statusmessage_sent = 1;
} }
if (m->friendlist[i].userstatus_sent == 0) { if (m->friendlist[i].userstatus_sent == 0) {
if (send_userstatus(m, i, m->userstatus)) if (send_userstatus(m, i, m->userstatus))
m->friendlist[i].userstatus_sent = 1; m->friendlist[i].userstatus_sent = 1;
} }
len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp); len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp);
uint8_t packet_id = temp[0]; uint8_t packet_id = temp[0];
uint8_t* data = temp + 1; uint8_t *data = temp + 1;
int data_length = len - 1; int data_length = len - 1;
if (len > 0) { if (len > 0) {
switch (packet_id) { switch (packet_id) {
case PACKET_ID_NICKNAME: { case PACKET_ID_NICKNAME: {
if (data_length >= MAX_NAME_LENGTH || data_length == 0) if (data_length >= MAX_NAME_LENGTH || data_length == 0)
break;
if (m->friend_namechange)
m->friend_namechange(m, i, data, data_length, m->friend_namechange_userdata);
memcpy(m->friendlist[i].name, data, data_length);
m->friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */
break; break;
if(m->friend_namechange)
m->friend_namechange(m, i, data, data_length, m->friend_namechange_userdata);
memcpy(m->friendlist[i].name, data, data_length);
m->friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */
break;
}
case PACKET_ID_STATUSMESSAGE: {
if (data_length == 0)
break;
uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1);
memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
if (m->friend_statusmessagechange)
m->friend_statusmessagechange(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH),
m->friend_statuschange_userdata);
set_friend_statusmessage(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
free(status);
break;
}
case PACKET_ID_USERSTATUS: {
if (data_length != 1)
break;
USERSTATUS status = data[0];
if (m->friend_userstatuschange)
m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata);
set_friend_userstatus(m, i, status);
break;
}
case PACKET_ID_MESSAGE: {
uint8_t *message_id = data;
uint8_t message_id_length = 4;
uint8_t *message = data + message_id_length;
uint16_t message_length = data_length - message_id_length;
if (m->friendlist[i].receives_read_receipts) {
write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
} }
if (m->friend_message)
(*m->friend_message)(m, i, message, message_length, m->friend_message_userdata); case PACKET_ID_STATUSMESSAGE: {
break; if (data_length == 0)
} break;
case PACKET_ID_ACTION: {
if (m->friend_action) uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1);
(*m->friend_action)(m, i, data, data_length, m->friend_action_userdata); memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
break;
} if (m->friend_statusmessagechange)
case PACKET_ID_RECEIPT: { m->friend_statusmessagechange(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH),
uint32_t msgid; m->friend_statuschange_userdata);
if (data_length < sizeof(msgid))
set_friend_statusmessage(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
free(status);
break; break;
memcpy(&msgid, data, sizeof(msgid)); }
msgid = ntohl(msgid);
if (m->read_receipt) case PACKET_ID_USERSTATUS: {
(*m->read_receipt)(m, i, msgid, m->read_receipt_userdata); if (data_length != 1)
break; break;
}
USERSTATUS status = data[0];
if (m->friend_userstatuschange)
m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata);
set_friend_userstatus(m, i, status);
break;
}
case PACKET_ID_MESSAGE: {
uint8_t *message_id = data;
uint8_t message_id_length = 4;
uint8_t *message = data + message_id_length;
uint16_t message_length = data_length - message_id_length;
if (m->friendlist[i].receives_read_receipts) {
write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
}
if (m->friend_message)
(*m->friend_message)(m, i, message, message_length, m->friend_message_userdata);
break;
}
case PACKET_ID_ACTION: {
if (m->friend_action)
(*m->friend_action)(m, i, data, data_length, m->friend_action_userdata);
break;
}
case PACKET_ID_RECEIPT: {
uint32_t msgid;
if (data_length < sizeof(msgid))
break;
memcpy(&msgid, data, sizeof(msgid));
msgid = ntohl(msgid);
if (m->read_receipt)
(*m->read_receipt)(m, i, msgid, m->read_receipt_userdata);
break;
}
} }
} else { } else {
if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
@ -709,6 +800,7 @@ void doFriends(Messenger *m)
m->friendlist[i].crypt_connection_id = -1; m->friendlist[i].crypt_connection_id = -1;
set_friend_status(m, i, FRIEND_CONFIRMED); set_friend_status(m, i, FRIEND_CONFIRMED);
} }
break; break;
} }
} }
@ -721,8 +813,10 @@ void doInbound(Messenger *m)
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES]; uint8_t session_key[crypto_box_PUBLICKEYBYTES];
int inconnection = crypto_inbound(public_key, secret_nonce, session_key); int inconnection = crypto_inbound(public_key, secret_nonce, session_key);
if (inconnection != -1) { if (inconnection != -1) {
int friend_id = getfriend_id(m, public_key); int friend_id = getfriend_id(m, public_key);
if (friend_id != -1) { if (friend_id != -1) {
crypto_kill(m->friendlist[friend_id].crypt_connection_id); crypto_kill(m->friendlist[friend_id].crypt_connection_id);
m->friendlist[friend_id].crypt_connection_id = m->friendlist[friend_id].crypt_connection_id =
@ -775,12 +869,14 @@ void Messenger_save(Messenger *m, uint8_t *data)
} }
/* load the messenger from data of size length. */ /* load the messenger from data of size length. */
int Messenger_load(Messenger *m, uint8_t * data, uint32_t length) int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
{ {
if (length == ~0) if (length == ~0)
return -1; return -1;
if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3) if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3)
return -1; return -1;
length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3; length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3;
load_keys(data); load_keys(data);
data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
@ -794,23 +890,28 @@ int Messenger_load(Messenger *m, uint8_t * data, uint32_t length)
if (length < size) if (length < size)
return -1; return -1;
length -= size; length -= size;
if (DHT_load(data, size) == -1) if (DHT_load(data, size) == -1)
return -1; return -1;
data += size; data += size;
memcpy(&size, data, sizeof(size)); memcpy(&size, data, sizeof(size));
data += sizeof(size); data += sizeof(size);
if (length != size || length % sizeof(Friend) != 0) if (length != size || length % sizeof(Friend) != 0)
return -1; return -1;
Friend * temp = malloc(size); Friend *temp = malloc(size);
memcpy(temp, data, size); memcpy(temp, data, size);
uint16_t num = size / sizeof(Friend); uint16_t num = size / sizeof(Friend);
uint32_t i; uint32_t i;
for (i = 0; i < num; ++i) { for (i = 0; i < num; ++i) {
if(temp[i].status >= 3) { if (temp[i].status >= 3) {
int fnum = m_addfriend_norequest(m, temp[i].client_id); int fnum = m_addfriend_norequest(m, temp[i].client_id);
setfriendname(m, fnum, temp[i].name); setfriendname(m, fnum, temp[i].name);
/* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */
@ -824,6 +925,7 @@ int Messenger_load(Messenger *m, uint8_t * data, uint32_t length)
m_addfriend(m, address, temp[i].info, temp[i].info_size); m_addfriend(m, address, temp[i].info, temp[i].info_size);
} }
} }
free(temp); free(temp);
return 0; return 0;
} }

View File

@ -76,7 +76,8 @@ typedef enum {
USERSTATUS_AWAY, USERSTATUS_AWAY,
USERSTATUS_BUSY, USERSTATUS_BUSY,
USERSTATUS_INVALID USERSTATUS_INVALID
} USERSTATUS; }
USERSTATUS;
typedef struct { typedef struct {
uint8_t client_id[CLIENT_ID_SIZE]; uint8_t client_id[CLIENT_ID_SIZE];
@ -111,22 +112,22 @@ typedef struct Messenger {
Friend *friendlist; Friend *friendlist;
uint32_t numfriends; uint32_t numfriends;
void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void*); void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
void* friend_message_userdata; void *friend_message_userdata;
void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void*); void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
void* friend_action_userdata; void *friend_action_userdata;
void (*friend_namechange)(struct Messenger *m, int, uint8_t *, uint16_t, void*); void (*friend_namechange)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
void* friend_namechange_userdata; void *friend_namechange_userdata;
void (*friend_statusmessagechange)(struct Messenger *m, int, uint8_t *, uint16_t, void*); void (*friend_statusmessagechange)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
void* friend_statusmessagechange_userdata; void *friend_statusmessagechange_userdata;
void (*friend_userstatuschange)(struct Messenger *m, int, USERSTATUS, void*); void (*friend_userstatuschange)(struct Messenger *m, int, USERSTATUS, void *);
void* friend_userstatuschange_userdata; void *friend_userstatuschange_userdata;
void (*read_receipt)(struct Messenger *m, int, uint32_t, void*); void (*read_receipt)(struct Messenger *m, int, uint32_t, void *);
void* read_receipt_userdata; void *read_receipt_userdata;
void (*friend_statuschange)(struct Messenger *m, int, uint8_t, void*); void (*friend_statuschange)(struct Messenger *m, int, uint8_t, void *);
void* friend_statuschange_userdata; void *friend_statuschange_userdata;
void (*friend_connectionstatuschange)(struct Messenger *m, int, uint8_t, void*); void (*friend_connectionstatuschange)(struct Messenger *m, int, uint8_t, void *);
void* friend_connectionstatuschange_userdata; void *friend_connectionstatuschange_userdata;
} Messenger; } Messenger;
@ -255,29 +256,32 @@ void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno);
/* set the function that will be executed when a friend request is received. /* set the function that will be executed when a friend request is received.
function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata); void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata);
/* set the function that will be executed when a message from a friend is received. /* set the function that will be executed when a message from a friend is received.
function format is: function(int friendnumber, uint8_t * message, uint32_t length) */ function format is: function(int friendnumber, uint8_t * message, uint32_t length) */
void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata); void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
void *userdata);
/* set the function that will be executed when an action from a friend is received. /* set the function that will be executed when an action from a friend is received.
function format is: function(int friendnumber, uint8_t * action, uint32_t length) */ function format is: function(int friendnumber, uint8_t * action, uint32_t length) */
void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata); void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *), void *userdata);
/* set the callback for name changes /* set the callback for name changes
function(int friendnumber, uint8_t *newname, uint16_t length) function(int friendnumber, uint8_t *newname, uint16_t length)
you are not responsible for freeing newname */ you are not responsible for freeing newname */
void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata); void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
void *userdata);
/* set the callback for status message changes /* set the callback for status message changes
function(int friendnumber, uint8_t *newstatus, uint16_t length) function(int friendnumber, uint8_t *newstatus, uint16_t length)
you are not responsible for freeing newstatus */ you are not responsible for freeing newstatus */
void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata); void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
void *userdata);
/* set the callback for status type changes /* set the callback for status type changes
function(int friendnumber, USERSTATUS kind) */ function(int friendnumber, USERSTATUS kind) */
void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void*), void* userdata); void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void *), void *userdata);
/* set the callback for read receipts /* set the callback for read receipts
function(int friendnumber, uint32_t receipt) function(int friendnumber, uint32_t receipt)
@ -286,7 +290,7 @@ void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USE
has been received on the other side. since core doesn't has been received on the other side. since core doesn't
track ids for you, receipt may not correspond to any message track ids for you, receipt may not correspond to any message
in that case, you should discard it. */ in that case, you should discard it. */
void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void*), void* userdata); void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void *), void *userdata);
/* set the callback for connection status changes /* set the callback for connection status changes
function(int friendnumber, uint8_t status) function(int friendnumber, uint8_t status)
@ -296,12 +300,12 @@ void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, u
note that this callback is not called when adding friends, thus the "after note that this callback is not called when adding friends, thus the "after
being previously online" part. it's assumed that when adding friends, being previously online" part. it's assumed that when adding friends,
their connection status is offline. */ their connection status is offline. */
void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void*), void* userdata); void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void *), void *userdata);
/* run this at startup /* run this at startup
* returns allocated instance of Messenger on success * returns allocated instance of Messenger on success
* returns 0 if there are problems */ * returns 0 if there are problems */
Messenger * initMessenger(void); Messenger *initMessenger(void);
/* run this before closing shop /* run this before closing shop
* free all datastructures */ * free all datastructures */

View File

@ -31,16 +31,17 @@ uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
return -1 if failure. return -1 if failure.
return 0 if it sent the friend request directly to the friend. return 0 if it sent the friend request directly to the friend.
return the number of peers it was routed through if it did not send it directly.*/ return the number of peers it was routed through if it did not send it directly.*/
int send_friendrequest(uint8_t * public_key, uint32_t nospam_num, uint8_t * data, uint32_t length) int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
{ {
if(length + sizeof(nospam_num) > MAX_DATA_SIZE) if (length + sizeof(nospam_num) > MAX_DATA_SIZE)
return -1; return -1;
uint8_t temp[MAX_DATA_SIZE]; uint8_t temp[MAX_DATA_SIZE];
memcpy(temp, &nospam_num, sizeof(nospam_num)); memcpy(temp, &nospam_num, sizeof(nospam_num));
memcpy(temp + sizeof(nospam_num), data, length); memcpy(temp + sizeof(nospam_num), data, length);
uint8_t packet[MAX_DATA_SIZE]; uint8_t packet[MAX_DATA_SIZE];
int len = create_request(packet, public_key, temp, length + sizeof(nospam_num), 32); /* 32 is friend request packet id */ int len = create_request(packet, public_key, temp, length + sizeof(nospam_num),
32); /* 32 is friend request packet id */
if (len == -1) if (len == -1)
return -1; return -1;
@ -53,6 +54,7 @@ int send_friendrequest(uint8_t * public_key, uint32_t nospam_num, uint8_t * data
if (ip_port.ip.i != 0) { if (ip_port.ip.i != 0) {
if (sendpacket(ip_port, packet, len) != -1) if (sendpacket(ip_port, packet, len) != -1)
return 0; return 0;
return -1; return -1;
} }
@ -78,11 +80,11 @@ uint32_t get_nospam()
return nospam; return nospam;
} }
static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void*); static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void *);
static uint8_t handle_friendrequest_isset = 0; static uint8_t handle_friendrequest_isset = 0;
static void* handle_friendrequest_userdata; static void *handle_friendrequest_userdata;
/* set the function that will be executed when a friend request is received. */ /* set the function that will be executed when a friend request is received. */
void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata) void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
{ {
handle_friendrequest = function; handle_friendrequest = function;
handle_friendrequest_isset = 1; handle_friendrequest_isset = 1;
@ -99,7 +101,7 @@ static uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES]
static uint16_t received_requests_index; static uint16_t received_requests_index;
/*Add to list of received friend requests*/ /*Add to list of received friend requests*/
static void addto_receivedlist(uint8_t * client_id) static void addto_receivedlist(uint8_t *client_id)
{ {
if (received_requests_index >= MAX_RECEIVED_STORED) if (received_requests_index >= MAX_RECEIVED_STORED)
received_requests_index = 0; received_requests_index = 0;
@ -110,7 +112,7 @@ static void addto_receivedlist(uint8_t * client_id)
/* Check if a friend request was already received /* Check if a friend request was already received
return 0 if not, 1 if we did */ return 0 if not, 1 if we did */
static int request_received(uint8_t * client_id) static int request_received(uint8_t *client_id)
{ {
uint32_t i; uint32_t i;
@ -123,14 +125,17 @@ static int request_received(uint8_t * client_id)
} }
static int friendreq_handlepacket(IP_Port source, uint8_t * source_pubkey, uint8_t * packet, uint32_t length) static int friendreq_handlepacket(IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
{ {
if (handle_friendrequest_isset == 0) if (handle_friendrequest_isset == 0)
return 1; return 1;
if (length <= sizeof(nospam)) if (length <= sizeof(nospam))
return 1; return 1;
if (request_received(source_pubkey)) if (request_received(source_pubkey))
return 1; return 1;
if (memcmp(packet, &nospam, sizeof(nospam)) != 0) if (memcmp(packet, &nospam, sizeof(nospam)) != 0)
return 1; return 1;

View File

@ -33,7 +33,7 @@ extern "C" {
/* Try to send a friendrequest to peer with public_key /* Try to send a friendrequest to peer with public_key
data is the data in the request and length is the length. */ data is the data in the request and length is the length. */
int send_friendrequest(uint8_t * public_key, uint32_t nospam_num, uint8_t * data, uint32_t length); int send_friendrequest(uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
/* /*
* Set and get the nospam variable used to prevent one type of friend request spam * Set and get the nospam variable used to prevent one type of friend request spam
*/ */
@ -42,7 +42,7 @@ uint32_t get_nospam();
/* set the function that will be executed when a friend request for us is received. /* set the function that will be executed when a friend request for us is received.
function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata); void callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata);
/* sets up friendreq packet handlers */ /* sets up friendreq packet handlers */
void friendreq_init(void); void friendreq_init(void);

View File

@ -65,14 +65,16 @@ uint8_t crypto_iszero(uint8_t *mem, uint32_t length)
{ {
uint8_t check = 0; uint8_t check = 0;
uint32_t i; uint32_t i;
for (i = 0; i < length; ++i) { for (i = 0; i < length; ++i) {
check |= mem[i]; check |= mem[i];
} }
return check; // We return zero if mem is made out of zeroes. return check; // We return zero if mem is made out of zeroes.
} }
/* Precomputes the shared key from their public_key and our secret_key. /* Precomputes the shared key from their public_key and our secret_key.
This way we can avoid an expensive elliptic curve scalar multiply for each This way we can avoid an expensive elliptic curve scalar multiply for each
encrypt/decrypt operation. encrypt/decrypt operation.
enc_key has to be crypto_box_BEFORENMBYTES bytes long. */ enc_key has to be crypto_box_BEFORENMBYTES bytes long. */
void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key) void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key)
@ -81,7 +83,7 @@ void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_k
} }
/* Fast encrypt. Depends on enc_key from encrypt_precompute. */ /* Fast encrypt. Depends on enc_key from encrypt_precompute. */
int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
uint8_t *plain, uint32_t length, uint8_t *encrypted) uint8_t *plain, uint32_t length, uint8_t *encrypted)
{ {
if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0) if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0)
@ -94,7 +96,7 @@ int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key); crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key);
if(crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0) if (crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0)
return -1; return -1;
/* unpad the encrypted message */ /* unpad the encrypted message */
@ -118,9 +120,9 @@ int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
nonce, enc_key) == -1) nonce, enc_key) == -1)
return -1; return -1;
/* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero /* if decryption is successful the first crypto_box_ZEROBYTES of the message will be zero
apparently memcmp should not be used so we do this instead:*/ apparently memcmp should not be used so we do this instead:*/
if(crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0) if (crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0)
return -1; return -1;
/* unpad the plain message */ /* unpad the plain message */
@ -148,9 +150,11 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
static void increment_nonce(uint8_t *nonce) static void increment_nonce(uint8_t *nonce)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < crypto_box_NONCEBYTES; ++i) { for (i = 0; i < crypto_box_NONCEBYTES; ++i) {
++nonce[i]; ++nonce[i];
if(nonce[i] != 0)
if (nonce[i] != 0)
break; break;
} }
} }
@ -159,6 +163,7 @@ static void increment_nonce(uint8_t *nonce)
void random_nonce(uint8_t *nonce) void random_nonce(uint8_t *nonce)
{ {
uint32_t i, temp; uint32_t i, temp;
for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) { for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) {
temp = random_int(); temp = random_int();
memcpy(nonce + 4 * i, &temp, 4); memcpy(nonce + 4 * i, &temp, 4);
@ -172,21 +177,28 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
{ {
if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
return 0; return 0;
if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
return 0; return 0;
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data);
if (length == 0) if (length == 0)
return 0; return 0;
if (temp_data[0] != 3) if (temp_data[0] != 3)
return -1; return -1;
int len = decrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, int len = decrypt_data_fast(crypto_connections[crypt_connection_id].shared_key,
crypto_connections[crypt_connection_id].recv_nonce, crypto_connections[crypt_connection_id].recv_nonce,
temp_data + 1, length - 1, data); temp_data + 1, length - 1, data);
if (len != -1) { if (len != -1) {
increment_nonce(crypto_connections[crypt_connection_id].recv_nonce); increment_nonce(crypto_connections[crypt_connection_id].recv_nonce);
return len; return len;
} }
return -1; return -1;
} }
@ -196,19 +208,26 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length)
{ {
if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
return 0; return 0;
if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
return 0; return 0;
if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED) if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
return 0; return 0;
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
int len = encrypt_data_fast(crypto_connections[crypt_connection_id].shared_key, int len = encrypt_data_fast(crypto_connections[crypt_connection_id].shared_key,
crypto_connections[crypt_connection_id].sent_nonce, crypto_connections[crypt_connection_id].sent_nonce,
data, length, temp_data + 1); data, length, temp_data + 1);
if (len == -1) if (len == -1)
return 0; return 0;
temp_data[0] = 3; temp_data[0] = 3;
if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0) if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0)
return 0; return 0;
increment_nonce(crypto_connections[crypt_connection_id].sent_nonce); increment_nonce(crypto_connections[crypt_connection_id].sent_nonce);
return 1; return 1;
} }
@ -223,6 +242,7 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
{ {
if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING)
return -1; return -1;
uint8_t nonce[crypto_box_NONCEBYTES]; uint8_t nonce[crypto_box_NONCEBYTES];
uint8_t temp[MAX_DATA_SIZE]; uint8_t temp[MAX_DATA_SIZE];
memcpy(temp + 1, data, length); memcpy(temp + 1, data, length);
@ -230,8 +250,10 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t
random_nonce(nonce); random_nonce(nonce);
int len = encrypt_data(public_key, self_secret_key, nonce, temp, length + 1, int len = encrypt_data(public_key, self_secret_key, nonce, temp, length + 1,
1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
if (len == -1) if (len == -1)
return -1; return -1;
packet[0] = 32; packet[0] = 32;
memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES);
@ -248,16 +270,19 @@ static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_i
{ {
if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING &&
length <= MAX_DATA_SIZE + ENCRYPTION_PADDING && length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
uint8_t nonce[crypto_box_NONCEBYTES]; uint8_t nonce[crypto_box_NONCEBYTES];
uint8_t temp[MAX_DATA_SIZE]; uint8_t temp[MAX_DATA_SIZE];
memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, int len1 = decrypt_data(public_key, self_secret_key, nonce,
packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp);
if(len1 == -1 || len1 == 0)
if (len1 == -1 || len1 == 0)
return -1; return -1;
request_id[0] = temp[0]; request_id[0] = temp[0];
--len1; --len1;
memcpy(data, temp + 1, len1); memcpy(data, temp + 1, len1);
@ -273,27 +298,32 @@ void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb
cryptopackethandlers[byte] = cb; cryptopackethandlers[byte] = cb;
} }
static int cryptopacket_handle(IP_Port source, uint8_t * packet, uint32_t length) static int cryptopacket_handle(IP_Port source, uint8_t *packet, uint32_t length)
{ {
if (packet[0] == 32) { if (packet[0] == 32) {
if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING ||
length > MAX_DATA_SIZE + ENCRYPTION_PADDING) length > MAX_DATA_SIZE + ENCRYPTION_PADDING)
return 1; return 1;
if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us.
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t data[MAX_DATA_SIZE]; uint8_t data[MAX_DATA_SIZE];
uint8_t number; uint8_t number;
int len = handle_request(public_key, data, &number, packet, length); int len = handle_request(public_key, data, &number, packet, length);
if (len == -1 || len == 0) if (len == -1 || len == 0)
return 1; return 1;
if (!cryptopackethandlers[number]) return 1; if (!cryptopackethandlers[number]) return 1;
cryptopackethandlers[number](source, public_key, data, len); cryptopackethandlers[number](source, public_key, data, len);
} else { /* if request is not for us, try routing it. */ } else { /* if request is not for us, try routing it. */
if(route_packet(packet + 1, packet, length) == length) if (route_packet(packet + 1, packet, length) == length)
return 0; return 0;
} }
} }
return 1; return 1;
} }
@ -312,8 +342,10 @@ static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t
int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, int len = encrypt_data(public_key, self_secret_key, nonce, temp, crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data); 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
if (len == -1) if (len == -1)
return 0; return 0;
temp_data[0] = 2; temp_data[0] = 2;
memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES);
memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); memcpy(temp_data + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
@ -324,15 +356,18 @@ static int send_cryptohandshake(int connection_id, uint8_t *public_key, uint8_t
return 1 if successful return 1 if successful
return 0 if failure */ return 0 if failure */
static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce, static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
uint8_t *session_key, uint8_t *data, uint16_t length) uint8_t *session_key, uint8_t *data, uint16_t length)
{ {
int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); int pad = (- crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES);
if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES if (length != 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES
+ crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) { + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + pad) {
return 0; return 0;
} }
if (data[0] != 2) if (data[0] != 2)
return 0; return 0;
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES]; uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES); memcpy(public_key, data + 1, crypto_box_PUBLICKEYBYTES);
@ -355,11 +390,13 @@ static int handle_cryptohandshake(uint8_t *public_key, uint8_t *secret_nonce,
static int getcryptconnection_id(uint8_t *public_key) static int getcryptconnection_id(uint8_t *public_key)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if (crypto_connections[i].status != CONN_NO_CONNECTION) if (crypto_connections[i].status != CONN_NO_CONNECTION)
if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
return i; return i;
} }
return -1; return -1;
} }
@ -370,16 +407,21 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
{ {
uint32_t i; uint32_t i;
int id = getcryptconnection_id(public_key); int id = getcryptconnection_id(public_key);
if (id != -1) { if (id != -1) {
IP_Port c_ip = connection_ip(crypto_connections[id].number); IP_Port c_ip = connection_ip(crypto_connections[id].number);
if(c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port)
if (c_ip.ip.i == ip_port.ip.i && c_ip.port == ip_port.port)
return -1; return -1;
} }
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if (crypto_connections[i].status == CONN_NO_CONNECTION) { if (crypto_connections[i].status == CONN_NO_CONNECTION) {
int id = new_connection(ip_port); int id = new_connection(ip_port);
if (id == -1) if (id == -1)
return -1; return -1;
crypto_connections[i].number = id; crypto_connections[i].number = id;
crypto_connections[i].status = CONN_HANDSHAKE_SENT; crypto_connections[i].status = CONN_HANDSHAKE_SENT;
random_nonce(crypto_connections[i].recv_nonce); random_nonce(crypto_connections[i].recv_nonce);
@ -391,9 +433,11 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
increment_nonce(crypto_connections[i].recv_nonce); increment_nonce(crypto_connections[i].recv_nonce);
return i; return i;
} }
return -1; /* this should never happen. */ return -1; /* this should never happen. */
} }
} }
return -1; return -1;
} }
@ -407,6 +451,7 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < MAX_INCOMING; ++i) { for (i = 0; i < MAX_INCOMING; ++i) {
if (incoming_connections[i] != -1) { if (incoming_connections[i] != -1) {
if (is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) { if (is_connected(incoming_connections[i]) == 4 || is_connected(incoming_connections[i]) == 0) {
@ -414,9 +459,11 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_
incoming_connections[i] = -1; incoming_connections[i] = -1;
continue; continue;
} }
if (id_packet(incoming_connections[i]) == 2) { if (id_packet(incoming_connections[i]) == 2) {
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
uint16_t len = read_packet(incoming_connections[i], temp_data); uint16_t len = read_packet(incoming_connections[i], temp_data);
if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) {
int connection_id = incoming_connections[i]; int connection_id = incoming_connections[i];
incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */ incoming_connections[i] = -1; /* remove this connection from the incoming connection list. */
@ -425,6 +472,7 @@ int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_
} }
} }
} }
return -1; return -1;
} }
@ -435,13 +483,15 @@ int crypto_kill(int crypt_connection_id)
{ {
if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
return 1; return 1;
if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) { if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) {
crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION; crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION;
kill_connection(crypto_connections[crypt_connection_id].number); kill_connection(crypto_connections[crypt_connection_id].number);
memset(&crypto_connections[crypt_connection_id], 0 ,sizeof(Crypto_Connection)); memset(&crypto_connections[crypt_connection_id], 0 , sizeof(Crypto_Connection));
crypto_connections[crypt_connection_id].number = ~0; crypto_connections[crypt_connection_id].number = ~0;
return 0; return 0;
} }
return 1; return 1;
} }
@ -451,15 +501,17 @@ int crypto_kill(int crypt_connection_id)
int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key) int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key)
{ {
uint32_t i; uint32_t i;
if (connection_id == -1) if (connection_id == -1)
return -1; return -1;
/* /*
if(getcryptconnection_id(public_key) != -1) if(getcryptconnection_id(public_key) != -1)
{ {
return -1; return -1;
}*/ }*/
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if(crypto_connections[i].status == CONN_NO_CONNECTION) { if (crypto_connections[i].status == CONN_NO_CONNECTION) {
crypto_connections[i].number = connection_id; crypto_connections[i].number = connection_id;
crypto_connections[i].status = CONN_NOT_CONFIRMED; crypto_connections[i].status = CONN_NOT_CONFIRMED;
random_nonce(crypto_connections[i].recv_nonce); random_nonce(crypto_connections[i].recv_nonce);
@ -474,17 +526,19 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
crypto_connections[i].sessionpublic_key) == 1) { crypto_connections[i].sessionpublic_key) == 1) {
increment_nonce(crypto_connections[i].recv_nonce); increment_nonce(crypto_connections[i].recv_nonce);
uint32_t zero = 0; uint32_t zero = 0;
encrypt_precompute(crypto_connections[i].peersessionpublic_key, encrypt_precompute(crypto_connections[i].peersessionpublic_key,
crypto_connections[i].sessionsecret_key, crypto_connections[i].sessionsecret_key,
crypto_connections[i].shared_key); crypto_connections[i].shared_key);
crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ 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)); write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */ crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */
return i; return i;
} }
return -1; /* this should never happen. */ return -1; /* this should never happen. */
} }
} }
return -1; return -1;
} }
@ -495,6 +549,7 @@ int is_cryptoconnected(int crypt_connection_id)
{ {
if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS)
return crypto_connections[crypt_connection_id].status; return crypto_connections[crypt_connection_id].status;
return CONN_NO_CONNECTION; return CONN_NO_CONNECTION;
} }
@ -502,7 +557,7 @@ int is_cryptoconnected(int crypt_connection_id)
Only call this function the first time the program starts. */ Only call this function the first time the program starts. */
void new_keys(void) void new_keys(void)
{ {
crypto_box_keypair(self_public_key,self_secret_key); crypto_box_keypair(self_public_key, self_secret_key);
} }
/* save the public and private keys to the keys array /* save the public and private keys to the keys array
@ -528,12 +583,14 @@ void load_keys(uint8_t *keys)
static int new_incoming(int id) static int new_incoming(int id)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < MAX_INCOMING; ++i) { for (i = 0; i < MAX_INCOMING; ++i) {
if (incoming_connections[i] == -1) { if (incoming_connections[i] == -1) {
incoming_connections[i] = id; incoming_connections[i] = id;
return 0; return 0;
} }
} }
return 1; return 1;
} }
@ -542,9 +599,11 @@ static int new_incoming(int id)
static void handle_incomings(void) static void handle_incomings(void)
{ {
int income; int income;
while (1) { while (1) {
income = incoming_connection(); income = incoming_connection();
if(income == -1 || new_incoming(income) )
if (income == -1 || new_incoming(income) )
break; break;
} }
} }
@ -553,6 +612,7 @@ static void handle_incomings(void)
static void receive_crypto(void) static void receive_crypto(void)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) { if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) {
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
@ -560,19 +620,22 @@ static void receive_crypto(void)
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES]; uint8_t session_key[crypto_box_PUBLICKEYBYTES];
uint16_t len; uint16_t len;
if (id_packet(crypto_connections[i].number) == 1) if (id_packet(crypto_connections[i].number) == 1)
/* if the packet is a friend request drop it (because we are already friends) */ /* if the packet is a friend request drop it (because we are already friends) */
len = read_packet(crypto_connections[i].number, temp_data); len = read_packet(crypto_connections[i].number, temp_data);
if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */ if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */
len = read_packet(crypto_connections[i].number, temp_data); len = read_packet(crypto_connections[i].number, temp_data);
if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) { 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) { 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].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
increment_nonce(crypto_connections[i].sent_nonce); increment_nonce(crypto_connections[i].sent_nonce);
uint32_t zero = 0; uint32_t zero = 0;
encrypt_precompute(crypto_connections[i].peersessionpublic_key, encrypt_precompute(crypto_connections[i].peersessionpublic_key,
crypto_connections[i].sessionsecret_key, crypto_connections[i].sessionsecret_key,
crypto_connections[i].shared_key); crypto_connections[i].shared_key);
crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */ 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)); write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
@ -583,6 +646,7 @@ static void receive_crypto(void)
crypto_kill(crypto_connections[i].number); crypto_kill(crypto_connections[i].number);
} }
if (crypto_connections[i].status == CONN_NOT_CONFIRMED) { if (crypto_connections[i].status == CONN_NOT_CONFIRMED) {
if (id_packet(crypto_connections[i].number) == 3) { if (id_packet(crypto_connections[i].number) == 3) {
uint8_t temp_data[MAX_DATA_SIZE]; uint8_t temp_data[MAX_DATA_SIZE];
@ -592,10 +656,11 @@ static void receive_crypto(void)
crypto_connections[i].sessionsecret_key, crypto_connections[i].sessionsecret_key,
crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data); crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data);
uint32_t zero = 0; uint32_t zero = 0;
if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
increment_nonce(crypto_connections[i].recv_nonce); increment_nonce(crypto_connections[i].recv_nonce);
encrypt_precompute(crypto_connections[i].peersessionpublic_key, encrypt_precompute(crypto_connections[i].peersessionpublic_key,
crypto_connections[i].sessionsecret_key, crypto_connections[i].sessionsecret_key,
crypto_connections[i].shared_key); crypto_connections[i].shared_key);
crypto_connections[i].status = CONN_ESTABLISHED; crypto_connections[i].status = CONN_ESTABLISHED;
@ -603,7 +668,7 @@ static void receive_crypto(void)
kill_connection_in(crypto_connections[i].number, 3000000); kill_connection_in(crypto_connections[i].number, 3000000);
} else } else
crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does 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) } else if (id_packet(crypto_connections[i].number) != -1)
/* This should not happen /* This should not happen
kill the connection if it does */ kill the connection if it does */
crypto_kill(crypto_connections[i].number); crypto_kill(crypto_connections[i].number);
@ -615,10 +680,11 @@ static void receive_crypto(void)
sets all the global connection variables to their default values. */ sets all the global connection variables to their default values. */
void initNetCrypto(void) void initNetCrypto(void)
{ {
memset(crypto_connections, 0 ,sizeof(crypto_connections)); memset(crypto_connections, 0 , sizeof(crypto_connections));
memset(incoming_connections, -1 ,sizeof(incoming_connections)); memset(incoming_connections, -1 , sizeof(incoming_connections));
networking_registerhandler(32, &cryptopacket_handle); networking_registerhandler(32, &cryptopacket_handle);
uint32_t i; uint32_t i;
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i)
crypto_connections[i].number = ~0; crypto_connections[i].number = ~0;
} }
@ -626,6 +692,7 @@ void initNetCrypto(void)
static void killTimedout(void) static void killTimedout(void)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4) if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4)
crypto_connections[i].status = CONN_TIMED_OUT; crypto_connections[i].status = CONN_TIMED_OUT;

View File

@ -38,14 +38,14 @@ extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) #define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
/* returns zero if the buffer contains only zeros */ /* returns zero if the buffer contains only zeros */
uint8_t crypto_iszero(uint8_t* buffer, uint32_t blen); uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen);
/* encrypts plain of length length to encrypted of length + 16 using the /* encrypts plain of length length to encrypted of length + 16 using the
public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce
return -1 if there was a problem. return -1 if there was a problem.
return length of encrypted data if everything was fine. */ return length of encrypted data if everything was fine. */
int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
uint8_t *plain, uint32_t length, uint8_t *encrypted); uint8_t *plain, uint32_t length, uint8_t *encrypted);
/* decrypts encrypted of length length to plain of length length - 16 using the /* decrypts encrypted of length length to plain of length length - 16 using the
@ -53,15 +53,15 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
return -1 if there was a problem(decryption failed) return -1 if there was a problem(decryption failed)
return length of plain data if everything was fine. */ return length of plain data if everything was fine. */
int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
uint8_t *encrypted, uint32_t length, uint8_t *plain); uint8_t *encrypted, uint32_t length, uint8_t *plain);
/* Fast encrypt/decrypt operations. Use if this is not a one-time communication. /* Fast encrypt/decrypt operations. Use if this is not a one-time communication.
encrypt_precompute does the shared-key generation once so it does not have encrypt_precompute does the shared-key generation once so it does not have
to be preformed on every encrypt/decrypt. */ to be preformed on every encrypt/decrypt. */
void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key); void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key);
/* Fast encrypt. Depends on enc_key from encrypt_precompute. */ /* Fast encrypt. Depends on enc_key from encrypt_precompute. */
int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
uint8_t *plain, uint32_t length, uint8_t *encrypted); uint8_t *plain, uint32_t length, uint8_t *encrypted);
/* Fast decrypt. Depends on enc_ley from encrypt_precompute. */ /* Fast decrypt. Depends on enc_ley from encrypt_precompute. */
@ -87,10 +87,10 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length);
request_id is the id of the request (32 = friend request, 254 = ping request) request_id is the id of the request (32 = friend request, 254 = ping request)
returns -1 on failure returns -1 on failure
returns the length of the created packet on success */ returns the length of the created packet on success */
int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id);
typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t * source_pubkey, uint8_t *data, uint32_t len); typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
/* Function to call when request beginning with byte is received */ /* Function to call when request beginning with byte is received */
void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb); void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb);
@ -111,12 +111,12 @@ int crypto_kill(int crypt_connection_id);
and the session public key for the connection in session_key and the session public key for the connection in session_key
to accept it see: accept_crypto_inbound(...) to accept it see: accept_crypto_inbound(...)
to refuse it just call kill_connection(...) on the connection id */ to refuse it just call kill_connection(...) on the connection id */
int crypto_inbound(uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); int crypto_inbound(uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key);
/* accept an incoming connection using the parameters provided by crypto_inbound /* accept an incoming connection using the parameters provided by crypto_inbound
return -1 if not successful return -1 if not successful
returns the crypt_connection_id if successful */ returns the crypt_connection_id if successful */
int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t * secret_nonce, uint8_t *session_key); int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secret_nonce, uint8_t *session_key);
/* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet /* return 0 if no connection, 1 we have sent a handshake, 2 if connexion is not confirmed yet
(we have received a handshake but no empty data packet), 3 if the connection is established. (we have received a handshake but no empty data packet), 3 if the connection is established.
@ -130,11 +130,11 @@ void new_keys(void);
/* save the public and private keys to the keys array /* save the public and private keys to the keys array
Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
void save_keys(uint8_t * keys); void save_keys(uint8_t *keys);
/* load the public and private keys from the keys array /* load the public and private keys from the keys array
Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */ Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES */
void load_keys(uint8_t * keys); void load_keys(uint8_t *keys);
/* run this to (re)initialize net_crypto /* run this to (re)initialize net_crypto
sets all the global connection variables to their default values. */ sets all the global connection variables to their default values. */

View File

@ -32,14 +32,14 @@ uint64_t current_time(void)
FILETIME ft; FILETIME ft;
GetSystemTimeAsFileTime(&ft); GetSystemTimeAsFileTime(&ft);
time = ft.dwHighDateTime; time = ft.dwHighDateTime;
time <<=32; time <<= 32;
time |= ft.dwLowDateTime; time |= ft.dwLowDateTime;
time -= 116444736000000000UL; time -= 116444736000000000UL;
return time/10; return time / 10;
#else #else
struct timeval a; struct timeval a;
gettimeofday(&a, NULL); gettimeofday(&a, NULL);
time = 1000000UL*a.tv_sec + a.tv_usec; time = 1000000UL * a.tv_sec + a.tv_usec;
return time; return time;
#endif #endif
} }
@ -61,17 +61,17 @@ static int sock;
/* Basic network functions: /* Basic network functions:
Function to send packet(data) of length length to ip_port */ Function to send packet(data) of length length to ip_port */
int sendpacket(IP_Port ip_port, uint8_t * data, uint32_t length) int sendpacket(IP_Port ip_port, uint8_t *data, uint32_t length)
{ {
ADDR addr = {AF_INET, ip_port.port, ip_port.ip}; ADDR addr = {AF_INET, ip_port.port, ip_port.ip};
return sendto(sock,(char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); return sendto(sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr));
} }
/* Function to receive data, ip and port of sender is put into ip_port /* Function to receive data, ip and port of sender is put into ip_port
the packet data into data the packet data into data
the packet length into length. the packet length into length.
dump all empty packets. */ dump all empty packets. */
static int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length) static int receivepacket(IP_Port *ip_port, uint8_t *data, uint32_t *length)
{ {
ADDR addr; ADDR addr;
#ifdef WIN32 #ifdef WIN32
@ -79,8 +79,9 @@ static int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
#else #else
uint32_t addrlen = sizeof(addr); uint32_t addrlen = sizeof(addr);
#endif #endif
(*(int32_t*)length) = recvfrom(sock,(char*) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addrlen); (*(int32_t *)length) = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
if (*(int32_t*)length <= 0)
if (*(int32_t *)length <= 0)
return -1; /* nothing received or empty packet */ return -1; /* nothing received or empty packet */
ip_port->ip = addr.ip; ip_port->ip = addr.ip;
@ -100,11 +101,12 @@ void networking_poll()
IP_Port ip_port; IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; uint32_t length;
while (receivepacket(&ip_port, data, &length) != -1) while (receivepacket(&ip_port, data, &length) != -1) {
{
if (length < 1) continue; if (length < 1) continue;
if (!packethandlers[data[0]]) continue; if (!packethandlers[data[0]]) continue;
packethandlers[data[0]](ip_port, data, length); packethandlers[data[0]](ip_port, data, length);
} }
} }
@ -119,8 +121,10 @@ int init_networking(IP ip, uint16_t port)
{ {
#ifdef WIN32 #ifdef WIN32
WSADATA wsaData; WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR)
return -1; return -1;
#else #else
srandom((uint32_t)current_time()); srandom((uint32_t)current_time());
#endif #endif
@ -131,11 +135,15 @@ int init_networking(IP ip, uint16_t port)
/* Check for socket error */ /* Check for socket error */
#ifdef WIN32 #ifdef WIN32
if (sock == INVALID_SOCKET) /* MSDN recommends this */ if (sock == INVALID_SOCKET) /* MSDN recommends this */
return -1; return -1;
#else #else
if (sock < 0) if (sock < 0)
return -1; return -1;
#endif #endif
/* Functions to increase the size of the send and receive UDP buffers /* Functions to increase the size of the send and receive UDP buffers
@ -153,7 +161,7 @@ int init_networking(IP ip, uint16_t port)
/* Enable broadcast on socket */ /* Enable broadcast on socket */
int broadcast = 1; int broadcast = 1;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast)); setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast));
/* Set socket nonblocking */ /* Set socket nonblocking */
#ifdef WIN32 #ifdef WIN32
@ -167,7 +175,7 @@ int init_networking(IP ip, uint16_t port)
/* Bind our socket to port PORT and address 0.0.0.0 */ /* Bind our socket to port PORT and address 0.0.0.0 */
ADDR addr = {AF_INET, htons(port), ip}; ADDR addr = {AF_INET, htons(port), ip};
bind(sock, (struct sockaddr*)&addr, sizeof(addr)); bind(sock, (struct sockaddr *)&addr, sizeof(addr));
return 0; return 0;
} }
@ -207,18 +215,18 @@ uint32_t resolve_addr(const char *address)
rc = getaddrinfo(address, "echo", &hints, &server); rc = getaddrinfo(address, "echo", &hints, &server);
// Lookup failed. // Lookup failed.
if(rc != 0) { if (rc != 0) {
return 0; return 0;
} }
// IPv4 records only.. // IPv4 records only..
if(server->ai_family != AF_INET) { if (server->ai_family != AF_INET) {
freeaddrinfo(server); freeaddrinfo(server);
return 0; return 0;
} }
addr = ((struct sockaddr_in*)server->ai_addr)->sin_addr.s_addr;
addr = ((struct sockaddr_in *)server->ai_addr)->sin_addr.s_addr;
freeaddrinfo(server); freeaddrinfo(server);
return addr; return addr;

View File

@ -26,7 +26,7 @@ typedef struct {
static pinged_t pings[PING_NUM_MAX]; static pinged_t pings[PING_NUM_MAX];
static size_t num_pings; static size_t num_pings;
static size_t pos_pings; static size_t pos_pings;
static clientid_t* self_id = (clientid_t*) &self_public_key; static clientid_t *self_id = (clientid_t *) &self_public_key;
extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c
@ -48,10 +48,10 @@ static void remove_timeouts() // O(n)
size_t new_num = num_pings; size_t new_num = num_pings;
// Loop through buffer, oldest first // Loop through buffer, oldest first
for (i=0; i<num_pings; i++) { for (i = 0; i < num_pings; i++) {
id = (pos_pings + i) % PING_NUM_MAX; id = (pos_pings + i) % PING_NUM_MAX;
if(is_timeout(pings[id].timestamp)) { if (is_timeout(pings[id].timestamp)) {
new_pos++; new_pos++;
new_num--; new_num--;
} }
@ -92,12 +92,12 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with
{ {
if (ipp.ip.i == 0 && ping_id == 0) if (ipp.ip.i == 0 && ping_id == 0)
return false; return false;
size_t i, id; size_t i, id;
remove_timeouts(); remove_timeouts();
for (i=0; i<num_pings; i++) { for (i = 0; i < num_pings; i++) {
id = (pos_pings + i) % PING_NUM_MAX; id = (pos_pings + i) % PING_NUM_MAX;
// ping_id = 0 means match any id // ping_id = 0 means match any id
@ -109,7 +109,7 @@ bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with
return false; return false;
} }
int send_ping_request(IP_Port ipp, clientid_t* client_id) int send_ping_request(IP_Port ipp, clientid_t *client_id)
{ {
pingreq_t pk; pingreq_t pk;
int rc; int rc;
@ -123,22 +123,22 @@ int send_ping_request(IP_Port ipp, clientid_t* client_id)
pk.magic = PACKET_PING_REQ; pk.magic = PACKET_PING_REQ;
id_cpy(&pk.client_id, self_id); // Our pubkey id_cpy(&pk.client_id, self_id); // Our pubkey
random_nonce((uint8_t*) &pk.nonce); // Generate random nonce random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
// Encrypt ping_id using recipient privkey // Encrypt ping_id using recipient privkey
rc = encrypt_data((uint8_t*) client_id, rc = encrypt_data((uint8_t *) client_id,
self_secret_key, self_secret_key,
(uint8_t*) &pk.nonce, (uint8_t *) &pk.nonce,
(uint8_t*) &ping_id, sizeof(ping_id), (uint8_t *) &ping_id, sizeof(ping_id),
(uint8_t*) &pk.ping_id); (uint8_t *) &pk.ping_id);
if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
return 1; return 1;
return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk));
} }
int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id) int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id)
{ {
pingres_t pk; pingres_t pk;
int rc; int rc;
@ -148,24 +148,24 @@ int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id)
pk.magic = PACKET_PING_RES; pk.magic = PACKET_PING_RES;
id_cpy(&pk.client_id, self_id); // Our pubkey id_cpy(&pk.client_id, self_id); // Our pubkey
random_nonce((uint8_t*) &pk.nonce); // Generate random nonce random_nonce((uint8_t *) &pk.nonce); // Generate random nonce
// Encrypt ping_id using recipient privkey // Encrypt ping_id using recipient privkey
rc = encrypt_data((uint8_t*) client_id, rc = encrypt_data((uint8_t *) client_id,
self_secret_key, self_secret_key,
(uint8_t*) &pk.nonce, (uint8_t *) &pk.nonce,
(uint8_t*) &ping_id, sizeof(ping_id), (uint8_t *) &ping_id, sizeof(ping_id),
(uint8_t*) &pk.ping_id); (uint8_t *) &pk.ping_id);
if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
return 1; return 1;
return sendpacket(ipp, (uint8_t*) &pk, sizeof(pk)); return sendpacket(ipp, (uint8_t *) &pk, sizeof(pk));
} }
int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length) int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length)
{ {
pingreq_t* p = (pingreq_t*) packet; pingreq_t *p = (pingreq_t *) packet;
int rc; int rc;
uint64_t ping_id; uint64_t ping_id;
@ -173,26 +173,26 @@ int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length)
return 1; return 1;
// Decrypt ping_id // Decrypt ping_id
rc = decrypt_data((uint8_t*) &p->client_id, rc = decrypt_data((uint8_t *) &p->client_id,
self_secret_key, self_secret_key,
(uint8_t*) &p->nonce, (uint8_t *) &p->nonce,
(uint8_t*) &p->ping_id, (uint8_t *) &p->ping_id,
sizeof(ping_id) + ENCRYPTION_PADDING, sizeof(ping_id) + ENCRYPTION_PADDING,
(uint8_t*) &ping_id); (uint8_t *) &ping_id);
if (rc != sizeof(ping_id)) if (rc != sizeof(ping_id))
return 1; return 1;
// Send response // Send response
send_ping_response(source, &p->client_id, ping_id); send_ping_response(source, &p->client_id, ping_id);
add_toping((uint8_t*) &p->client_id, source); add_toping((uint8_t *) &p->client_id, source);
return 0; return 0;
} }
int handle_ping_response(IP_Port source, uint8_t* packet, uint32_t length) int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length)
{ {
pingres_t* p = (pingres_t*) packet; pingres_t *p = (pingres_t *) packet;
int rc; int rc;
uint64_t ping_id; uint64_t ping_id;
@ -200,21 +200,21 @@ int handle_ping_response(IP_Port source, uint8_t* packet, uint32_t length)
return 1; return 1;
// Decrypt ping_id // Decrypt ping_id
rc = decrypt_data((uint8_t*) &p->client_id, rc = decrypt_data((uint8_t *) &p->client_id,
self_secret_key, self_secret_key,
(uint8_t*) &p->nonce, (uint8_t *) &p->nonce,
(uint8_t*) &p->ping_id, (uint8_t *) &p->ping_id,
sizeof(ping_id) + ENCRYPTION_PADDING, sizeof(ping_id) + ENCRYPTION_PADDING,
(uint8_t*) &ping_id); (uint8_t *) &ping_id);
if (rc != sizeof(ping_id)) if (rc != sizeof(ping_id))
return 1; return 1;
// Make sure ping_id is correct // Make sure ping_id is correct
if(!is_pinging(source, ping_id)) if (!is_pinging(source, ping_id))
return 1; return 1;
// Associate source ip with client_id // Associate source ip with client_id
addto_lists(source, (uint8_t*) &p->client_id); addto_lists(source, (uint8_t *) &p->client_id);
return 0; return 0;
} }

View File

@ -10,7 +10,7 @@
void init_ping(); void init_ping();
uint64_t add_ping(IP_Port ipp); uint64_t add_ping(IP_Port ipp);
bool is_pinging(IP_Port ipp, uint64_t ping_id); bool is_pinging(IP_Port ipp, uint64_t ping_id);
int send_ping_request(IP_Port ipp, clientid_t* client_id); int send_ping_request(IP_Port ipp, clientid_t *client_id);
int send_ping_response(IP_Port ipp, clientid_t* client_id, uint64_t ping_id); int send_ping_response(IP_Port ipp, clientid_t *client_id, uint64_t ping_id);
int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length); int handle_ping_request(IP_Port source, uint8_t *packet, uint32_t length);
int handle_ping_response(IP_Port source, uint8_t* packet, uint32_t length); int handle_ping_response(IP_Port source, uint8_t *packet, uint32_t length);

View File

@ -4,7 +4,7 @@
#include "timer.h" #include "timer.h"
#include "network.h" #include "network.h"
/* /*
A nested linked list increases efficiency of insertions. A nested linked list increases efficiency of insertions.
Depending on the number of timers we have, we might need to have nested linked lists Depending on the number of timers we have, we might need to have nested linked lists
in order to improve insertion efficiency. in order to improve insertion efficiency.
@ -46,35 +46,37 @@ enum timer_state {
STATE_CALLBACK STATE_CALLBACK
}; };
struct timer struct timer {
{
enum timer_state state; enum timer_state state;
timer* _prev; timer *_prev;
timer* _next; timer *_next;
timer_callback cb; timer_callback cb;
void* userdata; void *userdata;
uint64_t deadline; uint64_t deadline;
}; };
static timer* timer_main_queue; static timer *timer_main_queue;
static timer* timer_us_queue; /* hi-speed queue */ static timer *timer_us_queue; /* hi-speed queue */
inline static void timer_dequeue(timer* t, timer** queue) inline static void timer_dequeue(timer *t, timer **queue)
{ {
if (t->state == STATE_INACTIVE) return; /* not in a queue */ if (t->state == STATE_INACTIVE) return; /* not in a queue */
if (t->_prev) { if (t->_prev) {
t->_prev->_next = t->_next; t->_prev->_next = t->_next;
} else { } else {
*queue = t->_next; *queue = t->_next;
} }
if (t->_next) t->_next->_prev = t->_prev; if (t->_next) t->_next->_prev = t->_prev;
t->state = STATE_INACTIVE; t->state = STATE_INACTIVE;
} }
static void timer_enqueue(timer* t, timer** queue, timer* prev) static void timer_enqueue(timer *t, timer **queue, timer *prev)
{ {
t->state = STATE_ACTIVE; t->state = STATE_ACTIVE;
while (true) { while (true) {
if (!*queue) { if (!*queue) {
t->_next = 0; t->_next = 0;
@ -104,22 +106,24 @@ void timer_init()
} }
/* Do not depend on fields being zeroed */ /* Do not depend on fields being zeroed */
static timer* timer_pool; /* timer_pool is SINGLY LINKED!! */ static timer *timer_pool; /* timer_pool is SINGLY LINKED!! */
timer* new_timer(void) timer *new_timer(void)
{ {
timer* ret; timer *ret;
if (timer_pool) { if (timer_pool) {
ret = timer_pool; ret = timer_pool;
timer_pool = timer_pool->_next; timer_pool = timer_pool->_next;
} else { } else {
ret = calloc(1, sizeof(struct timer)); ret = calloc(1, sizeof(struct timer));
} }
ret->state = STATE_INACTIVE; ret->state = STATE_INACTIVE;
return ret; return ret;
} }
void delete_timer(timer* t) void delete_timer(timer *t)
{ {
timer_dequeue(t, &timer_main_queue); timer_dequeue(t, &timer_main_queue);
t->_next = timer_pool; t->_next = timer_pool;
@ -127,93 +131,99 @@ void delete_timer(timer* t)
timer_pool = t; timer_pool = t;
} }
void timer_setup(timer* t, timer_callback cb, void* userarg) void timer_setup(timer *t, timer_callback cb, void *userarg)
{ {
t->cb = cb; t->cb = cb;
t->userdata = userarg; t->userdata = userarg;
} }
void* timer_get_userdata(timer* t) void *timer_get_userdata(timer *t)
{ {
return t->userdata; return t->userdata;
} }
static void timer_delay_us(timer* t, int us) static void timer_delay_us(timer *t, int us)
{ {
t->deadline += us; t->deadline += us;
timer** queue = t->_prev ? &(t->_prev->_next) : &timer_main_queue; timer **queue = t->_prev ? &(t->_prev->_next) : &timer_main_queue;
timer_dequeue(t, &timer_main_queue); timer_dequeue(t, &timer_main_queue);
timer_enqueue(t, queue, t->_prev); timer_enqueue(t, queue, t->_prev);
} }
/* Starts the timer so that it's called in sec seconds in the future. /* Starts the timer so that it's called in sec seconds in the future.
* A non-positive value of sec results in the callback being called immediately. * A non-positive value of sec results in the callback being called immediately.
* This function may be called again after a timer has been started to adjust * This function may be called again after a timer has been started to adjust
* the expiry time. */ * the expiry time. */
void timer_start(timer* t, int sec) void timer_start(timer *t, int sec)
{ {
uint64_t newdeadline = current_time() + sec * US_PER_SECOND; uint64_t newdeadline = current_time() + sec * US_PER_SECOND;
if (timer_is_active(t)){
if (timer_is_active(t)) {
if (t->deadline < newdeadline) { if (t->deadline < newdeadline) {
timer_delay_us(t, newdeadline - t->deadline); timer_delay_us(t, newdeadline - t->deadline);
return; return;
} }
timer_dequeue(t, &timer_main_queue); timer_dequeue(t, &timer_main_queue);
} }
t->deadline = newdeadline; t->deadline = newdeadline;
timer_enqueue(t, &timer_main_queue, 0); timer_enqueue(t, &timer_main_queue, 0);
} }
/* Stops the timer. Returns -1 if the timer was not active. */ /* Stops the timer. Returns -1 if the timer was not active. */
int timer_stop(timer* t) int timer_stop(timer *t)
{ {
int ret = timer_is_active(t) ? -1 : 0; int ret = timer_is_active(t) ? -1 : 0;
timer_dequeue(t, &timer_main_queue); timer_dequeue(t, &timer_main_queue);
return ret; return ret;
} }
/* Adds additionalsec seconds to the timer. /* Adds additionalsec seconds to the timer.
* Returns -1 and does nothing if the timer was not active. */ * Returns -1 and does nothing if the timer was not active. */
int timer_delay(timer* t, int additonalsec) int timer_delay(timer *t, int additonalsec)
{ {
if (!timer_is_active(t)) return -1; if (!timer_is_active(t)) return -1;
timer_delay_us(t, additonalsec * US_PER_SECOND); timer_delay_us(t, additonalsec * US_PER_SECOND);
return 0; return 0;
} }
static uint64_t timer_diff(timer* t, uint64_t time) static uint64_t timer_diff(timer *t, uint64_t time)
{ {
if (t->deadline <= time) return 0; if (t->deadline <= time) return 0;
return time - t->deadline; return time - t->deadline;
} }
/* Returns the time remaining on a timer in seconds. /* Returns the time remaining on a timer in seconds.
* Returns -1 if the timer is not active. * Returns -1 if the timer is not active.
* Returns 0 if the timer has expired and will be called upon the next call to timer_poll. */ * Returns 0 if the timer has expired and will be called upon the next call to timer_poll. */
int timer_time_remaining(timer* t) int timer_time_remaining(timer *t)
{ {
if (!timer_is_active(t)) return -1; if (!timer_is_active(t)) return -1;
return timer_diff(t, current_time()) / US_PER_SECOND; return timer_diff(t, current_time()) / US_PER_SECOND;
} }
bool timer_is_active(timer* t) bool timer_is_active(timer *t)
{ {
return t->state != STATE_INACTIVE; return t->state != STATE_INACTIVE;
} }
/* Single-use timer. /* Single-use timer.
* Creates a new timer, preforms setup and starts it. */ * Creates a new timer, preforms setup and starts it. */
void timer_single(timer_callback cb, void* userarg, int sec) void timer_single(timer_callback cb, void *userarg, int sec)
{ {
timer* t = new_timer(); timer *t = new_timer();
timer_setup(t, cb, userarg); timer_setup(t, cb, userarg);
timer_start(t, sec); timer_start(t, sec);
} }
/* Single-use microsecond timer. */ /* Single-use microsecond timer. */
void timer_us(timer_callback cb, void* userarg, int us) void timer_us(timer_callback cb, void *userarg, int us)
{ {
timer* t = new_timer(); timer *t = new_timer();
timer_setup(t, cb, userarg); timer_setup(t, cb, userarg);
t->deadline = current_time() + us; t->deadline = current_time() + us;
t->state = STATE_ACTIVE; t->state = STATE_ACTIVE;
@ -228,26 +238,30 @@ void timer_poll(void)
/* Handle millisecond timers */ /* Handle millisecond timers */
while (timer_us_queue) { while (timer_us_queue) {
if (timer_diff(timer_us_queue, time) != 0) break; if (timer_diff(timer_us_queue, time) != 0) break;
timer* t = timer_us_queue;
timer *t = timer_us_queue;
timer_dequeue(t, &timer_us_queue); timer_dequeue(t, &timer_us_queue);
t->cb(0, t->userdata); t->cb(0, t->userdata);
delete_timer(t); delete_timer(t);
} }
if (time - prevtime > US_PER_SECOND || prevtime == 0 || prevtime > time) { if (time - prevtime > US_PER_SECOND || prevtime == 0 || prevtime > time) {
/* time moving backwards is just a sanity check */ /* time moving backwards is just a sanity check */
prevtime = time; prevtime = time;
while (timer_main_queue) { while (timer_main_queue) {
if (timer_diff(timer_main_queue, time) != 0) break; if (timer_diff(timer_main_queue, time) != 0) break;
timer* t = timer_main_queue;
timer *t = timer_main_queue;
t->state = STATE_CALLBACK; t->state = STATE_CALLBACK;
int rv = t->cb(t, t->userdata); int rv = t->cb(t, t->userdata);
if (rv != 0) { if (rv != 0) {
timer_dequeue(t, &timer_main_queue); timer_dequeue(t, &timer_main_queue);
delete_timer(t); delete_timer(t);
continue; continue;
} }
if (t->state != STATE_ACTIVE) { if (t->state != STATE_ACTIVE) {
timer_dequeue(t, &timer_main_queue); timer_dequeue(t, &timer_main_queue);
} }
@ -257,19 +271,20 @@ void timer_poll(void)
/*** Internal Testing ***/ /*** Internal Testing ***/
/* I do not want to expose internals to the public, /* I do not want to expose internals to the public,
* which is why internals testing is done this way. */ * which is why internals testing is done this way. */
void timer_internal_tests(bool (*assert)(bool, char*)) void timer_internal_tests(bool (*assert)(bool, char *))
{ {
} }
void timer_debug_print() void timer_debug_print()
{ {
timer* t = timer_main_queue; timer *t = timer_main_queue;
printf("Queue:\n"); printf("Queue:\n");
while (t) { while (t) {
printf("%" PRIu64 " (%" PRIu64 ") : %s\n", t->deadline, t->deadline/US_PER_SECOND, (char*)t->userdata); printf("%" PRIu64 " (%" PRIu64 ") : %s\n", t->deadline, t->deadline / US_PER_SECOND, (char *)t->userdata);
t = t->_next; t = t->_next;
} }
} }

View File

@ -44,7 +44,7 @@ typedef struct timer timer;
* You may call any of the timer functions within the callback: * You may call any of the timer functions within the callback:
* For example, you may call timer_start to restart the timer from * For example, you may call timer_start to restart the timer from
* within a callback. */ * within a callback. */
typedef int (*timer_callback)(timer* t, void* userarg); typedef int (*timer_callback)(timer *t, void *userarg);
/* Initisalise timer subsystem */ /* Initisalise timer subsystem */
void timer_init(void); void timer_init(void);
@ -53,52 +53,52 @@ void timer_init(void);
void timer_poll(void); void timer_poll(void);
/* Creates a new timer. Does not enqueue/start it. */ /* Creates a new timer. Does not enqueue/start it. */
timer* new_timer(void); timer *new_timer(void);
/* Destroys a timer instance. */ /* Destroys a timer instance. */
void delete_timer(timer* t); void delete_timer(timer *t);
/* Sets up the timer callback. */ /* Sets up the timer callback. */
void timer_setup(timer* t, timer_callback cb, void* userarg); void timer_setup(timer *t, timer_callback cb, void *userarg);
/* Accessor Function. */ /* Accessor Function. */
void* timer_get_userdata(timer* t); void *timer_get_userdata(timer *t);
/* Starts the timer so that it's called in sec seconds in the future from now. /* Starts the timer so that it's called in sec seconds in the future from now.
* A non-positive value of sec results in the callback being called immediately. * A non-positive value of sec results in the callback being called immediately.
* This function may be called again after a timer has been started to adjust * This function may be called again after a timer has been started to adjust
* the expiry time. */ * the expiry time. */
void timer_start(timer* t, int sec); void timer_start(timer *t, int sec);
/* Stops the timer. Returns -1 if the timer was not active. */ /* Stops the timer. Returns -1 if the timer was not active. */
int timer_stop(timer* t); int timer_stop(timer *t);
/* Adds additionalsec seconds to the timer. /* Adds additionalsec seconds to the timer.
* Returns -1 and does nothing if the timer was not active. */ * Returns -1 and does nothing if the timer was not active. */
int timer_delay(timer* t, int additonalsec); int timer_delay(timer *t, int additonalsec);
/* Returns the time remaining on a timer in seconds. /* Returns the time remaining on a timer in seconds.
* Returns -1 if the timer is not active. * Returns -1 if the timer is not active.
* Returns 0 if the timer has expired and the callback hasn't been called yet. */ * Returns 0 if the timer has expired and the callback hasn't been called yet. */
int timer_time_remaining(timer* t); int timer_time_remaining(timer *t);
/* Determines if timer is active. Returns TRUE if it is active */ /* Determines if timer is active. Returns TRUE if it is active */
bool timer_is_active(timer* t); bool timer_is_active(timer *t);
/* Single-use timer. /* Single-use timer.
* Creates a new timer, preforms setup and starts it. * Creates a new timer, preforms setup and starts it.
* Callback must return a non-zero value to prevent memory leak. */ * Callback must return a non-zero value to prevent memory leak. */
void timer_single(timer_callback cb, void* userarg, int sec); void timer_single(timer_callback cb, void *userarg, int sec);
/* Single-use microsecond timer. /* Single-use microsecond timer.
* Creates a new timer, preforms setup and starts it. * Creates a new timer, preforms setup and starts it.
* Please do not use this when accuracy is not absolutely required. * Please do not use this when accuracy is not absolutely required.
* Use when one needs to time a period < 1 s. * Use when one needs to time a period < 1 s.
* Use the more coarse timers above for periods > 5 s. * Use the more coarse timers above for periods > 5 s.
* WARNING: the callback will be called with NULL as the first argument */ * WARNING: the callback will be called with NULL as the first argument */
void timer_us(timer_callback cb, void* userarg, int us); void timer_us(timer_callback cb, void *userarg, int us);
/* Internal Testing */ /* Internal Testing */
void timer_internal_tests(bool(*)(bool, char*)); void timer_internal_tests(bool( *)(bool, char *));
#endif #endif

View File

@ -34,12 +34,12 @@ bool ipp_eq(IP_Port a, IP_Port b)
return (a.ip.i == b.ip.i) && (a.port == b.port); return (a.ip.i == b.ip.i) && (a.port == b.port);
} }
bool id_eq(clientid_t* dest, clientid_t* src) bool id_eq(clientid_t *dest, clientid_t *src)
{ {
return memcmp(dest, src, sizeof(clientid_t)) == 0; return memcmp(dest, src, sizeof(clientid_t)) == 0;
} }
void id_cpy(clientid_t* dest, clientid_t* src) void id_cpy(clientid_t *dest, clientid_t *src)
{ {
memcpy(dest, src, sizeof(clientid_t)); memcpy(dest, src, sizeof(clientid_t));
} }

View File

@ -8,5 +8,5 @@
uint64_t now(); uint64_t now();
uint64_t random_64b(); uint64_t random_64b();
bool ipp_eq(IP_Port a, IP_Port b); bool ipp_eq(IP_Port a, IP_Port b);
bool id_eq(clientid_t* dest, clientid_t* src); bool id_eq(clientid_t *dest, clientid_t *src);
void id_cpy(clientid_t* dest, clientid_t* src); void id_cpy(clientid_t *dest, clientid_t *src);

View File

@ -6,7 +6,7 @@
* gcc -O2 -Wall -D VANILLA_NACL -o bootstrap_server ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../core/friend_requests.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} DHT_bootstrap.c * gcc -O2 -Wall -D VANILLA_NACL -o bootstrap_server ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../core/friend_requests.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} DHT_bootstrap.c
* *
* gcc -O2 -Wall -o bootstrap_server ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../core/friend_requests.c -lsodium DHT_bootstrap.c * gcc -O2 -Wall -o bootstrap_server ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../core/DHT.c ../core/friend_requests.c -lsodium DHT_bootstrap.c
* *
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
* *
@ -24,7 +24,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>. * along with Tox. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include "../core/DHT.h" #include "../core/DHT.h"
@ -50,13 +50,16 @@ void manage_keys()
uint8_t keys[KEYS_SIZE]; uint8_t keys[KEYS_SIZE];
FILE *keys_file = fopen("key", "r"); FILE *keys_file = fopen("key", "r");
if (keys_file != NULL) { if (keys_file != NULL) {
//if file was opened successfully -- load keys //if file was opened successfully -- load keys
size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file); size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
if (read_size != KEYS_SIZE) { if (read_size != KEYS_SIZE) {
printf("Error while reading the key file\nExiting.\n"); printf("Error while reading the key file\nExiting.\n");
exit(1); exit(1);
} }
load_keys(keys); load_keys(keys);
printf("Keys loaded successfully\n"); printf("Keys loaded successfully\n");
} else { } else {
@ -64,10 +67,12 @@ void manage_keys()
new_keys(); new_keys();
save_keys(keys); save_keys(keys);
keys_file = fopen("key", "w"); keys_file = fopen("key", "w");
if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file) != KEYS_SIZE) { if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file) != KEYS_SIZE) {
printf("Error while writing the key file.\nExiting.\n"); printf("Error while writing the key file.\nExiting.\n");
exit(1); exit(1);
} }
printf("Keys saved successfully\n"); printf("Keys saved successfully\n");
} }
@ -83,12 +88,12 @@ int main(int argc, char *argv[])
FILE *file; FILE *file;
file = fopen("PUBLIC_ID.txt", "w"); file = fopen("PUBLIC_ID.txt", "w");
for(i = 0; i < 32; i++) for (i = 0; i < 32; i++) {
{ if (self_public_key[i] < 16)
if(self_public_key[i] < 16)
printf("0"); printf("0");
printf("%hhX",self_public_key[i]);
fprintf(file, "%hhX",self_public_key[i]); printf("%hhX", self_public_key[i]);
fprintf(file, "%hhX", self_public_key[i]);
} }
fclose(file); fclose(file);
@ -117,19 +122,20 @@ int main(int argc, char *argv[])
friendreq_init(); friendreq_init();
int is_waiting_for_dht_connection = 1; int is_waiting_for_dht_connection = 1;
while(1)
{ while (1) {
if (is_waiting_for_dht_connection && DHT_isconnected()) if (is_waiting_for_dht_connection && DHT_isconnected()) {
{
printf("Connected to other bootstrap server successfully.\n"); printf("Connected to other bootstrap server successfully.\n");
is_waiting_for_dht_connection = 0; is_waiting_for_dht_connection = 0;
} }
doDHT(); doDHT();
networking_poll(); networking_poll();
c_sleep(1); c_sleep(1);
} }
shutdown_networking(); shutdown_networking();
return 0; return 0;
} }

View File

@ -1,7 +1,7 @@
/* DHT boostrap /* DHT boostrap
* *
* A simple DHT boostrap server for tox - daemon edition. * A simple DHT boostrap server for tox - daemon edition.
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
* *
* This file is part of Tox. * This file is part of Tox.
@ -18,7 +18,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>. * along with Tox. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include <sys/types.h> /* pid_t */ #include <sys/types.h> /* pid_t */
@ -55,19 +55,20 @@ struct server_conf_s {
struct server_info_s info[32]; struct server_info_s info[32];
}; };
int b16_to_key(char b16_string[], uint8_t *bs_pubkey) { int b16_to_key(char b16_string[], uint8_t *bs_pubkey)
{
int i; int i;
unsigned int num1 = 0, num2 = 0; unsigned int num1 = 0, num2 = 0;
for(i = 0; i < 32; ++i) for (i = 0; i < 32; ++i) {
{ sscanf(&b16_string[i * 2], "%1X", &num1);
sscanf(&b16_string[i*2], "%1X", &num1); sscanf(&b16_string[i * 2 + 1], "%1X", &num2);
sscanf(&b16_string[i*2+1], "%1X", &num2);
num1 = num1 << 4; num1 = num1 << 4;
bs_pubkey[i] = bs_pubkey[i] | num1; bs_pubkey[i] = bs_pubkey[i] | num1;
bs_pubkey[i] = bs_pubkey[i] | num2; bs_pubkey[i] = bs_pubkey[i] | num2;
} }
return 0; return 0;
} }
@ -81,8 +82,8 @@ int connect_to_servers(struct server_info_s *info)
int i; int i;
int c; int c;
for(i = 0; i < 32; ++i) { for (i = 0; i < 32; ++i) {
if(info[i].valid) { if (info[i].valid) {
/* Actual bootstrapping code goes here */ /* Actual bootstrapping code goes here */
//puts("Calling DHT_bootstrap"); //puts("Calling DHT_bootstrap");
DHT_bootstrap(info[i].conn, info[i].bs_pk); DHT_bootstrap(info[i].conn, info[i].bs_pk);
@ -90,14 +91,16 @@ int connect_to_servers(struct server_info_s *info)
} }
/* Check if we're connected to the DHT */ /* Check if we're connected to the DHT */
for(c = 0; c != 100; ++c) { for (c = 0; c != 100; ++c) {
usleep(10000); usleep(10000);
if(DHT_isconnected()) {
if (DHT_isconnected()) {
//puts("Connected"); //puts("Connected");
return 1; return 1;
break; break;
} }
if(DHT_isconnected() == 0 && c == 99) {
if (DHT_isconnected() == 0 && c == 99) {
//puts("Not connected"); //puts("Not connected");
return -1; return -1;
break; break;
@ -118,17 +121,19 @@ void manage_keys(char *keys_file)
uint8_t keys[KEYS_SIZE]; uint8_t keys[KEYS_SIZE];
struct stat existence; struct stat existence;
FILE *keysf; FILE *keysf;
/* Check if file exits, proceed to open and load keys */ /* Check if file exits, proceed to open and load keys */
if(stat(keys_file,&existence) >= 0) { if (stat(keys_file, &existence) >= 0) {
keysf = fopen(keys_file, "r"); keysf = fopen(keys_file, "r");
size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keysf); size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keysf);
if (read_size != KEYS_SIZE) { if (read_size != KEYS_SIZE) {
printf("Error while reading the key file\nExiting.\n"); printf("Error while reading the key file\nExiting.\n");
exit(1); exit(1);
} else { } else {
printf("Keys loaded successfully\n"); printf("Keys loaded successfully\n");
} }
load_keys(keys); load_keys(keys);
} else { } else {
@ -137,6 +142,7 @@ void manage_keys(char *keys_file)
new_keys(); new_keys();
save_keys(keys); save_keys(keys);
keysf = fopen(keys_file, "w"); keysf = fopen(keys_file, "w");
if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keysf) != KEYS_SIZE) { if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keysf) != KEYS_SIZE) {
printf("Error while writing the key file.\nExiting.\n"); printf("Error while writing the key file.\nExiting.\n");
exit(1); exit(1);
@ -183,8 +189,7 @@ struct server_conf_s configure_server(char *cfg_file)
config_init(&cfg); config_init(&cfg);
/* Read the file. If there is an error, report it and exit. */ /* Read the file. If there is an error, report it and exit. */
if(! config_read_file(&cfg, cfg_file)) if (! config_read_file(&cfg, cfg_file)) {
{
fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg),
config_error_line(&cfg), config_error_text(&cfg)); config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg); config_destroy(&cfg);
@ -193,14 +198,14 @@ struct server_conf_s configure_server(char *cfg_file)
} }
/* Get the port to listen on */ /* Get the port to listen on */
if(config_lookup_int(&cfg, "port", &server_conf.port)) { if (config_lookup_int(&cfg, "port", &server_conf.port)) {
//printf("Port: %d\n", port); //printf("Port: %d\n", port);
} else { } else {
fprintf(stderr, "No 'port' setting in configuration file.\n"); fprintf(stderr, "No 'port' setting in configuration file.\n");
} }
/* Get PID file location */ /* Get PID file location */
if(config_lookup_string(&cfg, "pid_file", &pid_file_tmp)) { if (config_lookup_string(&cfg, "pid_file", &pid_file_tmp)) {
//printf("PID file: %s\n", pid_file_tmp); //printf("PID file: %s\n", pid_file_tmp);
strcpy(server_conf.pid_file, pid_file_tmp); strcpy(server_conf.pid_file, pid_file_tmp);
} else { } else {
@ -208,7 +213,7 @@ struct server_conf_s configure_server(char *cfg_file)
} }
/* Get keys file location */ /* Get keys file location */
if(config_lookup_string(&cfg, "keys_file", &keys_file_tmp)) { if (config_lookup_string(&cfg, "keys_file", &keys_file_tmp)) {
//printf("Keys file: %s\n", keys_file_tmp); //printf("Keys file: %s\n", keys_file_tmp);
strcpy(server_conf.keys_file, keys_file_tmp); strcpy(server_conf.keys_file, keys_file_tmp);
} else { } else {
@ -217,38 +222,40 @@ struct server_conf_s configure_server(char *cfg_file)
/* Get all the servers in the list */ /* Get all the servers in the list */
server_list = config_lookup(&cfg, "bootstrap_servers"); server_list = config_lookup(&cfg, "bootstrap_servers");
if(server_list != NULL) {
if (server_list != NULL) {
int count = config_setting_length(server_list); int count = config_setting_length(server_list);
int i; int i;
char tmp_ip[30]; /* IP */ char tmp_ip[30]; /* IP */
char tmp_pk[64]; /* bs_pk */ char tmp_pk[64]; /* bs_pk */
for(i = 0; i < count; ++i) {
for (i = 0; i < count; ++i) {
config_setting_t *server = config_setting_get_elem(server_list, i); config_setting_t *server = config_setting_get_elem(server_list, i);
/* Get a pointer on the key aray */ /* Get a pointer on the key aray */
uint8_t *bs_pk_p = server_conf.info[i].bs_pk; uint8_t *bs_pk_p = server_conf.info[i].bs_pk;
/* Only output the record if all of the expected fields are present. */ /* Only output the record if all of the expected fields are present. */
if(!(config_setting_lookup_string(server, "ip", &bs_ip) if (!(config_setting_lookup_string(server, "ip", &bs_ip)
&& config_setting_lookup_int(server, "port", &bs_port) && config_setting_lookup_int(server, "port", &bs_port)
&& config_setting_lookup_string(server, "bs_pk", &bs_pk))) && config_setting_lookup_string(server, "bs_pk", &bs_pk)))
continue; continue;
/* Converting all that stuff into usable formats and storing /* Converting all that stuff into usable formats and storing
it away in the server_info struct */ it away in the server_info struct */
server_conf.info[i].valid = 1; server_conf.info[i].valid = 1;
if(resolve_addr(strcpy(tmp_ip, bs_ip)) == 0) { if (resolve_addr(strcpy(tmp_ip, bs_ip)) == 0) {
server_conf.info[i].valid = 0; server_conf.info[i].valid = 0;
printf("bootstrap_server %d: Invalid IP\n", i); printf("bootstrap_server %d: Invalid IP\n", i);
} }
if(strlen(bs_pk) != 64) { if (strlen(bs_pk) != 64) {
server_conf.info[i].valid = 0; server_conf.info[i].valid = 0;
printf("bootstrap_server %d: Invalid public key\n", i); printf("bootstrap_server %d: Invalid public key\n", i);
} }
if(!bs_port) { if (!bs_port) {
server_conf.info[i].valid = 0; server_conf.info[i].valid = 0;
printf("bootstrap_server %d: Invalid port\n", i); printf("bootstrap_server %d: Invalid port\n", i);
} }
@ -259,8 +266,8 @@ struct server_conf_s configure_server(char *cfg_file)
} }
/* Check if at least one server entry is valid */ /* Check if at least one server entry is valid */
for(i = 0; i < 32; ++i) { for (i = 0; i < 32; ++i) {
if(server_conf.info[i].valid) if (server_conf.info[i].valid)
break; break;
else else
server_conf.err = -2; server_conf.err = -2;
@ -274,14 +281,15 @@ struct server_conf_s configure_server(char *cfg_file)
return server_conf; return server_conf;
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[])
{
pid_t pid, sid; /* Process- and Session-ID */ pid_t pid, sid; /* Process- and Session-ID */
struct server_conf_s server_conf; struct server_conf_s server_conf;
FILE *pidf; /* The PID file */ FILE *pidf; /* The PID file */
if(argc < 2) { if (argc < 2) {
printf("Please specify a configuration file.\n"); printf("Please specify a configuration file.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -292,10 +300,10 @@ int main(int argc, char *argv[]) {
printf("PID file: %s\n", server_conf.pid_file); printf("PID file: %s\n", server_conf.pid_file);
printf("Key file: %s\n", server_conf.keys_file); printf("Key file: %s\n", server_conf.keys_file);
if(server_conf.err == -1) if (server_conf.err == -1)
printf("Config file not read.\n"); printf("Config file not read.\n");
if(server_conf.err == -2) if (server_conf.err == -2)
printf("No valid servers in list.\n"); printf("No valid servers in list.\n");
/* Open PID file for writing - if an error happens, /* Open PID file for writing - if an error happens,
@ -311,14 +319,15 @@ int main(int argc, char *argv[]) {
/* Public key */ /* Public key */
int i; int i;
printf("\nPublic Key: "); printf("\nPublic Key: ");
for(i = 0; i < 32; ++i)
{ for (i = 0; i < 32; ++i) {
uint8_t ln, hn; uint8_t ln, hn;
ln = 0x0F & self_public_key[i]; ln = 0x0F & self_public_key[i];
hn = 0xF0 & self_public_key[i]; hn = 0xF0 & self_public_key[i];
hn = hn >> 4; hn = hn >> 4;
printf("%X%X", hn, ln); printf("%X%X", hn, ln);
} }
printf("\n"); printf("\n");
/* initialize networking /* initialize networking
@ -335,7 +344,7 @@ int main(int argc, char *argv[]) {
connect_to_servers(server_conf.info); connect_to_servers(server_conf.info);
errno = tmperr; errno = tmperr;
if(!DHT_isconnected()) { if (!DHT_isconnected()) {
puts("Could not establish DHT connection. Check server settings.\n"); puts("Could not establish DHT connection. Check server settings.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else { } else {
@ -355,6 +364,7 @@ int main(int argc, char *argv[]) {
/* Fork off from the parent process */ /* Fork off from the parent process */
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
printf("Forking failed.\n"); printf("Forking failed.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -378,6 +388,7 @@ int main(int argc, char *argv[]) {
/* Create a new SID for the child process */ /* Create a new SID for the child process */
sid = setsid(); sid = setsid();
if (sid < 0) { if (sid < 0) {
printf("SID creation failure.\n"); printf("SID creation failure.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -396,8 +407,7 @@ int main(int argc, char *argv[]) {
/* Main loop */ /* Main loop */
friendreq_init(); friendreq_init();
while(1) while (1) {
{
doDHT(); doDHT();
networking_poll(); networking_poll();

View File

@ -1,19 +1,19 @@
/* DHT cryptosendfiletest /* DHT cryptosendfiletest
* *
* This program sends or receives a friend request. * This program sends or receives a friend request.
* *
* it also sends the encrypted data from a file to another client. * it also sends the encrypted data from a file to another client.
* Receives the file data that that client sends us. * Receives the file data that that client sends us.
*
* NOTE: this program simulates 33% packet loss.
*
* This is how I compile it: gcc -O2 -Wall -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/DHT.c ../nacl/build/$HOSTNAME/lib/amd64/* DHT_cryptosendfiletest.c
* *
* * NOTE: this program simulates 33% packet loss.
*
* This is how I compile it: gcc -O2 -Wall -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/DHT.c ../nacl/build/$HOSTNAME/lib/amd64/* DHT_cryptosendfiletest.c
*
*
* Command line arguments are the ip and port of a node (for bootstrapping). * Command line arguments are the ip and port of a node (for bootstrapping).
* *
* Saves all received data to: received.txt * Saves all received data to: received.txt
* *
* EX: ./test 127.0.0.1 33445 filename.txt * EX: ./test 127.0.0.1 33445 filename.txt
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
@ -32,9 +32,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>. * along with Tox. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include "../core/network.h" #include "../core/network.h"
#include "../core/DHT.h" #include "../core/DHT.h"
#include "../core/net_crypto.h" #include "../core/net_crypto.h"
@ -58,7 +58,8 @@
void printip(IP_Port ip_port) void printip(IP_Port ip_port)
{ {
printf("\nIP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port)); printf("\nIP: %u.%u.%u.%u Port: %u\n", ip_port.ip.c[0], ip_port.ip.c[1], ip_port.ip.c[2], ip_port.ip.c[3],
ntohs(ip_port.port));
} }
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
@ -69,68 +70,81 @@ int main(int argc, char *argv[])
printf("usage %s ip port filename(of file to send)\n", argv[0]); printf("usage %s ip port filename(of file to send)\n", argv[0]);
exit(0); exit(0);
} }
new_keys(); new_keys();
printf("OUR ID: "); printf("OUR ID: ");
uint32_t i; uint32_t i;
for(i = 0; i < 32; i++) {
if(self_public_key[i] < 16) for (i = 0; i < 32; i++) {
if (self_public_key[i] < 16)
printf("0"); printf("0");
printf("%hhX",self_public_key[i]);
printf("%hhX", self_public_key[i]);
} }
printf("\n"); printf("\n");
memcpy(self_client_id, self_public_key, 32); memcpy(self_client_id, self_public_key, 32);
char temp_id[128]; char temp_id[128];
printf("Enter the client_id of the friend to connect to (32 bytes HEX format):\n"); printf("Enter the client_id of the friend to connect to (32 bytes HEX format):\n");
scanf("%s", temp_id); scanf("%s", temp_id);
uint8_t friend_id[32]; uint8_t friend_id[32];
memcpy(friend_id, hex_string_to_bin(temp_id), 32); memcpy(friend_id, hex_string_to_bin(temp_id), 32);
/* memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); */ /* memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); */
DHT_addfriend(friend_id); DHT_addfriend(friend_id);
IP_Port friend_ip; IP_Port friend_ip;
int connection = -1; int connection = -1;
int inconnection = -1; int inconnection = -1;
uint8_t acceptedfriend_public_key[crypto_box_PUBLICKEYBYTES]; uint8_t acceptedfriend_public_key[crypto_box_PUBLICKEYBYTES];
int friendrequest = -1; int friendrequest = -1;
uint8_t request_data[512]; uint8_t request_data[512];
/* initialize networking /* initialize networking
* bind to ip 0.0.0.0:PORT */ * bind to ip 0.0.0.0:PORT */
IP ip; IP ip;
ip.i = 0; ip.i = 0;
init_networking(ip, PORT); init_networking(ip, PORT);
initNetCrypto(); initNetCrypto();
perror("Initialization"); perror("Initialization");
IP_Port bootstrap_ip_port; IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2])); bootstrap_ip_port.port = htons(atoi(argv[2]));
bootstrap_ip_port.ip.i = inet_addr(argv[1]); bootstrap_ip_port.ip.i = inet_addr(argv[1]);
DHT_bootstrap(bootstrap_ip_port); DHT_bootstrap(bootstrap_ip_port);
IP_Port ip_port; IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; uint32_t length;
uint8_t buffer1[128]; uint8_t buffer1[128];
int read1 = 0; int read1 = 0;
uint8_t buffer2[128]; uint8_t buffer2[128];
int read2 = 0; int read2 = 0;
FILE *file1 = fopen(argv[3], "rb"); FILE *file1 = fopen(argv[3], "rb");
if ( file1==NULL ){printf("Error opening file.\n");return 1;}
if ( file1 == NULL ) {
printf("Error opening file.\n");
return 1;
}
FILE *file2 = fopen("received.txt", "wb"); FILE *file2 = fopen("received.txt", "wb");
if ( file2==NULL ){return 1;}
if ( file2 == NULL ) {
return 1;
}
read1 = fread(buffer1, 1, 128, file1); read1 = fread(buffer1, 1, 128, file1);
while(1) { while (1) {
while(receivepacket(&ip_port, data, &length) != -1) { while (receivepacket(&ip_port, data, &length) != -1) {
if(rand() % 3 != 1) { /* simulate packet loss */ if (rand() % 3 != 1) { /* simulate packet loss */
if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) { if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) {
/* if packet is not recognized */ /* if packet is not recognized */
printf("Received unhandled packet with length: %u\n", length); printf("Received unhandled packet with length: %u\n", length);
} else { } else {
@ -138,82 +152,98 @@ int main(int argc, char *argv[])
} }
} }
} }
friend_ip = DHT_getfriendip(friend_id); friend_ip = DHT_getfriendip(friend_id);
if(friend_ip.ip.i != 0) {
if(connection == -1 && friendrequest == -1) { if (friend_ip.ip.i != 0) {
if (connection == -1 && friendrequest == -1) {
printf("Sending friend request to peer:"); printf("Sending friend request to peer:");
printip(friend_ip); printip(friend_ip);
friendrequest = send_friendrequest(friend_id, friend_ip,(uint8_t *) "Hello World", 12); friendrequest = send_friendrequest(friend_id, friend_ip, (uint8_t *) "Hello World", 12);
/* connection = crypto_connect((uint8_t *)friend_id, friend_ip); */ /* connection = crypto_connect((uint8_t *)friend_id, friend_ip); */
/* connection = new_connection(friend_ip); */ /* connection = new_connection(friend_ip); */
} }
if(check_friendrequest(friendrequest) == 1) {
if (check_friendrequest(friendrequest) == 1) {
printf("Started connecting to friend:"); printf("Started connecting to friend:");
connection = crypto_connect(friend_id, friend_ip); connection = crypto_connect(friend_id, friend_ip);
} }
} }
if(inconnection == -1) {
if (inconnection == -1) {
uint8_t secret_nonce[crypto_box_NONCEBYTES]; uint8_t secret_nonce[crypto_box_NONCEBYTES];
uint8_t public_key[crypto_box_PUBLICKEYBYTES]; uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES]; uint8_t session_key[crypto_box_PUBLICKEYBYTES];
inconnection = crypto_inbound(public_key, secret_nonce, session_key); inconnection = crypto_inbound(public_key, secret_nonce, session_key);
inconnection = accept_crypto_inbound(inconnection, acceptedfriend_public_key, secret_nonce, session_key); inconnection = accept_crypto_inbound(inconnection, acceptedfriend_public_key, secret_nonce, session_key);
/* inconnection = incoming_connection(); */ /* inconnection = incoming_connection(); */
if(inconnection != -1) { if (inconnection != -1) {
printf("Someone connected to us:\n"); printf("Someone connected to us:\n");
/* printip(connection_ip(inconnection)); */ /* printip(connection_ip(inconnection)); */
} }
} }
if(handle_friendrequest(acceptedfriend_public_key, request_data) > 1) {
if (handle_friendrequest(acceptedfriend_public_key, request_data) > 1) {
printf("RECEIVED FRIEND REQUEST: %s\n", request_data); printf("RECEIVED FRIEND REQUEST: %s\n", request_data);
} }
/* if someone connected to us write what he sends to a file /* if someone connected to us write what he sends to a file
* also send him our file. */ * also send him our file. */
if(inconnection != -1) { if (inconnection != -1) {
if(write_cryptpacket(inconnection, buffer1, read1)) { if (write_cryptpacket(inconnection, buffer1, read1)) {
printf("Wrote data1.\n"); printf("Wrote data1.\n");
read1 = fread(buffer1, 1, 128, file1); read1 = fread(buffer1, 1, 128, file1);
} }
read2 = read_cryptpacket(inconnection, buffer2); read2 = read_cryptpacket(inconnection, buffer2);
if(read2 != 0) {
if (read2 != 0) {
printf("Received data1.\n"); printf("Received data1.\n");
if(!fwrite(buffer2, read2, 1, file2)) {
printf("file write error1\n"); if (!fwrite(buffer2, read2, 1, file2)) {
printf("file write error1\n");
} }
if(read2 < 128) {
if (read2 < 128) {
printf("Closed file1 %u\n", read2); printf("Closed file1 %u\n", read2);
fclose(file2); fclose(file2);
} }
} }
/* if buffer is empty and the connection timed out. */ /* if buffer is empty and the connection timed out. */
else if(is_cryptoconnected(inconnection) == 4) { else if (is_cryptoconnected(inconnection) == 4) {
crypto_kill(inconnection); crypto_kill(inconnection);
} }
} }
/* if we are connected to a friend send him data from the file. /* if we are connected to a friend send him data from the file.
* also put what he sends us in a file. */ * also put what he sends us in a file. */
if(is_cryptoconnected(connection) >= 3) { if (is_cryptoconnected(connection) >= 3) {
if(write_cryptpacket(0, buffer1, read1)) { if (write_cryptpacket(0, buffer1, read1)) {
printf("Wrote data2.\n"); printf("Wrote data2.\n");
read1 = fread(buffer1, 1, 128, file1); read1 = fread(buffer1, 1, 128, file1);
} }
read2 = read_cryptpacket(0, buffer2); read2 = read_cryptpacket(0, buffer2);
if(read2 != 0) {
if (read2 != 0) {
printf("Received data2.\n"); printf("Received data2.\n");
if(!fwrite(buffer2, read2, 1, file2)) {
printf("file write error2\n"); if (!fwrite(buffer2, read2, 1, file2)) {
printf("file write error2\n");
} }
if(read2 < 128) {
if (read2 < 128) {
printf("Closed file2 %u\n", read2); printf("Closed file2 %u\n", read2);
fclose(file2); fclose(file2);
} }
} }
/* if buffer is empty and the connection timed out. */ /* if buffer is empty and the connection timed out. */
else if(is_cryptoconnected(connection) == 4) { else if (is_cryptoconnected(connection) == 4) {
crypto_kill(connection); crypto_kill(connection);
} }
} }
doDHT(); doDHT();
doLossless_UDP(); doLossless_UDP();
doNetCrypto(); doNetCrypto();
@ -222,7 +252,7 @@ int main(int argc, char *argv[])
*c_sleep(300); */ *c_sleep(300); */
c_sleep(1); c_sleep(1);
} }
shutdown_networking(); shutdown_networking();
return 0; return 0;
} }

View File

@ -1,18 +1,18 @@
/* DHT sendfiletest /* DHT sendfiletest
* *
* Sends the data from a file to another client. * Sends the data from a file to another client.
* Receives the file data that that client sends us. * Receives the file data that that client sends us.
* *
* NOTE: this program simulates 33% packet loss. * NOTE: this program simulates 33% packet loss.
* *
* Compile with: gcc -O2 -Wall -o test ../core/DHT.c ../core/network.c ../core/Lossless_UDP.c DHT_sendfiletest.c * Compile with: gcc -O2 -Wall -o test ../core/DHT.c ../core/network.c ../core/Lossless_UDP.c DHT_sendfiletest.c
* *
* Command line arguments are the ip and port of a node (for bootstrapping), the * Command line arguments are the ip and port of a node (for bootstrapping), the
* client_id (32 bytes) of the friend you want to send the data in filename to and * client_id (32 bytes) of the friend you want to send the data in filename to and
* the client_id this node will take. * the client_id this node will take.
* *
* Saves all received data to: received.txt * Saves all received data to: received.txt
* *
* EX: ./test 127.0.0.1 33445 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef filename.txt ABCDEFGHIJKLMNOPQRSTUVWXYZabcdeg * EX: ./test 127.0.0.1 33445 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef filename.txt ABCDEFGHIJKLMNOPQRSTUVWXYZabcdeg
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
@ -31,9 +31,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>. * along with Tox. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include "../core/network.h" #include "../core/network.h"
#include "../core/DHT.h" #include "../core/DHT.h"
#include "../core/Lossless_UDP.h" #include "../core/Lossless_UDP.h"
@ -56,56 +56,61 @@
void printip(IP_Port ip_port) void printip(IP_Port ip_port)
{ {
printf("\nIP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port)); printf("\nIP: %u.%u.%u.%u Port: %u\n", ip_port.ip.c[0], ip_port.ip.c[1], ip_port.ip.c[2], ip_port.ip.c[3],
ntohs(ip_port.port));
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
//memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
if (argc < 6) { if (argc < 6) {
printf("usage %s ip port client_id(of friend to find ip_port of) filename(of file to send) client_id(ours)\n", argv[0]); printf("usage %s ip port client_id(of friend to find ip_port of) filename(of file to send) client_id(ours)\n", argv[0]);
exit(0); exit(0);
} }
DHT_addfriend((uint8_t *)argv[3]); DHT_addfriend((uint8_t *)argv[3]);
IP_Port friend_ip; IP_Port friend_ip;
int connection = -1; int connection = -1;
int inconnection = -1; int inconnection = -1;
//initialize networking //initialize networking
//bind to ip 0.0.0.0:PORT //bind to ip 0.0.0.0:PORT
IP ip; IP ip;
ip.i = 0; ip.i = 0;
init_networking(ip, PORT); init_networking(ip, PORT);
memcpy(self_client_id, argv[5], 32); memcpy(self_client_id, argv[5], 32);
perror("Initialization"); perror("Initialization");
IP_Port bootstrap_ip_port; IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2])); bootstrap_ip_port.port = htons(atoi(argv[2]));
bootstrap_ip_port.ip.i = inet_addr(argv[1]); bootstrap_ip_port.ip.i = inet_addr(argv[1]);
DHT_bootstrap(bootstrap_ip_port); DHT_bootstrap(bootstrap_ip_port);
IP_Port ip_port; IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; uint32_t length;
uint8_t buffer1[128]; uint8_t buffer1[128];
int read1 = 0; int read1 = 0;
uint8_t buffer2[128]; uint8_t buffer2[128];
int read2 = 0; int read2 = 0;
FILE *file1 = fopen(argv[4], "rb"); FILE *file1 = fopen(argv[4], "rb");
if (file1 == NULL) { if (file1 == NULL) {
printf("Error opening file.\n"); printf("Error opening file.\n");
return 1; return 1;
} }
FILE *file2 = fopen("received.txt", "wb"); FILE *file2 = fopen("received.txt", "wb");
if (file2 == NULL) if (file2 == NULL)
return 1; return 1;
read1 = fread(buffer1, 1, 128, file1); read1 = fread(buffer1, 1, 128, file1);
while (1) { while (1) {
while (receivepacket(&ip_port, data, &length) != -1) { while (receivepacket(&ip_port, data, &length) != -1) {
if (rand() % 3 != 1) { /* simulate packet loss */ if (rand() % 3 != 1) { /* simulate packet loss */
@ -115,7 +120,9 @@ int main(int argc, char *argv[])
printf("Received handled packet with length: %u\n", length); printf("Received handled packet with length: %u\n", length);
} }
} }
friend_ip = DHT_getfriendip((uint8_t *)argv[3]); friend_ip = DHT_getfriendip((uint8_t *)argv[3]);
if (friend_ip.ip.i != 0) { if (friend_ip.ip.i != 0) {
if (connection == -1) { if (connection == -1) {
printf("Started connecting to friend:"); printf("Started connecting to friend:");
@ -123,13 +130,16 @@ int main(int argc, char *argv[])
connection = new_connection(friend_ip); connection = new_connection(friend_ip);
} }
} }
if (inconnection == -1) { if (inconnection == -1) {
inconnection = incoming_connection(); inconnection = incoming_connection();
if (inconnection != -1) { if (inconnection != -1) {
printf("Someone connected to us:"); printf("Someone connected to us:");
printip(connection_ip(inconnection)); printip(connection_ip(inconnection));
} }
} }
/* if someone connected to us write what he sends to a file */ /* if someone connected to us write what he sends to a file */
/* also send him our file. */ /* also send him our file. */
if (inconnection != -1) { if (inconnection != -1) {
@ -137,16 +147,21 @@ int main(int argc, char *argv[])
printf("Wrote data.\n"); printf("Wrote data.\n");
read1 = fread(buffer1, 1, 128, file1); read1 = fread(buffer1, 1, 128, file1);
} }
read2 = read_packet(inconnection, buffer2); read2 = read_packet(inconnection, buffer2);
if (read2 != 0) { if (read2 != 0) {
printf("Received data.\n"); printf("Received data.\n");
if (!fwrite(buffer2, read2, 1, file2)) if (!fwrite(buffer2, read2, 1, file2))
printf("file write error\n"); printf("file write error\n");
if (read2 < 128) { if (read2 < 128) {
fclose(file2); fclose(file2);
} }
} }
} }
/* if we are connected to a friend send him data from the file. /* if we are connected to a friend send him data from the file.
* also put what he sends us in a file. */ * also put what he sends us in a file. */
if (is_connected(connection) == 3) { if (is_connected(connection) == 3) {
@ -154,15 +169,20 @@ int main(int argc, char *argv[])
printf("Wrote data.\n"); printf("Wrote data.\n");
read1 = fread(buffer1, 1, 128, file1); read1 = fread(buffer1, 1, 128, file1);
} }
read2 = read_packet(0, buffer2); read2 = read_packet(0, buffer2);
if (read2 != 0) { if (read2 != 0) {
printf("Received data.\n"); printf("Received data.\n");
if(!fwrite(buffer2, read2, 1, file2))
printf("file write error\n"); if (!fwrite(buffer2, read2, 1, file2))
if(read2 < 128) printf("file write error\n");
if (read2 < 128)
fclose(file2); fclose(file2);
} }
} }
doDHT(); doDHT();
doLossless_UDP(); doLossless_UDP();
/* print_clientlist(); /* print_clientlist();
@ -170,7 +190,7 @@ int main(int argc, char *argv[])
* c_sleep(300); */ * c_sleep(300); */
c_sleep(1); c_sleep(1);
} }
shutdown_networking(); shutdown_networking();
return 0; return 0;
} }

View File

@ -1,11 +1,11 @@
/* DHT test /* DHT test
* A file with a main that runs our DHT for testing. * A file with a main that runs our DHT for testing.
* *
* Compile with: gcc -O2 -Wall -D VANILLA_NACL -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} DHT_test.c * Compile with: gcc -O2 -Wall -D VANILLA_NACL -o test ../core/Lossless_UDP.c ../core/network.c ../core/net_crypto.c ../core/Messenger.c ../nacl/build/${HOSTNAME%.*}/lib/amd64/{cpucycles.o,libnacl.a,randombytes.o} DHT_test.c
* *
* Command line arguments are the ip, port and public key of a node. * Command line arguments are the ip, port and public key of a node.
* EX: ./test 127.0.0.1 33445 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA * EX: ./test 127.0.0.1 33445 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
* *
* The test will then ask you for the id (in hex format) of the friend you wish to add * The test will then ask you for the id (in hex format) of the friend you wish to add
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
@ -24,9 +24,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>. * along with Tox. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
//#include "../core/network.h" //#include "../core/network.h"
#include "../core/DHT.c" #include "../core/DHT.c"
#include "../core/friend_requests.c" #include "../core/friend_requests.c"
@ -53,19 +53,22 @@ void print_clientlist()
uint32_t i, j; uint32_t i, j;
IP_Port p_ip; IP_Port p_ip;
printf("___________________CLOSE________________________________\n"); printf("___________________CLOSE________________________________\n");
for(i = 0; i < 32; i++) {
for (i = 0; i < 32; i++) {
printf("ClientID: "); printf("ClientID: ");
for(j = 0; j < 32; j++) {
for (j = 0; j < 32; j++) {
printf("%02hhX", close_clientlist[i].client_id[j]); printf("%02hhX", close_clientlist[i].client_id[j]);
} }
p_ip = close_clientlist[i].ip_port; p_ip = close_clientlist[i].ip_port;
printf("\nIP: %u.%u.%u.%u Port: %u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); printf("\nIP: %u.%u.%u.%u Port: %u", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port));
printf("\nTimestamp: %llu",(long long unsigned int) close_clientlist[i].timestamp); printf("\nTimestamp: %llu", (long long unsigned int) close_clientlist[i].timestamp);
printf("\nLast pinged: %llu\n",(long long unsigned int) close_clientlist[i].last_pinged); printf("\nLast pinged: %llu\n", (long long unsigned int) close_clientlist[i].last_pinged);
p_ip = close_clientlist[i].ret_ip_port; p_ip = close_clientlist[i].ret_ip_port;
printf("OUR IP: %u.%u.%u.%u Port: %u\n",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); printf("OUR IP: %u.%u.%u.%u Port: %u\n", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port));
printf("Timestamp: %llu\n",(long long unsigned int) close_clientlist[i].ret_timestamp); printf("Timestamp: %llu\n", (long long unsigned int) close_clientlist[i].ret_timestamp);
} }
} }
void print_friendlist() void print_friendlist()
@ -73,78 +76,91 @@ void print_friendlist()
uint32_t i, j, k; uint32_t i, j, k;
IP_Port p_ip; IP_Port p_ip;
printf("_________________FRIENDS__________________________________\n"); printf("_________________FRIENDS__________________________________\n");
for(k = 0; k < num_friends; k++) {
for (k = 0; k < num_friends; k++) {
printf("FRIEND %u\n", k); printf("FRIEND %u\n", k);
printf("ID: "); printf("ID: ");
for(j = 0; j < 32; j++) {
for (j = 0; j < 32; j++) {
printf("%c", friends_list[k].client_id[j]); printf("%c", friends_list[k].client_id[j]);
} }
p_ip = DHT_getfriendip(friends_list[k].client_id); p_ip = DHT_getfriendip(friends_list[k].client_id);
printf("\nIP: %u.%u.%u.%u:%u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port));
printf("\nCLIENTS IN LIST:\n\n"); printf("\nCLIENTS IN LIST:\n\n");
for(i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
printf("ClientID: "); printf("ClientID: ");
for(j = 0; j < 32; j++) {
if(friends_list[k].client_list[i].client_id[j] < 16) for (j = 0; j < 32; j++) {
if (friends_list[k].client_list[i].client_id[j] < 16)
printf("0"); printf("0");
printf("%hhX", friends_list[k].client_list[i].client_id[j]); printf("%hhX", friends_list[k].client_list[i].client_id[j]);
} }
p_ip = friends_list[k].client_list[i].ip_port; p_ip = friends_list[k].client_list[i].ip_port;
printf("\nIP: %u.%u.%u.%u:%u",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port));
printf("\nTimestamp: %llu",(long long unsigned int) friends_list[k].client_list[i].timestamp); printf("\nTimestamp: %llu", (long long unsigned int) friends_list[k].client_list[i].timestamp);
printf("\nLast pinged: %llu\n",(long long unsigned int) friends_list[k].client_list[i].last_pinged); printf("\nLast pinged: %llu\n", (long long unsigned int) friends_list[k].client_list[i].last_pinged);
p_ip = friends_list[k].client_list[i].ret_ip_port; p_ip = friends_list[k].client_list[i].ret_ip_port;
printf("ret IP: %u.%u.%u.%u:%u\n",p_ip.ip.c[0],p_ip.ip.c[1],p_ip.ip.c[2],p_ip.ip.c[3],ntohs(p_ip.port)); printf("ret IP: %u.%u.%u.%u:%u\n", p_ip.ip.c[0], p_ip.ip.c[1], p_ip.ip.c[2], p_ip.ip.c[3], ntohs(p_ip.port));
printf("Timestamp: %llu\n", (long long unsigned int)friends_list[k].client_list[i].ret_timestamp); printf("Timestamp: %llu\n", (long long unsigned int)friends_list[k].client_list[i].ret_timestamp);
} }
} }
} }
void printpacket(uint8_t * data, uint32_t length, IP_Port ip_port) void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
{ {
uint32_t i; uint32_t i;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
printf("--------------------BEGIN-----------------------------\n"); printf("--------------------BEGIN-----------------------------\n");
for(i = 0; i < length; i++) {
if(data[i] < 16) for (i = 0; i < length; i++) {
if (data[i] < 16)
printf("0"); printf("0");
printf("%hhX",data[i]);
printf("%hhX", data[i]);
} }
printf("\n--------------------END-----------------------------\n\n\n"); printf("\n--------------------END-----------------------------\n\n\n");
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
//memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
if (argc < 4) { if (argc < 4) {
printf("usage %s ip port public_key\n", argv[0]); printf("usage %s ip port public_key\n", argv[0]);
exit(0); exit(0);
} }
new_keys(); new_keys();
printf("OUR ID: "); printf("OUR ID: ");
uint32_t i; uint32_t i;
for(i = 0; i < 32; i++) {
if(self_public_key[i] < 16) for (i = 0; i < 32; i++) {
if (self_public_key[i] < 16)
printf("0"); printf("0");
printf("%hhX",self_public_key[i]);
printf("%hhX", self_public_key[i]);
} }
char temp_id[128]; char temp_id[128];
printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n"); printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n");
if(scanf("%s", temp_id) != 1)
if (scanf("%s", temp_id) != 1)
exit(0); exit(0);
DHT_addfriend(hex_string_to_bin(temp_id)); DHT_addfriend(hex_string_to_bin(temp_id));
/* initialize networking */ /* initialize networking */
/* bind to ip 0.0.0.0:PORT */ /* bind to ip 0.0.0.0:PORT */
IP ip; IP ip;
ip.i = 0; ip.i = 0;
init_networking(ip, PORT); init_networking(ip, PORT);
perror("Initialization"); perror("Initialization");
IP_Port bootstrap_ip_port; IP_Port bootstrap_ip_port;
@ -155,37 +171,37 @@ int main(int argc, char *argv[])
* bootstrap_ip_port.ip.c[3] = 1; */ * bootstrap_ip_port.ip.c[3] = 1; */
bootstrap_ip_port.ip.i = inet_addr(argv[1]); bootstrap_ip_port.ip.i = inet_addr(argv[1]);
DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
/* /*
IP_Port ip_port; IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; uint32_t length;
*/ */
DHT_init(); DHT_init();
friendreq_init(); friendreq_init();
while(1) { while (1) {
doDHT(); doDHT();
/* slvrTODO: /* slvrTODO:
while(receivepacket(&ip_port, data, &length) != -1) { while(receivepacket(&ip_port, data, &length) != -1) {
if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) { if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) {
//unhandled packet //unhandled packet
printpacket(data, length, ip_port); printpacket(data, length, ip_port);
} else { } else {
printf("Received handled packet with length: %u\n", length); printf("Received handled packet with length: %u\n", length);
} }
} }
*/ */
networking_poll(); networking_poll();
print_clientlist(); print_clientlist();
print_friendlist(); print_friendlist();
c_sleep(300); c_sleep(300);
} }
shutdown_networking(); shutdown_networking();
return 0; return 0;
} }

View File

@ -1,11 +1,11 @@
/* Lossless_UDP testclient /* Lossless_UDP testclient
* A program that connects and sends a file using our lossless UDP algorithm. * A program that connects and sends a file using our lossless UDP algorithm.
* NOTE: this program simulates a 33% packet loss. * NOTE: this program simulates a 33% packet loss.
* *
* Best used in combination with Lossless_UDP_testserver * Best used in combination with Lossless_UDP_testserver
* *
* Compile with: gcc -O2 -Wall -lsodium -o testclient ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testclient.c * Compile with: gcc -O2 -Wall -lsodium -o testclient ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testclient.c
* *
* Command line arguments are the ip and port to connect and send the file to. * Command line arguments are the ip and port to connect and send the file to.
* EX: ./testclient 127.0.0.1 33445 filename.txt * EX: ./testclient 127.0.0.1 33445 filename.txt
* *
@ -25,7 +25,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>. * along with Tox. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include "../core/network.h" #include "../core/network.h"
@ -49,17 +49,21 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
uint32_t i; uint32_t i;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
printf("--------------------BEGIN-----------------------------\n"); printf("--------------------BEGIN-----------------------------\n");
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (data[i] < 16) if (data[i] < 16)
printf("0"); printf("0");
printf("%hhX",data[i]);
printf("%hhX", data[i]);
} }
printf("\n--------------------END-----------------------------\n\n\n"); printf("\n--------------------END-----------------------------\n\n\n");
} }
void printip(IP_Port ip_port) void printip(IP_Port ip_port)
{ {
printf("\nIP: %u.%u.%u.%u Port: %u", ip_port.ip.c[0], ip_port.ip.c[1], ip_port.ip.c[2], ip_port.ip.c[3], ntohs(ip_port.port)); printf("\nIP: %u.%u.%u.%u Port: %u", ip_port.ip.c[0], ip_port.ip.c[1], ip_port.ip.c[2], ip_port.ip.c[3],
ntohs(ip_port.port));
} }
/* /*
void printpackets(Data test) void printpackets(Data test)
@ -80,9 +84,9 @@ void printconnection(int connection_id)
printf("--------------------BEGIN---------------------\n"); printf("--------------------BEGIN---------------------\n");
IP_Port ip_port = connections[connection_id].ip_port; IP_Port ip_port = connections[connection_id].ip_port;
printf("IP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port)); printf("IP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port));
printf("status: %u, inbound: %u, SYNC_rate: %u\n", connections[connection_id].status, printf("status: %u, inbound: %u, SYNC_rate: %u\n", connections[connection_id].status,
connections[connection_id].inbound, connections[connection_id].SYNC_rate); connections[connection_id].inbound, connections[connection_id].SYNC_rate);
printf("data rate: %u, last sync: %llu, last sent: %llu, last recv: %llu \n", connections[connection_id].data_rate, printf("data rate: %u, last sync: %llu, last sent: %llu, last recv: %llu \n", connections[connection_id].data_rate,
connections[connection_id].last_SYNC, connections[connection_id].last_sent, connections[connection_id].last_recv); connections[connection_id].last_SYNC, connections[connection_id].last_sent, connections[connection_id].last_recv);
int i; int i;
for(i =0; i < MAX_QUEUE_NUM; i++) for(i =0; i < MAX_QUEUE_NUM; i++)
@ -97,12 +101,12 @@ void printconnection(int connection_id)
} }
Data sendbuffer[MAX_QUEUE_NUM]; Data sendbuffer[MAX_QUEUE_NUM];
Data recvbuffer[MAX_QUEUE_NUM]; Data recvbuffer[MAX_QUEUE_NUM];
printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n", printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n",
connections[connection_id].recv_packetnum, connections[connection_id].recv_packetnum,
connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum, connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
connections[connection_id].successful_sent, connections[connection_id].successful_sent,
connections[connection_id].successful_read); connections[connection_id].successful_read);
printf("req packets: \n"); printf("req packets: \n");
for(i = 0; i < BUFFER_PACKET_NUM; i++) for(i = 0; i < BUFFER_PACKET_NUM; i++)
{ {
@ -112,7 +116,7 @@ void printconnection(int connection_id)
connections[connection_id].recv_counter, connections[connection_id].send_counter); connections[connection_id].recv_counter, connections[connection_id].send_counter);
printf("--------------------END---------------------\n"); printf("--------------------END---------------------\n");
} }
*/ */
@ -120,26 +124,26 @@ void printconnection(int connection_id)
/*run doLossless_UDP(); */ /*run doLossless_UDP(); */
void Lossless_UDP() void Lossless_UDP()
{ {
/* IP_Port ip_port; /* IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; uint32_t length;
while (receivepacket(&ip_port, data, &length) != -1) { while (receivepacket(&ip_port, data, &length) != -1) {
printf("packet with length: %u\n", length); */ printf("packet with length: %u\n", length); */
/* if(rand() % 3 != 1)//add packet loss /* if(rand() % 3 != 1)//add packet loss
{ */ { */
/* /*
if (LosslessUDP_handlepacket(data, length, ip_port)) if (LosslessUDP_handlepacket(data, length, ip_port))
printpacket(data, length, ip_port); printpacket(data, length, ip_port);
else else
printf("Received handled packet with length: %u\n", length); //printconnection(0); */ printf("Received handled packet with length: %u\n", length); //printconnection(0); */
/* } */ /* } */
/* }*/ /* }*/
networking_poll(); networking_poll();
doLossless_UDP(); doLossless_UDP();
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -148,15 +152,16 @@ int main(int argc, char *argv[])
printf("usage: %s ip port filename\n", argv[0]); printf("usage: %s ip port filename\n", argv[0]);
exit(0); exit(0);
} }
uint8_t buffer[512]; uint8_t buffer[512];
int read; int read;
FILE *file = fopen(argv[3], "rb"); FILE *file = fopen(argv[3], "rb");
if (file == NULL) if (file == NULL)
return 1; return 1;
/* initialize networking */ /* initialize networking */
/* bind to ip 0.0.0.0:PORT */ /* bind to ip 0.0.0.0:PORT */
IP ip; IP ip;
@ -169,36 +174,43 @@ int main(int argc, char *argv[])
printip(serverip); printip(serverip);
int connection = new_connection(serverip); int connection = new_connection(serverip);
uint64_t timer = current_time(); uint64_t timer = current_time();
while (1) { while (1) {
/* printconnection(connection); */ /* printconnection(connection); */
Lossless_UDP(); Lossless_UDP();
if (is_connected(connection) == 3) { if (is_connected(connection) == 3) {
printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer)); printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer));
break; break;
} }
if (is_connected(connection) == 0) { if (is_connected(connection) == 0) {
printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer)); printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer));
return 1; return 1;
} }
c_sleep(1); c_sleep(1);
} }
timer = current_time(); timer = current_time();
LosslessUDP_init(); LosslessUDP_init();
/*read first part of file */ /*read first part of file */
read = fread(buffer, 1, 512, file); read = fread(buffer, 1, 512, file);
while (1) { while (1) {
/* printconnection(connection); */ /* printconnection(connection); */
Lossless_UDP(); Lossless_UDP();
if (is_connected(connection) == 3) { if (is_connected(connection) == 3) {
if (write_packet(connection, buffer, read)) { if (write_packet(connection, buffer, read)) {
/* printf("Wrote data.\n"); */ /* printf("Wrote data.\n"); */
read = fread(buffer, 1, 512, file); read = fread(buffer, 1, 512, file);
} }
/* printf("%u\n", sendqueue(connection)); */ /* printf("%u\n", sendqueue(connection)); */
if (sendqueue(connection) == 0) { if (sendqueue(connection) == 0) {
if (read == 0) { if (read == 0) {
@ -206,13 +218,13 @@ int main(int argc, char *argv[])
break; break;
} }
} }
} } else {
else {
printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer)); printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer));
return 0; return 0;
} }
/* c_sleep(1); */ /* c_sleep(1); */
} }
return 0; return 0;
} }

View File

@ -1,11 +1,11 @@
/* Lossless_UDP testserver /* Lossless_UDP testserver
* A program that waits for a lossless UDP connection and then saves all the data received to a file. * A program that waits for a lossless UDP connection and then saves all the data received to a file.
* NOTE: this program simulates a 33% packet loss. * NOTE: this program simulates a 33% packet loss.
* *
* Best used in combination with Lossless_UDP_testclient * Best used in combination with Lossless_UDP_testclient
* *
* Compile with: gcc -O2 -Wall -lsodium -o testserver ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testserver.c * Compile with: gcc -O2 -Wall -lsodium -o testserver ../core/network.c ../core/Lossless_UDP.c Lossless_UDP_testserver.c
* *
* Command line argument is the name of the file to save what we receive to. * Command line argument is the name of the file to save what we receive to.
* EX: ./testserver filename1.txt * EX: ./testserver filename1.txt
* *
@ -25,7 +25,7 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>. * along with Tox. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include "../core/network.h" #include "../core/network.h"
@ -50,11 +50,14 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
uint32_t i; uint32_t i;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length); printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
printf("--------------------BEGIN-----------------------------\n"); printf("--------------------BEGIN-----------------------------\n");
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if(data[i] < 16) if (data[i] < 16)
printf("0"); printf("0");
printf("%hhX",data[i]);
printf("%hhX", data[i]);
} }
printf("\n--------------------END-----------------------------\n\n\n"); printf("\n--------------------END-----------------------------\n\n\n");
} }
@ -77,9 +80,9 @@ void printconnection(int connection_id)
printf("--------------------BEGIN---------------------\n"); printf("--------------------BEGIN---------------------\n");
IP_Port ip_port = connections[connection_id].ip_port; IP_Port ip_port = connections[connection_id].ip_port;
printf("IP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port)); printf("IP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port));
printf("status: %u, inbound: %u, SYNC_rate: %u\n", connections[connection_id].status, printf("status: %u, inbound: %u, SYNC_rate: %u\n", connections[connection_id].status,
connections[connection_id].inbound, connections[connection_id].SYNC_rate); connections[connection_id].inbound, connections[connection_id].SYNC_rate);
printf("data rate: %u, last sync: %llu, last sent: %llu, last recv: %llu \n", connections[connection_id].data_rate, printf("data rate: %u, last sync: %llu, last sent: %llu, last recv: %llu \n", connections[connection_id].data_rate,
connections[connection_id].last_SYNC, connections[connection_id].last_sent, connections[connection_id].last_recv); connections[connection_id].last_SYNC, connections[connection_id].last_sent, connections[connection_id].last_recv);
int i; int i;
for(i =0; i < MAX_QUEUE_NUM; i++) for(i =0; i < MAX_QUEUE_NUM; i++)
@ -94,12 +97,12 @@ void printconnection(int connection_id)
} }
Data sendbuffer[MAX_QUEUE_NUM]; Data sendbuffer[MAX_QUEUE_NUM];
Data recvbuffer[MAX_QUEUE_NUM]; Data recvbuffer[MAX_QUEUE_NUM];
printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n", printf("recv_num: %u, orecv_num: %u, sent_packetnum %u, osent_packetnum: %u, successful_sent: %u, successful_read: %u\n",
connections[connection_id].recv_packetnum, connections[connection_id].recv_packetnum,
connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum, connections[connection_id].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
connections[connection_id].successful_sent, connections[connection_id].successful_sent,
connections[connection_id].successful_read); connections[connection_id].successful_read);
printf("req packets: \n"); printf("req packets: \n");
for(i = 0; i < BUFFER_PACKET_NUM; i++) for(i = 0; i < BUFFER_PACKET_NUM; i++)
{ {
@ -109,7 +112,7 @@ void printconnection(int connection_id)
connections[connection_id].recv_counter, connections[connection_id].send_counter); connections[connection_id].recv_counter, connections[connection_id].send_counter);
printf("--------------------END---------------------\n"); printf("--------------------END---------------------\n");
} }
*/ */
@ -121,20 +124,20 @@ void Lossless_UDP()
// uint8_t data[MAX_UDP_PACKET_SIZE]; // uint8_t data[MAX_UDP_PACKET_SIZE];
// uint32_t length; // uint32_t length;
// while (receivepacket(&ip_port, data, &length) != -1) { // while (receivepacket(&ip_port, data, &length) != -1) {
//if(rand() % 3 != 1)//add packet loss //if(rand() % 3 != 1)//add packet loss
//{ //{
// if (LosslessUDP_handlepacket(data, length, ip_port)) { // if (LosslessUDP_handlepacket(data, length, ip_port)) {
// printpacket(data, length, ip_port); // printpacket(data, length, ip_port);
// } else { // } else {
//printconnection(0); //printconnection(0);
// printf("Received handled packet with length: %u\n", length); // printf("Received handled packet with length: %u\n", length);
// } // }
//} //}
// } // }
networking_poll(); networking_poll();
doLossless_UDP(); doLossless_UDP();
} }
@ -144,61 +147,69 @@ int main(int argc, char *argv[])
printf("usage: %s filename\n", argv[0]); printf("usage: %s filename\n", argv[0]);
exit(0); exit(0);
} }
uint8_t buffer[512]; uint8_t buffer[512];
int read; int read;
FILE *file = fopen(argv[1], "wb"); FILE *file = fopen(argv[1], "wb");
if (file == NULL) if (file == NULL)
return 1; return 1;
//initialize networking //initialize networking
//bind to ip 0.0.0.0:PORT //bind to ip 0.0.0.0:PORT
IP ip; IP ip;
ip.i = 0; ip.i = 0;
init_networking(ip, PORT); init_networking(ip, PORT);
perror("Initialization"); perror("Initialization");
int connection; int connection;
uint64_t timer = current_time(); uint64_t timer = current_time();
LosslessUDP_init(); LosslessUDP_init();
while (1) { while (1) {
Lossless_UDP(); Lossless_UDP();
connection = incoming_connection(); connection = incoming_connection();
if(connection != -1) {
if(is_connected(connection) == 2) { if (connection != -1) {
if (is_connected(connection) == 2) {
printf("Received the connection.\n"); printf("Received the connection.\n");
} }
break; break;
} }
c_sleep(1); c_sleep(1);
} }
timer = current_time(); timer = current_time();
while (1) { while (1) {
//printconnection(0); //printconnection(0);
Lossless_UDP(); Lossless_UDP();
if (is_connected(connection) >= 2) { if (is_connected(connection) >= 2) {
kill_connection_in(connection, 3000000); kill_connection_in(connection, 3000000);
read = read_packet(connection, buffer); read = read_packet(connection, buffer);
if (read != 0) { if (read != 0) {
// printf("Received data.\n"); // printf("Received data.\n");
if (!fwrite(buffer, read, 1, file)) if (!fwrite(buffer, read, 1, file))
printf("file write error\n"); printf("file write error\n");
} }
} }
if(is_connected(connection) == 4) {
if (is_connected(connection) == 4) {
printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer)); printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer));
fclose(file); fclose(file);
return 1; return 1;
} }
c_sleep(1); c_sleep(1);
} }
return 0; return 0;
} }

View File

@ -55,35 +55,37 @@
* networking_requesthandler and so cannot take a Messenger * */ * networking_requesthandler and so cannot take a Messenger * */
static Messenger *m; static Messenger *m;
void print_request(uint8_t * public_key, uint8_t * data, uint16_t length, void* userdata) void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
{ {
printf("Friend request received from: \n"); printf("Friend request received from: \n");
printf("ClientID: "); printf("ClientID: ");
uint32_t j; uint32_t j;
for(j = 0; j < 32; j++)
{ for (j = 0; j < 32; j++) {
if(public_key[j] < 16) if (public_key[j] < 16)
printf("0"); printf("0");
printf("%hhX", public_key[j]); printf("%hhX", public_key[j]);
} }
printf("\nOf length: %u with data: %s \n", length, data); printf("\nOf length: %u with data: %s \n", length, data);
if(length != sizeof("Install Gentoo")) if (length != sizeof("Install Gentoo")) {
{
return; return;
} }
if(memcmp(data , "Install Gentoo", sizeof("Install Gentoo")) == 0 )
//if the request contained the message of peace the person is obviously a friend so we add him. if (memcmp(data , "Install Gentoo", sizeof("Install Gentoo")) == 0 )
//if the request contained the message of peace the person is obviously a friend so we add him.
{ {
printf("Friend request accepted.\n"); printf("Friend request accepted.\n");
m_addfriend_norequest(m, public_key); m_addfriend_norequest(m, public_key);
} }
} }
void print_message(Messenger *m, int friendnumber, uint8_t * string, uint16_t length, void* userdata) void print_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
printf("Message with length %u received from %u: %s \n", length, friendnumber, string); printf("Message with length %u received from %u: %s \n", length, friendnumber, string);
m_sendmessage(m, friendnumber, (uint8_t*)"Test1", 6); m_sendmessage(m, friendnumber, (uint8_t *)"Test1", 6);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -94,19 +96,24 @@ int main(int argc, char *argv[])
} }
m = initMessenger(); m = initMessenger();
if( !m ){
if ( !m ) {
fputs("Failed to allocate messenger datastructure\n", stderr); fputs("Failed to allocate messenger datastructure\n", stderr);
exit(0); exit(0);
} }
if(argc > 3) { if (argc > 3) {
IP_Port bootstrap_ip_port; IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2])); bootstrap_ip_port.port = htons(atoi(argv[2]));
bootstrap_ip_port.ip.i = inet_addr(argv[1]); bootstrap_ip_port.ip.i = inet_addr(argv[1]);
DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
} else { } else {
FILE *file = fopen(argv[1], "rb"); FILE *file = fopen(argv[1], "rb");
if ( file==NULL ){return 1;}
if ( file == NULL ) {
return 1;
}
int read; int read;
uint8_t buffer[128000]; uint8_t buffer[128000];
read = fread(buffer, 1, 128000, file); read = fread(buffer, 1, 128000, file);
@ -114,6 +121,7 @@ int main(int argc, char *argv[])
fclose(file); fclose(file);
} }
m_callback_friendrequest(m, print_request, NULL); m_callback_friendrequest(m, print_request, NULL);
m_callback_friendmessage(m, print_message, NULL); m_callback_friendmessage(m, print_message, NULL);
@ -121,39 +129,52 @@ int main(int argc, char *argv[])
uint32_t i; uint32_t i;
uint8_t address[FRIEND_ADDRESS_SIZE]; uint8_t address[FRIEND_ADDRESS_SIZE];
getaddress(m, address); getaddress(m, address);
for(i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
if(address[i] < 16) for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
if (address[i] < 16)
printf("0"); printf("0");
printf("%hhX",address[i]);
printf("%hhX", address[i]);
} }
setname(m, (uint8_t *)"Anon", 5); setname(m, (uint8_t *)"Anon", 5);
char temp_id[128]; char temp_id[128];
printf("\nEnter the address of the friend you wish to add (38 bytes HEX format):\n"); printf("\nEnter the address of the friend you wish to add (38 bytes HEX format):\n");
if(scanf("%s", temp_id) != 1) {
if (scanf("%s", temp_id) != 1) {
return 1; return 1;
} }
int num = m_addfriend(m, hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
int num = m_addfriend(m, hex_string_to_bin(temp_id), (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
perror("Initialization"); perror("Initialization");
while(1) { while (1) {
uint8_t name[128]; uint8_t name[128];
getname(m, num, name); getname(m, num, name);
printf("%s\n", name); printf("%s\n", name);
m_sendmessage(m, num, (uint8_t*)"Test", 5); m_sendmessage(m, num, (uint8_t *)"Test", 5);
doMessenger(m); doMessenger(m);
c_sleep(30); c_sleep(30);
FILE *file = fopen("Save.bak", "wb"); FILE *file = fopen("Save.bak", "wb");
if ( file==NULL ){return 1;}
uint8_t * buffer = malloc(Messenger_size(m)); if ( file == NULL ) {
return 1;
}
uint8_t *buffer = malloc(Messenger_size(m));
Messenger_save(m, buffer); Messenger_save(m, buffer);
size_t write_result = fwrite(buffer, 1, Messenger_size(m), file); size_t write_result = fwrite(buffer, 1, Messenger_size(m), file);
if (write_result < Messenger_size(m)) {return 1;}
if (write_result < Messenger_size(m)) {
return 1;
}
free(buffer); free(buffer);
fclose(file); fclose(file);
} }
cleanupMessenger(m); cleanupMessenger(m);
} }

View File

@ -10,7 +10,7 @@ double get_time()
LARGE_INTEGER t, f; LARGE_INTEGER t, f;
QueryPerformanceCounter(&t); QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&f); QueryPerformanceFrequency(&f);
return (double)t.QuadPart/(double)f.QuadPart; return (double)t.QuadPart / (double)f.QuadPart;
} }
#else #else
@ -23,7 +23,7 @@ double get_time()
struct timeval t; struct timeval t;
struct timezone tzp; struct timezone tzp;
gettimeofday(&t, &tzp); gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6; return t.tv_sec + t.tv_usec * 1e-6;
} }
#endif #endif
@ -35,16 +35,16 @@ double get_time()
void rand_bytes(uint8_t *b, size_t blen) void rand_bytes(uint8_t *b, size_t blen)
{ {
size_t i; size_t i;
for (i = 0; i < blen; i++)
{ for (i = 0; i < blen; i++) {
b[i] = rand(); b[i] = rand();
} }
} }
int main(int argc, char* argv[]) int main(int argc, char *argv[])
{ {
const int numtrials = 10000; const int numtrials = 10000;
unsigned char pk1[crypto_box_PUBLICKEYBYTES]; unsigned char pk1[crypto_box_PUBLICKEYBYTES];
unsigned char sk1[crypto_box_SECRETKEYBYTES]; unsigned char sk1[crypto_box_SECRETKEYBYTES];
unsigned char pk2[crypto_box_PUBLICKEYBYTES]; unsigned char pk2[crypto_box_PUBLICKEYBYTES];
@ -52,7 +52,7 @@ int main(int argc, char* argv[])
unsigned char k1[crypto_box_BEFORENMBYTES]; unsigned char k1[crypto_box_BEFORENMBYTES];
unsigned char k2[crypto_box_BEFORENMBYTES]; unsigned char k2[crypto_box_BEFORENMBYTES];
unsigned char n[crypto_box_NONCEBYTES]; unsigned char n[crypto_box_NONCEBYTES];
unsigned char m[500]; unsigned char m[500];
unsigned char c[sizeof(m) + ENCRYPTION_PADDING]; unsigned char c[sizeof(m) + ENCRYPTION_PADDING];
@ -78,46 +78,50 @@ int main(int argc, char* argv[])
printf("starting slow...\n"); printf("starting slow...\n");
starttime = get_time(); starttime = get_time();
for (trialno = 0; trialno < numtrials; trialno++)
{ for (trialno = 0; trialno < numtrials; trialno++) {
encrypt_data(pk1, sk2, n, m, sizeof(m), c); encrypt_data(pk1, sk2, n, m, sizeof(m), c);
decrypt_data(pk2, sk1, n, c, sizeof(c), m); decrypt_data(pk2, sk1, n, c, sizeof(c), m);
} }
endtime = get_time(); endtime = get_time();
slow_time = endtime-starttime; slow_time = endtime - starttime;
printf("starting fast...\n"); printf("starting fast...\n");
starttime = get_time(); starttime = get_time();
for (trialno = 0; trialno < numtrials; trialno++)
{ for (trialno = 0; trialno < numtrials; trialno++) {
encrypt_data_fast(k1, n, m, sizeof(m), c); encrypt_data_fast(k1, n, m, sizeof(m), c);
decrypt_data_fast(k2, n, c, sizeof(c), m); decrypt_data_fast(k2, n, c, sizeof(c), m);
} }
endtime = get_time(); endtime = get_time();
fast_time = endtime-starttime; fast_time = endtime - starttime;
printf("starting keygen...\n"); printf("starting keygen...\n");
starttime = get_time(); starttime = get_time();
for (trialno = 0; trialno < numtrials; trialno++)
{ for (trialno = 0; trialno < numtrials; trialno++) {
crypto_box_keypair(pk1, sk1); crypto_box_keypair(pk1, sk1);
crypto_box_keypair(pk2, sk2); crypto_box_keypair(pk2, sk2);
} }
endtime = get_time(); endtime = get_time();
keygen_time = endtime-starttime; keygen_time = endtime - starttime;
printf("starting precompute...\n"); printf("starting precompute...\n");
starttime = get_time(); starttime = get_time();
for (trialno = 0; trialno < numtrials; trialno++)
{ for (trialno = 0; trialno < numtrials; trialno++) {
encrypt_precompute(pk1, sk2, k); encrypt_precompute(pk1, sk2, k);
encrypt_precompute(pk2, sk1, k); encrypt_precompute(pk2, sk1, k);
} }
endtime = get_time(); endtime = get_time();
precompute_time = endtime-starttime; precompute_time = endtime - starttime;
printf("\n"); printf("\n");
printf("trials: %i\n", 2*numtrials); printf("trials: %i\n", 2 * numtrials);
printf("\n"); printf("\n");
printf("slow time: %f sec\n", slow_time); printf("slow time: %f sec\n", slow_time);
printf("fast time: %f sec\n", fast_time); printf("fast time: %f sec\n", fast_time);
@ -126,8 +130,8 @@ int main(int argc, char* argv[])
printf("\n"); printf("\n");
printf("Speed boost: %.1f%%\n", slow_time * 100 / fast_time); printf("Speed boost: %.1f%%\n", slow_time * 100 / fast_time);
printf("\n"); printf("\n");
printf("slow: %.1f per second\n", 2*numtrials/slow_time); printf("slow: %.1f per second\n", 2 * numtrials / slow_time);
printf("fast: %.1f per second\n", 2*numtrials/fast_time); printf("fast: %.1f per second\n", 2 * numtrials / fast_time);
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/* misc_tools.c /* misc_tools.c
* *
* Miscellaneous functions and data structures for doing random things. * Miscellaneous functions and data structures for doing random things.
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
@ -18,9 +18,9 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>. * along with Tox. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#include "misc_tools.h" #include "misc_tools.h"
#include <string.h> #include <string.h>
@ -32,14 +32,15 @@
#endif // DEBUG #endif // DEBUG
/* TODO: rewrite */ /* TODO: rewrite */
unsigned char * hex_string_to_bin(char hex_string[]) unsigned char *hex_string_to_bin(char hex_string[])
{ {
size_t len = strlen(hex_string); size_t len = strlen(hex_string);
unsigned char *val = malloc(len); unsigned char *val = malloc(len);
char *pos = hex_string; char *pos = hex_string;
int i; int i;
for(i = 0; i < len; ++i, pos+=2)
sscanf(pos,"%2hhx",&val[i]); for (i = 0; i < len; ++i, pos += 2)
sscanf(pos, "%2hhx", &val[i]);
return val; return val;
} }

View File

@ -1,5 +1,5 @@
/* misc_tools.h /* misc_tools.h
* *
* Miscellaneous functions and data structures for doing random things. * Miscellaneous functions and data structures for doing random things.
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
@ -18,51 +18,51 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>. * along with Tox. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#ifndef MISC_TOOLS_H #ifndef MISC_TOOLS_H
#define MISC_TOOLS_H #define MISC_TOOLS_H
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
unsigned char* hex_string_to_bin(char hex_string[]); unsigned char *hex_string_to_bin(char hex_string[]);
/*********************Debugging Macros******************** /*********************Debugging Macros********************
* wiki.tox.im/index.php/Internal_functions_and_data_structures#Debugging * wiki.tox.im/index.php/Internal_functions_and_data_structures#Debugging
*********************************************************/ *********************************************************/
#ifdef DEBUG #ifdef DEBUG
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#define DEBUG_PRINT(str, ...) do { \ #define DEBUG_PRINT(str, ...) do { \
char msg[1000]; \ char msg[1000]; \
sprintf(msg, "%s(): line %d (file %s): %s%%c\n", __FUNCTION__, __LINE__, __FILE__, str); \ sprintf(msg, "%s(): line %d (file %s): %s%%c\n", __FUNCTION__, __LINE__, __FILE__, str); \
fprintf(stderr, msg, __VA_ARGS__); \ fprintf(stderr, msg, __VA_ARGS__); \
} while (0) } while (0)
#define WARNING(...) do { \ #define WARNING(...) do { \
fprintf(stderr, "warning in "); \ fprintf(stderr, "warning in "); \
DEBUG_PRINT(__VA_ARGS__, ' '); \ DEBUG_PRINT(__VA_ARGS__, ' '); \
} while (0) } while (0)
#define INFO(...) do { \ #define INFO(...) do { \
DEBUG_PRINT(__VA_ARGS__, ' '); \ DEBUG_PRINT(__VA_ARGS__, ' '); \
} while (0) } while (0)
#undef ERROR #undef ERROR
#define ERROR(exit_status, ...) do { \ #define ERROR(exit_status, ...) do { \
fprintf(stderr, "error in "); \ fprintf(stderr, "error in "); \
DEBUG_PRINT(__VA_ARGS__, ' '); \ DEBUG_PRINT(__VA_ARGS__, ' '); \
exit(exit_status); \ exit(exit_status); \
} while (0) } while (0)
#else #else
#define WARNING(...) #define WARNING(...)
#define INFO(...) #define INFO(...)
#undef ERROR #undef ERROR
#define ERROR(...) #define ERROR(...)
#endif // DEBUG #endif // DEBUG
/************************Linked List*********************** /************************Linked List***********************
@ -81,31 +81,31 @@ unsigned char* hex_string_to_bin(char hex_string[]);
#define TOX_LIST_GET_VALUE(tmp_name, name_in_parent, parent_type) GET_PARENT(tmp_name, name_in_parent, parent_type) #define TOX_LIST_GET_VALUE(tmp_name, name_in_parent, parent_type) GET_PARENT(tmp_name, name_in_parent, parent_type)
typedef struct tox_list { typedef struct tox_list {
struct tox_list *prev, *next; struct tox_list *prev, *next;
} tox_list_t; } tox_list_t;
/* Returns a new tox_list_t. */ /* Returns a new tox_list_t. */
static inline void tox_list_new(tox_list_t* lst) static inline void tox_list_new(tox_list_t *lst)
{ {
lst->prev = lst->next = lst; lst->prev = lst->next = lst;
} }
/* Inserts a new tox_lst after lst and returns it. */ /* Inserts a new tox_lst after lst and returns it. */
static inline void tox_list_add(tox_list_t* lst, tox_list_t* new_lst) static inline void tox_list_add(tox_list_t *lst, tox_list_t *new_lst)
{ {
tox_list_new(new_lst); tox_list_new(new_lst);
new_lst->next = lst->next; new_lst->next = lst->next;
new_lst->next->prev = new_lst; new_lst->next->prev = new_lst;
lst->next = new_lst; lst->next = new_lst;
new_lst->prev = lst; new_lst->prev = lst;
} }
static inline void tox_list_remove(tox_list_t* lst) static inline void tox_list_remove(tox_list_t *lst)
{ {
lst->prev->next = lst->next; lst->prev->next = lst->next;
lst->next->prev = lst->prev; lst->next->prev = lst->prev;
} }
/****************************Array*************************** /****************************Array***************************
@ -124,7 +124,7 @@ static inline void tox_array_init(struct tox_array *arr)
{ {
arr->size = 1; arr->size = 1;
arr->length = 0; arr->length = 0;
arr->data = malloc(sizeof(void*)); arr->data = malloc(sizeof(void *));
} }
static inline void tox_array_delete(struct tox_array *arr) static inline void tox_array_delete(struct tox_array *arr)
@ -139,22 +139,24 @@ static inline void tox_array_delete(struct tox_array *arr)
static inline void tox_array_shrink_to_fit(struct tox_array *arr, int32_t extra) static inline void tox_array_shrink_to_fit(struct tox_array *arr, int32_t extra)
{ {
arr->size = arr->length + extra; arr->size = arr->length + extra;
arr->data = realloc(arr->data, arr->size * sizeof(void*)); arr->data = realloc(arr->data, arr->size * sizeof(void *));
} }
static inline void _tox_array_push(struct tox_array *arr, void *new) static inline void _tox_array_push(struct tox_array *arr, void *new)
{ {
if (arr->length+1 >= arr->size) if (arr->length + 1 >= arr->size)
tox_array_shrink_to_fit(arr, arr->size); tox_array_shrink_to_fit(arr, arr->size);
arr->data[arr->length++] = new; arr->data[arr->length++] = new;
} }
#define tox_array_push(arr, new) _tox_array_push(arr, (void*)new) #define tox_array_push(arr, new) _tox_array_push(arr, (void*)new)
static inline void* tox_array_pop(struct tox_array *arr) static inline void *tox_array_pop(struct tox_array *arr)
{ {
if (arr->length-1 < arr->size/4) if (arr->length - 1 < arr->size / 4)
tox_array_shrink_to_fit(arr, arr->length*2); tox_array_shrink_to_fit(arr, arr->length * 2);
return arr->data[arr->length--];
return arr->data[arr->length--];
} }
#endif // MISC_TOOLS_H #endif // MISC_TOOLS_H

View File

@ -57,17 +57,18 @@ void get_id(Messenger *m, char *data)
int i = 0; int i = 0;
uint8_t address[FRIEND_ADDRESS_SIZE]; uint8_t address[FRIEND_ADDRESS_SIZE];
getaddress(m, address); getaddress(m, address);
for(; i < FRIEND_ADDRESS_SIZE; i++)
{ for (; i < FRIEND_ADDRESS_SIZE; i++) {
sprintf(data + 2*i + offset, "%02X ", address[i]); sprintf(data + 2 * i + offset, "%02X ", address[i]);
} }
} }
void new_lines(char *line) void new_lines(char *line)
{ {
int i = 0; int i = 0;
for (i = HISTORY-1; i > 0; i--)
strncpy(lines[i], lines[i-1], STRING_LENGTH - 1); for (i = HISTORY - 1; i > 0; i--)
strncpy(lines[i], lines[i - 1], STRING_LENGTH - 1);
strncpy(lines[0], line, STRING_LENGTH - 1); strncpy(lines[0], line, STRING_LENGTH - 1);
do_refresh(); do_refresh();
@ -79,46 +80,52 @@ void print_friendlist(Messenger *m)
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
int i = 0; int i = 0;
new_lines("[i] Friend List:"); new_lines("[i] Friend List:");
while(getname(m, i, (uint8_t *)name) != -1) {
while (getname(m, i, (uint8_t *)name) != -1) {
/* account for the longest name and the longest "base" string */ /* account for the longest name and the longest "base" string */
char fstring[MAX_NAME_LENGTH + strlen("[i] Friend: NULL\n\tid: ")]; char fstring[MAX_NAME_LENGTH + strlen("[i] Friend: NULL\n\tid: ")];
if (strlen(name) <= 0) { if (strlen(name) <= 0) {
sprintf(fstring, "[i] Friend: No Friend!\n\tid: %i", i); sprintf(fstring, "[i] Friend: No Friend!\n\tid: %i", i);
} else { } else {
sprintf(fstring, "[i] Friend: %s\n\tid: %i", (uint8_t*)name, i); sprintf(fstring, "[i] Friend: %s\n\tid: %i", (uint8_t *)name, i);
} }
i++; i++;
new_lines(fstring); new_lines(fstring);
} }
if(i == 0) if (i == 0)
new_lines("\tno friends! D:"); new_lines("\tno friends! D:");
} }
char *format_message(Messenger *m, char *message, int friendnum) char *format_message(Messenger *m, char *message, int friendnum)
{ {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
if (friendnum != -1) { if (friendnum != -1) {
getname(m, friendnum, (uint8_t*)name); getname(m, friendnum, (uint8_t *)name);
} else { } else {
getself_name(m, (uint8_t*)name, sizeof(name)); getself_name(m, (uint8_t *)name, sizeof(name));
} }
char *msg = malloc(100+strlen(message)+strlen(name)+1);
char *msg = malloc(100 + strlen(message) + strlen(name) + 1);
time_t rawtime; time_t rawtime;
struct tm * timeinfo; struct tm *timeinfo;
time ( &rawtime ); time ( &rawtime );
timeinfo = localtime ( &rawtime ); timeinfo = localtime ( &rawtime );
char* time = asctime(timeinfo); char *time = asctime(timeinfo);
size_t len = strlen(time); size_t len = strlen(time);
time[len-1] = '\0'; time[len - 1] = '\0';
if (friendnum != -1) { if (friendnum != -1) {
sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message); sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message);
} else { } else {
// This message came from ourselves // This message came from ourselves
sprintf(msg, "%s <%s> %s", time, name, message); sprintf(msg, "%s <%s> %s", time, name, message);
} }
return msg; return msg;
} }
@ -126,110 +133,127 @@ void line_eval(Messenger *m, char *line)
{ {
if (line[0] == '/') { if (line[0] == '/') {
char inpt_command = line[1]; char inpt_command = line[1];
char prompt[STRING_LENGTH+2] = "> "; char prompt[STRING_LENGTH + 2] = "> ";
int prompt_offset = 3; int prompt_offset = 3;
strcat(prompt, line); strcat(prompt, line);
new_lines(prompt); new_lines(prompt);
if (inpt_command == 'f') { // add friend command: /f ID if (inpt_command == 'f') { // add friend command: /f ID
int i; int i;
char temp_id[128]; char temp_id[128];
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
temp_id[i] = line[i+prompt_offset]; temp_id[i] = line[i + prompt_offset];
unsigned char *bin_string = hex_string_to_bin(temp_id); unsigned char *bin_string = hex_string_to_bin(temp_id);
int num = m_addfriend(m, bin_string, (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); int num = m_addfriend(m, bin_string, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
free(bin_string); free(bin_string);
char numstring[100]; char numstring[100];
switch (num) { switch (num) {
case FAERR_TOOLONG: case FAERR_TOOLONG:
sprintf(numstring, "[i] Message is too long."); sprintf(numstring, "[i] Message is too long.");
break; break;
case FAERR_NOMESSAGE:
sprintf(numstring, "[i] Please add a message to your request."); case FAERR_NOMESSAGE:
break; sprintf(numstring, "[i] Please add a message to your request.");
case FAERR_OWNKEY: break;
sprintf(numstring, "[i] That appears to be your own ID.");
break; case FAERR_OWNKEY:
case FAERR_ALREADYSENT: sprintf(numstring, "[i] That appears to be your own ID.");
sprintf(numstring, "[i] Friend request already sent."); break;
break;
case FAERR_UNKNOWN: case FAERR_ALREADYSENT:
sprintf(numstring, "[i] Undefined error when adding friend."); sprintf(numstring, "[i] Friend request already sent.");
break; break;
default:
sprintf(numstring, "[i] Added friend as %d.", num); case FAERR_UNKNOWN:
break; sprintf(numstring, "[i] Undefined error when adding friend.");
break;
default:
sprintf(numstring, "[i] Added friend as %d.", num);
break;
} }
new_lines(numstring); new_lines(numstring);
do_refresh(); do_refresh();
} } else if (inpt_command == 'd') {
else if (inpt_command == 'd') {
doMessenger(m); doMessenger(m);
} } else if (inpt_command == 'm') { //message command: /m friendnumber messsage
else if (inpt_command == 'm') { //message command: /m friendnumber messsage
size_t len = strlen(line); size_t len = strlen(line);
if(len < 3)
if (len < 3)
return; return;
char numstring[len-3]; char numstring[len - 3];
char message[len-3]; char message[len - 3];
int i; int i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (line[i+3] != ' ') { if (line[i + 3] != ' ') {
numstring[i] = line[i+3]; numstring[i] = line[i + 3];
} else { } else {
int j; int j;
for (j = (i+1); j < (len+1); j++)
message[j-i-1] = line[j+3]; for (j = (i + 1); j < (len + 1); j++)
message[j - i - 1] = line[j + 3];
break; break;
} }
} }
int num = atoi(numstring); int num = atoi(numstring);
if (m_sendmessage(m, num, (uint8_t*) message, strlen(message) + 1) != 1) {
if (m_sendmessage(m, num, (uint8_t *) message, strlen(message) + 1) != 1) {
new_lines("[i] could not send message"); new_lines("[i] could not send message");
} else { } else {
new_lines(format_message(m, message, -1)); new_lines(format_message(m, message, -1));
} }
} } else if (inpt_command == 'n') {
else if (inpt_command == 'n') {
uint8_t name[MAX_NAME_LENGTH]; uint8_t name[MAX_NAME_LENGTH];
int i = 0; int i = 0;
size_t len = strlen(line); size_t len = strlen(line);
for (i = 3; i < len; i++) { for (i = 3; i < len; i++) {
if (line[i] == 0 || line[i] == '\n') break; if (line[i] == 0 || line[i] == '\n') break;
name[i-3] = line[i];
name[i - 3] = line[i];
} }
name[i-3] = 0;
name[i - 3] = 0;
setname(m, name, i - 2); setname(m, name, i - 2);
char numstring[100]; char numstring[100];
sprintf(numstring, "[i] changed nick to %s", (char*)name); sprintf(numstring, "[i] changed nick to %s", (char *)name);
new_lines(numstring); new_lines(numstring);
} } else if (inpt_command == 'l') {
else if (inpt_command == 'l') {
print_friendlist(m); print_friendlist(m);
} } else if (inpt_command == 's') {
else if (inpt_command == 's') {
uint8_t status[MAX_STATUSMESSAGE_LENGTH]; uint8_t status[MAX_STATUSMESSAGE_LENGTH];
int i = 0; int i = 0;
size_t len = strlen(line); size_t len = strlen(line);
for (i = 3; i < len; i++) { for (i = 3; i < len; i++) {
if (line[i] == 0 || line[i] == '\n') break; if (line[i] == 0 || line[i] == '\n') break;
status[i-3] = line[i];
status[i - 3] = line[i];
} }
status[i-3] = 0;
m_set_statusmessage(m, status, strlen((char*)status) + 1); status[i - 3] = 0;
m_set_statusmessage(m, status, strlen((char *)status) + 1);
char numstring[100]; char numstring[100];
sprintf(numstring, "[i] changed status to %s", (char*)status); sprintf(numstring, "[i] changed status to %s", (char *)status);
new_lines(numstring); new_lines(numstring);
} } else if (inpt_command == 'a') {
else if (inpt_command == 'a') {
uint8_t numf = atoi(line + 3); uint8_t numf = atoi(line + 3);
char numchar[100]; char numchar[100];
if (numf >= num_requests || pending_requests[numf].accepted) { if (numf >= num_requests || pending_requests[numf].accepted) {
sprintf(numchar,"[i] you either didn't receive that request or you already accepted it"); sprintf(numchar, "[i] you either didn't receive that request or you already accepted it");
new_lines(numchar); new_lines(numchar);
} else { } else {
int num = m_addfriend_norequest(m, pending_requests[numf].id); int num = m_addfriend_norequest(m, pending_requests[numf].id);
if (num != -1) { if (num != -1) {
pending_requests[numf].accepted = 1; pending_requests[numf].accepted = 1;
sprintf(numchar, "[i] friend request %u accepted", numf); sprintf(numchar, "[i] friend request %u accepted", numf);
@ -241,16 +265,15 @@ void line_eval(Messenger *m, char *line)
new_lines(numchar); new_lines(numchar);
} }
} }
do_refresh(); do_refresh();
} else if (inpt_command == 'h') { //help
new_lines(help);
} else if (inpt_command == 'i') { //info
char idstring[200];
get_id(m, idstring);
new_lines(idstring);
} }
else if (inpt_command == 'h') { //help
new_lines(help);
}
else if (inpt_command == 'i') { //info
char idstring[200];
get_id(m, idstring);
new_lines(idstring);
}
else if (inpt_command == 'q') { //exit else if (inpt_command == 'q') { //exit
endwin(); endwin();
@ -266,13 +289,15 @@ void line_eval(Messenger *m, char *line)
void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width) void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width)
{ {
strcpy(output,input); strcpy(output, input);
size_t len = strlen(output); size_t len = strlen(output);
int i = 0; int i = 0;
for (i = line_width; i < len; i = i + line_width) { for (i = line_width; i < len; i = i + line_width) {
while (output[i] != ' ' && i != 0) { while (output[i] != ' ' && i != 0) {
i--; i--;
} }
if (i > 0) { if (i > 0) {
output[i] = '\n'; output[i] = '\n';
} }
@ -284,40 +309,47 @@ int count_lines(char *string)
size_t len = strlen(string); size_t len = strlen(string);
int count = 1; int count = 1;
int i; int i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (string[i] == '\n') if (string[i] == '\n')
count++; count++;
} }
return count; return count;
} }
char *appender(char *str, const char c) char *appender(char *str, const char c)
{ {
size_t len = strlen(str); size_t len = strlen(str);
if (len < STRING_LENGTH) { if (len < STRING_LENGTH) {
str[len+1] = str[len]; str[len + 1] = str[len];
str[len] = c; str[len] = c;
} }
return str; return str;
} }
void do_refresh() void do_refresh()
{ {
int count=0; int count = 0;
char wrap_output[STRING_LENGTH]; char wrap_output[STRING_LENGTH];
int L; int L;
int i; int i;
for (i = 0; i < HISTORY; i++) { for (i = 0; i < HISTORY; i++) {
wrap(wrap_output, lines[i], x); wrap(wrap_output, lines[i], x);
L = count_lines(wrap_output); L = count_lines(wrap_output);
count = count + L; count = count + L;
if (count < y) { if (count < y) {
move(y-1-count, 0); move(y - 1 - count, 0);
printw(wrap_output); printw(wrap_output);
clrtoeol(); clrtoeol();
} }
} }
move(y-1, 0);
move(y - 1, 0);
clrtoeol(); clrtoeol();
printw(">> "); printw(">> ");
printw(line); printw(line);
@ -325,7 +357,7 @@ void do_refresh()
refresh(); refresh();
} }
void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void* userdata) void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
{ {
new_lines("[i] received friend request with message:"); new_lines("[i] received friend request with message:");
new_lines((char *)data); new_lines((char *)data);
@ -338,26 +370,28 @@ void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void* us
do_refresh(); do_refresh();
} }
void print_message(Messenger *m, int friendnumber, uint8_t * string, uint16_t length, void* userdata) void print_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
new_lines(format_message(m, (char*)string, friendnumber)); new_lines(format_message(m, (char *)string, friendnumber));
} }
void print_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata) void print_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
if(getname(m, friendnumber, (uint8_t*)name) != -1) {
char msg[100+length]; if (getname(m, friendnumber, (uint8_t *)name) != -1) {
char msg[100 + length];
sprintf(msg, "[i] [%d] %s is now known as %s.", friendnumber, name, string); sprintf(msg, "[i] [%d] %s is now known as %s.", friendnumber, name, string);
new_lines(msg); new_lines(msg);
} }
} }
void print_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata) void print_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
if(getname(m, friendnumber, (uint8_t*)name) != -1) {
char msg[100+length+strlen(name)+1]; if (getname(m, friendnumber, (uint8_t *)name) != -1) {
char msg[100 + length + strlen(name) + 1];
sprintf(msg, "[i] [%d] %s's status changed to %s.", friendnumber, name, string); sprintf(msg, "[i] [%d] %s's status changed to %s.", friendnumber, name, string);
new_lines(msg); new_lines(msg);
} }
@ -375,10 +409,12 @@ void load_key(Messenger *m, char *path)
rewind(data_file); rewind(data_file);
uint8_t data[size]; uint8_t data[size];
if (fread(data, sizeof(uint8_t), size, data_file) != size){
if (fread(data, sizeof(uint8_t), size, data_file) != size) {
fputs("[!] could not read data file! exiting...\n", stderr); fputs("[!] could not read data file! exiting...\n", stderr);
goto FILE_ERROR; goto FILE_ERROR;
} }
Messenger_load(m, data, size); Messenger_load(m, data, size);
} else { } else {
@ -388,24 +424,27 @@ void load_key(Messenger *m, char *path)
Messenger_save(m, data); Messenger_save(m, data);
data_file = fopen(path, "w"); data_file = fopen(path, "w");
if(!data_file) { if (!data_file) {
perror("[!] load_key"); perror("[!] load_key");
exit(1); exit(1);
} }
if (fwrite(data, sizeof(uint8_t), size, data_file) != size){ if (fwrite(data, sizeof(uint8_t), size, data_file) != size) {
fputs("[!] could not write data file! exiting...", stderr); fputs("[!] could not write data file! exiting...", stderr);
goto FILE_ERROR; goto FILE_ERROR;
} }
} }
if(fclose(data_file) < 0) if (fclose(data_file) < 0)
perror("[!] fclose failed"); perror("[!] fclose failed");
return; return;
FILE_ERROR: FILE_ERROR:
if(fclose(data_file) < 0)
if (fclose(data_file) < 0)
perror("[!] fclose failed"); perror("[!] fclose failed");
exit(1); exit(1);
} }
@ -431,15 +470,15 @@ int main(int argc, char *argv[])
exit(0); exit(0);
} }
for(i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
if (argv[i] == NULL){ if (argv[i] == NULL) {
break; break;
} else if(argv[i][0] == '-') { } else if (argv[i][0] == '-') {
if(argv[i][1] == 'h') { if (argv[i][1] == 'h') {
print_help(); print_help();
exit(0); exit(0);
} else if(argv[i][1] == 'f') { } else if (argv[i][1] == 'f') {
if(argv[i + 1] != NULL) if (argv[i + 1] != NULL)
filename = argv[i + 1]; filename = argv[i + 1];
else { else {
fputs("[!] you passed '-f' without giving an argument!\n", stderr); fputs("[!] you passed '-f' without giving an argument!\n", stderr);
@ -449,7 +488,8 @@ int main(int argc, char *argv[])
} }
m = initMessenger(); m = initMessenger();
if( !m ){
if ( !m ) {
fputs("Failed to allocate Messenger datastructure", stderr); fputs("Failed to allocate Messenger datastructure", stderr);
exit(0); exit(0);
} }
@ -474,6 +514,7 @@ int main(int argc, char *argv[])
IP_Port bootstrap_ip_port; IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2])); bootstrap_ip_port.port = htons(atoi(argv[2]));
int resolved_address = resolve_addr(argv[1]); int resolved_address = resolve_addr(argv[1]);
if (resolved_address != 0) if (resolved_address != 0)
bootstrap_ip_port.ip.i = resolved_address; bootstrap_ip_port.ip.i = resolved_address;
else else
@ -483,7 +524,8 @@ int main(int argc, char *argv[])
DHT_bootstrap(bootstrap_ip_port, binary_string); DHT_bootstrap(bootstrap_ip_port, binary_string);
free(binary_string); free(binary_string);
nodelay(stdscr, TRUE); nodelay(stdscr, TRUE);
while(true) {
while (true) {
if (on == 0 && DHT_isconnected()) { if (on == 0 && DHT_isconnected()) {
new_lines("[i] connected to DHT\n[i] define username with /n"); new_lines("[i] connected to DHT\n[i] define username with /n");
on = 1; on = 1;
@ -494,19 +536,22 @@ int main(int argc, char *argv[])
do_refresh(); do_refresh();
c = getch(); c = getch();
if (c == ERR || c == 27) if (c == ERR || c == 27)
continue; continue;
getmaxyx(stdscr, y, x); getmaxyx(stdscr, y, x);
if (c == '\n') { if (c == '\n') {
line_eval(m, line); line_eval(m, line);
strcpy(line, ""); strcpy(line, "");
} else if (c == 8 || c == 127) { } else if (c == 8 || c == 127) {
line[strlen(line)-1] = '\0'; line[strlen(line) - 1] = '\0';
} else if (isalnum(c) || ispunct(c) || c == ' ') { } else if (isalnum(c) || ispunct(c) || c == ' ') {
strcpy(line, appender(line, (char) c)); strcpy(line, appender(line, (char) c));
} }
} }
cleanupMessenger(m); cleanupMessenger(m);
endwin(); endwin();
return 0; return 0;

View File

@ -54,7 +54,7 @@ void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *us
{ {
friend_request_received = 1; friend_request_received = 1;
printf("\n\n[i] received friend request with message\n"); printf("\n\n[i] received friend request with message\n");
printf("'%s'",(char *)data); printf("'%s'", (char *)data);
char numchar[100]; char numchar[100];
sprintf(numchar, "\n[i] accept request with /a %u\n\n", num_requests); sprintf(numchar, "\n[i] accept request with /a %u\n\n", num_requests);
printf(numchar); printf(numchar);
@ -63,18 +63,18 @@ void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *us
++num_requests; ++num_requests;
} }
void print_message(Messenger *messenger, int friendnumber, uint8_t * string, uint16_t length, void *userdata) void print_message(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
getname(messenger, friendnumber, (uint8_t*)name); getname(messenger, friendnumber, (uint8_t *)name);
char msg[100+length+strlen(name)+1]; char msg[100 + length + strlen(name) + 1];
time_t rawtime; time_t rawtime;
struct tm * timeinfo; struct tm *timeinfo;
time (&rawtime); time (&rawtime);
timeinfo = localtime (&rawtime); timeinfo = localtime (&rawtime);
char* temp = asctime(timeinfo); char *temp = asctime(timeinfo);
size_t len = strlen(temp); size_t len = strlen(temp);
temp[len-1]='\0'; temp[len - 1] = '\0';
sprintf(msg, "\n[%d] %s <%s> %s\n\n", friendnumber, temp, name, string); // timestamp sprintf(msg, "\n[%d] %s <%s> %s\n\n", friendnumber, temp, name, string); // timestamp
printf(msg); printf(msg);
} }
@ -82,8 +82,8 @@ void print_message(Messenger *messenger, int friendnumber, uint8_t * string, uin
void print_nickchange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata) void print_nickchange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
getname(messenger, friendnumber, (uint8_t*)name); getname(messenger, friendnumber, (uint8_t *)name);
char msg[100+length]; char msg[100 + length];
sprintf(msg, "\n\n[i] [%d] %s is now known as %s.\n\n", friendnumber, name, string); sprintf(msg, "\n\n[i] [%d] %s is now known as %s.\n\n", friendnumber, name, string);
printf(msg); printf(msg);
} }
@ -91,8 +91,8 @@ void print_nickchange(Messenger *messenger, int friendnumber, uint8_t *string, u
void print_statuschange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata) void print_statuschange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
getname(messenger, friendnumber, (uint8_t*)name); getname(messenger, friendnumber, (uint8_t *)name);
char msg[100+length+strlen(name)+1]; char msg[100 + length + strlen(name) + 1];
sprintf(msg, "\n\n[i] [%d] %s's status changed to %s.\n\n", friendnumber, name, string); sprintf(msg, "\n\n[i] [%d] %s's status changed to %s.\n\n", friendnumber, name, string);
printf(msg); printf(msg);
} }
@ -100,12 +100,14 @@ void print_statuschange(Messenger *messenger, int friendnumber, uint8_t *string,
void load_key() void load_key()
{ {
FILE *data_file = NULL; FILE *data_file = NULL;
data_file = fopen("data","r"); data_file = fopen("data", "r");
if (data_file) { if (data_file) {
fseek(data_file, 0, SEEK_END); fseek(data_file, 0, SEEK_END);
int size = ftell(data_file); int size = ftell(data_file);
fseek(data_file, 0, SEEK_SET); fseek(data_file, 0, SEEK_SET);
uint8_t data[size]; uint8_t data[size];
if (fread(data, sizeof(uint8_t), size, data_file) != size) { if (fread(data, sizeof(uint8_t), size, data_file) != size) {
printf("\n[i] Could not read the data file. Exiting."); printf("\n[i] Could not read the data file. Exiting.");
exit(1); exit(1);
@ -124,6 +126,7 @@ void load_key()
exit(1); exit(1);
} }
} }
fclose(data_file); fclose(data_file);
} }
@ -131,30 +134,29 @@ void add_friend()
{ {
int i; int i;
char temp_id[128]; char temp_id[128];
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
temp_id[i] = line[i+3]; temp_id[i] = line[i + 3];
int num = m_addfriend(messenger, hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); int num = m_addfriend(messenger, hex_string_to_bin(temp_id), (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
if (num >= 0) { if (num >= 0) {
char numstring[100]; char numstring[100];
sprintf(numstring, "\n[i] Friend request sent. Wait to be accepted. Friend id: %d\n\n", num); sprintf(numstring, "\n[i] Friend request sent. Wait to be accepted. Friend id: %d\n\n", num);
printf(numstring); printf(numstring);
++maxnumfriends; ++maxnumfriends;
} } else if (num == -1)
else if (num == -1)
printf("\n[i] Message is too long.\n\n"); printf("\n[i] Message is too long.\n\n");
else if (num == -2) else if (num == -2)
printf("\n[i] Please add a message to your friend request.\n\n"); printf("\n[i] Please add a message to your friend request.\n\n");
else if (num == -3) else if (num == -3)
printf("\n[i] That appears to be your own ID.\n\n"); printf("\n[i] That appears to be your own ID.\n\n");
else if (num == -4) else if (num == -4)
printf("\n[i] Friend request already sent.\n\n"); printf("\n[i] Friend request already sent.\n\n");
else if (num == -5) else if (num == -5)
printf("\n[i] Undefined error when adding friend\n\n"); printf("\n[i] Undefined error when adding friend\n\n");
} }
@ -162,28 +164,29 @@ void add_friend()
void list_friends() void list_friends()
{ {
int i; int i;
printf("\n[i] Friend List"); printf("\n[i] Friend List");
printf("----- PENDING -----\n\n"); printf("----- PENDING -----\n\n");
for (i = 0; i <= maxnumfriends; i++) { for (i = 0; i <= maxnumfriends; i++) {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
getname(messenger, i, (uint8_t*)name); getname(messenger, i, (uint8_t *)name);
if (m_friendstatus(messenger, i) > 0 && m_friendstatus(messenger, i) < 4) if (m_friendstatus(messenger, i) > 0 && m_friendstatus(messenger, i) < 4)
printf("[%d] %s\n", i, (uint8_t*)name); printf("[%d] %s\n", i, (uint8_t *)name);
} }
printf("\n"); printf("\n");
printf("----- ACTIVE -----\n\n"); printf("----- ACTIVE -----\n\n");
for (i = 0; i <= maxnumfriends; i++) { for (i = 0; i <= maxnumfriends; i++) {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
getname(messenger, i, (uint8_t*)name); getname(messenger, i, (uint8_t *)name);
if (m_friendstatus(messenger, i) == 4) if (m_friendstatus(messenger, i) == 4)
printf("[%d] %s\n", i, (uint8_t*)name); printf("[%d] %s\n", i, (uint8_t *)name);
} }
printf("\n"); printf("\n");
@ -192,14 +195,14 @@ void list_friends()
void delete_friend() void delete_friend()
{ {
size_t len = strlen(line); size_t len = strlen(line);
char numstring[len-3]; char numstring[len - 3];
int i; int i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (line[i+3] != ' ') if (line[i + 3] != ' ')
numstring[i] = line[i+3]; numstring[i] = line[i + 3];
} }
int num = atoi(numstring); int num = atoi(numstring);
m_delfriend(messenger, num); m_delfriend(messenger, num);
--maxnumfriends; --maxnumfriends;
@ -209,20 +212,20 @@ void delete_friend()
void message_friend() void message_friend()
{ {
size_t len = strlen(line); size_t len = strlen(line);
char numstring[len-3]; char numstring[len - 3];
char message[len-3]; char message[len - 3];
int i; int i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (line[i+3] != ' ') if (line[i + 3] != ' ')
numstring[i] = line[i+3]; numstring[i] = line[i + 3];
else { else {
int j; int j;
for (j = (i+1); j < len; j++) for (j = (i + 1); j < len; j++)
message[j-i-1] = line[j+3]; message[j - i - 1] = line[j + 3];
break; break;
} }
@ -230,9 +233,9 @@ void message_friend()
int num = atoi(numstring); int num = atoi(numstring);
if(m_sendmessage(messenger, num, (uint8_t*) message, sizeof(message)) != 1) if (m_sendmessage(messenger, num, (uint8_t *) message, sizeof(message)) != 1)
printf("\n[i] could not send message (they may be offline): %s\n", message); printf("\n[i] could not send message (they may be offline): %s\n", message);
else else
printf("\n"); printf("\n");
} }
@ -242,24 +245,24 @@ void change_nickname()
uint8_t name[MAX_NAME_LENGTH]; uint8_t name[MAX_NAME_LENGTH];
int i = 0; int i = 0;
size_t len = strlen(line); size_t len = strlen(line);
for (i = 3; i < len; i++) { for (i = 3; i < len; i++) {
if (line[i] == 0 || line[i] == '\n') if (line[i] == 0 || line[i] == '\n')
break; break;
name[i-3] = line[i]; name[i - 3] = line[i];
} }
name[i-3] = 0; name[i - 3] = 0;
setname(messenger, name, i); setname(messenger, name, i);
char numstring[100]; char numstring[100];
sprintf(numstring, "\n[i] changed nick to %s\n\n", (char*)name); sprintf(numstring, "\n[i] changed nick to %s\n\n", (char *)name);
printf(numstring); printf(numstring);
FILE *name_file = NULL; FILE *name_file = NULL;
name_file = fopen("namefile.txt", "w"); name_file = fopen("namefile.txt", "w");
fprintf(name_file, "%s", (char*)name); fprintf(name_file, "%s", (char *)name);
fclose(name_file); fclose(name_file);
} }
@ -268,24 +271,24 @@ void change_status(int savetofile)
uint8_t status[MAX_STATUSMESSAGE_LENGTH]; uint8_t status[MAX_STATUSMESSAGE_LENGTH];
int i = 0; int i = 0;
size_t len = strlen(line); size_t len = strlen(line);
for (i = 3; i < len; i++) { for (i = 3; i < len; i++) {
if (line[i] == 0 || line[i] == '\n') if (line[i] == 0 || line[i] == '\n')
break; break;
status[i-3] = line[i]; status[i - 3] = line[i];
} }
status[i-3] = 0; status[i - 3] = 0;
m_set_statusmessage(messenger, status, strlen((char*)status)); m_set_statusmessage(messenger, status, strlen((char *)status));
char numstring[100]; char numstring[100];
sprintf(numstring, "\n[i] changed status to %s\n\n", (char*)status); sprintf(numstring, "\n[i] changed status to %s\n\n", (char *)status);
printf(numstring); printf(numstring);
if (savetofile == 1) { if (savetofile == 1) {
FILE* status_file = NULL; FILE *status_file = NULL;
status_file = fopen("statusfile.txt", "w"); status_file = fopen("statusfile.txt", "w");
fprintf(status_file, "%s", (char*)status); fprintf(status_file, "%s", (char *)status);
fclose(status_file); fclose(status_file);
} }
} }
@ -295,11 +298,13 @@ void accept_friend_request()
friend_request_received = 0; friend_request_received = 0;
uint8_t numf = atoi(line + 3); uint8_t numf = atoi(line + 3);
char numchar[100]; char numchar[100];
if (numf >= num_requests || pending_requests[numf].accepted) { if (numf >= num_requests || pending_requests[numf].accepted) {
sprintf(numchar, "\n[i] you either didn't receive that request or you already accepted it"); sprintf(numchar, "\n[i] you either didn't receive that request or you already accepted it");
printf(numchar); printf(numchar);
} else { } else {
int num = m_addfriend_norequest(messenger, pending_requests[numf].id); int num = m_addfriend_norequest(messenger, pending_requests[numf].id);
if (num != -1) { if (num != -1) {
pending_requests[numf].accepted = 1; pending_requests[numf].accepted = 1;
sprintf(numchar, "\n[i] Added friendnumber: %d\n\n", num); sprintf(numchar, "\n[i] Added friendnumber: %d\n\n", num);
@ -312,13 +317,13 @@ void accept_friend_request()
} }
} }
void line_eval(char* line) void line_eval(char *line)
{ {
if(line[0] == '/') { if (line[0] == '/') {
char inpt_command = line[1]; char inpt_command = line[1];
if(inpt_command == 'f') { if (inpt_command == 'f') {
add_friend(); add_friend();
} }
@ -362,7 +367,7 @@ void line_eval(char* line)
void get_input() void get_input()
{ {
while(1) { while (1) {
fgets(line, STRING_LENGTH, stdin); fgets(line, STRING_LENGTH, stdin);
line_eval(line); line_eval(line);
strcpy(line, ""); strcpy(line, "");
@ -375,13 +380,16 @@ int main(int argc, char *argv[])
printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]); printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]);
exit(0); exit(0);
} }
messenger = initMessenger(); messenger = initMessenger();
if (messenger == 0) { if (messenger == 0) {
printf("initMessenger failed"); printf("initMessenger failed");
exit(0); exit(0);
} }
if (argc > 4) { if (argc > 4) {
if(strncmp(argv[4], "nokey", 6) < 0) { if (strncmp(argv[4], "nokey", 6) < 0) {
} }
} else { } else {
load_key(); load_key();
@ -390,27 +398,33 @@ int main(int argc, char *argv[])
int nameloaded = 0; int nameloaded = 0;
int statusloaded = 0; int statusloaded = 0;
FILE* name_file = NULL; FILE *name_file = NULL;
name_file = fopen("namefile.txt", "r"); name_file = fopen("namefile.txt", "r");
if(name_file) {
if (name_file) {
uint8_t name[MAX_NAME_LENGTH]; uint8_t name[MAX_NAME_LENGTH];
while (fgets(line, MAX_NAME_LENGTH, name_file) != NULL) { while (fgets(line, MAX_NAME_LENGTH, name_file) != NULL) {
sscanf(line, "%s", (char*)name); sscanf(line, "%s", (char *)name);
} }
setname(messenger, name, strlen((char*)name)+1);
setname(messenger, name, strlen((char *)name) + 1);
nameloaded = 1; nameloaded = 1;
printf("%s\n", name); printf("%s\n", name);
fclose(name_file); fclose(name_file);
} }
FILE* status_file = NULL; FILE *status_file = NULL;
status_file = fopen("statusfile.txt", "r"); status_file = fopen("statusfile.txt", "r");
if(status_file) {
if (status_file) {
uint8_t status[MAX_STATUSMESSAGE_LENGTH]; uint8_t status[MAX_STATUSMESSAGE_LENGTH];
while (fgets(line, MAX_STATUSMESSAGE_LENGTH, status_file) != NULL) { while (fgets(line, MAX_STATUSMESSAGE_LENGTH, status_file) != NULL) {
sscanf(line, "%s", (char*)status); sscanf(line, "%s", (char *)status);
} }
m_set_statusmessage(messenger, status, strlen((char*)status)+1);
m_set_statusmessage(messenger, status, strlen((char *)status) + 1);
statusloaded = 1; statusloaded = 1;
printf("%s\n", status); printf("%s\n", status);
fclose(status_file); fclose(status_file);
@ -423,31 +437,35 @@ int main(int argc, char *argv[])
char idstring1[PUB_KEY_BYTES][5]; char idstring1[PUB_KEY_BYTES][5];
char idstring2[PUB_KEY_BYTES][5]; char idstring2[PUB_KEY_BYTES][5];
int i; int i;
for(i = 0; i < PUB_KEY_BYTES; i++)
{ for (i = 0; i < PUB_KEY_BYTES; i++) {
if(self_public_key[i] < (PUB_KEY_BYTES/2)) if (self_public_key[i] < (PUB_KEY_BYTES / 2))
strcpy(idstring1[i],"0"); strcpy(idstring1[i], "0");
else else
strcpy(idstring1[i], ""); strcpy(idstring1[i], "");
sprintf(idstring2[i], "%hhX",self_public_key[i]);
sprintf(idstring2[i], "%hhX", self_public_key[i]);
} }
strcpy(users_id,"[i] your ID: ");
strcpy(users_id, "[i] your ID: ");
int j; int j;
for (j = 0; j < PUB_KEY_BYTES; j++) { for (j = 0; j < PUB_KEY_BYTES; j++) {
strcat(users_id,idstring1[j]); strcat(users_id, idstring1[j]);
strcat(users_id,idstring2[j]); strcat(users_id, idstring2[j]);
} }
do_header(); do_header();
IP_Port bootstrap_ip_port; IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2])); bootstrap_ip_port.port = htons(atoi(argv[2]));
int resolved_address = resolve_addr(argv[1]); int resolved_address = resolve_addr(argv[1]);
if (resolved_address != 0) if (resolved_address != 0)
bootstrap_ip_port.ip.i = resolved_address; bootstrap_ip_port.ip.i = resolved_address;
else else
exit(1); exit(1);
DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
int c; int c;
@ -465,20 +483,23 @@ int main(int argc, char *argv[])
printf("\n---------------------------------"); printf("\n---------------------------------");
} }
while(1) { while (1) {
if (on == 1 && DHT_isconnected() == -1) { if (on == 1 && DHT_isconnected() == -1) {
printf("\n---------------------------------"); printf("\n---------------------------------");
printf("\n[i] Disconnected from the DHT"); printf("\n[i] Disconnected from the DHT");
printf("\n---------------------------------\n\n"); printf("\n---------------------------------\n\n");
on = 0; on = 0;
} }
if (on == 0 && DHT_isconnected()) { if (on == 0 && DHT_isconnected()) {
printf("\n[i] Connected to DHT"); printf("\n[i] Connected to DHT");
printf("\n---------------------------------\n\n"); printf("\n---------------------------------\n\n");
on = 1; on = 1;
} }
doMessenger(messenger); doMessenger(messenger);
Sleep(1); Sleep(1);
} }
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/* nTox_win32.h /* nTox_win32.h
* *
* Textual frontend for Tox - Windows version * Textual frontend for Tox - Windows version
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
@ -31,7 +31,7 @@
void do_header(); void do_header();
void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata); void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata);
void print_message(Messenger *messenger, int friendnumber, uint8_t * string, uint16_t length, void *userdata); void print_message(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
void print_nickchange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata); void print_nickchange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
void print_statuschange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata); void print_statuschange(Messenger *messenger, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
void load_key(); void load_key();
@ -42,7 +42,7 @@ void message_friend();
void change_nickname(); void change_nickname();
void change_status(int savetofile); void change_status(int savetofile);
void accept_friend_request(); void accept_friend_request();
void line_eval(char* line); void line_eval(char *line);
void get_input(); void get_input();
#endif #endif

View File

@ -3,7 +3,7 @@
#ifdef WINDOWS #ifdef WINDOWS
#include <windows.h> #include <windows.h>
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -16,30 +16,32 @@ void mssleep(int ms)
#endif #endif
} }
int callback(timer* t, void* arg){ int callback(timer *t, void *arg)
printf("%s\n", (char*)arg); {
printf("%s\n", (char *)arg);
return 1; return 1;
} }
int repeating(timer* t, void *arg) { int repeating(timer *t, void *arg)
printf("%s\n", (char*)arg); {
printf("%s\n", (char *)arg);
timer_start(t, 3); timer_start(t, 3);
return 0; return 0;
} }
extern void timer_debug_print(); extern void timer_debug_print();
int main(int argc, char** argv) int main(int argc, char **argv)
{ {
timer_init(); timer_init();
timer_debug_print(); timer_debug_print();
timer* t = new_timer(); timer *t = new_timer();
timer_setup(t, &callback, "Long setup method, 4 seconds"); timer_setup(t, &callback, "Long setup method, 4 seconds");
timer_start(t, 4); timer_start(t, 4);
timer_debug_print(); timer_debug_print();
timer_single(&repeating, (void*)"This repeats every 3 seconds", 3); timer_single(&repeating, (void *)"This repeats every 3 seconds", 3);
timer_debug_print(); timer_debug_print();
timer_single(&callback, "Short method, 4 seconds", 4); timer_single(&callback, "Short method, 4 seconds", 4);
@ -53,7 +55,7 @@ int main(int argc, char** argv)
timer_single(&callback, "10 seconds", 10); timer_single(&callback, "10 seconds", 10);
timer_debug_print(); timer_debug_print();
timer_us(&callback, "100000us", 100000); timer_us(&callback, "100000us", 100000);
timer_us(&callback, "13s", 13 * US_PER_SECOND); timer_us(&callback, "13s", 13 * US_PER_SECOND);

View File

@ -19,376 +19,391 @@
#define CURS_Y_OFFSET 3 #define CURS_Y_OFFSET 3
typedef struct { typedef struct {
int friendnum; int friendnum;
char line[MAX_STR_SIZE]; char line[MAX_STR_SIZE];
size_t pos; size_t pos;
WINDOW* history; WINDOW *history;
WINDOW* linewin; WINDOW *linewin;
} ChatContext; } ChatContext;
void print_help(ChatContext *self); void print_help(ChatContext *self);
void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd); void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd);
struct tm *get_time(void) struct tm *get_time(void)
{ {
struct tm *timeinfo; struct tm *timeinfo;
time_t now; time_t now;
time(&now); time(&now);
timeinfo = localtime(&now); timeinfo = localtime(&now);
return timeinfo; return timeinfo;
} }
static void chat_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *msg, uint16_t len) static void chat_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *msg, uint16_t len)
{ {
ChatContext *ctx = (ChatContext*) self->x; ChatContext *ctx = (ChatContext *) self->x;
uint8_t nick[MAX_NAME_LENGTH] = {0}; uint8_t nick[MAX_NAME_LENGTH] = {0};
struct tm *timeinfo = get_time(); struct tm *timeinfo = get_time();
if (ctx->friendnum != num) if (ctx->friendnum != num)
return; return;
getname(m, num, (uint8_t*) &nick); getname(m, num, (uint8_t *) &nick);
msg[len-1] = '\0'; msg[len - 1] = '\0';
nick[MAX_NAME_LENGTH-1] = '\0'; nick[MAX_NAME_LENGTH - 1] = '\0';
fix_name(msg); fix_name(msg);
fix_name(nick); fix_name(nick);
wattron(ctx->history, COLOR_PAIR(2)); wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2)); wattroff(ctx->history, COLOR_PAIR(2));
wattron(ctx->history, COLOR_PAIR(4)); wattron(ctx->history, COLOR_PAIR(4));
wprintw(ctx->history, "%s: ", nick); wprintw(ctx->history, "%s: ", nick);
wattroff(ctx->history, COLOR_PAIR(4)); wattroff(ctx->history, COLOR_PAIR(4));
wprintw(ctx->history, "%s\n", msg); wprintw(ctx->history, "%s\n", msg);
self->blink = true; self->blink = true;
beep(); beep();
} }
static void chat_onAction(ToxWindow *self, Messenger *m, int num, uint8_t *action, uint16_t len) static void chat_onAction(ToxWindow *self, Messenger *m, int num, uint8_t *action, uint16_t len)
{ {
ChatContext *ctx = (ChatContext*) self->x; ChatContext *ctx = (ChatContext *) self->x;
struct tm *timeinfo = get_time();
if (ctx->friendnum != num)
return;
action[len-1] = '\0';
fix_name(action);
wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2));
wattron(ctx->history, COLOR_PAIR(5));
wprintw(ctx->history, "%s\n", action);
wattroff(ctx->history, COLOR_PAIR(5));
self->blink = true;
beep();
}
static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t len)
{
ChatContext *ctx = (ChatContext*) self->x;
struct tm *timeinfo = get_time();
if (ctx->friendnum != num)
return;
wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2));
nick[len-1] = '\0';
fix_name(nick);
snprintf(self->title, sizeof(self->title), "[%s (%d)]", nick, num);
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, "* Your partner changed nick to '%s'\n", nick);
wattroff(ctx->history, COLOR_PAIR(3));
}
static void chat_onStatusChange(ToxWindow *self, int num, uint8_t *status, uint16_t len)
{
ChatContext *ctx = (ChatContext*) self->x;
struct tm *timeinfo = get_time();
if (ctx->friendnum != num)
return;
wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2));
status[len-1] = '\0';
fix_name(status);
snprintf(self->title, sizeof(self->title), "[%s (%d)]", status, num);
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, "* Your partner changed status to '%s'\n", status);
wattroff(ctx->history, COLOR_PAIR(3));
}
/* check that the string has one non-space character */
int string_is_empty(char *string)
{
int rc = 0;
char *copy = strdup(string);
rc = ((strtok(copy, " ") == NULL) ? 1:0);
free(copy);
return rc;
}
static void chat_onKey(ToxWindow *self, Messenger *m, int key)
{
ChatContext *ctx = (ChatContext*) self->x;
struct tm *timeinfo = get_time();
int x, y, y2, x2;
getyx(self->window, y, x);
getmaxyx(self->window, y2, x2);
/* Add printable chars to buffer and print on input space */
if (isprint(key)) {
if (ctx->pos != sizeof(ctx->line)-1) {
mvwaddch(self->window, y, x, key);
ctx->line[ctx->pos++] = key;
ctx->line[ctx->pos] = '\0';
}
}
/* BACKSPACE key: Remove one character from line */
else if (key == 0x107 || key == 0x8 || key == 0x7f) {
if (ctx->pos > 0) {
ctx->line[--ctx->pos] = '\0';
if (x == 0)
mvwdelch(self->window, y-1, x2-1);
else
mvwdelch(self->window, y, x-1);
}
}
/* RETURN key: Execute command or print line */
else if (key == '\n') {
wclear(ctx->linewin);
wmove(self->window, y2-CURS_Y_OFFSET, 0);
wclrtobot(self->window);
if (ctx->line[0] == '/')
execute(self, ctx, m, ctx->line);
else {
/* make sure the string has at least non-space character */
if (!string_is_empty(ctx->line)) {
uint8_t selfname[MAX_NAME_LENGTH];
getself_name(m, selfname, sizeof(selfname));
fix_name(selfname);
wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2));
wattron(ctx->history, COLOR_PAIR(1));
wprintw(ctx->history, "%s: ", selfname);
wattroff(ctx->history, COLOR_PAIR(1));
wprintw(ctx->history, "%s\n", ctx->line);
if (m_sendmessage(m, ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) == 0) {
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, " * Failed to send message.\n");
wattroff(ctx->history, COLOR_PAIR(3));
}
}
}
ctx->line[0] = '\0';
ctx->pos = 0;
}
}
void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd)
{
if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
wclear(self->window);
wclear(ctx->history);
int x, y;
getmaxyx(self->window, y, x);
(void) x;
wmove(self->window, y-CURS_Y_OFFSET, 0);
}
else if (!strcmp(cmd, "/help") || !strcmp(cmd, "/h"))
print_help(ctx);
else if (!strcmp(cmd, "/quit") || !strcmp(cmd, "/exit") || !strcmp(cmd, "/q")) {
endwin();
exit(0);
}
else if (!strncmp(cmd, "/me ", strlen("/me "))) {
struct tm *timeinfo = get_time(); struct tm *timeinfo = get_time();
char *action = strchr(cmd, ' ');
if (action == NULL) { if (ctx->friendnum != num)
wprintw(self->window, "Invalid syntax.\n"); return;
return;
} action[len - 1] = '\0';
action++; fix_name(action);
wattron(ctx->history, COLOR_PAIR(2)); wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2)); wattroff(ctx->history, COLOR_PAIR(2));
uint8_t selfname[MAX_NAME_LENGTH];
int len = getself_name(m, selfname, sizeof(selfname));
char msg[MAX_STR_SIZE-len-4];
snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t*) selfname, action);
wattron(ctx->history, COLOR_PAIR(5)); wattron(ctx->history, COLOR_PAIR(5));
wprintw(ctx->history, msg); wprintw(ctx->history, "%s\n", action);
wattroff(ctx->history, COLOR_PAIR(5)); wattroff(ctx->history, COLOR_PAIR(5));
if (m_sendaction(m, ctx->friendnum, (uint8_t*) msg, strlen(msg)+1) < 0) {
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, " * Failed to send action\n");
wattroff(ctx->history, COLOR_PAIR(3));
}
}
else if (!strncmp(cmd, "/status ", strlen("/status "))) { self->blink = true;
char *status = strchr(cmd, ' '); beep();
char *msg; }
char *status_text;
if (status == NULL) { static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t len)
wprintw(ctx->history, "Invalid syntax.\n"); {
return; ChatContext *ctx = (ChatContext *) self->x;
} struct tm *timeinfo = get_time();
status++;
USERSTATUS status_kind; if (ctx->friendnum != num)
if (!strncmp(status, "online", strlen("online"))) { return;
status_kind = USERSTATUS_NONE;
status_text = "ONLINE"; wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2));
nick[len - 1] = '\0';
fix_name(nick);
snprintf(self->title, sizeof(self->title), "[%s (%d)]", nick, num);
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, "* Your partner changed nick to '%s'\n", nick);
wattroff(ctx->history, COLOR_PAIR(3));
}
static void chat_onStatusChange(ToxWindow *self, int num, uint8_t *status, uint16_t len)
{
ChatContext *ctx = (ChatContext *) self->x;
struct tm *timeinfo = get_time();
if (ctx->friendnum != num)
return;
wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2));
status[len - 1] = '\0';
fix_name(status);
snprintf(self->title, sizeof(self->title), "[%s (%d)]", status, num);
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, "* Your partner changed status to '%s'\n", status);
wattroff(ctx->history, COLOR_PAIR(3));
}
/* check that the string has one non-space character */
int string_is_empty(char *string)
{
int rc = 0;
char *copy = strdup(string);
rc = ((strtok(copy, " ") == NULL) ? 1 : 0);
free(copy);
return rc;
}
static void chat_onKey(ToxWindow *self, Messenger *m, int key)
{
ChatContext *ctx = (ChatContext *) self->x;
struct tm *timeinfo = get_time();
int x, y, y2, x2;
getyx(self->window, y, x);
getmaxyx(self->window, y2, x2);
/* Add printable chars to buffer and print on input space */
if (isprint(key)) {
if (ctx->pos != sizeof(ctx->line) - 1) {
mvwaddch(self->window, y, x, key);
ctx->line[ctx->pos++] = key;
ctx->line[ctx->pos] = '\0';
}
} }
else if (!strncmp(status, "away", strlen("away"))) { /* BACKSPACE key: Remove one character from line */
status_kind = USERSTATUS_AWAY; else if (key == 0x107 || key == 0x8 || key == 0x7f) {
status_text = "AWAY"; if (ctx->pos > 0) {
ctx->line[--ctx->pos] = '\0';
if (x == 0)
mvwdelch(self->window, y - 1, x2 - 1);
else
mvwdelch(self->window, y, x - 1);
}
} }
else if (!strncmp(status, "busy", strlen("busy"))) { /* RETURN key: Execute command or print line */
status_kind = USERSTATUS_BUSY; else if (key == '\n') {
status_text = "BUSY"; wclear(ctx->linewin);
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
wclrtobot(self->window);
if (ctx->line[0] == '/')
execute(self, ctx, m, ctx->line);
else {
/* make sure the string has at least non-space character */
if (!string_is_empty(ctx->line)) {
uint8_t selfname[MAX_NAME_LENGTH];
getself_name(m, selfname, sizeof(selfname));
fix_name(selfname);
wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2));
wattron(ctx->history, COLOR_PAIR(1));
wprintw(ctx->history, "%s: ", selfname);
wattroff(ctx->history, COLOR_PAIR(1));
wprintw(ctx->history, "%s\n", ctx->line);
if (m_sendmessage(m, ctx->friendnum, (uint8_t *) ctx->line, strlen(ctx->line) + 1) == 0) {
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, " * Failed to send message.\n");
wattroff(ctx->history, COLOR_PAIR(3));
}
}
}
ctx->line[0] = '\0';
ctx->pos = 0;
}
}
void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd)
{
if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
wclear(self->window);
wclear(ctx->history);
int x, y;
getmaxyx(self->window, y, x);
(void) x;
wmove(self->window, y - CURS_Y_OFFSET, 0);
} }
else { else if (!strcmp(cmd, "/help") || !strcmp(cmd, "/h"))
wprintw(ctx->history, "Invalid status.\n"); print_help(ctx);
return;
else if (!strcmp(cmd, "/quit") || !strcmp(cmd, "/exit") || !strcmp(cmd, "/q")) {
endwin();
exit(0);
} }
msg = strchr(status, ' '); else if (!strncmp(cmd, "/me ", strlen("/me "))) {
if (msg == NULL) { struct tm *timeinfo = get_time();
m_set_userstatus(m, status_kind); char *action = strchr(cmd, ' ');
wprintw(ctx->history, "Status set to: %s\n", status_text);
}
else {
msg++;
m_set_userstatus(m, status_kind);
m_set_statusmessage(m, ( uint8_t*) msg, strlen(msg)+1);
wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg);
}
}
else if (!strncmp(cmd, "/nick ", strlen("/nick "))) { if (action == NULL) {
char *nick; wprintw(self->window, "Invalid syntax.\n");
nick = strchr(cmd, ' '); return;
if (nick == NULL) { }
wprintw(ctx->history, "Invalid syntax.\n");
return; action++;
wattron(ctx->history, COLOR_PAIR(2));
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
wattroff(ctx->history, COLOR_PAIR(2));
uint8_t selfname[MAX_NAME_LENGTH];
int len = getself_name(m, selfname, sizeof(selfname));
char msg[MAX_STR_SIZE - len - 4];
snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t *) selfname, action);
wattron(ctx->history, COLOR_PAIR(5));
wprintw(ctx->history, msg);
wattroff(ctx->history, COLOR_PAIR(5));
if (m_sendaction(m, ctx->friendnum, (uint8_t *) msg, strlen(msg) + 1) < 0) {
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, " * Failed to send action\n");
wattroff(ctx->history, COLOR_PAIR(3));
}
} }
nick++; else if (!strncmp(cmd, "/status ", strlen("/status "))) {
setname(m, (uint8_t*) nick, strlen(nick)+1); char *status = strchr(cmd, ' ');
wprintw(ctx->history, "Nickname set to: %s\n", nick); char *msg;
} char *status_text;
else if (!strcmp(cmd, "/myid")) { if (status == NULL) {
char id[FRIEND_ADDRESS_SIZE*2+1] = {0}; wprintw(ctx->history, "Invalid syntax.\n");
int i; return;
uint8_t address[FRIEND_ADDRESS_SIZE]; }
getaddress(m, address);
for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) { status++;
char xx[3]; USERSTATUS status_kind;
snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff);
strcat(id, xx); if (!strncmp(status, "online", strlen("online"))) {
status_kind = USERSTATUS_NONE;
status_text = "ONLINE";
}
else if (!strncmp(status, "away", strlen("away"))) {
status_kind = USERSTATUS_AWAY;
status_text = "AWAY";
}
else if (!strncmp(status, "busy", strlen("busy"))) {
status_kind = USERSTATUS_BUSY;
status_text = "BUSY";
}
else {
wprintw(ctx->history, "Invalid status.\n");
return;
}
msg = strchr(status, ' ');
if (msg == NULL) {
m_set_userstatus(m, status_kind);
wprintw(ctx->history, "Status set to: %s\n", status_text);
} else {
msg++;
m_set_userstatus(m, status_kind);
m_set_statusmessage(m, ( uint8_t *) msg, strlen(msg) + 1);
wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg);
}
} }
wprintw(ctx->history, "%s\n", id);
}
else if (strcmp(ctx->line, "/close") == 0) { else if (!strncmp(cmd, "/nick ", strlen("/nick "))) {
int f_num = ctx->friendnum; char *nick;
delwin(ctx->linewin); nick = strchr(cmd, ' ');
del_window(self, f_num);
}
else if (nick == NULL) {
wprintw(ctx->history, "Invalid command.\n"); wprintw(ctx->history, "Invalid syntax.\n");
return;
}
nick++;
setname(m, (uint8_t *) nick, strlen(nick) + 1);
wprintw(ctx->history, "Nickname set to: %s\n", nick);
}
else if (!strcmp(cmd, "/myid")) {
char id[FRIEND_ADDRESS_SIZE * 2 + 1] = {0};
int i;
uint8_t address[FRIEND_ADDRESS_SIZE];
getaddress(m, address);
for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
char xx[3];
snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff);
strcat(id, xx);
}
wprintw(ctx->history, "%s\n", id);
}
else if (strcmp(ctx->line, "/close") == 0) {
int f_num = ctx->friendnum;
delwin(ctx->linewin);
del_window(self, f_num);
}
else
wprintw(ctx->history, "Invalid command.\n");
} }
static void chat_onDraw(ToxWindow *self) static void chat_onDraw(ToxWindow *self)
{ {
curs_set(1); curs_set(1);
int x, y; int x, y;
getmaxyx(self->window, y, x); getmaxyx(self->window, y, x);
(void) y; (void) y;
ChatContext *ctx = (ChatContext*) self->x; ChatContext *ctx = (ChatContext *) self->x;
mvwhline(ctx->linewin, 0, 0, '_', x); mvwhline(ctx->linewin, 0, 0, '_', x);
wrefresh(self->window); wrefresh(self->window);
} }
static void chat_onInit(ToxWindow *self, Messenger *m) static void chat_onInit(ToxWindow *self, Messenger *m)
{ {
int x, y; int x, y;
ChatContext *ctx = (ChatContext*) self->x; ChatContext *ctx = (ChatContext *) self->x;
getmaxyx(self->window, y, x); getmaxyx(self->window, y, x);
ctx->history = subwin(self->window, y-4, x, 0, 0); ctx->history = subwin(self->window, y - 4, x, 0, 0);
scrollok(ctx->history, 1); scrollok(ctx->history, 1);
ctx->linewin = subwin(self->window, 2, x, y-4, 0); ctx->linewin = subwin(self->window, 2, x, y - 4, 0);
print_help(ctx); print_help(ctx);
wmove(self->window, y-CURS_Y_OFFSET, 0); wmove(self->window, y - CURS_Y_OFFSET, 0);
} }
void print_help(ChatContext *self) void print_help(ChatContext *self)
{ {
wattron(self->history, COLOR_PAIR(2) | A_BOLD); wattron(self->history, COLOR_PAIR(2) | A_BOLD);
wprintw(self->history, "Commands:\n"); wprintw(self->history, "Commands:\n");
wattroff(self->history, A_BOLD); wattroff(self->history, A_BOLD);
wprintw(self->history, " /status <type> <message> : Set your status\n"); wprintw(self->history, " /status <type> <message> : Set your status\n");
wprintw(self->history, " /nick <nickname> : Set your nickname\n"); wprintw(self->history, " /nick <nickname> : Set your nickname\n");
wprintw(self->history, " /me <action> : Do an action\n"); wprintw(self->history, " /me <action> : Do an action\n");
wprintw(self->history, " /myid : Print your ID\n"); wprintw(self->history, " /myid : Print your ID\n");
wprintw(self->history, " /clear : Clear the screen\n"); wprintw(self->history, " /clear : Clear the screen\n");
wprintw(self->history, " /close : Close the current chat window\n"); wprintw(self->history, " /close : Close the current chat window\n");
wprintw(self->history, " /quit or /exit : Exit program\n"); wprintw(self->history, " /quit or /exit : Exit program\n");
wprintw(self->history, " /help : Print this message again\n\n"); wprintw(self->history, " /help : Print this message again\n\n");
wattroff(self->history, COLOR_PAIR(2)); wattroff(self->history, COLOR_PAIR(2));
} }
ToxWindow new_chat(Messenger *m, int friendnum) ToxWindow new_chat(Messenger *m, int friendnum)
{ {
ToxWindow ret; ToxWindow ret;
memset(&ret, 0, sizeof(ret)); memset(&ret, 0, sizeof(ret));
ret.onKey = &chat_onKey; ret.onKey = &chat_onKey;
ret.onDraw = &chat_onDraw; ret.onDraw = &chat_onDraw;
ret.onInit = &chat_onInit; ret.onInit = &chat_onInit;
ret.onMessage = &chat_onMessage; ret.onMessage = &chat_onMessage;
ret.onNickChange = &chat_onNickChange; ret.onNickChange = &chat_onNickChange;
ret.onStatusChange = &chat_onStatusChange; ret.onStatusChange = &chat_onStatusChange;
ret.onAction = &chat_onAction; ret.onAction = &chat_onAction;
uint8_t nick[MAX_NAME_LENGTH] = {0}; uint8_t nick[MAX_NAME_LENGTH] = {0};
getname(m, friendnum, (uint8_t*) &nick); getname(m, friendnum, (uint8_t *) &nick);
fix_name(nick); fix_name(nick);
snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum); snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum);
ChatContext *x = calloc(1, sizeof(ChatContext)); ChatContext *x = calloc(1, sizeof(ChatContext));
x->friendnum = friendnum; x->friendnum = friendnum;
ret.x = (void*) x; ret.x = (void *) x;
return ret; return ret;
} }

View File

@ -50,6 +50,7 @@ char *get_user_config_dir(void)
BOOL ok; BOOL ok;
ok = SHGetSpecialFolderPathA(NULL, appdata, CSIDL_PROFILE, TRUE); ok = SHGetSpecialFolderPathA(NULL, appdata, CSIDL_PROFILE, TRUE);
if (!ok) { if (!ok) {
return NULL; return NULL;
} }
@ -72,13 +73,16 @@ char *get_user_config_dir(void)
int rc; int rc;
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf); rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
if (rc == 0) { if (rc == 0) {
home = pwd.pw_dir; home = pwd.pw_dir;
} else { } else {
home = getenv("HOME"); home = getenv("HOME");
if (home == NULL) { if (home == NULL) {
return NULL; return NULL;
} }
/* env variables can be tainted */ /* env variables can be tainted */
snprintf(buf, sizeof(buf), "%s", home); snprintf(buf, sizeof(buf), "%s", home);
home = buf; home = buf;
@ -87,6 +91,7 @@ char *get_user_config_dir(void)
# if defined(__APPLE__) # if defined(__APPLE__)
len = strlen(home) + strlen("/Library/Application Support") + 1; len = strlen(home) + strlen("/Library/Application Support") + 1;
user_config_dir = malloc(len); user_config_dir = malloc(len);
if (user_config_dir == NULL) { if (user_config_dir == NULL) {
return NULL; return NULL;
} }
@ -95,6 +100,7 @@ char *get_user_config_dir(void)
# else /* __APPLE__ */ # else /* __APPLE__ */
len = strlen(home) + strlen("/.config") + 1; len = strlen(home) + strlen("/.config") + 1;
user_config_dir = malloc(len); user_config_dir = malloc(len);
if (user_config_dir == NULL) { if (user_config_dir == NULL) {
return NULL; return NULL;
} }
@ -111,44 +117,45 @@ char *get_user_config_dir(void)
* Creates the config directory. * Creates the config directory.
*/ */
int create_user_config_dir(char *path) int create_user_config_dir(char *path)
{ {
int mkdir_err; int mkdir_err;
#ifdef WIN32 #ifdef WIN32
char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1); char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1);
strcpy(fullpath, path); strcpy(fullpath, path);
strcat(fullpath, CONFIGDIR); strcat(fullpath, CONFIGDIR);
mkdir_err = _mkdir(fullpath); mkdir_err = _mkdir(fullpath);
struct __stat64 buf; struct __stat64 buf;
if (mkdir_err && (errno != EEXIST || _wstat64(fullpath, &buf) || !S_ISDIR(buf.st_mode))) {
if (mkdir_err && (errno != EEXIST || _wstat64(fullpath, &buf) || !S_ISDIR(buf.st_mode))) {
free(fullpath);
return -1;
}
#else
mkdir_err = mkdir(path, 0700);
struct stat buf;
if (mkdir_err && (errno != EEXIST || stat(path, &buf) || !S_ISDIR(buf.st_mode))) {
return -1;
}
char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1);
strcpy(fullpath, path);
strcat(fullpath, CONFIGDIR);
mkdir_err = mkdir(fullpath, 0700);
if (mkdir_err && (errno != EEXIST || stat(fullpath, &buf) || !S_ISDIR(buf.st_mode))) {
free(fullpath);
return -1;
}
#endif
free(fullpath); free(fullpath);
return -1; return 0;
}
#else
mkdir_err = mkdir(path, 0700);
struct stat buf;
if(mkdir_err && (errno != EEXIST || stat(path, &buf) || !S_ISDIR(buf.st_mode))) {
return -1;
}
char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1);
strcpy(fullpath, path);
strcat(fullpath, CONFIGDIR);
mkdir_err = mkdir(fullpath, 0700);
if(mkdir_err && (errno != EEXIST || stat(fullpath, &buf) || !S_ISDIR(buf.st_mode))) {
free(fullpath);
return -1;
}
#endif
free(fullpath);
return 0;
} }

View File

@ -23,7 +23,7 @@
#else #else
#define CONFIGDIR "/toxic/" #define CONFIGDIR "/toxic/"
#endif #endif
#ifndef S_ISDIR #ifndef S_ISDIR
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif #endif

View File

@ -3,87 +3,97 @@
#include "../../core/network.h" #include "../../core/network.h"
#include "../../core/DHT.h" #include "../../core/DHT.h"
typedef uint8_t ipbuf[3*4+3+1]; typedef uint8_t ipbuf[3 * 4 + 3 + 1];
static int num_selected = 0; static int num_selected = 0;
static void printip(ipbuf buf, IP ip) static void printip(ipbuf buf, IP ip)
{ {
sprintf((char*)buf, "%u.%u.%u.%u", ip.c[0], ip.c[1], ip.c[2], ip.c[3]); sprintf((char *)buf, "%u.%u.%u.%u", ip.c[0], ip.c[1], ip.c[2], ip.c[3]);
} }
static void dhtstatus_onKey(ToxWindow *self, Messenger *m, int key) static void dhtstatus_onKey(ToxWindow *self, Messenger *m, int key)
{ {
switch(key) { switch (key) {
case KEY_UP: case KEY_UP:
case 'k': case 'k':
if (--num_selected < 0) if (--num_selected < 0)
num_selected = CLIENT_ID_SIZE-1; num_selected = CLIENT_ID_SIZE - 1;
break;
break;
case KEY_DOWN:
case 'j': case KEY_DOWN:
num_selected = (num_selected+1) % CLIENT_ID_SIZE; case 'j':
break; num_selected = (num_selected + 1) % CLIENT_ID_SIZE;
break;
case '\n':
break; case '\n':
break;
default:
break; default:
} break;
}
} }
static void dhtstatus_onDraw(ToxWindow *self) static void dhtstatus_onDraw(ToxWindow *self)
{ {
Client_data * close_clientlist = DHT_get_close_list(); Client_data *close_clientlist = DHT_get_close_list();
curs_set(0); curs_set(0);
werase(self->window); werase(self->window);
uint64_t now = unix_time(); uint64_t now = unix_time();
uint32_t i, j; uint32_t i, j;
ipbuf ipbuf; ipbuf ipbuf;
wprintw(self->window,"\n%llu ______________________ CLOSE LIST ________________________ ___ IP ADDR ___ _PRT_ LST PNG ____ SELF ____ _PRT_ LST\n\n", now); wprintw(self->window,
for(i = 0; i < 32; i++) { /*Number of nodes in closelist*/ "\n%llu ______________________ CLOSE LIST ________________________ ___ IP ADDR ___ _PRT_ LST PNG ____ SELF ____ _PRT_ LST\n\n",
Client_data * client = close_clientlist + i; now);
if (i == num_selected) wattron(self->window, COLOR_PAIR(3));
wprintw(self->window,"[%02i] ", i); for (i = 0; i < 32; i++) { /*Number of nodes in closelist*/
uint16_t port = ntohs(client->ip_port.port); Client_data *client = close_clientlist + i;
if(port) {
for(j = 0; j < CLIENT_ID_SIZE; j++) if (i == num_selected) wattron(self->window, COLOR_PAIR(3));
wprintw(self->window, "%02hhx", client->client_id[j]);
wprintw(self->window, "[%02i] ", i);
printip(ipbuf, client->ip_port.ip); uint16_t port = ntohs(client->ip_port.port);
wprintw(self->window, " %15s %5u ", ipbuf, port);
wprintw(self->window, " %3llu ", now - client->timestamp); if (port) {
wprintw(self->window, " %3llu ", now - client->last_pinged); for (j = 0; j < CLIENT_ID_SIZE; j++)
wprintw(self->window, "%02hhx", client->client_id[j]);
port = ntohs(client->ret_ip_port.port);
if(port) { printip(ipbuf, client->ip_port.ip);
printip(ipbuf, client->ret_ip_port.ip); wprintw(self->window, " %15s %5u ", ipbuf, port);
wprintw(self->window, " %15s %5u %3llu", ipbuf, port, now - close_clientlist[i].ret_timestamp); wprintw(self->window, " %3llu ", now - client->timestamp);
} wprintw(self->window, " %3llu ", now - client->last_pinged);
port = ntohs(client->ret_ip_port.port);
if (port) {
printip(ipbuf, client->ret_ip_port.ip);
wprintw(self->window, " %15s %5u %3llu", ipbuf, port, now - close_clientlist[i].ret_timestamp);
}
}
wprintw(self->window, "\n");
if (i == num_selected) wattroff(self->window, COLOR_PAIR(3));
} }
wprintw(self->window, "\n");
if (i == num_selected) wattroff(self->window, COLOR_PAIR(3)); wrefresh(self->window);
}
wrefresh(self->window);
} }
static void dhtstatus_onInit(ToxWindow *self, Messenger *m) static void dhtstatus_onInit(ToxWindow *self, Messenger *m)
{ {
} }
ToxWindow new_dhtstatus() ToxWindow new_dhtstatus()
{ {
ToxWindow ret; ToxWindow ret;
memset(&ret, 0, sizeof(ret)); memset(&ret, 0, sizeof(ret));
ret.onKey = &dhtstatus_onKey; ret.onKey = &dhtstatus_onKey;
ret.onDraw = &dhtstatus_onDraw; ret.onDraw = &dhtstatus_onDraw;
ret.onInit = &dhtstatus_onInit; ret.onInit = &dhtstatus_onInit;
strcpy(ret.title, "[dht status]"); strcpy(ret.title, "[dht status]");
return ret; return ret;
} }

View File

@ -13,13 +13,13 @@
#include "windows.h" #include "windows.h"
#include "friendlist.h" #include "friendlist.h"
static char * WINDOW_STATUS; static char *WINDOW_STATUS;
typedef struct { typedef struct {
uint8_t name[MAX_NAME_LENGTH]; uint8_t name[MAX_NAME_LENGTH];
uint8_t status[MAX_STATUSMESSAGE_LENGTH]; uint8_t status[MAX_STATUSMESSAGE_LENGTH];
int num; int num;
int chatwin; int chatwin;
} friend_t; } friend_t;
static friend_t friends[MAX_FRIENDS_NUM]; static friend_t friends[MAX_FRIENDS_NUM];
@ -28,135 +28,143 @@ static int num_selected = 0;
void fix_name(uint8_t *name) void fix_name(uint8_t *name)
{ {
/* Remove all non alphanumeric characters */ /* Remove all non alphanumeric characters */
uint8_t *p = name; uint8_t *p = name;
uint8_t *q = name; uint8_t *q = name;
while(*p != 0) {
if (isprint(*p)) while (*p != 0) {
*q++ = *p; if (isprint(*p))
p++; *q++ = *p;
}
*q = 0; p++;
}
*q = 0;
} }
void friendlist_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *str, uint16_t len) void friendlist_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *str, uint16_t len)
{ {
if (num >= num_friends) if (num >= num_friends)
return; return;
if (friends[num].chatwin == -1) { if (friends[num].chatwin == -1) {
friends[num].chatwin = num; friends[num].chatwin = num;
int i; int i;
/* Find first open slot to hold chat window */
for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) { /* Find first open slot to hold chat window */
if (WINDOW_STATUS[i] == -1) { for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) {
WINDOW_STATUS[i] = num; if (WINDOW_STATUS[i] == -1) {
add_window(m, new_chat(m, num), i); WINDOW_STATUS[i] = num;
break; add_window(m, new_chat(m, num), i);
} break;
}
}
} }
}
} }
void friendlist_onNickChange(ToxWindow *self, int num, uint8_t *str, uint16_t len) void friendlist_onNickChange(ToxWindow *self, int num, uint8_t *str, uint16_t len)
{ {
if (len >= MAX_NAME_LENGTH || num >= num_friends) if (len >= MAX_NAME_LENGTH || num >= num_friends)
return; return;
memcpy((char*) &friends[num].name, (char*) str, len); memcpy((char *) &friends[num].name, (char *) str, len);
friends[num].name[len] = 0; friends[num].name[len] = 0;
fix_name(friends[num].name); fix_name(friends[num].name);
} }
void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t len) void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t len)
{ {
if (len >= MAX_STATUSMESSAGE_LENGTH || num >= num_friends) if (len >= MAX_STATUSMESSAGE_LENGTH || num >= num_friends)
return; return;
memcpy((char*) &friends[num].status, (char*) str, len); memcpy((char *) &friends[num].status, (char *) str, len);
friends[num].status[len] = 0; friends[num].status[len] = 0;
fix_name(friends[num].status); fix_name(friends[num].status);
} }
int friendlist_onFriendAdded(Messenger *m, int num) int friendlist_onFriendAdded(Messenger *m, int num)
{ {
if (num_friends == MAX_FRIENDS_NUM) if (num_friends == MAX_FRIENDS_NUM)
return -1; return -1;
friends[num_friends].num = num; friends[num_friends].num = num;
getname(m, num, friends[num_friends].name); getname(m, num, friends[num_friends].name);
strcpy((char*) friends[num_friends].name, "unknown"); strcpy((char *) friends[num_friends].name, "unknown");
strcpy((char*) friends[num_friends].status, "unknown"); strcpy((char *) friends[num_friends].status, "unknown");
friends[num_friends++].chatwin = -1; friends[num_friends++].chatwin = -1;
return 0; return 0;
} }
static void friendlist_onKey(ToxWindow *self, Messenger *m, int key) static void friendlist_onKey(ToxWindow *self, Messenger *m, int key)
{ {
if (key == KEY_UP) { if (key == KEY_UP) {
if (--num_selected < 0) if (--num_selected < 0)
num_selected = num_friends-1; num_selected = num_friends - 1;
} } else if (key == KEY_DOWN) {
else if (key == KEY_DOWN) { if (num_friends != 0)
if (num_friends != 0) num_selected = (num_selected + 1) % num_friends;
num_selected = (num_selected+1) % num_friends; } else if (key == '\n') {
} /* Jump to chat window if already open */
else if (key == '\n') { if (friends[num_selected].chatwin != -1) {
/* Jump to chat window if already open */ int i;
if (friends[num_selected].chatwin != -1) {
int i; for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) {
for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) { if (WINDOW_STATUS[i] == num_selected) {
if (WINDOW_STATUS[i] == num_selected) { set_active_window(i);
set_active_window(i); break;
break; }
}
} else {
int i;
for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) {
if (WINDOW_STATUS[i] == -1) {
WINDOW_STATUS[i] = num_selected;
friends[num_selected].chatwin = num_selected;
add_window(m, new_chat(m, num_selected), i);
break;
}
}
} }
}
}else {
int i;
for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) {
if (WINDOW_STATUS[i] == -1) {
WINDOW_STATUS[i] = num_selected;
friends[num_selected].chatwin = num_selected;
add_window(m, new_chat(m, num_selected), i);
break;
}
}
} }
}
} }
static void friendlist_onDraw(ToxWindow *self) static void friendlist_onDraw(ToxWindow *self)
{ {
curs_set(0); curs_set(0);
werase(self->window); werase(self->window);
if (num_friends == 0) {
wprintw(self->window, "Empty. Add some friends! :-)\n");
}
else {
wattron(self->window, COLOR_PAIR(2) | A_BOLD);
wprintw(self->window, "Open chat with.. (up/down keys, enter)\n");
wattroff(self->window, COLOR_PAIR(2) | A_BOLD);
}
wprintw(self->window, "\n"); if (num_friends == 0) {
int i; wprintw(self->window, "Empty. Add some friends! :-)\n");
for (i = 0; i < num_friends; ++i) { } else {
if (i == num_selected) wattron(self->window, COLOR_PAIR(3)); wattron(self->window, COLOR_PAIR(2) | A_BOLD);
wprintw(self->window, " [#%d] ", friends[i].num); wprintw(self->window, "Open chat with.. (up/down keys, enter)\n");
if (i == num_selected) wattroff(self->window, COLOR_PAIR(3)); wattroff(self->window, COLOR_PAIR(2) | A_BOLD);
}
attron(A_BOLD); wprintw(self->window, "\n");
wprintw(self->window, "%s ", friends[i].name); int i;
attroff(A_BOLD);
wprintw(self->window, "(%s)\n", friends[i].status); for (i = 0; i < num_friends; ++i) {
} if (i == num_selected) wattron(self->window, COLOR_PAIR(3));
wrefresh(self->window);
wprintw(self->window, " [#%d] ", friends[i].num);
if (i == num_selected) wattroff(self->window, COLOR_PAIR(3));
attron(A_BOLD);
wprintw(self->window, "%s ", friends[i].name);
attroff(A_BOLD);
wprintw(self->window, "(%s)\n", friends[i].status);
}
wrefresh(self->window);
} }
void disable_chatwin(int f_num) void disable_chatwin(int f_num)
{ {
friends[f_num].chatwin = -1; friends[f_num].chatwin = -1;
} }
static void friendlist_onInit(ToxWindow *self, Messenger *m) static void friendlist_onInit(ToxWindow *self, Messenger *m)
@ -164,19 +172,20 @@ static void friendlist_onInit(ToxWindow *self, Messenger *m)
} }
ToxWindow new_friendlist(char * ws) { ToxWindow new_friendlist(char *ws)
WINDOW_STATUS = ws; {
ToxWindow ret; WINDOW_STATUS = ws;
memset(&ret, 0, sizeof(ret)); ToxWindow ret;
memset(&ret, 0, sizeof(ret));
ret.onKey = &friendlist_onKey; ret.onKey = &friendlist_onKey;
ret.onDraw = &friendlist_onDraw; ret.onDraw = &friendlist_onDraw;
ret.onInit = &friendlist_onInit; ret.onInit = &friendlist_onInit;
ret.onMessage = &friendlist_onMessage; ret.onMessage = &friendlist_onMessage;
ret.onAction = &friendlist_onMessage; // Action has identical behaviour to message ret.onAction = &friendlist_onMessage; // Action has identical behaviour to message
ret.onNickChange = &friendlist_onNickChange; ret.onNickChange = &friendlist_onNickChange;
ret.onStatusChange = &friendlist_onStatusChange; ret.onStatusChange = &friendlist_onStatusChange;
strcpy(ret.title, "[friends]"); strcpy(ret.title, "[friends]");
return ret; return ret;
} }

View File

@ -4,7 +4,7 @@
#include "windows.h" #include "windows.h"
#include "chat.h" #include "chat.h"
ToxWindow new_friendlist(char * ws); ToxWindow new_friendlist(char *ws);
int friendlist_onFriendAdded(Messenger *m, int num); int friendlist_onFriendAdded(Messenger *m, int num);
void disable_chatwin(int f_num); void disable_chatwin(int f_num);
void fix_name(uint8_t *name); void fix_name(uint8_t *name);

View File

@ -28,7 +28,7 @@
/* Export for use in Callbacks */ /* Export for use in Callbacks */
char *DATA_FILE = NULL; char *DATA_FILE = NULL;
void on_window_resize(int sig) void on_window_resize(int sig)
{ {
endwin(); endwin();
refresh(); refresh();
@ -37,44 +37,45 @@ void on_window_resize(int sig)
static void init_term() static void init_term()
{ {
/* Setup terminal */ /* Setup terminal */
signal(SIGWINCH, on_window_resize); signal(SIGWINCH, on_window_resize);
initscr(); initscr();
cbreak(); cbreak();
keypad(stdscr, 1); keypad(stdscr, 1);
noecho(); noecho();
timeout(100); timeout(100);
if (has_colors()) { if (has_colors()) {
start_color(); start_color();
init_pair(1, COLOR_GREEN, COLOR_BLACK); init_pair(1, COLOR_GREEN, COLOR_BLACK);
init_pair(2, COLOR_CYAN, COLOR_BLACK); init_pair(2, COLOR_CYAN, COLOR_BLACK);
init_pair(3, COLOR_RED, COLOR_BLACK); init_pair(3, COLOR_RED, COLOR_BLACK);
init_pair(4, COLOR_BLUE, COLOR_BLACK); init_pair(4, COLOR_BLUE, COLOR_BLACK);
init_pair(5, COLOR_YELLOW, COLOR_BLACK); init_pair(5, COLOR_YELLOW, COLOR_BLACK);
} }
refresh();
refresh();
} }
static Messenger *init_tox() static Messenger *init_tox()
{ {
/* Init core */ /* Init core */
Messenger *m = initMessenger(); Messenger *m = initMessenger();
/* Callbacks */ /* Callbacks */
m_callback_friendrequest(m, on_request, NULL); m_callback_friendrequest(m, on_request, NULL);
m_callback_friendmessage(m, on_message, NULL); m_callback_friendmessage(m, on_message, NULL);
m_callback_namechange(m, on_nickchange, NULL); m_callback_namechange(m, on_nickchange, NULL);
m_callback_statusmessage(m, on_statuschange, NULL); m_callback_statusmessage(m, on_statuschange, NULL);
m_callback_action(m, on_action, NULL); m_callback_action(m, on_action, NULL);
#ifdef __linux__ #ifdef __linux__
setname(m, (uint8_t*) "Cool guy", sizeof("Cool guy")); setname(m, (uint8_t *) "Cool guy", sizeof("Cool guy"));
#elif WIN32 #elif WIN32
setname(m, (uint8_t*) "I should install GNU/Linux", sizeof("I should install GNU/Linux")); setname(m, (uint8_t *) "I should install GNU/Linux", sizeof("I should install GNU/Linux"));
#else #else
setname(m, (uint8_t*) "Hipster", sizeof("Hipster")); setname(m, (uint8_t *) "Hipster", sizeof("Hipster"));
#endif #endif
return m; return m;
} }
#define MAXLINE 90 /* Approx max number of chars in a sever line (IP + port + key) */ #define MAXLINE 90 /* Approx max number of chars in a sever line (IP + port + key) */
@ -84,67 +85,75 @@ static Messenger *init_tox()
/* Connects to a random DHT server listed in the DHTservers file */ /* Connects to a random DHT server listed in the DHTservers file */
int init_connection(void) int init_connection(void)
{ {
if (DHT_isconnected()) if (DHT_isconnected())
return 0; return 0;
FILE *fp = fopen("../../../other/DHTservers", "r"); FILE *fp = fopen("../../../other/DHTservers", "r");
if (!fp)
return 1; if (!fp)
return 1;
char servers[MAXSERVERS][MAXLINE];
char line[MAXLINE];
int linecnt = 0;
while (fgets(line, sizeof(line), fp) && linecnt < MAXSERVERS) {
if (strlen(line) > MINLINE)
strcpy(servers[linecnt++], line);
}
if (linecnt < 1) {
fclose(fp);
return 2;
}
char servers[MAXSERVERS][MAXLINE];
char line[MAXLINE];
int linecnt = 0;
while (fgets(line, sizeof(line), fp) && linecnt < MAXSERVERS) {
if (strlen(line) > MINLINE)
strcpy(servers[linecnt++], line);
}
if (linecnt < 1) {
fclose(fp); fclose(fp);
return 2;
}
fclose(fp);
char *server = servers[rand() % linecnt]; char *server = servers[rand() % linecnt];
char *ip = strtok(server, " "); char *ip = strtok(server, " ");
char *port = strtok(NULL, " "); char *port = strtok(NULL, " ");
char *key = strtok(NULL, " "); char *key = strtok(NULL, " ");
if (!ip || !port || !key)
return 3;
IP_Port dht; if (!ip || !port || !key)
dht.port = htons(atoi(port)); return 3;
uint32_t resolved_address = resolve_addr(ip);
if (resolved_address == 0) IP_Port dht;
dht.port = htons(atoi(port));
uint32_t resolved_address = resolve_addr(ip);
if (resolved_address == 0)
return 0;
dht.ip.i = resolved_address;
unsigned char *binary_string = hex_string_to_bin(key);
DHT_bootstrap(dht, binary_string);
free(binary_string);
return 0; return 0;
dht.ip.i = resolved_address;
unsigned char *binary_string = hex_string_to_bin(key);
DHT_bootstrap(dht, binary_string);
free(binary_string);
return 0;
} }
static void do_tox(Messenger *m, ToxWindow * prompt) static void do_tox(Messenger *m, ToxWindow *prompt)
{ {
static int conn_try = 0; static int conn_try = 0;
static int conn_err = 0; static int conn_err = 0;
static bool dht_on = false; static bool dht_on = false;
if (!dht_on && !DHT_isconnected() && !(conn_try++ % 100)) {
if (!conn_err) { if (!dht_on && !DHT_isconnected() && !(conn_try++ % 100)) {
conn_err = init_connection(); if (!conn_err) {
wprintw(prompt->window, "\nEstablishing connection...\n"); conn_err = init_connection();
if (conn_err) wprintw(prompt->window, "\nEstablishing connection...\n");
wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err);
if (conn_err)
wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err);
}
} else if (!dht_on && DHT_isconnected()) {
dht_on = true;
wprintw(prompt->window, "\nDHT connected.\n");
} else if (dht_on && !DHT_isconnected()) {
dht_on = false;
wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n");
} }
}
else if (!dht_on && DHT_isconnected()) { doMessenger(m);
dht_on = true;
wprintw(prompt->window, "\nDHT connected.\n");
}
else if (dht_on && !DHT_isconnected()) {
dht_on = false;
wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n");
}
doMessenger(m);
} }
int f_loadfromfile; int f_loadfromfile;
@ -160,18 +169,22 @@ int store_data(Messenger *m, char *path)
{ {
if (f_loadfromfile == 0) /*If file loading/saving is disabled*/ if (f_loadfromfile == 0) /*If file loading/saving is disabled*/
return 0; return 0;
FILE *fd; FILE *fd;
size_t len; size_t len;
uint8_t *buf; uint8_t *buf;
len = Messenger_size(m); len = Messenger_size(m);
buf = malloc(len); buf = malloc(len);
if (buf == NULL) { if (buf == NULL) {
return 1; return 1;
} }
Messenger_save(m, buf); Messenger_save(m, buf);
fd = fopen(path, "w"); fd = fopen(path, "w");
if (fd == NULL) { if (fd == NULL) {
free(buf); free(buf);
return 2; return 2;
@ -192,6 +205,7 @@ static void load_data(Messenger *m, char *path)
{ {
if (f_loadfromfile == 0) /*If file loading/saving is disabled*/ if (f_loadfromfile == 0) /*If file loading/saving is disabled*/
return; return;
FILE *fd; FILE *fd;
size_t len; size_t len;
uint8_t *buf; uint8_t *buf;
@ -202,12 +216,14 @@ static void load_data(Messenger *m, char *path)
fseek(fd, 0, SEEK_SET); fseek(fd, 0, SEEK_SET);
buf = malloc(len); buf = malloc(len);
if (buf == NULL) { if (buf == NULL) {
fprintf(stderr, "malloc() failed.\n"); fprintf(stderr, "malloc() failed.\n");
fclose(fd); fclose(fd);
endwin(); endwin();
exit(1); exit(1);
} }
if (fread(buf, len, 1, fd) != 1) { if (fread(buf, len, 1, fd) != 1) {
fprintf(stderr, "fread() failed.\n"); fprintf(stderr, "fread() failed.\n");
free(buf); free(buf);
@ -215,9 +231,11 @@ static void load_data(Messenger *m, char *path)
endwin(); endwin();
exit(1); exit(1);
} }
Messenger_load(m, buf, len); Messenger_load(m, buf, len);
uint32_t i; uint32_t i;
for (i = 0; i < m->numfriends; i++) { for (i = 0; i < m->numfriends; i++) {
on_friendadded(m, i); on_friendadded(m, i);
} }
@ -226,6 +244,7 @@ static void load_data(Messenger *m, char *path)
fclose(fd); fclose(fd);
} else { } else {
int st; int st;
if ((st = store_data(m, path)) != 0) { if ((st = store_data(m, path)) != 0) {
fprintf(stderr, "Store messenger failed with return code: %d\n", st); fprintf(stderr, "Store messenger failed with return code: %d\n", st);
endwin(); endwin();
@ -236,70 +255,74 @@ static void load_data(Messenger *m, char *path)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *user_config_dir = get_user_config_dir(); char *user_config_dir = get_user_config_dir();
int config_err = 0; int config_err = 0;
f_loadfromfile = 1; f_loadfromfile = 1;
int f_flag = 0; int f_flag = 0;
int i = 0; int i = 0;
for (i = 0; i < argc; ++i) {
if (argv[i] == NULL) for (i = 0; i < argc; ++i) {
break; if (argv[i] == NULL)
else if (argv[i][0] == '-') { break;
if (argv[i][1] == 'f') { else if (argv[i][0] == '-') {
if (argv[i + 1] != NULL) if (argv[i][1] == 'f') {
DATA_FILE = strdup(argv[i + 1]); if (argv[i + 1] != NULL)
else DATA_FILE = strdup(argv[i + 1]);
f_flag = -1; else
} else if (argv[i][1] == 'n') { f_flag = -1;
f_loadfromfile = 0; } else if (argv[i][1] == 'n') {
} f_loadfromfile = 0;
}
}
}
if (DATA_FILE == NULL ) {
config_err = create_user_config_dir(user_config_dir);
if (config_err) {
DATA_FILE = strdup("data");
} else {
DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1);
strcpy(DATA_FILE, user_config_dir);
strcat(DATA_FILE, CONFIGDIR);
strcat(DATA_FILE, "data");
}
}
free(user_config_dir);
init_term();
Messenger *m = init_tox();
ToxWindow *prompt = init_windows(m);
init_window_status();
if (f_loadfromfile)
load_data(m, DATA_FILE);
if (f_flag == -1) {
attron(COLOR_PAIR(3) | A_BOLD);
wprintw(prompt->window, "You passed '-f' without giving an argument.\n"
"defaulting to 'data' for a keyfile...\n");
attroff(COLOR_PAIR(3) | A_BOLD);
} }
}
if (DATA_FILE == NULL ) {
config_err = create_user_config_dir(user_config_dir);
if (config_err) { if (config_err) {
DATA_FILE = strdup("data"); attron(COLOR_PAIR(3) | A_BOLD);
} else { wprintw(prompt->window, "Unable to determine configuration directory.\n"
DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1); "defaulting to 'data' for a keyfile...\n");
strcpy(DATA_FILE, user_config_dir); attroff(COLOR_PAIR(3) | A_BOLD);
strcat(DATA_FILE, CONFIGDIR);
strcat(DATA_FILE, "data");
} }
}
free(user_config_dir);
init_term(); while (true) {
Messenger *m = init_tox(); /* Update tox */
ToxWindow *prompt = init_windows(m); do_tox(m, prompt);
init_window_status();
if(f_loadfromfile) /* Draw */
load_data(m, DATA_FILE); draw_active_window(m);
}
if (f_flag == -1) { cleanupMessenger(m);
attron(COLOR_PAIR(3) | A_BOLD); free(DATA_FILE);
wprintw(prompt->window, "You passed '-f' without giving an argument.\n" return 0;
"defaulting to 'data' for a keyfile...\n");
attroff(COLOR_PAIR(3) | A_BOLD);
}
if(config_err) {
attron(COLOR_PAIR(3) | A_BOLD);
wprintw(prompt->window, "Unable to determine configuration directory.\n"
"defaulting to 'data' for a keyfile...\n");
attroff(COLOR_PAIR(3) | A_BOLD);
}
while(true) {
/* Update tox */
do_tox(m, prompt);
/* Draw */
draw_active_window(m);
}
cleanupMessenger(m);
free(DATA_FILE);
return 0;
} }

View File

@ -14,7 +14,7 @@
#include "prompt.h" #include "prompt.h"
uint8_t pending_requests[MAX_STR_SIZE][CLIENT_ID_SIZE]; // XXX uint8_t pending_requests[MAX_STR_SIZE][CLIENT_ID_SIZE]; // XXX
uint8_t num_requests=0; // XXX uint8_t num_requests = 0; // XXX
static friendAddedFn *on_friendadded_cb; static friendAddedFn *on_friendadded_cb;
static char prompt_buf[MAX_STR_SIZE] = {0}; static char prompt_buf[MAX_STR_SIZE] = {0};
@ -36,412 +36,441 @@ void cmd_statusmsg(ToxWindow *, Messenger *m, char **);
#define NUM_COMMANDS 13 #define NUM_COMMANDS 13
static struct { static struct {
char *name; char *name;
int numargs; int numargs;
void (*func)(ToxWindow *, Messenger *m, char **); void (*func)(ToxWindow *, Messenger *m, char **);
} commands[] = { } commands[] = {
{ "accept", 1, cmd_accept }, { "accept", 1, cmd_accept },
{ "add", 1, cmd_add }, { "add", 1, cmd_add },
{ "clear", 0, cmd_clear }, { "clear", 0, cmd_clear },
{ "connect", 3, cmd_connect }, { "connect", 3, cmd_connect },
{ "exit", 0, cmd_quit }, { "exit", 0, cmd_quit },
{ "help", 0, cmd_help }, { "help", 0, cmd_help },
{ "msg", 2, cmd_msg }, { "msg", 2, cmd_msg },
{ "myid", 0, cmd_myid }, { "myid", 0, cmd_myid },
{ "nick", 1, cmd_nick }, { "nick", 1, cmd_nick },
{ "q", 0, cmd_quit }, { "q", 0, cmd_quit },
{ "quit", 0, cmd_quit }, { "quit", 0, cmd_quit },
{ "status", 2, cmd_status }, { "status", 2, cmd_status },
{ "statusmsg", 1, cmd_statusmsg }, { "statusmsg", 1, cmd_statusmsg },
}; };
// XXX: // XXX:
int add_req(uint8_t *public_key) int add_req(uint8_t *public_key)
{ {
memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE); memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE);
++num_requests; ++num_requests;
return num_requests-1; return num_requests - 1;
} }
// XXX: FIX // XXX: FIX
unsigned char *hex_string_to_bin(char hex_string[]) unsigned char *hex_string_to_bin(char hex_string[])
{ {
size_t len = strlen(hex_string); size_t len = strlen(hex_string);
unsigned char *val = malloc(len); unsigned char *val = malloc(len);
char *pos = hex_string; char *pos = hex_string;
int i; int i;
for (i = 0; i < len; ++i, pos+=2)
sscanf(pos,"%2hhx",&val[i]); for (i = 0; i < len; ++i, pos += 2)
return val; sscanf(pos, "%2hhx", &val[i]);
return val;
} }
void cmd_accept(ToxWindow *self, Messenger *m, char **args) void cmd_accept(ToxWindow *self, Messenger *m, char **args)
{ {
int num = atoi(args[1]); int num = atoi(args[1]);
if (num >= num_requests) {
wprintw(self->window, "Invalid syntax.\n");
return;
}
num = m_addfriend_norequest(m, pending_requests[num]); if (num >= num_requests) {
if (num == -1) wprintw(self->window, "Invalid syntax.\n");
wprintw(self->window, "Failed to add friend.\n"); return;
else { }
wprintw(self->window, "Friend accepted as: %d.\n", num);
on_friendadded_cb(m, num); num = m_addfriend_norequest(m, pending_requests[num]);
}
if (num == -1)
wprintw(self->window, "Failed to add friend.\n");
else {
wprintw(self->window, "Friend accepted as: %d.\n", num);
on_friendadded_cb(m, num);
}
} }
void cmd_add(ToxWindow *self, Messenger *m, char **args) void cmd_add(ToxWindow *self, Messenger *m, char **args)
{ {
uint8_t id_bin[FRIEND_ADDRESS_SIZE]; uint8_t id_bin[FRIEND_ADDRESS_SIZE];
char xx[3]; char xx[3];
uint32_t x; uint32_t x;
char *id = args[1]; char *id = args[1];
char *msg = args[2]; char *msg = args[2];
if (!id) { if (!id) {
wprintw(self->window, "Invalid command: add expected at least one argument.\n"); wprintw(self->window, "Invalid command: add expected at least one argument.\n");
return; return;
} }
if (!msg)
msg = ""; if (!msg)
msg = "";
if (strlen(id) != 2*FRIEND_ADDRESS_SIZE) {
wprintw(self->window, "Invalid ID length.\n"); if (strlen(id) != 2 * FRIEND_ADDRESS_SIZE) {
return; wprintw(self->window, "Invalid ID length.\n");
} return;
int i; }
for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
xx[0] = id[2*i]; int i;
xx[1] = id[2*i+1];
xx[2] = '\0'; for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
if (sscanf(xx, "%02x", &x) != 1) { xx[0] = id[2 * i];
wprintw(self->window, "Invalid ID.\n"); xx[1] = id[2 * i + 1];
return; xx[2] = '\0';
if (sscanf(xx, "%02x", &x) != 1) {
wprintw(self->window, "Invalid ID.\n");
return;
}
id_bin[i] = x;
}
for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
id[i] = toupper(id[i]);
}
int num = m_addfriend(m, id_bin, (uint8_t *) msg, strlen(msg) + 1);
switch (num) {
case FAERR_TOOLONG:
wprintw(self->window, "Message is too long.\n");
break;
case FAERR_NOMESSAGE:
wprintw(self->window, "Please add a message to your request.\n");
break;
case FAERR_OWNKEY:
wprintw(self->window, "That appears to be your own ID.\n");
break;
case FAERR_ALREADYSENT:
wprintw(self->window, "Friend request already sent.\n");
break;
case FAERR_UNKNOWN:
wprintw(self->window, "Undefined error when adding friend.\n");
break;
case FAERR_BADCHECKSUM:
wprintw(self->window, "Bad checksum in address.\n");
break;
case FAERR_SETNEWNOSPAM:
wprintw(self->window, "Nospam was different.\n");
break;
default:
wprintw(self->window, "Friend added as %d.\n", num);
on_friendadded_cb(m, num);
break;
} }
id_bin[i] = x;
}
for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
id[i] = toupper(id[i]);
}
int num = m_addfriend(m, id_bin, (uint8_t*) msg, strlen(msg)+1);
switch (num) {
case FAERR_TOOLONG:
wprintw(self->window, "Message is too long.\n");
break;
case FAERR_NOMESSAGE:
wprintw(self->window, "Please add a message to your request.\n");
break;
case FAERR_OWNKEY:
wprintw(self->window, "That appears to be your own ID.\n");
break;
case FAERR_ALREADYSENT:
wprintw(self->window, "Friend request already sent.\n");
break;
case FAERR_UNKNOWN:
wprintw(self->window, "Undefined error when adding friend.\n");
break;
case FAERR_BADCHECKSUM:
wprintw(self->window, "Bad checksum in address.\n");
break;
case FAERR_SETNEWNOSPAM:
wprintw(self->window, "Nospam was different.\n");
break;
default:
wprintw(self->window, "Friend added as %d.\n", num);
on_friendadded_cb(m, num);
break;
}
} }
void cmd_clear(ToxWindow *self, Messenger *m, char **args) void cmd_clear(ToxWindow *self, Messenger *m, char **args)
{ {
wclear(self->window); wclear(self->window);
} }
void cmd_connect(ToxWindow *self, Messenger *m, char **args) void cmd_connect(ToxWindow *self, Messenger *m, char **args)
{ {
IP_Port dht; IP_Port dht;
char *ip = args[1]; char *ip = args[1];
char *port = args[2]; char *port = args[2];
char *key = args[3]; char *key = args[3];
if (atoi(port) == 0) { if (atoi(port) == 0) {
wprintw(self->window, "Invalid syntax.\n"); wprintw(self->window, "Invalid syntax.\n");
return; return;
} }
dht.port = htons(atoi(port)); dht.port = htons(atoi(port));
uint32_t resolved_address = resolve_addr(ip); uint32_t resolved_address = resolve_addr(ip);
if (resolved_address == 0) {
return;
}
dht.ip.i = resolved_address; if (resolved_address == 0) {
unsigned char *binary_string = hex_string_to_bin(key); return;
DHT_bootstrap(dht, binary_string); }
free(binary_string);
dht.ip.i = resolved_address;
unsigned char *binary_string = hex_string_to_bin(key);
DHT_bootstrap(dht, binary_string);
free(binary_string);
} }
void cmd_quit(ToxWindow *self, Messenger *m, char **args) void cmd_quit(ToxWindow *self, Messenger *m, char **args)
{ {
endwin(); endwin();
exit(0); exit(0);
} }
void cmd_help(ToxWindow *self, Messenger *m, char **args) void cmd_help(ToxWindow *self, Messenger *m, char **args)
{ {
wclear(self->window); wclear(self->window);
wattron(self->window, COLOR_PAIR(2) | A_BOLD); wattron(self->window, COLOR_PAIR(2) | A_BOLD);
wprintw(self->window, "Commands:\n"); wprintw(self->window, "Commands:\n");
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n"); wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n");
wprintw(self->window, " add <id> <message> : Add friend\n"); wprintw(self->window, " add <id> <message> : Add friend\n");
wprintw(self->window, " status <type> <message> : Set your status\n"); wprintw(self->window, " status <type> <message> : Set your status\n");
wprintw(self->window, " statusmsg <message> : Set your status\n"); wprintw(self->window, " statusmsg <message> : Set your status\n");
wprintw(self->window, " nick <nickname> : Set your nickname\n"); wprintw(self->window, " nick <nickname> : Set your nickname\n");
wprintw(self->window, " accept <number> : Accept friend request\n"); wprintw(self->window, " accept <number> : Accept friend request\n");
wprintw(self->window, " myid : Print your ID\n"); wprintw(self->window, " myid : Print your ID\n");
wprintw(self->window, " quit/exit : Exit program\n"); wprintw(self->window, " quit/exit : Exit program\n");
wprintw(self->window, " help : Print this message again\n"); wprintw(self->window, " help : Print this message again\n");
wprintw(self->window, " clear : Clear this window\n"); wprintw(self->window, " clear : Clear this window\n");
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
wattroff(self->window, COLOR_PAIR(2)); wattroff(self->window, COLOR_PAIR(2));
} }
void cmd_msg(ToxWindow *self, Messenger *m, char **args) void cmd_msg(ToxWindow *self, Messenger *m, char **args)
{ {
char *id = args[1]; char *id = args[1];
char *msg = args[2]; char *msg = args[2];
if (m_sendmessage(m, atoi(id), (uint8_t*) msg, strlen(msg)+1) == 0)
wprintw(self->window, "Error occurred while sending message.\n"); if (m_sendmessage(m, atoi(id), (uint8_t *) msg, strlen(msg) + 1) == 0)
else wprintw(self->window, "Error occurred while sending message.\n");
wprintw(self->window, "Message successfully sent.\n"); else
wprintw(self->window, "Message successfully sent.\n");
} }
void cmd_myid(ToxWindow *self, Messenger *m, char **args) void cmd_myid(ToxWindow *self, Messenger *m, char **args)
{ {
char id[FRIEND_ADDRESS_SIZE*2 + 1] = {0}; char id[FRIEND_ADDRESS_SIZE * 2 + 1] = {0};
size_t i; size_t i;
uint8_t address[FRIEND_ADDRESS_SIZE]; uint8_t address[FRIEND_ADDRESS_SIZE];
getaddress(m, address); getaddress(m, address);
for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
char xx[3]; for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff); char xx[3];
strcat(id, xx); snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff);
} strcat(id, xx);
wprintw(self->window, "%s\n", id); }
wprintw(self->window, "%s\n", id);
} }
void cmd_nick(ToxWindow *self, Messenger *m, char **args) void cmd_nick(ToxWindow *self, Messenger *m, char **args)
{ {
char *nick = args[1]; char *nick = args[1];
setname(m, (uint8_t*) nick, strlen(nick)+1); setname(m, (uint8_t *) nick, strlen(nick) + 1);
wprintw(self->window, "Nickname set to: %s\n", nick); wprintw(self->window, "Nickname set to: %s\n", nick);
} }
void cmd_status(ToxWindow *self, Messenger *m, char **args) void cmd_status(ToxWindow *self, Messenger *m, char **args)
{ {
char *status = args[1]; char *status = args[1];
char *status_text; char *status_text;
USERSTATUS status_kind; USERSTATUS status_kind;
if (!strncmp(status, "online", strlen("online"))) {
status_kind = USERSTATUS_NONE;
status_text = "ONLINE";
}
else if (!strncmp(status, "away", strlen("away"))) {
status_kind = USERSTATUS_AWAY;
status_text = "AWAY";
}
else if (!strncmp(status, "busy", strlen("busy"))) {
status_kind = USERSTATUS_BUSY;
status_text = "BUSY";
}
else
{
wprintw(self->window, "Invalid status.\n");
return;
}
char *msg = args[2]; if (!strncmp(status, "online", strlen("online"))) {
if (msg == NULL) { status_kind = USERSTATUS_NONE;
m_set_userstatus(m, status_kind); status_text = "ONLINE";
wprintw(self->window, "Status set to: %s\n", status_text); } else if (!strncmp(status, "away", strlen("away"))) {
} status_kind = USERSTATUS_AWAY;
else { status_text = "AWAY";
m_set_userstatus(m, status_kind); } else if (!strncmp(status, "busy", strlen("busy"))) {
m_set_statusmessage(m, (uint8_t*) msg, strlen(msg)+1); status_kind = USERSTATUS_BUSY;
wprintw(self->window, "Status set to: %s, %s\n", status_text, msg); status_text = "BUSY";
} } else {
wprintw(self->window, "Invalid status.\n");
return;
}
char *msg = args[2];
if (msg == NULL) {
m_set_userstatus(m, status_kind);
wprintw(self->window, "Status set to: %s\n", status_text);
} else {
m_set_userstatus(m, status_kind);
m_set_statusmessage(m, (uint8_t *) msg, strlen(msg) + 1);
wprintw(self->window, "Status set to: %s, %s\n", status_text, msg);
}
} }
void cmd_statusmsg(ToxWindow *self, Messenger *m, char **args) void cmd_statusmsg(ToxWindow *self, Messenger *m, char **args)
{ {
char *msg = args[1]; char *msg = args[1];
m_set_statusmessage(m, (uint8_t*) msg, strlen(msg)+1); m_set_statusmessage(m, (uint8_t *) msg, strlen(msg) + 1);
wprintw(self->window, "Status set to: %s\n", msg); wprintw(self->window, "Status set to: %s\n", msg);
} }
static void execute(ToxWindow *self, Messenger *m, char *u_cmd) static void execute(ToxWindow *self, Messenger *m, char *u_cmd)
{ {
int newlines = 0; int newlines = 0;
char cmd[MAX_STR_SIZE] = {0}; char cmd[MAX_STR_SIZE] = {0};
int i; int i;
for (i = 0; i < strlen(prompt_buf); ++i) {
if (u_cmd[i] == '\n')
++newlines;
else
cmd[i - newlines] = u_cmd[i];
}
int leading_spc = 0; for (i = 0; i < strlen(prompt_buf); ++i) {
for (i = 0; i < MAX_STR_SIZE && isspace(cmd[i]); ++i) if (u_cmd[i] == '\n')
leading_spc++; ++newlines;
memmove(cmd, cmd + leading_spc, MAX_STR_SIZE - leading_spc); else
cmd[i - newlines] = u_cmd[i];
int cmd_end = strlen(cmd);
while (cmd_end > 0 && cmd_end--)
if (!isspace(cmd[cmd_end]))
break;
cmd[cmd_end + 1] = '\0';
/* insert \0 at argument boundaries */
int numargs = 0;
for (i = 0; i < MAX_STR_SIZE; i++) {
if (cmd[i] == '\"')
while (cmd[++i] != '\"'); /* skip over strings */
if (cmd[i] == ' ') {
cmd[i] = '\0';
numargs++;
} }
}
/* excessive arguments */ int leading_spc = 0;
if (numargs > 3) {
wprintw(self->window, "Invalid command: too many arguments.\n");
return;
}
/* read arguments into array */ for (i = 0; i < MAX_STR_SIZE && isspace(cmd[i]); ++i)
char *cmdargs[5]; leading_spc++;
int pos = 0;
for (i = 0; i < 5; i++) {
cmdargs[i] = cmd + pos;
pos += strlen(cmdargs[i]) + 1;
}
/* no input */ memmove(cmd, cmd + leading_spc, MAX_STR_SIZE - leading_spc);
if (strlen(cmdargs[0]) == 0)
return;
/* match input to command list */ int cmd_end = strlen(cmd);
for (i = 0; i < NUM_COMMANDS; i++) {
if (!strcmp(cmdargs[0], commands[i].name)) { while (cmd_end > 0 && cmd_end--)
/* check for missing arguments */ if (!isspace(cmd[cmd_end]))
int j; break;
for (j = 0; j <= commands[i].numargs; j++) {
if (strlen(cmdargs[j]) == 0) { cmd[cmd_end + 1] = '\0';
wprintw(self->window, "Invalid command: %s expected %d arguments, got %d.\n",
commands[i].name, commands[i].numargs, j - 1); /* insert \0 at argument boundaries */
return; int numargs = 0;
for (i = 0; i < MAX_STR_SIZE; i++) {
if (cmd[i] == '\"')
while (cmd[++i] != '\"'); /* skip over strings */
if (cmd[i] == ' ') {
cmd[i] = '\0';
numargs++;
} }
}
/* check for excess arguments */
if (strcmp(cmdargs[0], "add") && strlen(cmdargs[j]) != 0) {
wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name);
return;
}
/* pass arguments to command function */
(commands[i].func)(self, m, cmdargs);
return;
} }
}
/* no match */ /* excessive arguments */
wprintw(self->window, "Invalid command.\n"); if (numargs > 3) {
wprintw(self->window, "Invalid command: too many arguments.\n");
return;
}
/* read arguments into array */
char *cmdargs[5];
int pos = 0;
for (i = 0; i < 5; i++) {
cmdargs[i] = cmd + pos;
pos += strlen(cmdargs[i]) + 1;
}
/* no input */
if (strlen(cmdargs[0]) == 0)
return;
/* match input to command list */
for (i = 0; i < NUM_COMMANDS; i++) {
if (!strcmp(cmdargs[0], commands[i].name)) {
/* check for missing arguments */
int j;
for (j = 0; j <= commands[i].numargs; j++) {
if (strlen(cmdargs[j]) == 0) {
wprintw(self->window, "Invalid command: %s expected %d arguments, got %d.\n",
commands[i].name, commands[i].numargs, j - 1);
return;
}
}
/* check for excess arguments */
if (strcmp(cmdargs[0], "add") && strlen(cmdargs[j]) != 0) {
wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name);
return;
}
/* pass arguments to command function */
(commands[i].func)(self, m, cmdargs);
return;
}
}
/* no match */
wprintw(self->window, "Invalid command.\n");
} }
static void prompt_onKey(ToxWindow *self, Messenger *m, int key) static void prompt_onKey(ToxWindow *self, Messenger *m, int key)
{ {
/* Add printable characters to line */ /* Add printable characters to line */
if (isprint(key)) { if (isprint(key)) {
if (prompt_buf_pos == (sizeof(prompt_buf) - 1)) { if (prompt_buf_pos == (sizeof(prompt_buf) - 1)) {
wprintw(self->window, "\nToo Long.\n"); wprintw(self->window, "\nToo Long.\n");
prompt_buf_pos = 0; prompt_buf_pos = 0;
prompt_buf[0] = 0; prompt_buf[0] = 0;
} } else if (!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS)
else if (!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS) && (prompt_buf_pos % (COLS - 3) == 0)) {
&& (prompt_buf_pos % (COLS - 3) == 0)) { prompt_buf[prompt_buf_pos++] = '\n';
prompt_buf[prompt_buf_pos++] = '\n'; } else if (!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS)
} && ((prompt_buf_pos - (COLS - 3)) % (COLS) == 0)) {
else if (!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS) prompt_buf[prompt_buf_pos++] = '\n';
&& ((prompt_buf_pos - (COLS - 3)) % (COLS) == 0)) { }
prompt_buf[prompt_buf_pos++] = '\n';
}
prompt_buf[prompt_buf_pos++] = key;
prompt_buf[prompt_buf_pos] = 0;
}
/* RETURN key: execute command */ prompt_buf[prompt_buf_pos++] = key;
else if (key == '\n') { prompt_buf[prompt_buf_pos] = 0;
wprintw(self->window, "\n"); }
execute(self, m, prompt_buf);
prompt_buf_pos = 0; /* RETURN key: execute command */
prompt_buf[0] = 0; else if (key == '\n') {
} wprintw(self->window, "\n");
execute(self, m, prompt_buf);
/* BACKSPACE key: Remove one character from line */ prompt_buf_pos = 0;
else if (key == 0x107 || key == 0x8 || key == 0x7f) { prompt_buf[0] = 0;
if (prompt_buf_pos != 0) { }
prompt_buf[--prompt_buf_pos] = 0;
/* BACKSPACE key: Remove one character from line */
else if (key == 0x107 || key == 0x8 || key == 0x7f) {
if (prompt_buf_pos != 0) {
prompt_buf[--prompt_buf_pos] = 0;
}
} }
}
} }
static void prompt_onDraw(ToxWindow *self) static void prompt_onDraw(ToxWindow *self)
{ {
curs_set(1); curs_set(1);
int x, y; int x, y;
getyx(self->window, y, x); getyx(self->window, y, x);
(void) x; (void) x;
int i; int i;
for (i = 0; i < (strlen(prompt_buf)); ++i) {
if ((prompt_buf[i] == '\n') && (y != 0))
--y;
}
wattron(self->window, COLOR_PAIR(1)); for (i = 0; i < (strlen(prompt_buf)); ++i) {
mvwprintw(self->window, y, 0, "# "); if ((prompt_buf[i] == '\n') && (y != 0))
wattroff(self->window, COLOR_PAIR(1)); --y;
mvwprintw(self->window, y, 2, "%s", prompt_buf); }
wclrtoeol(self->window);
wrefresh(self->window); wattron(self->window, COLOR_PAIR(1));
mvwprintw(self->window, y, 0, "# ");
wattroff(self->window, COLOR_PAIR(1));
mvwprintw(self->window, y, 2, "%s", prompt_buf);
wclrtoeol(self->window);
wrefresh(self->window);
} }
static void prompt_onInit(ToxWindow *self, Messenger *m) static void prompt_onInit(ToxWindow *self, Messenger *m)
{ {
scrollok(self->window, 1); scrollok(self->window, 1);
cmd_help(self, m, NULL); cmd_help(self, m, NULL);
wclrtoeol(self->window); wclrtoeol(self->window);
} }
ToxWindow new_prompt(friendAddedFn *f) ToxWindow new_prompt(friendAddedFn *f)
{ {
on_friendadded_cb = f; on_friendadded_cb = f;
ToxWindow ret; ToxWindow ret;
memset(&ret, 0, sizeof(ret)); memset(&ret, 0, sizeof(ret));
ret.onKey = &prompt_onKey; ret.onKey = &prompt_onKey;
ret.onDraw = &prompt_onDraw; ret.onDraw = &prompt_onDraw;
ret.onInit = &prompt_onInit; ret.onInit = &prompt_onInit;
strcpy(ret.title, "[prompt]"); strcpy(ret.title, "[prompt]");
return ret; return ret;
} }

View File

@ -14,232 +14,258 @@ static ToxWindow windows[MAX_WINDOW_SLOTS];
static Messenger *m; static Messenger *m;
int active_window; int active_window;
static ToxWindow* prompt; static ToxWindow *prompt;
/* CALLBACKS START */ /* CALLBACKS START */
void on_request(uint8_t *public_key, uint8_t *data, uint16_t length, void* userdata) void on_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
{ {
int n = add_req(public_key); int n = add_req(public_key);
wprintw(prompt->window, "\nFriend request from:\n"); wprintw(prompt->window, "\nFriend request from:\n");
int i; int i;
for (i = 0; i < KEY_SIZE_BYTES; ++i) {
wprintw(prompt->window, "%02x", public_key[i] & 0xff);
}
wprintw(prompt->window, "\nWith the message: %s\n", data); for (i = 0; i < KEY_SIZE_BYTES; ++i) {
wprintw(prompt->window, "\nUse \"accept %d\" to accept it.\n", n); wprintw(prompt->window, "%02x", public_key[i] & 0xff);
}
for (i = 0; i < MAX_WINDOW_SLOTS; ++i) { wprintw(prompt->window, "\nWith the message: %s\n", data);
if (windows[i].onFriendRequest != NULL) wprintw(prompt->window, "\nUse \"accept %d\" to accept it.\n", n);
windows[i].onFriendRequest(&windows[i], public_key, data, length);
} for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
if (windows[i].onFriendRequest != NULL)
windows[i].onFriendRequest(&windows[i], public_key, data, length);
}
} }
void on_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata) void on_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
int i; int i;
for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
if (windows[i].onMessage != NULL) for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
windows[i].onMessage(&windows[i], m, friendnumber, string, length); if (windows[i].onMessage != NULL)
} windows[i].onMessage(&windows[i], m, friendnumber, string, length);
}
} }
void on_action(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata) void on_action(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
int i; int i;
for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
if (windows[i].onAction != NULL) for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
windows[i].onAction(&windows[i], m, friendnumber, string, length); if (windows[i].onAction != NULL)
} windows[i].onAction(&windows[i], m, friendnumber, string, length);
}
} }
void on_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata) void on_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
wprintw(prompt->window, "\n(nickchange) %d: %s\n", friendnumber, string); wprintw(prompt->window, "\n(nickchange) %d: %s\n", friendnumber, string);
int i; int i;
for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
if (windows[i].onNickChange != NULL) for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
windows[i].onNickChange(&windows[i], friendnumber, string, length); if (windows[i].onNickChange != NULL)
} windows[i].onNickChange(&windows[i], friendnumber, string, length);
}
} }
void on_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata) void on_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata)
{ {
wprintw(prompt->window, "\n(statuschange) %d: %s\n", friendnumber, string); wprintw(prompt->window, "\n(statuschange) %d: %s\n", friendnumber, string);
int i; int i;
for (i=0; i<MAX_WINDOW_SLOTS; ++i) {
if (windows[i].onStatusChange != NULL) for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
windows[i].onStatusChange(&windows[i], friendnumber, string, length); if (windows[i].onStatusChange != NULL)
} windows[i].onStatusChange(&windows[i], friendnumber, string, length);
}
} }
void on_friendadded(Messenger *m, int friendnumber) void on_friendadded(Messenger *m, int friendnumber)
{ {
friendlist_onFriendAdded(m, friendnumber); friendlist_onFriendAdded(m, friendnumber);
if (store_data(m, DATA_FILE) != 0) {
wprintw(prompt->window, "\nCould not store Messenger data\n"); if (store_data(m, DATA_FILE) != 0) {
} wprintw(prompt->window, "\nCould not store Messenger data\n");
}
} }
/* CALLBACKS END */ /* CALLBACKS END */
int add_window(Messenger *m, ToxWindow w, int n) int add_window(Messenger *m, ToxWindow w, int n)
{ {
if (w_num >= TOXWINDOWS_MAX_NUM) if (w_num >= TOXWINDOWS_MAX_NUM)
return -1; return -1;
if (LINES < 2) if (LINES < 2)
return -1; return -1;
w.window = newwin(LINES - 2, COLS, 0, 0); w.window = newwin(LINES - 2, COLS, 0, 0);
if (w.window == NULL)
return -1;
windows[n] = w; if (w.window == NULL)
w.onInit(&w, m); return -1;
w_num++;
active_window = n; windows[n] = w;
return n; w.onInit(&w, m);
w_num++;
active_window = n;
return n;
} }
/* Deletes window w and cleans up */ /* Deletes window w and cleans up */
void del_window(ToxWindow *w, int f_num) void del_window(ToxWindow *w, int f_num)
{ {
active_window = 0; // Go to prompt screen active_window = 0; // Go to prompt screen
delwin(w->window); delwin(w->window);
int i; int i;
for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) {
if (WINDOW_STATUS[i] == f_num) { for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) {
WINDOW_STATUS[i] = -1; if (WINDOW_STATUS[i] == f_num) {
disable_chatwin(f_num); WINDOW_STATUS[i] = -1;
break; disable_chatwin(f_num);
break;
}
} }
}
clear(); clear();
refresh(); refresh();
} }
/* Shows next window when tab or back-tab is pressed */ /* Shows next window when tab or back-tab is pressed */
void set_active_window(int ch) void set_active_window(int ch)
{ {
int f_inf = 0; int f_inf = 0;
int max = MAX_WINDOW_SLOTS-1; int max = MAX_WINDOW_SLOTS - 1;
if (ch == '\t') {
int i = (active_window + 1) % max; if (ch == '\t') {
while (true) { int i = (active_window + 1) % max;
if (WINDOW_STATUS[i] != -1) {
active_window = i; while (true) {
return; if (WINDOW_STATUS[i] != -1) {
} active_window = i;
i = (i + 1) % max; return;
if (f_inf++ > max) { // infinite loop check }
endwin();
exit(2); i = (i + 1) % max;
}
if (f_inf++ > max) { // infinite loop check
endwin();
exit(2);
}
}
} else {
int i = active_window - 1;
if (i < 0) i = max;
while (true) {
if (WINDOW_STATUS[i] != -1) {
active_window = i;
return;
}
if (--i < 0) i = max;
if (f_inf++ > max) {
endwin();
exit(2);
}
}
} }
}else {
int i = active_window - 1;
if (i < 0) i = max;
while (true) {
if (WINDOW_STATUS[i] != -1) {
active_window = i;
return;
}
if (--i < 0) i = max;
if (f_inf++ > max) {
endwin();
exit(2);
}
}
}
} }
void init_window_status() void init_window_status()
{ {
/* Default window values decrement from -2 */ /* Default window values decrement from -2 */
int i; int i;
for (i = 0; i < N_DEFAULT_WINS; ++i)
WINDOW_STATUS[i] = -(i+2);
int j; for (i = 0; i < N_DEFAULT_WINS; ++i)
for (j = N_DEFAULT_WINS; j < MAX_WINDOW_SLOTS; j++) WINDOW_STATUS[i] = -(i + 2);
WINDOW_STATUS[j] = -1;
int j;
for (j = N_DEFAULT_WINS; j < MAX_WINDOW_SLOTS; j++)
WINDOW_STATUS[j] = -1;
} }
ToxWindow *init_windows() ToxWindow *init_windows()
{ {
w_num = 0; w_num = 0;
int n_prompt = 0; int n_prompt = 0;
int n_friendslist = 1; int n_friendslist = 1;
int n_dhtstatus = 2; int n_dhtstatus = 2;
if (add_window(m, new_prompt(on_friendadded), n_prompt) == -1
|| add_window(m, new_friendlist(WINDOW_STATUS), n_friendslist) == -1 if (add_window(m, new_prompt(on_friendadded), n_prompt) == -1
|| add_window(m, new_dhtstatus(), n_dhtstatus) == -1) { || add_window(m, new_friendlist(WINDOW_STATUS), n_friendslist) == -1
fprintf(stderr, "add_window() failed.\n"); || add_window(m, new_dhtstatus(), n_dhtstatus) == -1) {
endwin(); fprintf(stderr, "add_window() failed.\n");
exit(1); endwin();
} exit(1);
active_window = n_prompt; }
prompt = &windows[n_prompt];
return prompt; active_window = n_prompt;
prompt = &windows[n_prompt];
return prompt;
} }
static void draw_bar() static void draw_bar()
{ {
static int odd = 0; static int odd = 0;
int blinkrate = 30; int blinkrate = 30;
attron(COLOR_PAIR(4)); attron(COLOR_PAIR(4));
mvhline(LINES - 2, 0, '_', COLS); mvhline(LINES - 2, 0, '_', COLS);
attroff(COLOR_PAIR(4)); attroff(COLOR_PAIR(4));
move(LINES - 1, 0); move(LINES - 1, 0);
attron(COLOR_PAIR(4) | A_BOLD); attron(COLOR_PAIR(4) | A_BOLD);
printw(" TOXIC " TOXICVER "|"); printw(" TOXIC " TOXICVER "|");
attroff(COLOR_PAIR(4) | A_BOLD); attroff(COLOR_PAIR(4) | A_BOLD);
int i; int i;
for (i = 0; i < (MAX_WINDOW_SLOTS); ++i) {
if (WINDOW_STATUS[i] != -1) {
if (i == active_window)
attron(A_BOLD);
odd = (odd+1) % blinkrate; for (i = 0; i < (MAX_WINDOW_SLOTS); ++i) {
if (windows[i].blink && (odd < (blinkrate/2))) if (WINDOW_STATUS[i] != -1) {
attron(COLOR_PAIR(3)); if (i == active_window)
attron(A_BOLD);
printw(" %s", windows[i].title); odd = (odd + 1) % blinkrate;
if (windows[i].blink && (odd < (blinkrate/2)))
attroff(COLOR_PAIR(3));
if (i == active_window) { if (windows[i].blink && (odd < (blinkrate / 2)))
attroff(A_BOLD); attron(COLOR_PAIR(3));
}
printw(" %s", windows[i].title);
if (windows[i].blink && (odd < (blinkrate / 2)))
attroff(COLOR_PAIR(3));
if (i == active_window) {
attroff(A_BOLD);
}
}
} }
}
refresh(); refresh();
} }
void prepare_window(WINDOW *w) void prepare_window(WINDOW *w)
{ {
mvwin(w, 0, 0); mvwin(w, 0, 0);
wresize(w, LINES-2, COLS); wresize(w, LINES - 2, COLS);
} }
void draw_active_window(Messenger *m) void draw_active_window(Messenger *m)
{ {
ToxWindow *a = &windows[active_window]; ToxWindow *a = &windows[active_window];
prepare_window(a->window); prepare_window(a->window);
a->blink = false; a->blink = false;
draw_bar(); draw_bar();
a->onDraw(a); a->onDraw(a);
/* Handle input */ /* Handle input */
int ch = getch(); int ch = getch();
if (ch == '\t' || ch == KEY_BTAB)
set_active_window(ch); if (ch == '\t' || ch == KEY_BTAB)
else if (ch != ERR) set_active_window(ch);
a->onKey(a, m, ch); else if (ch != ERR)
a->onKey(a, m, ch);
} }

View File

@ -26,31 +26,31 @@
typedef struct ToxWindow_ ToxWindow; typedef struct ToxWindow_ ToxWindow;
struct ToxWindow_ { struct ToxWindow_ {
void(*onKey)(ToxWindow*, Messenger*, int); void(*onKey)(ToxWindow *, Messenger *, int);
void(*onDraw)(ToxWindow*); void(*onDraw)(ToxWindow *);
void(*onInit)(ToxWindow*, Messenger*); void(*onInit)(ToxWindow *, Messenger *);
void(*onFriendRequest)(ToxWindow*, uint8_t*, uint8_t*, uint16_t); void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t);
void(*onMessage)(ToxWindow*, Messenger*, int, uint8_t*, uint16_t); void(*onMessage)(ToxWindow *, Messenger *, int, uint8_t *, uint16_t);
void(*onNickChange)(ToxWindow*, int, uint8_t*, uint16_t); void(*onNickChange)(ToxWindow *, int, uint8_t *, uint16_t);
void(*onStatusChange)(ToxWindow*, int, uint8_t*, uint16_t); void(*onStatusChange)(ToxWindow *, int, uint8_t *, uint16_t);
void(*onAction)(ToxWindow*, Messenger*, int, uint8_t*, uint16_t); void(*onAction)(ToxWindow *, Messenger *, int, uint8_t *, uint16_t);
char title[256]; char title[256];
void* x; void *x;
bool blink; bool blink;
WINDOW* window; WINDOW *window;
}; };
void on_request(uint8_t *public_key, uint8_t *data, uint16_t length, void* userdata); void on_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata);
void on_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata); void on_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
void on_action(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata); void on_action(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
void on_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata); void on_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
void on_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void* userdata); void on_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
void on_friendadded(Messenger *m, int friendnumber); void on_friendadded(Messenger *m, int friendnumber);
void init_window_status(); void init_window_status();
ToxWindow * init_windows(); ToxWindow *init_windows();
void draw_active_window(Messenger * m); void draw_active_window(Messenger *m);
int add_window(Messenger *m, ToxWindow w, int n); int add_window(Messenger *m, ToxWindow w, int n);
void del_window(ToxWindow *w, int f_num); void del_window(ToxWindow *w, int f_num);
void set_active_window(int ch); void set_active_window(int ch);