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)
{
size_t i;
for (i = 0; i < blen; i++)
{
for (i = 0; i < blen; i++) {
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
unsigned char alicesk[32] = {
0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d,
0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45,
0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a,
0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d,
0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45,
0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a,
0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a
};
unsigned char bobpk[32] = {
0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4,
0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37,
0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d,
0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4,
0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37,
0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d,
0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f
};
unsigned char nonce[24] = {
0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73,
0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6,
0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73,
0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6,
0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37
};
unsigned char test_m[131] = {
0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5,
0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b,
0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4,
0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc,
0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a,
0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29,
0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4,
0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31,
0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d,
0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57,
0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a,
0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde,
0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd,
0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52,
0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40,
0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64,
0x5e,0x07,0x05
0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5,
0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b,
0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4,
0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc,
0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a,
0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29,
0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4,
0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31,
0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d,
0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57,
0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a,
0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde,
0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd,
0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52,
0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40,
0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64,
0x5e, 0x07, 0x05
};
unsigned char test_c[147] = {
0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,
0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,
0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73,
0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,
0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4,
0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,
0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b,
0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,
0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2,
0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,
0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a,
0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,
0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea,
0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,
0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde,
0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,
0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6,
0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,
0xe3,0x55,0xa5
0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9,
0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
0xe3, 0x55, 0xa5
};
START_TEST(test_known)
@ -86,19 +86,20 @@ START_TEST(test_known)
unsigned char m[131];
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_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(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(mlen == sizeof(m)/sizeof(unsigned char), "wrong plaintext length");
ck_assert_msg(mlen == sizeof(m) / sizeof(unsigned char), "wrong plaintext length");
}
END_TEST
@ -111,20 +112,21 @@ START_TEST(test_fast_known)
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_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(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(mlen == sizeof(m)/sizeof(unsigned char), "wrong plaintext length");
ck_assert_msg(mlen == sizeof(m) / sizeof(unsigned char), "wrong plaintext length");
}
END_TEST
@ -156,23 +158,22 @@ START_TEST(test_endtoend)
int testno;
// 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)
mlen = (rand() % 400) + 100;
rand_bytes(m, mlen);
rand_bytes(n, crypto_box_NONCEBYTES);
//Generate keypairs
crypto_box_keypair(pk1,sk1);
crypto_box_keypair(pk2,sk2);
crypto_box_keypair(pk1, sk1);
crypto_box_keypair(pk2, sk2);
//Precompute shared keys
encrypt_precompute(pk2, sk1, k1);
encrypt_precompute(pk1, sk2, k2);
ck_assert_msg(memcmp(k1, k2, crypto_box_BEFORENMBYTES) == 0, "encrypt_precompute: bad");
//Encrypt all four ways
c1len = encrypt_data(pk2, sk1, n, m, mlen, c1);
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 == 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
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 == 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");
}
}
@ -217,18 +220,18 @@ START_TEST(test_large_data)
rand_bytes(m1, sizeof(m1));
rand_bytes(m2, sizeof(m2));
rand_bytes(n, crypto_box_NONCEBYTES);
//Generate key
rand_bytes(k, crypto_box_BEFORENMBYTES);
c1len = encrypt_data_fast(k, n, m1, sizeof(m1), c1);
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(c2len == -1, "incorrectly succeeded encrypting massive size");
m1plen = decrypt_data_fast(k, n, c1, c1len, m1prime);
ck_assert_msg(m1plen == sizeof(m1), "decrypted text lengths 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); \
suite_add_tcase(s, NAME);
Suite* crypto_suite(void)
Suite *crypto_suite(void)
{
Suite *s = suite_create("Crypto");
@ -251,7 +254,7 @@ Suite* crypto_suite(void)
return s;
}
int main(int argc, char* argv[])
int main(int argc, char *argv[])
{
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;
if(!dht_on && DHT_isconnected()) {
if (!dht_on && DHT_isconnected()) {
dht_on = 1;
} else if(dht_on && !DHT_isconnected()) {
} else if (dht_on && !DHT_isconnected()) {
dht_on = 0;
}
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");
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");
request_flags |= FIRST_FLAG;
@ -89,16 +89,18 @@ int parent_friend_request(void)
m_addfriend(m, child_id, (uint8_t *)message, len);
/* wait on the status change */
for(i = 0; i < WAIT_COUNT; i++) {
for (i = 0; i < WAIT_COUNT; i++) {
do_tox();
if(request_flags & FIRST_FLAG)
if (request_flags & FIRST_FLAG)
break;
fputs(".", stdout);
fflush(stdout);
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"
"Friend requests may be broken, failing build!\n", stderr);
kill(child_pid, SIGKILL);
@ -108,7 +110,7 @@ int parent_friend_request(void)
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);
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;
}
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;
}
@ -128,16 +130,18 @@ int parent_wait_for_message(void)
fputs("Parent waiting for message.", stdout);
fflush(stdout);
for(i = 0; i < WAIT_COUNT; i++) {
for (i = 0; i < WAIT_COUNT; i++) {
do_tox();
if(request_flags & SECOND_FLAG)
if (request_flags & SECOND_FLAG)
break;
fputs(".", stdout);
fflush(stdout);
c_sleep(WAIT_TIME);
}
if(!(request_flags & SECOND_FLAG)) {
if (!(request_flags & SECOND_FLAG)) {
fputs("\nParent hasn't received the message yet!\n"
"Messaging may be broken, failing the build!\n", stderr);
kill(child_pid, SIGKILL);
@ -160,12 +164,13 @@ int main(int argc, char *argv[])
/* set up the global memory */
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,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
fputs("friends_test: Starting test...\n", stdout);
if((child_pid = fork()) == 0) {
if ((child_pid = fork()) == 0) {
/* child */
int i = 0;
char *message = "Y-yes Mr. Watson?";
@ -179,14 +184,14 @@ int main(int argc, char *argv[])
m_callback_statusmessage(m, child_got_statuschange, NULL);
/* wait on the friend request */
while(!(request_flags & FIRST_FLAG))
while (!(request_flags & FIRST_FLAG))
do_tox();
/* wait for the status change */
while(!(request_flags & SECOND_FLAG))
while (!(request_flags & SECOND_FLAG))
do_tox();
for(i = 0; i < 6; i++) {
for (i = 0; i < 6; i++) {
/* send the message six times, just to be sure */
m_sendmessage(m, 0, (uint8_t *)message, strlen(message));
do_tox();
@ -198,7 +203,7 @@ int main(int argc, char *argv[])
}
/* parent */
if(atexit(cleanup) != 0) {
if (atexit(cleanup) != 0) {
fputs("friends_test: atexit() failed!\nFailing build...\n", stderr);
kill(child_pid, SIGKILL);
return -1;
@ -215,10 +220,10 @@ int main(int argc, char *argv[])
Messenger_save(m, parent_id);
if(parent_friend_request() == -1)
if (parent_friend_request() == -1)
return -1;
if(parent_wait_for_message() == -1)
if (parent_wait_for_message() == -1)
return -1;
wait(NULL);

View File

@ -36,14 +36,16 @@ int friend_id_num = 0;
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);
unsigned char *val = calloc(1, len);
char *pos = hex_string;
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;
}
@ -65,17 +67,17 @@ START_TEST(test_m_get_userstatus_size)
{
int rc = 0;
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),
"m_get_statusmessage_size did NOT catch the following argument: %d\n",
REALLY_BIG_NUMBER);
"m_get_statusmessage_size did NOT catch the following argument: %d\n",
REALLY_BIG_NUMBER);
rc = m_get_statusmessage_size(m, friend_id_num);
/* this WILL error if the original m_addfriend_norequest() failed */
ck_assert_msg((rc > 0 && rc <= MAX_STATUSMESSAGE_LENGTH),
"m_get_statusmessage_size is returning out of range values!\n"
"(this can be caused by the error of m_addfriend_norequest"
" in the beginning of the suite)\n");
"m_get_statusmessage_size is returning out of range values!\n"
"(this can be caused by the error of m_addfriend_norequest"
" in the beginning of the suite)\n");
}
END_TEST
@ -85,11 +87,11 @@ START_TEST(test_m_set_userstatus)
uint16_t good_length = strlen(status);
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",
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"
"MAX_STATUSMESSAGE_LENGTH: %d\n", good_length, MAX_STATUSMESSAGE_LENGTH);
}
@ -98,20 +100,20 @@ END_TEST
START_TEST(test_m_friendstatus)
{
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),
"m_friendstatus did NOT catch an argument of %d.\n",
REALLY_BIG_NUMBER);
"m_friendstatus did NOT catch an argument of %d.\n",
REALLY_BIG_NUMBER);
}
END_TEST
START_TEST(test_m_delfriend)
{
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),
"m_delfriend did NOT catch the following number: %d\n",
REALLY_BIG_NUMBER);
"m_delfriend did NOT catch the following number: %d\n",
REALLY_BIG_NUMBER);
}
END_TEST
/*
@ -124,12 +126,12 @@ START_TEST(test_m_addfriend)
int bad_len = strlen(bad_data);
int really_bad_len = (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
- crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
+ crypto_box_ZEROBYTES + 100); */
+ crypto_box_ZEROBYTES + 100); */
/* TODO: Update this properly to latest master
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);
*/
/* 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)
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"
@ -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)
ck_abort_msg("m_addfriend did NOT catch the following length: %d\n", bad_len);
*/
/* this should REALLY error */
/*
* TODO: validate client_id in m_addfriend?
if(m_addfriend((uint8_t *)bad_id, (uint8_t *)good_data, good_len) >= 0)
ck_abort_msg("The following ID passed through "
"m_addfriend without an error:\n'%s'\n", bad_id_str);
/* this should REALLY error */
/*
* TODO: validate client_id in m_addfriend?
if(m_addfriend((uint8_t *)bad_id, (uint8_t *)good_data, good_len) >= 0)
ck_abort_msg("The following ID passed through "
"m_addfriend without an error:\n'%s'\n", bad_id_str);
}
END_TEST */
@ -154,10 +156,11 @@ START_TEST(test_setname)
int good_length = strlen(good_name);
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",
bad_length);
if(setname(m, (uint8_t *)good_name, good_length) != 0)
bad_length);
if (setname(m, (uint8_t *)good_name, good_length) != 0)
ck_abort_msg("setname() did NOT return 0 on good arguments!\n");
}
END_TEST
@ -172,8 +175,8 @@ START_TEST(test_getself_name)
getself_name(m, (uint8_t *)nick_check, len);
ck_assert_msg((!STRINGS_EQUAL(nickname, nick_check)),
"getself_name failed to return the known name!\n"
"known name: %s\nreturned: %s\n", nickname, nick_check);
"getself_name failed to return the known name!\n"
"known name: %s\nreturned: %s\n", nickname, nick_check);
}
END_TEST
@ -261,12 +264,12 @@ int main(int argc, char *argv[])
m = initMessenger();
/* 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"
"this was CRITICAL to the test, and the build WILL fail.\n"
"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"
"this was CRITICAL to the test, and the build WILL fail.\n"
"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;
uint64_t timestamp;
uint64_t last_pinged;
/* Returned by this node. Either our friend or us */
IP_Port ret_ip_port;
uint64_t ret_timestamp;
} Client_data;
Client_data * DHT_get_close_list(void);
Client_data *DHT_get_close_list(void);
/* Add a new friend to the friends list
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.
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
network while preventing amplification attacks.
network while preventing amplification attacks.
return 0 if node was added
return -1 if node was not added */
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 */
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
}

View File

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

View File

@ -21,7 +21,7 @@
*
*/
/*
/*
* TODO: clean this file a bit.
* There are a couple of useless variables to get rid of.
*/
@ -59,9 +59,9 @@ typedef struct {
*/
uint8_t status;
/*
/*
* 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;
@ -81,31 +81,31 @@ typedef struct {
uint32_t handshake_id2;
/* 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 */
uint32_t orecv_packetnum;
/* number of data packets sent */
uint32_t sent_packetnum;
uint32_t sent_packetnum;
/* number of packets sent by the other peer. */
uint32_t osent_packetnum;
uint32_t osent_packetnum;
/* number of latest packet written onto the sendbuffer */
uint32_t sendbuff_packetnum;
/* 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 */
uint32_t successful_read;
uint32_t successful_read;
/* 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) */
uint16_t num_req_paquets;
uint16_t num_req_paquets;
uint8_t recv_counter;
uint8_t send_counter;
@ -113,7 +113,7 @@ typedef struct {
} Connection;
static Connection * connections;
static Connection *connections;
static uint32_t connections_length; /* Length of 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 */
/*
/*
* Get connection id from IP_Port
* Return -1 if there are no connections like we are looking for
* 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)
{
uint32_t i;
for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].ip_port.ip.i == ip_port.ip.i &&
connections[i].ip_port.port == ip_port.port &&
connections[i].status > 0)
connections[i].ip_port.port == ip_port.port &&
connections[i].status > 0)
return i;
}
@ -143,7 +144,7 @@ int getconnection_id(IP_Port ip_port)
/* table of random numbers used below. */
static uint32_t randtable[6][256];
/*
/*
* Generate a handshake_id which depends on the 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)
{
uint32_t id = 0, 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();
id ^= randtable[i][((uint8_t *)&source)[i]];
}
if (id == 0) /* id can't be zero */
id = 1;
return id;
}
/*
/*
* Change the hanshake id associated with that ip_port
*
* TODO: make this better
@ -174,7 +178,7 @@ static void change_handshake(IP_Port source)
randtable[rand][((uint8_t *)&source)[rand]] = random_int();
}
/*
/*
* Initialize a new connection to ip_port
* Returns an integer corresponding to the connection idt
* 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 connect = getconnection_id(ip_port);
if (connect != -1)
return connect;
if(connections_number == connections_length) {
Connection * temp;
if (connections_number == connections_length) {
Connection *temp;
temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
if(temp == NULL)
if (temp == NULL)
return -1;
memset(&temp[connections_length], 0, sizeof(Connection));
++connections_length;
connections = temp;
}
uint32_t i;
for (i = 0; i < MAX_CONNECTIONS; ++i) {
if(connections[i].status == 0) {
if (connections[i].status == 0) {
memset(&connections[i], 0, sizeof(Connection));
uint32_t handshake_id1 = handshake_id(ip_port);
connections[i] = (Connection) {
.ip_port = ip_port,
.status = 1,
.inbound = 0,
.handshake_id1 = handshake_id1,
.sent_packetnum = handshake_id1,
.sendbuff_packetnum = handshake_id1,
.successful_sent = handshake_id1,
.SYNC_rate = SYNC_RATE,
.data_rate = DATA_SYNC_RATE,
.last_recvSYNC = current_time(),
.last_sent = current_time(),
.killat = ~0,
.send_counter = 0,
/* add randomness to timeout to prevent connections getting stuck in a loop. */
.timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
.ip_port = ip_port,
.status = 1,
.inbound = 0,
.handshake_id1 = handshake_id1,
.sent_packetnum = handshake_id1,
.sendbuff_packetnum = handshake_id1,
.successful_sent = handshake_id1,
.SYNC_rate = SYNC_RATE,
.data_rate = DATA_SYNC_RATE,
.last_recvSYNC = current_time(),
.last_sent = current_time(),
.killat = ~0,
.send_counter = 0,
/* add randomness to timeout to prevent connections getting stuck in a loop. */
.timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
};
++connections_number;
return i;
}
}
return -1;
}
/*
/*
* Initialize a new inbound connection from ip_port
* Returns an integer corresponding to the connection id.
* 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)
return -1;
if(connections_number == connections_length) {
Connection * temp;
if (connections_number == connections_length) {
Connection *temp;
temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
if(temp == NULL)
if (temp == NULL)
return -1;
memset(&temp[connections_length], 0, sizeof(Connection));
++connections_length;
connections = temp;
}
uint32_t i;
for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].status == 0) {
memset(&connections[i], 0, sizeof(Connection));
uint64_t timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT;
connections[i] = (Connection){
connections[i] = (Connection) {
.ip_port = ip_port,
.status = 2,
.inbound = 2,
.SYNC_rate = SYNC_RATE,
.data_rate = DATA_SYNC_RATE,
.last_recvSYNC = current_time(),
.last_sent = current_time(),
.send_counter = 127,
.status = 2,
.inbound = 2,
.SYNC_rate = SYNC_RATE,
.data_rate = DATA_SYNC_RATE,
.last_recvSYNC = current_time(),
.last_sent = current_time(),
.send_counter = 127,
/* add randomness to timeout to prevent connections getting stuck in a loop. */
.timeout = timeout,
/* add randomness to timeout to prevent connections getting stuck in a loop. */
.timeout = timeout,
/* if this connection isn't handled within the timeout kill it. */
.killat = current_time() + 1000000UL*timeout
/* if this connection isn't handled within the timeout kill it. */
.killat = current_time() + 1000000UL * timeout
};
++connections_number;
return i;
}
}
return -1;
}
/*
/*
* 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.
*/
int incoming_connection(void)
{
uint32_t i;
for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].inbound == 2) {
connections[i].inbound = 1;
@ -301,23 +311,25 @@ int incoming_connection(void)
static void free_connections(void)
{
uint32_t i;
for(i = connections_length; i != 0; --i)
for (i = connections_length; i != 0; --i)
if (connections[i - 1].status != 0)
break;
if(connections_length == i)
if (connections_length == i)
return;
Connection * temp;
Connection *temp;
temp = realloc(connections, sizeof(Connection) * i);
if(temp == NULL && i != 0)
if (temp == NULL && i != 0)
return;
connections = temp;
connections_length = i;
}
/*
/*
* Return -1 if it could not kill the connection.
* Return 0 if killed successfully
*/
@ -332,10 +344,11 @@ int kill_connection(int connection_id)
return 0;
}
}
return -1;
}
/*
/*
* Kill connection in seconds.
* Return -1 if it can not kill the connection.
* 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 (connections[connection_id].status > 0) {
connections[connection_id].killat = current_time() + 1000000UL*seconds;
connections[connection_id].killat = current_time() + 1000000UL * seconds;
return 0;
}
}
return -1;
}
/*
/*
* Check if connection is connected:
* Return 0 no.
* Return 1 if attempting handshake.
@ -363,6 +377,7 @@ int is_connected(int connection_id)
{
if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
return connections[connection_id].status;
return 0;
}
@ -371,6 +386,7 @@ IP_Port connection_ip(int connection_id)
{
if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
return connections[connection_id].ip_port;
IP_Port zero = {{{0}}, 0};
return zero;
}
@ -380,6 +396,7 @@ uint32_t sendqueue(int connection_id)
{
if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
return 0;
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)
return 0;
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 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) {
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;
return size;
}
return 0;
}
/*
/*
* Return 0 if data could not be put in packet 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)
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 */
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 i;
uint32_t temp;
/* 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;
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);
memcpy(requested + number, &temp, 4);
++number;
}
}
if(number == 0)
if (number == 0)
connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum;
return number;
}
/*
/*
* BEGIN Packet sending functions
* One per packet type.
* 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)
{
uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)];
uint8_t packet[(BUFFER_PACKET_NUM * 4 + 4 + 4 + 2)];
uint16_t index = 0;
IP_Port ip_port = connections[connection_id].ip_port;
@ -507,7 +526,7 @@ static int send_SYNC(uint32_t connection_id)
index += 4;
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;
uint32_t buffer[BUFFER_PACKET_NUM];
if (connections[connection_id].num_req_paquets > 0) {
ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]);
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);
return ret;
}
if (connections[connection_id].sendbuff_packetnum != connections[connection_id].sent_packetnum) {
ret = send_data_packet(connection_id, connections[connection_id].sent_packetnum);
connections[connection_id].sent_packetnum++;
return ret;
}
return 0;
}
/*
/*
* 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. */
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))
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);
return 0;
}
if (is_connected(connection) != 1)
return 1;
/* 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;
/* NOTE: is this necessary?
connections[connection].handshake_id2 = handshake_id1; */
@ -595,9 +618,11 @@ static int SYNC_valid(uint32_t length)
{
if (length < 4 + 4 + 2)
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 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) {
int x = new_inconnection(source);
if (x != -1) {
connections[x].orecv_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 -1;
}
@ -632,11 +659,13 @@ static int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packet
send_SYNC(connection_id);
return 0;
}
return 1;
}
/* 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,
uint16_t number)
static int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum,
uint32_t *req_packets,
uint16_t number)
{
uint8_t comp_counter = (counter - connections[connection_id].recv_counter );
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);
/* packet valid */
if (comp_1 <= BUFFER_PACKET_NUM &&
comp_2 <= BUFFER_PACKET_NUM &&
comp_counter < 10 && comp_counter != 0) {
if (comp_1 <= BUFFER_PACKET_NUM &&
comp_2 <= BUFFER_PACKET_NUM &&
comp_counter < 10 && comp_counter != 0) {
connections[connection_id].orecv_packetnum = recv_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;
return 0;
}
return 1;
}
@ -680,12 +710,12 @@ static int handle_SYNC(IP_Port source, uint8_t *packet, uint32_t length)
uint32_t temp;
uint32_t recv_packetnum, sent_packetnum;
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(&temp, packet + 2, 4);
recv_packetnum = ntohl(temp);
memcpy(&temp,packet + 6, 4);
memcpy(&temp, packet + 6, 4);
sent_packetnum = ntohl(temp);
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);
if (connections[connection].status == 2)
return handle_SYNC2(connection, counter,
return handle_SYNC2(connection, counter,
recv_packetnum, sent_packetnum);
if (connections[connection].status == 3)
return handle_SYNC3(connection, counter, recv_packetnum,
return handle_SYNC3(connection, counter, recv_packetnum,
sent_packetnum, req_packets, number);
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.
*/
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);
}
/*
* END of packet handling functions
/*
* END of packet handling functions
*/
void LosslessUDP_init(void)
@ -785,17 +816,18 @@ static void doNew(void)
{
uint32_t i;
uint64_t temp_time = current_time();
for (i = 0; i < MAX_CONNECTIONS; ++i) {
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);
connections[i].last_sent = temp_time;
}
/* kill all timed out connections */
if (connections[i].status > 0 &&
(connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
connections[i].status != 4) {
if (connections[i].status > 0 &&
(connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
connections[i].status != 4) {
connections[i].status = 4;
/* kill_connection(i); */
}
@ -809,9 +841,10 @@ static void doSYNC(void)
{
uint32_t i;
uint64_t temp_time = current_time();
for (i = 0; i < MAX_CONNECTIONS; ++i) {
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);
connections[i].last_SYNC = temp_time;
}
@ -823,18 +856,20 @@ static void doData(void)
uint32_t i;
uint64_t j;
uint64_t temp_time = current_time();
for (i = 0; i < MAX_CONNECTIONS; ++i)
if (connections[i].status == 3 && sendqueue(i) != 0)
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))
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))
send_DATA(i);
connections[i].last_sent = temp_time;
}
}
#define MAX_SYNC_RATE 10
/*
/*
* Automatically adjusts send rates of packets for optimal transmission.
*
* TODO: flow control.
@ -843,9 +878,11 @@ static void adjustRates(void)
{
uint32_t i;
uint64_t temp_time = current_time();
for (i = 0; i < MAX_CONNECTIONS; ++i) {
if (connections[i].status == 1 || connections[i].status == 2)
connections[i].SYNC_rate = MAX_SYNC_RATE;
if (connections[i].status == 3) {
if (sendqueue(i) != 0) {
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 */
#define MAX_DATA_SIZE 1024
/*
/*
* Initialize a new connection to ip_port
* Returns an integer corresponding to the connection id.
* Return -1 if it could not initialize the connection.
@ -41,51 +41,51 @@ extern "C" {
*/
int new_connection(IP_Port ip_port);
/*
/*
* Get connection id from IP_Port.
* Return -1 if there are no connections like we are looking for.
* Return id if it found it .
*/
int getconnection_id(IP_Port ip_port);
/*
/*
* 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.
*/
int incoming_connection(void);
/*
/*
* Return -1 if it could not kill the connection.
* Return 0 if killed successfully
*/
int kill_connection(int connection_id);
/*
/*
* Kill connection in seconds seconds.
* Return -1 if it can not kill the connection.
* Return 0 if it will kill it
*/
int kill_connection_in(int connection_id, uint32_t seconds);
/*
/*
* Returns the ip_port of the corresponding connection.
* Return 0 if there is no such connection.
*/
IP_Port connection_ip(int connection_id);
/*
* Returns the id of the next packet in the queue
* Return -1 if no packet in queue
/*
* Returns the id of the next packet in the queue
* Return -1 if no packet in queue
*/
char id_packet(int connection_id);
/*
/*
* 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);
/*
/*
* Return 0 if data could not be put in packet 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. */
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(...)
*/
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. */
void doLossless_UDP(void);
/*
/*
* This function sets up LosslessUDP packet handling.
*/
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
return -1 if realloc fails */
int realloc_friendlist(Messenger *m, uint32_t num) {
Friend *newfriendlist = realloc(m->friendlist, num*sizeof(Friend));
int realloc_friendlist(Messenger *m, uint32_t num)
{
Friend *newfriendlist = realloc(m->friendlist, num * sizeof(Friend));
if (newfriendlist == NULL)
return -1;
memset(&newfriendlist[num-1], 0, sizeof(Friend));
memset(&newfriendlist[num - 1], 0, sizeof(Friend));
m->friendlist = newfriendlist;
return 0;
}
@ -85,8 +88,10 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len)
uint8_t checksum[2] = {0};
uint16_t check;
uint32_t i;
for(i = 0; i < len; ++i)
for (i = 0; i < len; ++i)
checksum[i % 2] ^= address[i];
memcpy(&check, checksum, sizeof(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)
{
if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
- crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
+ crypto_box_ZEROBYTES))
- crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
+ crypto_box_ZEROBYTES))
return FAERR_TOOLONG;
uint8_t client_id[crypto_box_PUBLICKEYBYTES];
memcpy(client_id, address, crypto_box_PUBLICKEYBYTES);
uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check));
if (check != checksum)
return FAERR_BADCHECKSUM;
if (length < 1)
return FAERR_NOMESSAGE;
if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
return FAERR_OWNKEY;
int friend_id = getfriend_id(m, client_id);
if (friend_id != -1) {
uint32_t 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;
m->friendlist[friend_id].friendrequest_nospam = nospam;
return FAERR_SETNEWNOSPAM;
}
@ -153,6 +166,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
return FAERR_NOMEM;
uint32_t i;
for (i = 0; i <= m->numfriends; ++i) {
if (m->friendlist[i].status == NOFRIEND) {
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 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)
return -1;
@ -186,8 +201,9 @@ int m_addfriend_norequest(Messenger *m, uint8_t * client_id)
return FAERR_NOMEM;
uint32_t i;
for (i = 0; i <= m->numfriends; ++i) {
if(m->friendlist[i].status == NOFRIEND) {
if (m->friendlist[i].status == NOFRIEND) {
DHT_addfriend(client_id);
m->friendlist[i].status = FRIEND_REQUESTED;
m->friendlist[i].crypt_connection_id = -1;
@ -202,6 +218,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t * client_id)
return i;
}
}
return -1;
}
@ -220,9 +237,10 @@ int m_delfriend(Messenger *m, int friendnumber)
uint32_t i;
for (i = m->numfriends; i != 0; --i) {
if (m->friendlist[i-1].status != NOFRIEND)
if (m->friendlist[i - 1].status != NOFRIEND)
break;
}
m->numfriends = i;
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)
return NOFRIEND;
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)
return 0;
uint32_t msgid = ++m->friendlist[friendnumber].message_id;
if (msgid == 0)
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;
}
@ -264,6 +286,7 @@ uint32_t m_sendmessage_withid(Messenger *m, int friendnumber, uint32_t theid, ui
{
if (length >= (MAX_DATA_SIZE - sizeof(theid)))
return 0;
uint8_t temp[MAX_DATA_SIZE];
theid = htonl(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
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 write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length);
}
/* set the name of a friend
return 0 if success
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)
return -1;
memcpy(m->friendlist[friendnumber].name, name, MAX_NAME_LENGTH);
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
return 0 if success
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)
return -1;
memcpy(m->name, name, length);
m->name_length = length;
uint32_t i;
for (i = 0; i < m->numfriends; ++i)
m->friendlist[i].name_sent = 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.
return 0 if success
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)
return -1;
memcpy(name, m->friendlist[friendnumber].name, MAX_NAME_LENGTH);
return 0;
}
@ -352,12 +381,15 @@ int m_set_statusmessage(Messenger *m, uint8_t *status, uint16_t length)
{
if (length > MAX_STATUSMESSAGE_LENGTH)
return -1;
memcpy(m->statusmessage, status, length);
m->statusmessage_length = length;
uint32_t i;
for (i = 0; i < m->numfriends; ++i)
m->friendlist[i].statusmessage_sent = 0;
return 0;
}
@ -366,10 +398,13 @@ int m_set_userstatus(Messenger *m, USERSTATUS status)
if (status >= USERSTATUS_INVALID) {
return -1;
}
m->userstatus = status;
uint32_t i;
for (i = 0; i < m->numfriends; ++i)
m->friendlist[i].userstatus_sent = 0;
return 0;
}
@ -379,21 +414,23 @@ int m_get_statusmessage_size(Messenger *m, int friendnumber)
{
if (friendnumber >= m->numfriends || friendnumber < 0)
return -1;
return m->friendlist[friendnumber].statusmessage_length;
}
/* 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 */
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)
return -1;
memset(buf, 0, maxlen);
memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
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);
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)
return USERSTATUS_INVALID;
USERSTATUS status = m->friendlist[friendnumber].userstatus;
if (status >= USERSTATUS_INVALID) {
status = USERSTATUS_NONE;
}
return status;
}
@ -416,7 +456,7 @@ USERSTATUS m_get_self_userstatus(Messenger *m)
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);
}
@ -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));
}
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)
return -1;
uint8_t *newstatus = calloc(length, 1);
memcpy(newstatus, status, length);
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)
return;
if (friendnumber >= m->numfriends || friendnumber < 0)
return;
m->friendlist[friendnumber].receives_read_receipts = yesno;
}
/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */
/* 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);
}
/* 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_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_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_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_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_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_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_userdata = userdata;
@ -508,10 +554,13 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_
{
if (!m->friend_connectionstatuschange)
return;
if (status == NOFRIEND)
return;
const uint8_t was_connected = m->friendlist[friendnumber].status == FRIEND_ONLINE;
const uint8_t is_connected = status == FRIEND_ONLINE;
if (is_connected != was_connected)
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)
return 0;
if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
return 0;
uint8_t packet[length + 1];
packet[0] = packet_id;
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
/*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));
timer_start(t, LAN_DISCOVERY_INTERVAL);
@ -549,19 +600,20 @@ int LANdiscovery(timer* t, void* arg)
}
/* run this at startup */
Messenger * initMessenger(void)
Messenger *initMessenger(void)
{
Messenger *m = calloc(1, sizeof(Messenger));
if( ! m )
if ( ! m )
return 0;
new_keys();
m_set_statusmessage(m, (uint8_t*)"Online", sizeof("Online"));
m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
initNetCrypto();
IP ip;
ip.i = 0;
if(init_networking(ip,PORT) == -1)
if (init_networking(ip, PORT) == -1)
return 0;
DHT_init();
@ -576,7 +628,8 @@ Messenger * initMessenger(void)
}
/* run this before closing shop */
void cleanupMessenger(Messenger *m){
void cleanupMessenger(Messenger *m)
{
/* FIXME TODO ideally cleanupMessenger will mirror initMessenger
* this requires the other modules to expose cleanup functions
*/
@ -591,117 +644,155 @@ void doFriends(Messenger *m)
uint32_t i;
int len;
uint8_t temp[MAX_DATA_SIZE];
for (i = 0; i < m->numfriends; ++i) {
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 */
set_friend_status(m, i, FRIEND_REQUESTED);
else if (fr > 0)
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].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();
}
}
IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id);
switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) {
case 0:
if (friendip.ip.i > 1)
m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip);
break;
case 3: /* Connection is established */
set_friend_status(m, i, FRIEND_ONLINE);
m->friendlist[i].name_sent = 0;
m->friendlist[i].userstatus_sent = 0;
m->friendlist[i].statusmessage_sent = 0;
break;
case 4:
crypto_kill(m->friendlist[i].crypt_connection_id);
m->friendlist[i].crypt_connection_id = -1;
break;
default:
break;
case 0:
if (friendip.ip.i > 1)
m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip);
break;
case 3: /* Connection is established */
set_friend_status(m, i, FRIEND_ONLINE);
m->friendlist[i].name_sent = 0;
m->friendlist[i].userstatus_sent = 0;
m->friendlist[i].statusmessage_sent = 0;
break;
case 4:
crypto_kill(m->friendlist[i].crypt_connection_id);
m->friendlist[i].crypt_connection_id = -1;
break;
default:
break;
}
}
while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online */
if (m->friendlist[i].name_sent == 0) {
if (m_sendname(m, i, m->name, m->name_length))
m->friendlist[i].name_sent = 1;
}
if (m->friendlist[i].statusmessage_sent == 0) {
if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length))
m->friendlist[i].statusmessage_sent = 1;
}
if (m->friendlist[i].userstatus_sent == 0) {
if (send_userstatus(m, i, m->userstatus))
m->friendlist[i].userstatus_sent = 1;
}
len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp);
uint8_t packet_id = temp[0];
uint8_t* data = temp + 1;
uint8_t *data = temp + 1;
int data_length = len - 1;
if (len > 0) {
switch (packet_id) {
case PACKET_ID_NICKNAME: {
if (data_length >= MAX_NAME_LENGTH || data_length == 0)
case PACKET_ID_NICKNAME: {
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;
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);
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))
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;
memcpy(&msgid, data, sizeof(msgid));
msgid = ntohl(msgid);
if (m->read_receipt)
(*m->read_receipt)(m, i, msgid, m->read_receipt_userdata);
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);
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 {
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;
set_friend_status(m, i, FRIEND_CONFIRMED);
}
break;
}
}
@ -721,8 +813,10 @@ void doInbound(Messenger *m)
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES];
int inconnection = crypto_inbound(public_key, secret_nonce, session_key);
if (inconnection != -1) {
int friend_id = getfriend_id(m, public_key);
if (friend_id != -1) {
crypto_kill(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. */
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)
return -1;
if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3)
return -1;
length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3;
load_keys(data);
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)
return -1;
length -= size;
if (DHT_load(data, size) == -1)
return -1;
data += size;
memcpy(&size, data, sizeof(size));
data += sizeof(size);
if (length != size || length % sizeof(Friend) != 0)
return -1;
Friend * temp = malloc(size);
Friend *temp = malloc(size);
memcpy(temp, data, size);
uint16_t num = size / sizeof(Friend);
uint32_t 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);
setfriendname(m, fnum, temp[i].name);
/* 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);
}
}
free(temp);
return 0;
}

View File

@ -76,7 +76,8 @@ typedef enum {
USERSTATUS_AWAY,
USERSTATUS_BUSY,
USERSTATUS_INVALID
} USERSTATUS;
}
USERSTATUS;
typedef struct {
uint8_t client_id[CLIENT_ID_SIZE];
@ -111,22 +112,22 @@ typedef struct Messenger {
Friend *friendlist;
uint32_t numfriends;
void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void*);
void* friend_message_userdata;
void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void*);
void* friend_action_userdata;
void (*friend_namechange)(struct Messenger *m, int, uint8_t *, uint16_t, void*);
void* friend_namechange_userdata;
void (*friend_statusmessagechange)(struct Messenger *m, int, uint8_t *, uint16_t, void*);
void* friend_statusmessagechange_userdata;
void (*friend_userstatuschange)(struct Messenger *m, int, USERSTATUS, void*);
void* friend_userstatuschange_userdata;
void (*read_receipt)(struct Messenger *m, int, uint32_t, void*);
void* read_receipt_userdata;
void (*friend_statuschange)(struct Messenger *m, int, uint8_t, void*);
void* friend_statuschange_userdata;
void (*friend_connectionstatuschange)(struct Messenger *m, int, uint8_t, void*);
void* friend_connectionstatuschange_userdata;
void (*friend_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
void *friend_message_userdata;
void (*friend_action)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
void *friend_action_userdata;
void (*friend_namechange)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
void *friend_namechange_userdata;
void (*friend_statusmessagechange)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
void *friend_statusmessagechange_userdata;
void (*friend_userstatuschange)(struct Messenger *m, int, USERSTATUS, void *);
void *friend_userstatuschange_userdata;
void (*read_receipt)(struct Messenger *m, int, uint32_t, void *);
void *read_receipt_userdata;
void (*friend_statuschange)(struct Messenger *m, int, uint8_t, void *);
void *friend_statuschange_userdata;
void (*friend_connectionstatuschange)(struct Messenger *m, int, uint8_t, void *);
void *friend_connectionstatuschange_userdata;
} 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.
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.
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.
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
function(int friendnumber, uint8_t *newname, uint16_t length)
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
function(int friendnumber, uint8_t *newstatus, uint16_t length)
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
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
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
track ids for you, receipt may not correspond to any message
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
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
being previously online" part. it's assumed that when adding friends,
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
* returns allocated instance of Messenger on success
* returns 0 if there are problems */
Messenger * initMessenger(void);
Messenger *initMessenger(void);
/* run this before closing shop
* free all datastructures */

View File

@ -31,16 +31,17 @@ uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
return -1 if failure.
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.*/
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;
uint8_t temp[MAX_DATA_SIZE];
memcpy(temp, &nospam_num, sizeof(nospam_num));
memcpy(temp + sizeof(nospam_num), data, length);
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)
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 (sendpacket(ip_port, packet, len) != -1)
return 0;
return -1;
}
@ -78,11 +80,11 @@ uint32_t get_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 void* handle_friendrequest_userdata;
static void *handle_friendrequest_userdata;
/* 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_isset = 1;
@ -99,7 +101,7 @@ static uint8_t received_requests[MAX_RECEIVED_STORED][crypto_box_PUBLICKEYBYTES]
static uint16_t received_requests_index;
/*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)
received_requests_index = 0;
@ -110,7 +112,7 @@ static void addto_receivedlist(uint8_t * client_id)
/* Check if a friend request was already received
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;
@ -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)
return 1;
if (length <= sizeof(nospam))
return 1;
if (request_received(source_pubkey))
return 1;
if (memcmp(packet, &nospam, sizeof(nospam)) != 0)
return 1;

View File

@ -33,7 +33,7 @@ extern "C" {
/* Try to send a friendrequest to peer with public_key
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
*/
@ -42,7 +42,7 @@ uint32_t get_nospam();
/* 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) */
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 */
void friendreq_init(void);

View File

@ -65,14 +65,16 @@ uint8_t crypto_iszero(uint8_t *mem, uint32_t length)
{
uint8_t check = 0;
uint32_t i;
for (i = 0; i < length; ++i) {
check |= mem[i];
}
return check; // We return zero if mem is made out of zeroes.
}
/* 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.
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)
@ -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. */
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)
{
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);
if(crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0)
if (crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0)
return -1;
/* unpad the encrypted message */
@ -118,9 +120,9 @@ int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
nonce, enc_key) == -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:*/
if(crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0)
if (crypto_iszero(temp_plain, crypto_box_ZEROBYTES) != 0)
return -1;
/* 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)
{
uint32_t i;
for (i = 0; i < crypto_box_NONCEBYTES; ++i) {
++nonce[i];
if(nonce[i] != 0)
if (nonce[i] != 0)
break;
}
}
@ -159,6 +163,7 @@ static void increment_nonce(uint8_t *nonce)
void random_nonce(uint8_t *nonce)
{
uint32_t i, temp;
for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) {
temp = random_int();
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)
return 0;
if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
return 0;
uint8_t temp_data[MAX_DATA_SIZE];
int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data);
if (length == 0)
return 0;
if (temp_data[0] != 3)
return -1;
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);
if (len != -1) {
increment_nonce(crypto_connections[crypt_connection_id].recv_nonce);
return len;
}
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)
return 0;
if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
return 0;
if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
return 0;
uint8_t temp_data[MAX_DATA_SIZE];
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);
if (len == -1)
return 0;
temp_data[0] = 3;
if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0)
return 0;
increment_nonce(crypto_connections[crypt_connection_id].sent_nonce);
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)
return -1;
uint8_t nonce[crypto_box_NONCEBYTES];
uint8_t temp[MAX_DATA_SIZE];
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);
int len = encrypt_data(public_key, self_secret_key, nonce, temp, length + 1,
1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
if (len == -1)
return -1;
packet[0] = 32;
memcpy(packet + 1, 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 &&
length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
length <= MAX_DATA_SIZE + ENCRYPTION_PADDING &&
memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
uint8_t nonce[crypto_box_NONCEBYTES];
uint8_t temp[MAX_DATA_SIZE];
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);
if(len1 == -1 || len1 == 0)
if (len1 == -1 || len1 == 0)
return -1;
request_id[0] = temp[0];
--len1;
memcpy(data, temp + 1, len1);
@ -273,27 +298,32 @@ void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback 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 (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;
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 data[MAX_DATA_SIZE];
uint8_t number;
int len = handle_request(public_key, data, &number, packet, length);
if (len == -1 || len == 0)
return 1;
if (!cryptopackethandlers[number]) return 1;
cryptopackethandlers[number](source, public_key, data, len);
} 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 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,
1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + temp_data);
if (len == -1)
return 0;
temp_data[0] = 2;
memcpy(temp_data + 1, self_public_key, crypto_box_PUBLICKEYBYTES);
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 0 if failure */
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);
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;
}
if (data[0] != 2)
return 0;
uint8_t temp[crypto_box_NONCEBYTES + 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)
{
uint32_t i;
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if (crypto_connections[i].status != CONN_NO_CONNECTION)
if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
return i;
}
return -1;
}
@ -370,16 +407,21 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
{
uint32_t i;
int id = getcryptconnection_id(public_key);
if (id != -1) {
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;
}
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if (crypto_connections[i].status == CONN_NO_CONNECTION) {
int id = new_connection(ip_port);
if (id == -1)
return -1;
crypto_connections[i].number = id;
crypto_connections[i].status = CONN_HANDSHAKE_SENT;
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);
return i;
}
return -1; /* this should never happen. */
}
}
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)
{
uint32_t i;
for (i = 0; i < MAX_INCOMING; ++i) {
if (incoming_connections[i] != -1) {
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;
continue;
}
if (id_packet(incoming_connections[i]) == 2) {
uint8_t temp_data[MAX_DATA_SIZE];
uint16_t len = read_packet(incoming_connections[i], temp_data);
if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) {
int connection_id = incoming_connections[i];
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;
}
@ -435,13 +483,15 @@ int crypto_kill(int crypt_connection_id)
{
if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
return 1;
if (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);
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;
return 0;
}
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)
{
uint32_t i;
if (connection_id == -1)
return -1;
/*
if(getcryptconnection_id(public_key) != -1)
{
return -1;
}*/
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].status = CONN_NOT_CONFIRMED;
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) {
increment_nonce(crypto_connections[i].recv_nonce);
uint32_t zero = 0;
encrypt_precompute(crypto_connections[i].peersessionpublic_key,
crypto_connections[i].sessionsecret_key,
encrypt_precompute(crypto_connections[i].peersessionpublic_key,
crypto_connections[i].sessionsecret_key,
crypto_connections[i].shared_key);
crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */
return i;
}
return -1; /* this should never happen. */
}
}
return -1;
}
@ -495,6 +549,7 @@ int is_cryptoconnected(int crypt_connection_id)
{
if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS)
return crypto_connections[crypt_connection_id].status;
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. */
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
@ -528,12 +583,14 @@ void load_keys(uint8_t *keys)
static int new_incoming(int id)
{
uint32_t i;
for (i = 0; i < MAX_INCOMING; ++i) {
if (incoming_connections[i] == -1) {
incoming_connections[i] = id;
return 0;
}
}
return 1;
}
@ -542,9 +599,11 @@ static int new_incoming(int id)
static void handle_incomings(void)
{
int income;
while (1) {
income = incoming_connection();
if(income == -1 || new_incoming(income) )
if (income == -1 || new_incoming(income) )
break;
}
}
@ -553,6 +612,7 @@ static void handle_incomings(void)
static void receive_crypto(void)
{
uint32_t i;
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) {
uint8_t temp_data[MAX_DATA_SIZE];
@ -560,19 +620,22 @@ static void receive_crypto(void)
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES];
uint16_t len;
if (id_packet(crypto_connections[i].number) == 1)
/* if the packet is a friend request drop it (because we are already friends) */
len = read_packet(crypto_connections[i].number, temp_data);
if (id_packet(crypto_connections[i].number) == 2) { /* handle handshake packet. */
len = read_packet(crypto_connections[i].number, temp_data);
if (handle_cryptohandshake(public_key, secret_nonce, session_key, temp_data, len)) {
if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
increment_nonce(crypto_connections[i].sent_nonce);
uint32_t zero = 0;
encrypt_precompute(crypto_connections[i].peersessionpublic_key,
crypto_connections[i].sessionsecret_key,
encrypt_precompute(crypto_connections[i].peersessionpublic_key,
crypto_connections[i].sessionsecret_key,
crypto_connections[i].shared_key);
crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
@ -583,6 +646,7 @@ static void receive_crypto(void)
crypto_kill(crypto_connections[i].number);
}
if (crypto_connections[i].status == CONN_NOT_CONFIRMED) {
if (id_packet(crypto_connections[i].number) == 3) {
uint8_t temp_data[MAX_DATA_SIZE];
@ -592,10 +656,11 @@ static void receive_crypto(void)
crypto_connections[i].sessionsecret_key,
crypto_connections[i].recv_nonce, temp_data + 1, length - 1, data);
uint32_t zero = 0;
if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
increment_nonce(crypto_connections[i].recv_nonce);
encrypt_precompute(crypto_connections[i].peersessionpublic_key,
crypto_connections[i].sessionsecret_key,
encrypt_precompute(crypto_connections[i].peersessionpublic_key,
crypto_connections[i].sessionsecret_key,
crypto_connections[i].shared_key);
crypto_connections[i].status = CONN_ESTABLISHED;
@ -603,7 +668,7 @@ static void receive_crypto(void)
kill_connection_in(crypto_connections[i].number, 3000000);
} else
crypto_kill(crypto_connections[i].number); // This should not happen kill the connection if it does
} else if(id_packet(crypto_connections[i].number) != -1)
} else if (id_packet(crypto_connections[i].number) != -1)
/* This should not happen
kill the connection if it does */
crypto_kill(crypto_connections[i].number);
@ -615,10 +680,11 @@ static void receive_crypto(void)
sets all the global connection variables to their default values. */
void initNetCrypto(void)
{
memset(crypto_connections, 0 ,sizeof(crypto_connections));
memset(incoming_connections, -1 ,sizeof(incoming_connections));
memset(crypto_connections, 0 , sizeof(crypto_connections));
memset(incoming_connections, -1 , sizeof(incoming_connections));
networking_registerhandler(32, &cryptopacket_handle);
uint32_t i;
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i)
crypto_connections[i].number = ~0;
}
@ -626,6 +692,7 @@ void initNetCrypto(void)
static void killTimedout(void)
{
uint32_t i;
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4)
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)
/* 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
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 length of encrypted data if everything was fine. */
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
@ -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 length of plain data if everything was fine. */
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
to be preformed on every encrypt/decrypt. */
void encrypt_precompute(uint8_t *public_key, uint8_t *secret_key, uint8_t *enc_key);
/* 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);
/* 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)
returns -1 on failure
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 */
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
to accept it see: accept_crypto_inbound(...)
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
return -1 if not 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
(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
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
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
sets all the global connection variables to their default values. */

View File

@ -32,14 +32,14 @@ uint64_t current_time(void)
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
time = ft.dwHighDateTime;
time <<=32;
time <<= 32;
time |= ft.dwLowDateTime;
time -= 116444736000000000UL;
return time/10;
return time / 10;
#else
struct timeval a;
gettimeofday(&a, NULL);
time = 1000000UL*a.tv_sec + a.tv_usec;
time = 1000000UL * a.tv_sec + a.tv_usec;
return time;
#endif
}
@ -61,17 +61,17 @@ static int sock;
/* Basic network functions:
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};
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
the packet data into data
the packet length into length.
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;
#ifdef WIN32
@ -79,8 +79,9 @@ static int receivepacket(IP_Port * ip_port, uint8_t * data, uint32_t * length)
#else
uint32_t addrlen = sizeof(addr);
#endif
(*(int32_t*)length) = recvfrom(sock,(char*) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr*)&addr, &addrlen);
if (*(int32_t*)length <= 0)
(*(int32_t *)length) = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
if (*(int32_t *)length <= 0)
return -1; /* nothing received or empty packet */
ip_port->ip = addr.ip;
@ -100,11 +101,12 @@ void networking_poll()
IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length;
while (receivepacket(&ip_port, data, &length) != -1)
{
while (receivepacket(&ip_port, data, &length) != -1) {
if (length < 1) continue;
if (!packethandlers[data[0]]) continue;
packethandlers[data[0]](ip_port, data, length);
}
}
@ -119,8 +121,10 @@ int init_networking(IP ip, uint16_t port)
{
#ifdef WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR)
return -1;
#else
srandom((uint32_t)current_time());
#endif
@ -131,11 +135,15 @@ int init_networking(IP ip, uint16_t port)
/* Check for socket error */
#ifdef WIN32
if (sock == INVALID_SOCKET) /* MSDN recommends this */
return -1;
#else
if (sock < 0)
return -1;
#endif
/* 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 */
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 */
#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 */
ADDR addr = {AF_INET, htons(port), ip};
bind(sock, (struct sockaddr*)&addr, sizeof(addr));
bind(sock, (struct sockaddr *)&addr, sizeof(addr));
return 0;
}
@ -207,18 +215,18 @@ uint32_t resolve_addr(const char *address)
rc = getaddrinfo(address, "echo", &hints, &server);
// Lookup failed.
if(rc != 0) {
if (rc != 0) {
return 0;
}
// IPv4 records only..
if(server->ai_family != AF_INET) {
if (server->ai_family != AF_INET) {
freeaddrinfo(server);
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);
return addr;

View File

@ -26,7 +26,7 @@ typedef struct {
static pinged_t pings[PING_NUM_MAX];
static size_t num_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
@ -48,10 +48,10 @@ static void remove_timeouts() // O(n)
size_t new_num = num_pings;
// 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;
if(is_timeout(pings[id].timestamp)) {
if (is_timeout(pings[id].timestamp)) {
new_pos++;
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)
return false;
size_t i, id;
remove_timeouts();
for (i=0; i<num_pings; i++) {
for (i = 0; i < num_pings; i++) {
id = (pos_pings + i) % PING_NUM_MAX;
// 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;
}
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;
int rc;
@ -123,22 +123,22 @@ int send_ping_request(IP_Port ipp, clientid_t* client_id)
pk.magic = PACKET_PING_REQ;
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
rc = encrypt_data((uint8_t*) client_id,
rc = encrypt_data((uint8_t *) client_id,
self_secret_key,
(uint8_t*) &pk.nonce,
(uint8_t*) &ping_id, sizeof(ping_id),
(uint8_t*) &pk.ping_id);
(uint8_t *) &pk.nonce,
(uint8_t *) &ping_id, sizeof(ping_id),
(uint8_t *) &pk.ping_id);
if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
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;
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;
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
rc = encrypt_data((uint8_t*) client_id,
rc = encrypt_data((uint8_t *) client_id,
self_secret_key,
(uint8_t*) &pk.nonce,
(uint8_t*) &ping_id, sizeof(ping_id),
(uint8_t*) &pk.ping_id);
(uint8_t *) &pk.nonce,
(uint8_t *) &ping_id, sizeof(ping_id),
(uint8_t *) &pk.ping_id);
if (rc != sizeof(ping_id) + ENCRYPTION_PADDING)
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;
uint64_t ping_id;
@ -173,26 +173,26 @@ int handle_ping_request(IP_Port source, uint8_t* packet, uint32_t length)
return 1;
// Decrypt ping_id
rc = decrypt_data((uint8_t*) &p->client_id,
rc = decrypt_data((uint8_t *) &p->client_id,
self_secret_key,
(uint8_t*) &p->nonce,
(uint8_t*) &p->ping_id,
(uint8_t *) &p->nonce,
(uint8_t *) &p->ping_id,
sizeof(ping_id) + ENCRYPTION_PADDING,
(uint8_t*) &ping_id);
(uint8_t *) &ping_id);
if (rc != sizeof(ping_id))
return 1;
// Send response
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;
}
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;
uint64_t ping_id;
@ -200,21 +200,21 @@ int handle_ping_response(IP_Port source, uint8_t* packet, uint32_t length)
return 1;
// Decrypt ping_id
rc = decrypt_data((uint8_t*) &p->client_id,
rc = decrypt_data((uint8_t *) &p->client_id,
self_secret_key,
(uint8_t*) &p->nonce,
(uint8_t*) &p->ping_id,
(uint8_t *) &p->nonce,
(uint8_t *) &p->ping_id,
sizeof(ping_id) + ENCRYPTION_PADDING,
(uint8_t*) &ping_id);
(uint8_t *) &ping_id);
if (rc != sizeof(ping_id))
return 1;
// Make sure ping_id is correct
if(!is_pinging(source, ping_id))
if (!is_pinging(source, ping_id))
return 1;
// Associate source ip with client_id
addto_lists(source, (uint8_t*) &p->client_id);
addto_lists(source, (uint8_t *) &p->client_id);
return 0;
}

View File

@ -10,7 +10,7 @@
void init_ping();
uint64_t add_ping(IP_Port ipp);
bool is_pinging(IP_Port ipp, uint64_t ping_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 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 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 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);

View File

@ -4,7 +4,7 @@
#include "timer.h"
#include "network.h"
/*
/*
A nested linked list increases efficiency of insertions.
Depending on the number of timers we have, we might need to have nested linked lists
in order to improve insertion efficiency.
@ -46,35 +46,37 @@ enum timer_state {
STATE_CALLBACK
};
struct timer
{
struct timer {
enum timer_state state;
timer* _prev;
timer* _next;
timer *_prev;
timer *_next;
timer_callback cb;
void* userdata;
void *userdata;
uint64_t deadline;
};
static timer* timer_main_queue;
static timer* timer_us_queue; /* hi-speed queue */
static timer *timer_main_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->_prev) {
t->_prev->_next = t->_next;
} else {
*queue = t->_next;
}
if (t->_next) t->_next->_prev = t->_prev;
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;
while (true) {
if (!*queue) {
t->_next = 0;
@ -104,22 +106,24 @@ void timer_init()
}
/* 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) {
ret = timer_pool;
timer_pool = timer_pool->_next;
} else {
ret = calloc(1, sizeof(struct timer));
}
ret->state = STATE_INACTIVE;
return ret;
}
void delete_timer(timer* t)
void delete_timer(timer *t)
{
timer_dequeue(t, &timer_main_queue);
t->_next = timer_pool;
@ -127,93 +131,99 @@ void delete_timer(timer* 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->userdata = userarg;
}
void* timer_get_userdata(timer* t)
void *timer_get_userdata(timer *t)
{
return t->userdata;
}
static void timer_delay_us(timer* t, int us)
static void timer_delay_us(timer *t, int 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_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.
* 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. */
void timer_start(timer* t, int sec)
void timer_start(timer *t, int sec)
{
uint64_t newdeadline = current_time() + sec * US_PER_SECOND;
if (timer_is_active(t)){
if (timer_is_active(t)) {
if (t->deadline < newdeadline) {
timer_delay_us(t, newdeadline - t->deadline);
return;
}
timer_dequeue(t, &timer_main_queue);
}
t->deadline = newdeadline;
timer_enqueue(t, &timer_main_queue, 0);
}
/* 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;
timer_dequeue(t, &timer_main_queue);
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. */
int timer_delay(timer* t, int additonalsec)
int timer_delay(timer *t, int additonalsec)
{
if (!timer_is_active(t)) return -1;
timer_delay_us(t, additonalsec * US_PER_SECOND);
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;
return time - t->deadline;
}
/* Returns the time remaining on a timer in seconds.
* 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. */
int timer_time_remaining(timer* t)
int timer_time_remaining(timer *t)
{
if (!timer_is_active(t)) return -1;
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;
}
/* Single-use timer.
* 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_start(t, sec);
}
/* 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);
t->deadline = current_time() + us;
t->state = STATE_ACTIVE;
@ -228,26 +238,30 @@ void timer_poll(void)
/* Handle millisecond timers */
while (timer_us_queue) {
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);
t->cb(0, t->userdata);
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 */
prevtime = time;
while (timer_main_queue) {
if (timer_diff(timer_main_queue, time) != 0) break;
timer* t = timer_main_queue;
timer *t = timer_main_queue;
t->state = STATE_CALLBACK;
int rv = t->cb(t, t->userdata);
if (rv != 0) {
timer_dequeue(t, &timer_main_queue);
delete_timer(t);
continue;
}
if (t->state != STATE_ACTIVE) {
timer_dequeue(t, &timer_main_queue);
}
@ -257,19 +271,20 @@ void timer_poll(void)
/*** 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. */
void timer_internal_tests(bool (*assert)(bool, char*))
void timer_internal_tests(bool (*assert)(bool, char *))
{
}
void timer_debug_print()
{
timer* t = timer_main_queue;
timer *t = timer_main_queue;
printf("Queue:\n");
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;
}
}

View File

@ -44,7 +44,7 @@ typedef struct timer timer;
* You may call any of the timer functions within the callback:
* For example, you may call timer_start to restart the timer from
* within a callback. */
typedef int (*timer_callback)(timer* t, void* userarg);
typedef int (*timer_callback)(timer *t, void *userarg);
/* Initisalise timer subsystem */
void timer_init(void);
@ -53,52 +53,52 @@ void timer_init(void);
void timer_poll(void);
/* Creates a new timer. Does not enqueue/start it. */
timer* new_timer(void);
timer *new_timer(void);
/* Destroys a timer instance. */
void delete_timer(timer* t);
void delete_timer(timer *t);
/* 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. */
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.
* 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. */
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. */
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. */
int timer_delay(timer* t, int additonalsec);
int timer_delay(timer *t, int additonalsec);
/* Returns the time remaining on a timer in seconds.
* Returns -1 if the timer is not active.
* 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 */
bool timer_is_active(timer* t);
bool timer_is_active(timer *t);
/* 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. */
void timer_single(timer_callback cb, void* userarg, int sec);
void timer_single(timer_callback cb, void *userarg, int sec);
/* 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.
* 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 */
void timer_us(timer_callback cb, void* userarg, int us);
void timer_us(timer_callback cb, void *userarg, int us);
/* Internal Testing */
void timer_internal_tests(bool(*)(bool, char*));
void timer_internal_tests(bool( *)(bool, char *));
#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);
}
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;
}
void id_cpy(clientid_t* dest, clientid_t* src)
void id_cpy(clientid_t *dest, clientid_t *src)
{
memcpy(dest, src, sizeof(clientid_t));
}

View File

@ -8,5 +8,5 @@
uint64_t now();
uint64_t random_64b();
bool ipp_eq(IP_Port a, IP_Port b);
bool id_eq(clientid_t* dest, clientid_t* src);
void id_cpy(clientid_t* dest, clientid_t* src);
bool id_eq(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 -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.
*
@ -24,7 +24,7 @@
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#include "../core/DHT.h"
@ -50,13 +50,16 @@ void manage_keys()
uint8_t keys[KEYS_SIZE];
FILE *keys_file = fopen("key", "r");
if (keys_file != NULL) {
//if file was opened successfully -- load keys
size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
if (read_size != KEYS_SIZE) {
printf("Error while reading the key file\nExiting.\n");
exit(1);
}
load_keys(keys);
printf("Keys loaded successfully\n");
} else {
@ -64,10 +67,12 @@ void manage_keys()
new_keys();
save_keys(keys);
keys_file = fopen("key", "w");
if (fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file) != KEYS_SIZE) {
printf("Error while writing the key file.\nExiting.\n");
exit(1);
}
printf("Keys saved successfully\n");
}
@ -83,12 +88,12 @@ int main(int argc, char *argv[])
FILE *file;
file = fopen("PUBLIC_ID.txt", "w");
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("%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);
@ -117,19 +122,20 @@ int main(int argc, char *argv[])
friendreq_init();
int is_waiting_for_dht_connection = 1;
while(1)
{
if (is_waiting_for_dht_connection && DHT_isconnected())
{
while (1) {
if (is_waiting_for_dht_connection && DHT_isconnected()) {
printf("Connected to other bootstrap server successfully.\n");
is_waiting_for_dht_connection = 0;
}
doDHT();
networking_poll();
c_sleep(1);
}
shutdown_networking();
return 0;
}

View File

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

View File

@ -1,19 +1,19 @@
/* DHT cryptosendfiletest
*
*
* This program sends or receives a friend request.
*
*
* it also sends the encrypted data from a file to another client.
* 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).
*
*
* Saves all received data to: received.txt
*
*
* EX: ./test 127.0.0.1 33445 filename.txt
*
* Copyright (C) 2013 Tox project All Rights Reserved.
@ -32,9 +32,9 @@
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#include "../core/network.h"
#include "../core/DHT.h"
#include "../core/net_crypto.h"
@ -58,7 +58,8 @@
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];
@ -69,68 +70,81 @@ int main(int argc, char *argv[])
printf("usage %s ip port filename(of file to send)\n", argv[0]);
exit(0);
}
new_keys();
printf("OUR ID: ");
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("%hhX",self_public_key[i]);
printf("%hhX", self_public_key[i]);
}
printf("\n");
memcpy(self_client_id, self_public_key, 32);
char temp_id[128];
printf("Enter the client_id of the friend to connect to (32 bytes HEX format):\n");
scanf("%s", temp_id);
uint8_t friend_id[32];
memcpy(friend_id, hex_string_to_bin(temp_id), 32);
/* memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); */
DHT_addfriend(friend_id);
IP_Port friend_ip;
int connection = -1;
int inconnection = -1;
uint8_t acceptedfriend_public_key[crypto_box_PUBLICKEYBYTES];
int friendrequest = -1;
uint8_t request_data[512];
/* initialize networking
* bind to ip 0.0.0.0:PORT */
IP ip;
ip.i = 0;
init_networking(ip, PORT);
initNetCrypto();
perror("Initialization");
IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2]));
bootstrap_ip_port.ip.i = inet_addr(argv[1]);
DHT_bootstrap(bootstrap_ip_port);
IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length;
uint8_t buffer1[128];
int read1 = 0;
uint8_t buffer2[128];
int read2 = 0;
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");
if ( file2==NULL ){return 1;}
if ( file2 == NULL ) {
return 1;
}
read1 = fread(buffer1, 1, 128, file1);
while(1) {
while(receivepacket(&ip_port, data, &length) != -1) {
if(rand() % 3 != 1) { /* simulate packet loss */
if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) {
while (1) {
while (receivepacket(&ip_port, data, &length) != -1) {
if (rand() % 3 != 1) { /* simulate packet loss */
if (DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) {
/* if packet is not recognized */
printf("Received unhandled packet with length: %u\n", length);
} else {
@ -138,82 +152,98 @@ int main(int argc, char *argv[])
}
}
}
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:");
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 = new_connection(friend_ip); */
}
if(check_friendrequest(friendrequest) == 1) {
if (check_friendrequest(friendrequest) == 1) {
printf("Started connecting to friend:");
connection = crypto_connect(friend_id, friend_ip);
}
}
if(inconnection == -1) {
if (inconnection == -1) {
uint8_t secret_nonce[crypto_box_NONCEBYTES];
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
uint8_t session_key[crypto_box_PUBLICKEYBYTES];
inconnection = crypto_inbound(public_key, secret_nonce, session_key);
inconnection = accept_crypto_inbound(inconnection, acceptedfriend_public_key, secret_nonce, session_key);
/* inconnection = incoming_connection(); */
if(inconnection != -1) {
if (inconnection != -1) {
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);
}
/* if someone connected to us write what he sends to a file
* also send him our file. */
if(inconnection != -1) {
if(write_cryptpacket(inconnection, buffer1, read1)) {
if (inconnection != -1) {
if (write_cryptpacket(inconnection, buffer1, read1)) {
printf("Wrote data1.\n");
read1 = fread(buffer1, 1, 128, file1);
}
read2 = read_cryptpacket(inconnection, buffer2);
if(read2 != 0) {
if (read2 != 0) {
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);
fclose(file2);
}
}
/* if buffer is empty and the connection timed out. */
else if(is_cryptoconnected(inconnection) == 4) {
else if (is_cryptoconnected(inconnection) == 4) {
crypto_kill(inconnection);
}
}
/* if we are connected to a friend send him data from the file.
* also put what he sends us in a file. */
if(is_cryptoconnected(connection) >= 3) {
if(write_cryptpacket(0, buffer1, read1)) {
if (is_cryptoconnected(connection) >= 3) {
if (write_cryptpacket(0, buffer1, read1)) {
printf("Wrote data2.\n");
read1 = fread(buffer1, 1, 128, file1);
}
read2 = read_cryptpacket(0, buffer2);
if(read2 != 0) {
if (read2 != 0) {
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);
fclose(file2);
}
}
/* if buffer is empty and the connection timed out. */
else if(is_cryptoconnected(connection) == 4) {
else if (is_cryptoconnected(connection) == 4) {
crypto_kill(connection);
}
}
doDHT();
doLossless_UDP();
doNetCrypto();
@ -222,7 +252,7 @@ int main(int argc, char *argv[])
*c_sleep(300); */
c_sleep(1);
}
shutdown_networking();
return 0;
return 0;
}

View File

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

View File

@ -1,11 +1,11 @@
/* DHT test
* 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
*
*
* Command line arguments are the ip, port and public key of a node.
* 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
*
* Copyright (C) 2013 Tox project All Rights Reserved.
@ -24,9 +24,9 @@
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
//#include "../core/network.h"
#include "../core/DHT.c"
#include "../core/friend_requests.c"
@ -53,19 +53,22 @@ void print_clientlist()
uint32_t i, j;
IP_Port p_ip;
printf("___________________CLOSE________________________________\n");
for(i = 0; i < 32; i++) {
for (i = 0; i < 32; i++) {
printf("ClientID: ");
for(j = 0; j < 32; j++) {
for (j = 0; j < 32; j++) {
printf("%02hhX", close_clientlist[i].client_id[j]);
}
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("\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("\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("\nLast pinged: %llu\n", (long long unsigned int) close_clientlist[i].last_pinged);
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("Timestamp: %llu\n",(long long unsigned int) close_clientlist[i].ret_timestamp);
}
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);
}
}
void print_friendlist()
@ -73,78 +76,91 @@ void print_friendlist()
uint32_t i, j, k;
IP_Port p_ip;
printf("_________________FRIENDS__________________________________\n");
for(k = 0; k < num_friends; k++) {
for (k = 0; k < num_friends; k++) {
printf("FRIEND %u\n", k);
printf("ID: ");
for(j = 0; j < 32; j++) {
for (j = 0; j < 32; j++) {
printf("%c", friends_list[k].client_id[j]);
}
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");
for(i = 0; i < 4; i++) {
for (i = 0; i < 4; i++) {
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("%hhX", friends_list[k].client_list[i].client_id[j]);
}
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("\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("\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("\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;
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);
}
}
}
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;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
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("%hhX",data[i]);
printf("%hhX", data[i]);
}
printf("\n--------------------END-----------------------------\n\n\n");
}
int main(int argc, char *argv[])
{
//memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
if (argc < 4) {
printf("usage %s ip port public_key\n", argv[0]);
exit(0);
}
new_keys();
printf("OUR ID: ");
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("%hhX",self_public_key[i]);
printf("%hhX", self_public_key[i]);
}
char temp_id[128];
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);
DHT_addfriend(hex_string_to_bin(temp_id));
/* initialize networking */
/* bind to ip 0.0.0.0:PORT */
IP ip;
ip.i = 0;
init_networking(ip, PORT);
perror("Initialization");
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.i = inet_addr(argv[1]);
DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
/*
IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length;
*/
/*
IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length;
*/
DHT_init();
friendreq_init();
while(1) {
while (1) {
doDHT();
/* slvrTODO:
while(receivepacket(&ip_port, data, &length) != -1) {
if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) {
//unhandled packet
printpacket(data, length, ip_port);
} else {
printf("Received handled packet with length: %u\n", length);
}
}
*/
/* slvrTODO:
while(receivepacket(&ip_port, data, &length) != -1) {
if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) {
//unhandled packet
printpacket(data, length, ip_port);
} else {
printf("Received handled packet with length: %u\n", length);
}
}
*/
networking_poll();
print_clientlist();
print_friendlist();
c_sleep(300);
}
shutdown_networking();
return 0;
}

View File

@ -1,11 +1,11 @@
/* Lossless_UDP testclient
* A program that connects and sends a file using our lossless UDP algorithm.
* NOTE: this program simulates a 33% packet loss.
*
*
* 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
*
*
* Command line arguments are the ip and port to connect and send the file to.
* 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
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#include "../core/network.h"
@ -49,17 +49,21 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
uint32_t i;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
printf("--------------------BEGIN-----------------------------\n");
for (i = 0; i < length; i++) {
if (data[i] < 16)
printf("0");
printf("%hhX",data[i]);
printf("%hhX", data[i]);
}
printf("\n--------------------END-----------------------------\n\n\n");
}
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)
@ -80,9 +84,9 @@ void printconnection(int connection_id)
printf("--------------------BEGIN---------------------\n");
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("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);
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);
int i;
for(i =0; i < MAX_QUEUE_NUM; i++)
@ -97,12 +101,12 @@ void printconnection(int connection_id)
}
Data sendbuffer[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",
connections[connection_id].recv_packetnum,
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].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
connections[connection_id].successful_sent,
connections[connection_id].successful_read);
printf("req packets: \n");
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);
printf("--------------------END---------------------\n");
}
*/
@ -120,26 +124,26 @@ void printconnection(int connection_id)
/*run doLossless_UDP(); */
void Lossless_UDP()
{
/* IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length;
while (receivepacket(&ip_port, data, &length) != -1) {
printf("packet with length: %u\n", length); */
/* if(rand() % 3 != 1)//add packet loss
{ */
/*
if (LosslessUDP_handlepacket(data, length, ip_port))
printpacket(data, length, ip_port);
else
printf("Received handled packet with length: %u\n", length); //printconnection(0); */
/* } */
/* }*/
/* IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length;
while (receivepacket(&ip_port, data, &length) != -1) {
printf("packet with length: %u\n", length); */
/* if(rand() % 3 != 1)//add packet loss
{ */
/*
if (LosslessUDP_handlepacket(data, length, ip_port))
printpacket(data, length, ip_port);
else
printf("Received handled packet with length: %u\n", length); //printconnection(0); */
/* } */
/* }*/
networking_poll();
doLossless_UDP();
doLossless_UDP();
}
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]);
exit(0);
}
uint8_t buffer[512];
int read;
FILE *file = fopen(argv[3], "rb");
if (file == NULL)
return 1;
return 1;
/* initialize networking */
/* bind to ip 0.0.0.0:PORT */
IP ip;
@ -169,36 +174,43 @@ int main(int argc, char *argv[])
printip(serverip);
int connection = new_connection(serverip);
uint64_t timer = current_time();
while (1) {
/* printconnection(connection); */
/* printconnection(connection); */
Lossless_UDP();
if (is_connected(connection) == 3) {
printf("Connecting took: %llu us\n", (unsigned long long)(current_time() - timer));
break;
}
if (is_connected(connection) == 0) {
printf("Connection timeout after: %llu us\n", (unsigned long long)(current_time() - timer));
return 1;
}
c_sleep(1);
}
timer = current_time();
LosslessUDP_init();
/*read first part of file */
read = fread(buffer, 1, 512, file);
while (1) {
/* printconnection(connection); */
Lossless_UDP();
if (is_connected(connection) == 3) {
if (write_packet(connection, buffer, read)) {
/* printf("Wrote data.\n"); */
/* printf("Wrote data.\n"); */
read = fread(buffer, 1, 512, file);
}
/* printf("%u\n", sendqueue(connection)); */
if (sendqueue(connection) == 0) {
if (read == 0) {
@ -206,13 +218,13 @@ int main(int argc, char *argv[])
break;
}
}
}
else {
} else {
printf("Connecting Lost after: %llu us\n", (unsigned long long)(current_time() - timer));
return 0;
}
/* c_sleep(1); */
}
return 0;
}

View File

@ -1,11 +1,11 @@
/* Lossless_UDP testserver
* 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.
*
*
* 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
*
*
* Command line argument is the name of the file to save what we receive to.
* EX: ./testserver filename1.txt
*
@ -25,7 +25,7 @@
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#include "../core/network.h"
@ -50,11 +50,14 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port)
uint32_t i;
printf("UNHANDLED PACKET RECEIVED\nLENGTH:%u\nCONTENTS:\n", length);
printf("--------------------BEGIN-----------------------------\n");
for (i = 0; i < length; i++) {
if(data[i] < 16)
if (data[i] < 16)
printf("0");
printf("%hhX",data[i]);
printf("%hhX", data[i]);
}
printf("\n--------------------END-----------------------------\n\n\n");
}
@ -77,9 +80,9 @@ void printconnection(int connection_id)
printf("--------------------BEGIN---------------------\n");
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("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);
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);
int i;
for(i =0; i < MAX_QUEUE_NUM; i++)
@ -94,12 +97,12 @@ void printconnection(int connection_id)
}
Data sendbuffer[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",
connections[connection_id].recv_packetnum,
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].orecv_packetnum, connections[connection_id].sent_packetnum, connections[connection_id].osent_packetnum,
connections[connection_id].successful_sent,
connections[connection_id].successful_read);
printf("req packets: \n");
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);
printf("--------------------END---------------------\n");
}
*/
@ -121,20 +124,20 @@ void Lossless_UDP()
// uint8_t data[MAX_UDP_PACKET_SIZE];
// uint32_t length;
// 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)) {
// printpacket(data, length, ip_port);
// } else {
//printconnection(0);
//printconnection(0);
// printf("Received handled packet with length: %u\n", length);
// }
//}
//}
// }
networking_poll();
doLossless_UDP();
doLossless_UDP();
}
@ -144,61 +147,69 @@ int main(int argc, char *argv[])
printf("usage: %s filename\n", argv[0]);
exit(0);
}
uint8_t buffer[512];
int read;
FILE *file = fopen(argv[1], "wb");
if (file == NULL)
return 1;
return 1;
//initialize networking
//bind to ip 0.0.0.0:PORT
IP ip;
ip.i = 0;
init_networking(ip, PORT);
perror("Initialization");
int connection;
uint64_t timer = current_time();
LosslessUDP_init();
while (1) {
Lossless_UDP();
connection = incoming_connection();
if(connection != -1) {
if(is_connected(connection) == 2) {
if (connection != -1) {
if (is_connected(connection) == 2) {
printf("Received the connection.\n");
}
break;
}
c_sleep(1);
}
timer = current_time();
while (1) {
//printconnection(0);
Lossless_UDP();
if (is_connected(connection) >= 2) {
kill_connection_in(connection, 3000000);
read = read_packet(connection, buffer);
if (read != 0) {
// printf("Received data.\n");
if (!fwrite(buffer, read, 1, file))
printf("file write error\n");
// printf("Received data.\n");
if (!fwrite(buffer, read, 1, file))
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));
fclose(file);
return 1;
}
c_sleep(1);
}
return 0;
}

View File

@ -55,35 +55,37 @@
* networking_requesthandler and so cannot take a Messenger * */
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("ClientID: ");
uint32_t j;
for(j = 0; j < 32; j++)
{
if(public_key[j] < 16)
for (j = 0; j < 32; j++) {
if (public_key[j] < 16)
printf("0");
printf("%hhX", public_key[j]);
}
printf("\nOf length: %u with data: %s \n", length, data);
if(length != sizeof("Install Gentoo"))
{
if (length != sizeof("Install Gentoo")) {
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");
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);
m_sendmessage(m, friendnumber, (uint8_t*)"Test1", 6);
m_sendmessage(m, friendnumber, (uint8_t *)"Test1", 6);
}
int main(int argc, char *argv[])
@ -94,19 +96,24 @@ int main(int argc, char *argv[])
}
m = initMessenger();
if( !m ){
if ( !m ) {
fputs("Failed to allocate messenger datastructure\n", stderr);
exit(0);
}
if(argc > 3) {
if (argc > 3) {
IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2]));
bootstrap_ip_port.ip.i = inet_addr(argv[1]);
DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
} else {
FILE *file = fopen(argv[1], "rb");
if ( file==NULL ){return 1;}
if ( file == NULL ) {
return 1;
}
int read;
uint8_t buffer[128000];
read = fread(buffer, 1, 128000, file);
@ -114,6 +121,7 @@ int main(int argc, char *argv[])
fclose(file);
}
m_callback_friendrequest(m, print_request, NULL);
m_callback_friendmessage(m, print_message, NULL);
@ -121,39 +129,52 @@ int main(int argc, char *argv[])
uint32_t i;
uint8_t address[FRIEND_ADDRESS_SIZE];
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("%hhX",address[i]);
printf("%hhX", address[i]);
}
setname(m, (uint8_t *)"Anon", 5);
char temp_id[128];
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;
}
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");
while(1) {
while (1) {
uint8_t name[128];
getname(m, num, name);
printf("%s\n", name);
m_sendmessage(m, num, (uint8_t*)"Test", 5);
m_sendmessage(m, num, (uint8_t *)"Test", 5);
doMessenger(m);
c_sleep(30);
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);
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);
fclose(file);
}
cleanupMessenger(m);
}

View File

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

View File

@ -1,5 +1,5 @@
/* misc_tools.c
*
*
* Miscellaneous functions and data structures for doing random things.
*
* Copyright (C) 2013 Tox project All Rights Reserved.
@ -18,9 +18,9 @@
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#include "misc_tools.h"
#include <string.h>
@ -32,14 +32,15 @@
#endif // DEBUG
/* 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);
unsigned char *val = malloc(len);
char *pos = hex_string;
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;
}

View File

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

View File

@ -57,17 +57,18 @@ void get_id(Messenger *m, char *data)
int i = 0;
uint8_t address[FRIEND_ADDRESS_SIZE];
getaddress(m, address);
for(; i < FRIEND_ADDRESS_SIZE; i++)
{
sprintf(data + 2*i + offset, "%02X ", address[i]);
for (; i < FRIEND_ADDRESS_SIZE; i++) {
sprintf(data + 2 * i + offset, "%02X ", address[i]);
}
}
void new_lines(char *line)
{
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);
do_refresh();
@ -79,46 +80,52 @@ void print_friendlist(Messenger *m)
char name[MAX_NAME_LENGTH];
int i = 0;
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 */
char fstring[MAX_NAME_LENGTH + strlen("[i] Friend: NULL\n\tid: ")];
if (strlen(name) <= 0) {
sprintf(fstring, "[i] Friend: No Friend!\n\tid: %i", i);
} 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++;
new_lines(fstring);
}
if(i == 0)
if (i == 0)
new_lines("\tno friends! D:");
}
char *format_message(Messenger *m, char *message, int friendnum)
{
char name[MAX_NAME_LENGTH];
if (friendnum != -1) {
getname(m, friendnum, (uint8_t*)name);
getname(m, friendnum, (uint8_t *)name);
} 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;
struct tm * timeinfo;
struct tm *timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
char* time = asctime(timeinfo);
char *time = asctime(timeinfo);
size_t len = strlen(time);
time[len-1] = '\0';
time[len - 1] = '\0';
if (friendnum != -1) {
sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message);
} else {
// This message came from ourselves
sprintf(msg, "%s <%s> %s", time, name, message);
}
return msg;
}
@ -126,110 +133,127 @@ void line_eval(Messenger *m, char *line)
{
if (line[0] == '/') {
char inpt_command = line[1];
char prompt[STRING_LENGTH+2] = "> ";
char prompt[STRING_LENGTH + 2] = "> ";
int prompt_offset = 3;
strcat(prompt, line);
new_lines(prompt);
if (inpt_command == 'f') { // add friend command: /f ID
int i;
char temp_id[128];
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);
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);
char numstring[100];
switch (num) {
case FAERR_TOOLONG:
sprintf(numstring, "[i] Message is too long.");
break;
case FAERR_NOMESSAGE:
sprintf(numstring, "[i] Please add a message to your request.");
break;
case FAERR_OWNKEY:
sprintf(numstring, "[i] That appears to be your own ID.");
break;
case FAERR_ALREADYSENT:
sprintf(numstring, "[i] Friend request already sent.");
break;
case FAERR_UNKNOWN:
sprintf(numstring, "[i] Undefined error when adding friend.");
break;
default:
sprintf(numstring, "[i] Added friend as %d.", num);
break;
case FAERR_TOOLONG:
sprintf(numstring, "[i] Message is too long.");
break;
case FAERR_NOMESSAGE:
sprintf(numstring, "[i] Please add a message to your request.");
break;
case FAERR_OWNKEY:
sprintf(numstring, "[i] That appears to be your own ID.");
break;
case FAERR_ALREADYSENT:
sprintf(numstring, "[i] Friend request already sent.");
break;
case FAERR_UNKNOWN:
sprintf(numstring, "[i] Undefined error when adding friend.");
break;
default:
sprintf(numstring, "[i] Added friend as %d.", num);
break;
}
new_lines(numstring);
do_refresh();
}
else if (inpt_command == 'd') {
} else if (inpt_command == 'd') {
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);
if(len < 3)
if (len < 3)
return;
char numstring[len-3];
char message[len-3];
char numstring[len - 3];
char message[len - 3];
int i;
for (i = 0; i < len; i++) {
if (line[i+3] != ' ') {
numstring[i] = line[i+3];
if (line[i + 3] != ' ') {
numstring[i] = line[i + 3];
} else {
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;
}
}
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");
} else {
new_lines(format_message(m, message, -1));
}
}
else if (inpt_command == 'n') {
} else if (inpt_command == 'n') {
uint8_t name[MAX_NAME_LENGTH];
int i = 0;
size_t len = strlen(line);
for (i = 3; i < len; i++) {
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);
char numstring[100];
sprintf(numstring, "[i] changed nick to %s", (char*)name);
sprintf(numstring, "[i] changed nick to %s", (char *)name);
new_lines(numstring);
}
else if (inpt_command == 'l') {
} else if (inpt_command == 'l') {
print_friendlist(m);
}
else if (inpt_command == 's') {
} else if (inpt_command == 's') {
uint8_t status[MAX_STATUSMESSAGE_LENGTH];
int i = 0;
size_t len = strlen(line);
for (i = 3; i < len; i++) {
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];
sprintf(numstring, "[i] changed status to %s", (char*)status);
sprintf(numstring, "[i] changed status to %s", (char *)status);
new_lines(numstring);
}
else if (inpt_command == 'a') {
} else if (inpt_command == 'a') {
uint8_t numf = atoi(line + 3);
char numchar[100];
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);
} else {
int num = m_addfriend_norequest(m, pending_requests[numf].id);
if (num != -1) {
pending_requests[numf].accepted = 1;
sprintf(numchar, "[i] friend request %u accepted", numf);
@ -241,16 +265,15 @@ void line_eval(Messenger *m, char *line)
new_lines(numchar);
}
}
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
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)
{
strcpy(output,input);
strcpy(output, input);
size_t len = strlen(output);
int i = 0;
for (i = line_width; i < len; i = i + line_width) {
while (output[i] != ' ' && i != 0) {
i--;
}
if (i > 0) {
output[i] = '\n';
}
@ -284,40 +309,47 @@ int count_lines(char *string)
size_t len = strlen(string);
int count = 1;
int i;
for (i = 0; i < len; i++) {
if (string[i] == '\n')
count++;
}
return count;
}
char *appender(char *str, const char c)
{
size_t len = strlen(str);
if (len < STRING_LENGTH) {
str[len+1] = str[len];
str[len + 1] = str[len];
str[len] = c;
}
return str;
}
void do_refresh()
{
int count=0;
int count = 0;
char wrap_output[STRING_LENGTH];
int L;
int i;
for (i = 0; i < HISTORY; i++) {
wrap(wrap_output, lines[i], x);
L = count_lines(wrap_output);
count = count + L;
if (count < y) {
move(y-1-count, 0);
move(y - 1 - count, 0);
printw(wrap_output);
clrtoeol();
}
}
move(y-1, 0);
move(y - 1, 0);
clrtoeol();
printw(">> ");
printw(line);
@ -325,7 +357,7 @@ void do_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((char *)data);
@ -338,26 +370,28 @@ void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void* us
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];
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);
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];
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);
new_lines(msg);
}
@ -375,10 +409,12 @@ void load_key(Messenger *m, char *path)
rewind(data_file);
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);
goto FILE_ERROR;
}
Messenger_load(m, data, size);
} else {
@ -388,24 +424,27 @@ void load_key(Messenger *m, char *path)
Messenger_save(m, data);
data_file = fopen(path, "w");
if(!data_file) {
if (!data_file) {
perror("[!] load_key");
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);
goto FILE_ERROR;
}
}
if(fclose(data_file) < 0)
if (fclose(data_file) < 0)
perror("[!] fclose failed");
return;
FILE_ERROR:
if(fclose(data_file) < 0)
if (fclose(data_file) < 0)
perror("[!] fclose failed");
exit(1);
}
@ -431,15 +470,15 @@ int main(int argc, char *argv[])
exit(0);
}
for(i = 0; i < argc; i++) {
if (argv[i] == NULL){
break;
} else if(argv[i][0] == '-') {
if(argv[i][1] == 'h') {
for (i = 0; i < argc; i++) {
if (argv[i] == NULL) {
break;
} else if (argv[i][0] == '-') {
if (argv[i][1] == 'h') {
print_help();
exit(0);
} else if(argv[i][1] == 'f') {
if(argv[i + 1] != NULL)
} else if (argv[i][1] == 'f') {
if (argv[i + 1] != NULL)
filename = argv[i + 1];
else {
fputs("[!] you passed '-f' without giving an argument!\n", stderr);
@ -449,7 +488,8 @@ int main(int argc, char *argv[])
}
m = initMessenger();
if( !m ){
if ( !m ) {
fputs("Failed to allocate Messenger datastructure", stderr);
exit(0);
}
@ -474,6 +514,7 @@ int main(int argc, char *argv[])
IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2]));
int resolved_address = resolve_addr(argv[1]);
if (resolved_address != 0)
bootstrap_ip_port.ip.i = resolved_address;
else
@ -483,7 +524,8 @@ int main(int argc, char *argv[])
DHT_bootstrap(bootstrap_ip_port, binary_string);
free(binary_string);
nodelay(stdscr, TRUE);
while(true) {
while (true) {
if (on == 0 && DHT_isconnected()) {
new_lines("[i] connected to DHT\n[i] define username with /n");
on = 1;
@ -494,19 +536,22 @@ int main(int argc, char *argv[])
do_refresh();
c = getch();
if (c == ERR || c == 27)
continue;
getmaxyx(stdscr, y, x);
if (c == '\n') {
line_eval(m, line);
strcpy(line, "");
} else if (c == 8 || c == 127) {
line[strlen(line)-1] = '\0';
line[strlen(line) - 1] = '\0';
} else if (isalnum(c) || ispunct(c) || c == ' ') {
strcpy(line, appender(line, (char) c));
}
}
cleanupMessenger(m);
endwin();
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;
printf("\n\n[i] received friend request with message\n");
printf("'%s'",(char *)data);
printf("'%s'", (char *)data);
char numchar[100];
sprintf(numchar, "\n[i] accept request with /a %u\n\n", num_requests);
printf(numchar);
@ -63,18 +63,18 @@ void print_request(uint8_t *public_key, uint8_t *data, uint16_t length, void *us
++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];
getname(messenger, friendnumber, (uint8_t*)name);
char msg[100+length+strlen(name)+1];
getname(messenger, friendnumber, (uint8_t *)name);
char msg[100 + length + strlen(name) + 1];
time_t rawtime;
struct tm * timeinfo;
struct tm *timeinfo;
time (&rawtime);
timeinfo = localtime (&rawtime);
char* temp = asctime(timeinfo);
char *temp = asctime(timeinfo);
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
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)
{
char name[MAX_NAME_LENGTH];
getname(messenger, friendnumber, (uint8_t*)name);
char msg[100+length];
getname(messenger, friendnumber, (uint8_t *)name);
char msg[100 + length];
sprintf(msg, "\n\n[i] [%d] %s is now known as %s.\n\n", friendnumber, name, string);
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)
{
char name[MAX_NAME_LENGTH];
getname(messenger, friendnumber, (uint8_t*)name);
char msg[100+length+strlen(name)+1];
getname(messenger, friendnumber, (uint8_t *)name);
char msg[100 + length + strlen(name) + 1];
sprintf(msg, "\n\n[i] [%d] %s's status changed to %s.\n\n", friendnumber, name, string);
printf(msg);
}
@ -100,12 +100,14 @@ void print_statuschange(Messenger *messenger, int friendnumber, uint8_t *string,
void load_key()
{
FILE *data_file = NULL;
data_file = fopen("data","r");
data_file = fopen("data", "r");
if (data_file) {
fseek(data_file, 0, SEEK_END);
int size = ftell(data_file);
fseek(data_file, 0, SEEK_SET);
uint8_t data[size];
if (fread(data, sizeof(uint8_t), size, data_file) != size) {
printf("\n[i] Could not read the data file. Exiting.");
exit(1);
@ -124,6 +126,7 @@ void load_key()
exit(1);
}
}
fclose(data_file);
}
@ -131,30 +134,29 @@ void add_friend()
{
int i;
char temp_id[128];
for (i = 0; i < 128; i++)
temp_id[i] = line[i+3];
int num = m_addfriend(messenger, hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
temp_id[i] = line[i + 3];
int num = m_addfriend(messenger, hex_string_to_bin(temp_id), (uint8_t *)"Install Gentoo", sizeof("Install Gentoo"));
if (num >= 0) {
char numstring[100];
sprintf(numstring, "\n[i] Friend request sent. Wait to be accepted. Friend id: %d\n\n", num);
printf(numstring);
++maxnumfriends;
}
else if (num == -1)
} else if (num == -1)
printf("\n[i] Message is too long.\n\n");
else if (num == -2)
printf("\n[i] Please add a message to your friend request.\n\n");
else if (num == -3)
printf("\n[i] That appears to be your own ID.\n\n");
else if (num == -4)
printf("\n[i] Friend request already sent.\n\n");
else if (num == -5)
printf("\n[i] Undefined error when adding friend\n\n");
}
@ -162,28 +164,29 @@ void add_friend()
void list_friends()
{
int i;
printf("\n[i] Friend List");
printf("----- PENDING -----\n\n");
for (i = 0; i <= maxnumfriends; i++) {
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)
printf("[%d] %s\n", i, (uint8_t*)name);
printf("[%d] %s\n", i, (uint8_t *)name);
}
printf("\n");
printf("----- ACTIVE -----\n\n");
for (i = 0; i <= maxnumfriends; i++) {
char name[MAX_NAME_LENGTH];
getname(messenger, i, (uint8_t*)name);
getname(messenger, i, (uint8_t *)name);
if (m_friendstatus(messenger, i) == 4)
printf("[%d] %s\n", i, (uint8_t*)name);
printf("[%d] %s\n", i, (uint8_t *)name);
}
printf("\n");
@ -192,14 +195,14 @@ void list_friends()
void delete_friend()
{
size_t len = strlen(line);
char numstring[len-3];
char numstring[len - 3];
int i;
for (i = 0; i < len; i++) {
if (line[i+3] != ' ')
numstring[i] = line[i+3];
if (line[i + 3] != ' ')
numstring[i] = line[i + 3];
}
int num = atoi(numstring);
m_delfriend(messenger, num);
--maxnumfriends;
@ -209,20 +212,20 @@ void delete_friend()
void message_friend()
{
size_t len = strlen(line);
char numstring[len-3];
char message[len-3];
char numstring[len - 3];
char message[len - 3];
int i;
for (i = 0; i < len; i++) {
if (line[i+3] != ' ')
numstring[i] = line[i+3];
if (line[i + 3] != ' ')
numstring[i] = line[i + 3];
else {
int j;
for (j = (i+1); j < len; j++)
message[j-i-1] = line[j+3];
for (j = (i + 1); j < len; j++)
message[j - i - 1] = line[j + 3];
break;
}
@ -230,9 +233,9 @@ void message_friend()
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);
else
printf("\n");
}
@ -242,24 +245,24 @@ void change_nickname()
uint8_t name[MAX_NAME_LENGTH];
int i = 0;
size_t len = strlen(line);
for (i = 3; i < len; i++) {
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(messenger, name, i);
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);
FILE *name_file = NULL;
name_file = fopen("namefile.txt", "w");
fprintf(name_file, "%s", (char*)name);
fprintf(name_file, "%s", (char *)name);
fclose(name_file);
}
@ -268,24 +271,24 @@ void change_status(int savetofile)
uint8_t status[MAX_STATUSMESSAGE_LENGTH];
int i = 0;
size_t len = strlen(line);
for (i = 3; i < len; i++) {
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(messenger, status, strlen((char*)status));
status[i - 3] = 0;
m_set_statusmessage(messenger, status, strlen((char *)status));
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);
if (savetofile == 1) {
FILE* status_file = NULL;
FILE *status_file = NULL;
status_file = fopen("statusfile.txt", "w");
fprintf(status_file, "%s", (char*)status);
fprintf(status_file, "%s", (char *)status);
fclose(status_file);
}
}
@ -295,11 +298,13 @@ void accept_friend_request()
friend_request_received = 0;
uint8_t numf = atoi(line + 3);
char numchar[100];
if (numf >= num_requests || pending_requests[numf].accepted) {
sprintf(numchar, "\n[i] you either didn't receive that request or you already accepted it");
printf(numchar);
} else {
int num = m_addfriend_norequest(messenger, pending_requests[numf].id);
if (num != -1) {
pending_requests[numf].accepted = 1;
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];
if(inpt_command == 'f') {
if (inpt_command == 'f') {
add_friend();
}
@ -362,7 +367,7 @@ void line_eval(char* line)
void get_input()
{
while(1) {
while (1) {
fgets(line, STRING_LENGTH, stdin);
line_eval(line);
strcpy(line, "");
@ -375,13 +380,16 @@ int main(int argc, char *argv[])
printf("[!] Usage: %s [IP] [port] [public_key] <nokey>\n", argv[0]);
exit(0);
}
messenger = initMessenger();
if (messenger == 0) {
printf("initMessenger failed");
exit(0);
}
if (argc > 4) {
if(strncmp(argv[4], "nokey", 6) < 0) {
if (strncmp(argv[4], "nokey", 6) < 0) {
}
} else {
load_key();
@ -390,27 +398,33 @@ int main(int argc, char *argv[])
int nameloaded = 0;
int statusloaded = 0;
FILE* name_file = NULL;
FILE *name_file = NULL;
name_file = fopen("namefile.txt", "r");
if(name_file) {
if (name_file) {
uint8_t name[MAX_NAME_LENGTH];
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;
printf("%s\n", name);
fclose(name_file);
}
FILE* status_file = NULL;
FILE *status_file = NULL;
status_file = fopen("statusfile.txt", "r");
if(status_file) {
if (status_file) {
uint8_t status[MAX_STATUSMESSAGE_LENGTH];
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;
printf("%s\n", status);
fclose(status_file);
@ -423,31 +437,35 @@ int main(int argc, char *argv[])
char idstring1[PUB_KEY_BYTES][5];
char idstring2[PUB_KEY_BYTES][5];
int i;
for(i = 0; i < PUB_KEY_BYTES; i++)
{
if(self_public_key[i] < (PUB_KEY_BYTES/2))
strcpy(idstring1[i],"0");
for (i = 0; i < PUB_KEY_BYTES; i++) {
if (self_public_key[i] < (PUB_KEY_BYTES / 2))
strcpy(idstring1[i], "0");
else
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;
for (j = 0; j < PUB_KEY_BYTES; j++) {
strcat(users_id,idstring1[j]);
strcat(users_id,idstring2[j]);
strcat(users_id, idstring1[j]);
strcat(users_id, idstring2[j]);
}
do_header();
IP_Port bootstrap_ip_port;
bootstrap_ip_port.port = htons(atoi(argv[2]));
int resolved_address = resolve_addr(argv[1]);
if (resolved_address != 0)
bootstrap_ip_port.ip.i = resolved_address;
else
exit(1);
DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
int c;
@ -465,20 +483,23 @@ int main(int argc, char *argv[])
printf("\n---------------------------------");
}
while(1) {
while (1) {
if (on == 1 && DHT_isconnected() == -1) {
printf("\n---------------------------------");
printf("\n[i] Disconnected from the DHT");
printf("\n---------------------------------\n\n");
on = 0;
}
if (on == 0 && DHT_isconnected()) {
printf("\n[i] Connected to DHT");
printf("\n---------------------------------\n\n");
on = 1;
}
doMessenger(messenger);
Sleep(1);
}
return 0;
}

View File

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

View File

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

View File

@ -19,376 +19,391 @@
#define CURS_Y_OFFSET 3
typedef struct {
int friendnum;
char line[MAX_STR_SIZE];
size_t pos;
WINDOW* history;
WINDOW* linewin;
int friendnum;
char line[MAX_STR_SIZE];
size_t pos;
WINDOW *history;
WINDOW *linewin;
} ChatContext;
void print_help(ChatContext *self);
void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd);
struct tm *get_time(void)
struct tm *get_time(void)
{
struct tm *timeinfo;
time_t now;
time(&now);
timeinfo = localtime(&now);
return timeinfo;
struct tm *timeinfo;
time_t now;
time(&now);
timeinfo = localtime(&now);
return timeinfo;
}
static void chat_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *msg, uint16_t len)
{
ChatContext *ctx = (ChatContext*) self->x;
uint8_t nick[MAX_NAME_LENGTH] = {0};
struct tm *timeinfo = get_time();
ChatContext *ctx = (ChatContext *) self->x;
uint8_t nick[MAX_NAME_LENGTH] = {0};
struct tm *timeinfo = get_time();
if (ctx->friendnum != num)
return;
if (ctx->friendnum != num)
return;
getname(m, num, (uint8_t*) &nick);
msg[len-1] = '\0';
nick[MAX_NAME_LENGTH-1] = '\0';
fix_name(msg);
fix_name(nick);
getname(m, num, (uint8_t *) &nick);
msg[len - 1] = '\0';
nick[MAX_NAME_LENGTH - 1] = '\0';
fix_name(msg);
fix_name(nick);
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(4));
wprintw(ctx->history, "%s: ", nick);
wattroff(ctx->history, COLOR_PAIR(4));
wprintw(ctx->history, "%s\n", msg);
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(4));
wprintw(ctx->history, "%s: ", nick);
wattroff(ctx->history, COLOR_PAIR(4));
wprintw(ctx->history, "%s\n", msg);
self->blink = true;
beep();
self->blink = true;
beep();
}
static void chat_onAction(ToxWindow *self, Messenger *m, int num, uint8_t *action, uint16_t len)
{
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 "))) {
ChatContext *ctx = (ChatContext *) self->x;
struct tm *timeinfo = get_time();
char *action = strchr(cmd, ' ');
if (action == NULL) {
wprintw(self->window, "Invalid syntax.\n");
return;
}
action++;
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));
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);
wprintw(ctx->history, "%s\n", action);
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 "))) {
char *status = strchr(cmd, ' ');
char *msg;
char *status_text;
if (status == NULL) {
wprintw(ctx->history, "Invalid syntax.\n");
return;
}
status++;
USERSTATUS status_kind;
if (!strncmp(status, "online", strlen("online"))) {
status_kind = USERSTATUS_NONE;
status_text = "ONLINE";
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';
}
}
else if (!strncmp(status, "away", strlen("away"))) {
status_kind = USERSTATUS_AWAY;
status_text = "AWAY";
/* 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);
}
}
else if (!strncmp(status, "busy", strlen("busy"))) {
status_kind = USERSTATUS_BUSY;
status_text = "BUSY";
/* 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 {
wprintw(ctx->history, "Invalid status.\n");
return;
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);
}
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);
}
}
else if (!strncmp(cmd, "/me ", strlen("/me "))) {
struct tm *timeinfo = get_time();
char *action = strchr(cmd, ' ');
else if (!strncmp(cmd, "/nick ", strlen("/nick "))) {
char *nick;
nick = strchr(cmd, ' ');
if (nick == NULL) {
wprintw(ctx->history, "Invalid syntax.\n");
return;
if (action == NULL) {
wprintw(self->window, "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++;
setname(m, (uint8_t*) nick, strlen(nick)+1);
wprintw(ctx->history, "Nickname set to: %s\n", nick);
}
else if (!strncmp(cmd, "/status ", strlen("/status "))) {
char *status = strchr(cmd, ' ');
char *msg;
char *status_text;
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);
if (status == NULL) {
wprintw(ctx->history, "Invalid syntax.\n");
return;
}
status++;
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(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) {
int f_num = ctx->friendnum;
delwin(ctx->linewin);
del_window(self, f_num);
}
else if (!strncmp(cmd, "/nick ", strlen("/nick "))) {
char *nick;
nick = strchr(cmd, ' ');
else
wprintw(ctx->history, "Invalid command.\n");
if (nick == NULL) {
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)
{
curs_set(1);
int x, y;
getmaxyx(self->window, y, x);
(void) y;
ChatContext *ctx = (ChatContext*) self->x;
mvwhline(ctx->linewin, 0, 0, '_', x);
wrefresh(self->window);
curs_set(1);
int x, y;
getmaxyx(self->window, y, x);
(void) y;
ChatContext *ctx = (ChatContext *) self->x;
mvwhline(ctx->linewin, 0, 0, '_', x);
wrefresh(self->window);
}
static void chat_onInit(ToxWindow *self, Messenger *m)
{
int x, y;
ChatContext *ctx = (ChatContext*) self->x;
getmaxyx(self->window, y, x);
ctx->history = subwin(self->window, y-4, x, 0, 0);
scrollok(ctx->history, 1);
ctx->linewin = subwin(self->window, 2, x, y-4, 0);
print_help(ctx);
wmove(self->window, y-CURS_Y_OFFSET, 0);
int x, y;
ChatContext *ctx = (ChatContext *) self->x;
getmaxyx(self->window, y, x);
ctx->history = subwin(self->window, y - 4, x, 0, 0);
scrollok(ctx->history, 1);
ctx->linewin = subwin(self->window, 2, x, y - 4, 0);
print_help(ctx);
wmove(self->window, y - CURS_Y_OFFSET, 0);
}
void print_help(ChatContext *self)
{
wattron(self->history, COLOR_PAIR(2) | A_BOLD);
wprintw(self->history, "Commands:\n");
wattroff(self->history, A_BOLD);
wattron(self->history, COLOR_PAIR(2) | A_BOLD);
wprintw(self->history, "Commands:\n");
wattroff(self->history, A_BOLD);
wprintw(self->history, " /status <type> <message> : Set your status\n");
wprintw(self->history, " /nick <nickname> : Set your nickname\n");
wprintw(self->history, " /me <action> : Do an action\n");
wprintw(self->history, " /myid : Print your ID\n");
wprintw(self->history, " /clear : Clear the screen\n");
wprintw(self->history, " /close : Close the current chat window\n");
wprintw(self->history, " /quit or /exit : Exit program\n");
wprintw(self->history, " /help : Print this message again\n\n");
wprintw(self->history, " /status <type> <message> : Set your status\n");
wprintw(self->history, " /nick <nickname> : Set your nickname\n");
wprintw(self->history, " /me <action> : Do an action\n");
wprintw(self->history, " /myid : Print your ID\n");
wprintw(self->history, " /clear : Clear the screen\n");
wprintw(self->history, " /close : Close the current chat window\n");
wprintw(self->history, " /quit or /exit : Exit program\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 ret;
memset(&ret, 0, sizeof(ret));
ToxWindow ret;
memset(&ret, 0, sizeof(ret));
ret.onKey = &chat_onKey;
ret.onDraw = &chat_onDraw;
ret.onInit = &chat_onInit;
ret.onMessage = &chat_onMessage;
ret.onNickChange = &chat_onNickChange;
ret.onStatusChange = &chat_onStatusChange;
ret.onAction = &chat_onAction;
ret.onKey = &chat_onKey;
ret.onDraw = &chat_onDraw;
ret.onInit = &chat_onInit;
ret.onMessage = &chat_onMessage;
ret.onNickChange = &chat_onNickChange;
ret.onStatusChange = &chat_onStatusChange;
ret.onAction = &chat_onAction;
uint8_t nick[MAX_NAME_LENGTH] = {0};
getname(m, friendnum, (uint8_t*) &nick);
fix_name(nick);
uint8_t nick[MAX_NAME_LENGTH] = {0};
getname(m, friendnum, (uint8_t *) &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));
x->friendnum = friendnum;
ret.x = (void*) x;
return ret;
ChatContext *x = calloc(1, sizeof(ChatContext));
x->friendnum = friendnum;
ret.x = (void *) x;
return ret;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@
/* Export for use in Callbacks */
char *DATA_FILE = NULL;
void on_window_resize(int sig)
void on_window_resize(int sig)
{
endwin();
refresh();
@ -37,44 +37,45 @@ void on_window_resize(int sig)
static void init_term()
{
/* Setup terminal */
signal(SIGWINCH, on_window_resize);
initscr();
cbreak();
keypad(stdscr, 1);
noecho();
timeout(100);
/* Setup terminal */
signal(SIGWINCH, on_window_resize);
initscr();
cbreak();
keypad(stdscr, 1);
noecho();
timeout(100);
if (has_colors()) {
start_color();
init_pair(1, COLOR_GREEN, COLOR_BLACK);
init_pair(2, COLOR_CYAN, COLOR_BLACK);
init_pair(3, COLOR_RED, COLOR_BLACK);
init_pair(4, COLOR_BLUE, COLOR_BLACK);
init_pair(5, COLOR_YELLOW, COLOR_BLACK);
}
refresh();
if (has_colors()) {
start_color();
init_pair(1, COLOR_GREEN, COLOR_BLACK);
init_pair(2, COLOR_CYAN, COLOR_BLACK);
init_pair(3, COLOR_RED, COLOR_BLACK);
init_pair(4, COLOR_BLUE, COLOR_BLACK);
init_pair(5, COLOR_YELLOW, COLOR_BLACK);
}
refresh();
}
static Messenger *init_tox()
{
/* Init core */
Messenger *m = initMessenger();
/* Init core */
Messenger *m = initMessenger();
/* Callbacks */
m_callback_friendrequest(m, on_request, NULL);
m_callback_friendmessage(m, on_message, NULL);
m_callback_namechange(m, on_nickchange, NULL);
m_callback_statusmessage(m, on_statuschange, NULL);
m_callback_action(m, on_action, NULL);
/* Callbacks */
m_callback_friendrequest(m, on_request, NULL);
m_callback_friendmessage(m, on_message, NULL);
m_callback_namechange(m, on_nickchange, NULL);
m_callback_statusmessage(m, on_statuschange, NULL);
m_callback_action(m, on_action, NULL);
#ifdef __linux__
setname(m, (uint8_t*) "Cool guy", sizeof("Cool guy"));
setname(m, (uint8_t *) "Cool guy", sizeof("Cool guy"));
#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
setname(m, (uint8_t*) "Hipster", sizeof("Hipster"));
setname(m, (uint8_t *) "Hipster", sizeof("Hipster"));
#endif
return m;
return m;
}
#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 */
int init_connection(void)
{
if (DHT_isconnected())
return 0;
if (DHT_isconnected())
return 0;
FILE *fp = fopen("../../../other/DHTservers", "r");
if (!fp)
return 1;
FILE *fp = fopen("../../../other/DHTservers", "r");
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);
return 2;
}
fclose(fp);
char *server = servers[rand() % linecnt];
char *ip = strtok(server, " ");
char *port = strtok(NULL, " ");
char *key = strtok(NULL, " ");
if (!ip || !port || !key)
return 3;
char *server = servers[rand() % linecnt];
char *ip = strtok(server, " ");
char *port = strtok(NULL, " ");
char *key = strtok(NULL, " ");
IP_Port dht;
dht.port = htons(atoi(port));
uint32_t resolved_address = resolve_addr(ip);
if (resolved_address == 0)
if (!ip || !port || !key)
return 3;
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;
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_err = 0;
static bool dht_on = false;
if (!dht_on && !DHT_isconnected() && !(conn_try++ % 100)) {
if (!conn_err) {
conn_err = init_connection();
wprintw(prompt->window, "\nEstablishing connection...\n");
if (conn_err)
wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err);
static int conn_try = 0;
static int conn_err = 0;
static bool dht_on = false;
if (!dht_on && !DHT_isconnected() && !(conn_try++ % 100)) {
if (!conn_err) {
conn_err = init_connection();
wprintw(prompt->window, "\nEstablishing connection...\n");
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()) {
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);
doMessenger(m);
}
int f_loadfromfile;
@ -160,18 +169,22 @@ int store_data(Messenger *m, char *path)
{
if (f_loadfromfile == 0) /*If file loading/saving is disabled*/
return 0;
FILE *fd;
size_t len;
uint8_t *buf;
len = Messenger_size(m);
buf = malloc(len);
if (buf == NULL) {
return 1;
}
Messenger_save(m, buf);
fd = fopen(path, "w");
if (fd == NULL) {
free(buf);
return 2;
@ -192,6 +205,7 @@ static void load_data(Messenger *m, char *path)
{
if (f_loadfromfile == 0) /*If file loading/saving is disabled*/
return;
FILE *fd;
size_t len;
uint8_t *buf;
@ -202,12 +216,14 @@ static void load_data(Messenger *m, char *path)
fseek(fd, 0, SEEK_SET);
buf = malloc(len);
if (buf == NULL) {
fprintf(stderr, "malloc() failed.\n");
fclose(fd);
endwin();
exit(1);
}
if (fread(buf, len, 1, fd) != 1) {
fprintf(stderr, "fread() failed.\n");
free(buf);
@ -215,9 +231,11 @@ static void load_data(Messenger *m, char *path)
endwin();
exit(1);
}
Messenger_load(m, buf, len);
uint32_t i;
for (i = 0; i < m->numfriends; i++) {
on_friendadded(m, i);
}
@ -226,6 +244,7 @@ static void load_data(Messenger *m, char *path)
fclose(fd);
} else {
int st;
if ((st = store_data(m, path)) != 0) {
fprintf(stderr, "Store messenger failed with return code: %d\n", st);
endwin();
@ -236,70 +255,74 @@ static void load_data(Messenger *m, char *path)
int main(int argc, char *argv[])
{
char *user_config_dir = get_user_config_dir();
int config_err = 0;
char *user_config_dir = get_user_config_dir();
int config_err = 0;
f_loadfromfile = 1;
int f_flag = 0;
int i = 0;
for (i = 0; i < argc; ++i) {
if (argv[i] == NULL)
break;
else if (argv[i][0] == '-') {
if (argv[i][1] == 'f') {
if (argv[i + 1] != NULL)
DATA_FILE = strdup(argv[i + 1]);
else
f_flag = -1;
} else if (argv[i][1] == 'n') {
f_loadfromfile = 0;
}
f_loadfromfile = 1;
int f_flag = 0;
int i = 0;
for (i = 0; i < argc; ++i) {
if (argv[i] == NULL)
break;
else if (argv[i][0] == '-') {
if (argv[i][1] == 'f') {
if (argv[i + 1] != NULL)
DATA_FILE = strdup(argv[i + 1]);
else
f_flag = -1;
} 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) {
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");
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);
}
}
free(user_config_dir);
init_term();
Messenger *m = init_tox();
ToxWindow *prompt = init_windows(m);
init_window_status();
while (true) {
/* Update tox */
do_tox(m, prompt);
if(f_loadfromfile)
load_data(m, DATA_FILE);
/* Draw */
draw_active_window(m);
}
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(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;
cleanupMessenger(m);
free(DATA_FILE);
return 0;
}

View File

@ -14,7 +14,7 @@
#include "prompt.h"
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 char prompt_buf[MAX_STR_SIZE] = {0};
@ -36,412 +36,441 @@ void cmd_statusmsg(ToxWindow *, Messenger *m, char **);
#define NUM_COMMANDS 13
static struct {
char *name;
int numargs;
void (*func)(ToxWindow *, Messenger *m, char **);
char *name;
int numargs;
void (*func)(ToxWindow *, Messenger *m, char **);
} commands[] = {
{ "accept", 1, cmd_accept },
{ "add", 1, cmd_add },
{ "clear", 0, cmd_clear },
{ "connect", 3, cmd_connect },
{ "exit", 0, cmd_quit },
{ "help", 0, cmd_help },
{ "msg", 2, cmd_msg },
{ "myid", 0, cmd_myid },
{ "nick", 1, cmd_nick },
{ "q", 0, cmd_quit },
{ "quit", 0, cmd_quit },
{ "status", 2, cmd_status },
{ "statusmsg", 1, cmd_statusmsg },
{ "accept", 1, cmd_accept },
{ "add", 1, cmd_add },
{ "clear", 0, cmd_clear },
{ "connect", 3, cmd_connect },
{ "exit", 0, cmd_quit },
{ "help", 0, cmd_help },
{ "msg", 2, cmd_msg },
{ "myid", 0, cmd_myid },
{ "nick", 1, cmd_nick },
{ "q", 0, cmd_quit },
{ "quit", 0, cmd_quit },
{ "status", 2, cmd_status },
{ "statusmsg", 1, cmd_statusmsg },
};
// XXX:
int add_req(uint8_t *public_key)
{
memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE);
++num_requests;
return num_requests-1;
memcpy(pending_requests[num_requests], public_key, CLIENT_ID_SIZE);
++num_requests;
return num_requests - 1;
}
// XXX: FIX
unsigned char *hex_string_to_bin(char hex_string[])
{
size_t len = strlen(hex_string);
unsigned char *val = malloc(len);
char *pos = hex_string;
int i;
for (i = 0; i < len; ++i, pos+=2)
sscanf(pos,"%2hhx",&val[i]);
return val;
size_t len = strlen(hex_string);
unsigned char *val = malloc(len);
char *pos = hex_string;
int i;
for (i = 0; i < len; ++i, pos += 2)
sscanf(pos, "%2hhx", &val[i]);
return val;
}
void cmd_accept(ToxWindow *self, Messenger *m, char **args)
{
int num = atoi(args[1]);
if (num >= num_requests) {
wprintw(self->window, "Invalid syntax.\n");
return;
}
int num = atoi(args[1]);
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);
}
if (num >= num_requests) {
wprintw(self->window, "Invalid syntax.\n");
return;
}
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)
{
uint8_t id_bin[FRIEND_ADDRESS_SIZE];
char xx[3];
uint32_t x;
char *id = args[1];
char *msg = args[2];
uint8_t id_bin[FRIEND_ADDRESS_SIZE];
char xx[3];
uint32_t x;
char *id = args[1];
char *msg = args[2];
if (!id) {
wprintw(self->window, "Invalid command: add expected at least one argument.\n");
return;
}
if (!msg)
msg = "";
if (strlen(id) != 2*FRIEND_ADDRESS_SIZE) {
wprintw(self->window, "Invalid ID length.\n");
return;
}
int i;
for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
xx[0] = id[2*i];
xx[1] = id[2*i+1];
xx[2] = '\0';
if (sscanf(xx, "%02x", &x) != 1) {
wprintw(self->window, "Invalid ID.\n");
return;
if (!id) {
wprintw(self->window, "Invalid command: add expected at least one argument.\n");
return;
}
if (!msg)
msg = "";
if (strlen(id) != 2 * FRIEND_ADDRESS_SIZE) {
wprintw(self->window, "Invalid ID length.\n");
return;
}
int i;
for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
xx[0] = id[2 * i];
xx[1] = id[2 * i + 1];
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)
{
wclear(self->window);
wclear(self->window);
}
void cmd_connect(ToxWindow *self, Messenger *m, char **args)
{
IP_Port dht;
char *ip = args[1];
char *port = args[2];
char *key = args[3];
IP_Port dht;
char *ip = args[1];
char *port = args[2];
char *key = args[3];
if (atoi(port) == 0) {
wprintw(self->window, "Invalid syntax.\n");
return;
}
if (atoi(port) == 0) {
wprintw(self->window, "Invalid syntax.\n");
return;
}
dht.port = htons(atoi(port));
uint32_t resolved_address = resolve_addr(ip);
if (resolved_address == 0) {
return;
}
dht.port = htons(atoi(port));
uint32_t resolved_address = resolve_addr(ip);
dht.ip.i = resolved_address;
unsigned char *binary_string = hex_string_to_bin(key);
DHT_bootstrap(dht, binary_string);
free(binary_string);
if (resolved_address == 0) {
return;
}
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)
{
endwin();
exit(0);
endwin();
exit(0);
}
void cmd_help(ToxWindow *self, Messenger *m, char **args)
{
wclear(self->window);
wattron(self->window, COLOR_PAIR(2) | A_BOLD);
wprintw(self->window, "Commands:\n");
wattroff(self->window, A_BOLD);
wclear(self->window);
wattron(self->window, COLOR_PAIR(2) | A_BOLD);
wprintw(self->window, "Commands:\n");
wattroff(self->window, A_BOLD);
wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n");
wprintw(self->window, " add <id> <message> : Add friend\n");
wprintw(self->window, " status <type> <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, " accept <number> : Accept friend request\n");
wprintw(self->window, " myid : Print your ID\n");
wprintw(self->window, " quit/exit : Exit program\n");
wprintw(self->window, " help : Print this message again\n");
wprintw(self->window, " clear : Clear this window\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, " status <type> <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, " accept <number> : Accept friend request\n");
wprintw(self->window, " myid : Print your ID\n");
wprintw(self->window, " quit/exit : Exit program\n");
wprintw(self->window, " help : Print this message again\n");
wprintw(self->window, " clear : Clear this window\n");
wattron(self->window, A_BOLD);
wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");
wattroff(self->window, A_BOLD);
wattron(self->window, A_BOLD);
wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");
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)
{
char *id = args[1];
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");
else
wprintw(self->window, "Message successfully sent.\n");
char *id = args[1];
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");
else
wprintw(self->window, "Message successfully sent.\n");
}
void cmd_myid(ToxWindow *self, Messenger *m, char **args)
{
char id[FRIEND_ADDRESS_SIZE*2 + 1] = {0};
size_t 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(self->window, "%s\n", id);
char id[FRIEND_ADDRESS_SIZE * 2 + 1] = {0};
size_t 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(self->window, "%s\n", id);
}
void cmd_nick(ToxWindow *self, Messenger *m, char **args)
{
char *nick = args[1];
setname(m, (uint8_t*) nick, strlen(nick)+1);
wprintw(self->window, "Nickname set to: %s\n", nick);
char *nick = args[1];
setname(m, (uint8_t *) nick, strlen(nick) + 1);
wprintw(self->window, "Nickname set to: %s\n", nick);
}
void cmd_status(ToxWindow *self, Messenger *m, char **args)
{
char *status = args[1];
char *status_text;
char *status = args[1];
char *status_text;
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;
}
USERSTATUS status_kind;
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);
}
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 (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)
{
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);
}
static void execute(ToxWindow *self, Messenger *m, char *u_cmd)
{
int newlines = 0;
char cmd[MAX_STR_SIZE] = {0};
int i;
for (i = 0; i < strlen(prompt_buf); ++i) {
if (u_cmd[i] == '\n')
++newlines;
else
cmd[i - newlines] = u_cmd[i];
}
int newlines = 0;
char cmd[MAX_STR_SIZE] = {0};
int i;
int leading_spc = 0;
for (i = 0; i < MAX_STR_SIZE && isspace(cmd[i]); ++i)
leading_spc++;
memmove(cmd, cmd + leading_spc, MAX_STR_SIZE - leading_spc);
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++;
for (i = 0; i < strlen(prompt_buf); ++i) {
if (u_cmd[i] == '\n')
++newlines;
else
cmd[i - newlines] = u_cmd[i];
}
}
/* excessive arguments */
if (numargs > 3) {
wprintw(self->window, "Invalid command: too many arguments.\n");
return;
}
int leading_spc = 0;
/* 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;
}
for (i = 0; i < MAX_STR_SIZE && isspace(cmd[i]); ++i)
leading_spc++;
/* no input */
if (strlen(cmdargs[0]) == 0)
return;
memmove(cmd, cmd + leading_spc, MAX_STR_SIZE - leading_spc);
/* 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;
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++;
}
}
/* 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");
/* excessive arguments */
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)
{
/* Add printable characters to line */
if (isprint(key)) {
if (prompt_buf_pos == (sizeof(prompt_buf) - 1)) {
wprintw(self->window, "\nToo Long.\n");
prompt_buf_pos = 0;
prompt_buf[0] = 0;
}
else if (!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS)
&& (prompt_buf_pos % (COLS - 3) == 0)) {
prompt_buf[prompt_buf_pos++] = '\n';
}
else if (!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS)
&& ((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;
}
/* Add printable characters to line */
if (isprint(key)) {
if (prompt_buf_pos == (sizeof(prompt_buf) - 1)) {
wprintw(self->window, "\nToo Long.\n");
prompt_buf_pos = 0;
prompt_buf[0] = 0;
} else if (!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS)
&& (prompt_buf_pos % (COLS - 3) == 0)) {
prompt_buf[prompt_buf_pos++] = '\n';
} else if (!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS)
&& ((prompt_buf_pos - (COLS - 3)) % (COLS) == 0)) {
prompt_buf[prompt_buf_pos++] = '\n';
}
/* RETURN key: execute command */
else if (key == '\n') {
wprintw(self->window, "\n");
execute(self, m, prompt_buf);
prompt_buf_pos = 0;
prompt_buf[0] = 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;
prompt_buf[prompt_buf_pos++] = key;
prompt_buf[prompt_buf_pos] = 0;
}
/* RETURN key: execute command */
else if (key == '\n') {
wprintw(self->window, "\n");
execute(self, m, prompt_buf);
prompt_buf_pos = 0;
prompt_buf[0] = 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)
{
curs_set(1);
int x, y;
getyx(self->window, y, x);
(void) x;
int i;
for (i = 0; i < (strlen(prompt_buf)); ++i) {
if ((prompt_buf[i] == '\n') && (y != 0))
--y;
}
curs_set(1);
int x, y;
getyx(self->window, y, x);
(void) x;
int i;
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);
for (i = 0; i < (strlen(prompt_buf)); ++i) {
if ((prompt_buf[i] == '\n') && (y != 0))
--y;
}
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)
{
scrollok(self->window, 1);
cmd_help(self, m, NULL);
wclrtoeol(self->window);
scrollok(self->window, 1);
cmd_help(self, m, NULL);
wclrtoeol(self->window);
}
ToxWindow new_prompt(friendAddedFn *f)
{
on_friendadded_cb = f;
ToxWindow ret;
memset(&ret, 0, sizeof(ret));
ret.onKey = &prompt_onKey;
ret.onDraw = &prompt_onDraw;
ret.onInit = &prompt_onInit;
strcpy(ret.title, "[prompt]");
return ret;
on_friendadded_cb = f;
ToxWindow ret;
memset(&ret, 0, sizeof(ret));
ret.onKey = &prompt_onKey;
ret.onDraw = &prompt_onDraw;
ret.onInit = &prompt_onInit;
strcpy(ret.title, "[prompt]");
return ret;
}

View File

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

View File

@ -26,31 +26,31 @@
typedef struct ToxWindow_ ToxWindow;
struct ToxWindow_ {
void(*onKey)(ToxWindow*, Messenger*, int);
void(*onDraw)(ToxWindow*);
void(*onInit)(ToxWindow*, Messenger*);
void(*onFriendRequest)(ToxWindow*, uint8_t*, uint8_t*, uint16_t);
void(*onMessage)(ToxWindow*, Messenger*, int, uint8_t*, uint16_t);
void(*onNickChange)(ToxWindow*, int, uint8_t*, uint16_t);
void(*onStatusChange)(ToxWindow*, int, uint8_t*, uint16_t);
void(*onAction)(ToxWindow*, Messenger*, int, uint8_t*, uint16_t);
char title[256];
void(*onKey)(ToxWindow *, Messenger *, int);
void(*onDraw)(ToxWindow *);
void(*onInit)(ToxWindow *, Messenger *);
void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t);
void(*onMessage)(ToxWindow *, Messenger *, int, uint8_t *, uint16_t);
void(*onNickChange)(ToxWindow *, int, uint8_t *, uint16_t);
void(*onStatusChange)(ToxWindow *, int, uint8_t *, uint16_t);
void(*onAction)(ToxWindow *, Messenger *, int, uint8_t *, uint16_t);
char title[256];
void* x;
bool blink;
void *x;
bool blink;
WINDOW* window;
WINDOW *window;
};
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_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_statuschange(Messenger *m, int friendnumber, uint8_t *string, 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_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_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata);
void on_friendadded(Messenger *m, int friendnumber);
void init_window_status();
ToxWindow * init_windows();
void draw_active_window(Messenger * m);
ToxWindow *init_windows();
void draw_active_window(Messenger *m);
int add_window(Messenger *m, ToxWindow w, int n);
void del_window(ToxWindow *w, int f_num);
void set_active_window(int ch);