summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rwxr-xr-xCMakeLists.txt1
-rw-r--r--INSTALL.md11
-rw-r--r--README.md6
-rw-r--r--_vimrc_local.vim9
-rw-r--r--cmake/FindSphinx.cmake16
-rw-r--r--core/DHT.c51
-rw-r--r--core/DHT.h2
-rw-r--r--core/LAN_discovery.c61
-rw-r--r--core/LAN_discovery.h7
-rw-r--r--core/Lossless_UDP.c427
-rw-r--r--core/Lossless_UDP.h96
-rw-r--r--core/Messenger.c39
-rw-r--r--core/Messenger.h21
-rw-r--r--core/net_crypto.c56
-rw-r--r--docs/CMakeLists.txt40
-rw-r--r--docs/commands.md25
-rw-r--r--docs/commands.rst48
-rw-r--r--docs/conf.py242
-rw-r--r--docs/index.rst25
-rw-r--r--docs/install.rst129
-rw-r--r--docs/start_guide.de.md40
-rw-r--r--docs/start_guide.de.rst66
-rw-r--r--docs/start_guide.md38
-rw-r--r--docs/start_guide.rst63
-rw-r--r--testing/nTox.c63
-rw-r--r--testing/nTox_win32.c10
-rw-r--r--testing/toxic/main.c21
-rw-r--r--testing/toxic/prompt.c24
29 files changed, 1219 insertions, 423 deletions
diff --git a/.travis.yml b/.travis.yml
index 8e71c327..a1a17f61 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,12 +21,15 @@ before_script:
21 - cd .. 21 - cd ..
22# creating librarys' links and updating cache 22# creating librarys' links and updating cache
23 - sudo ldconfig 23 - sudo ldconfig
24 24# installing sphinx, needed for documentation
25 - sudo apt-get install python-sphinx
25 26
26script: 27script:
27 - mkdir build && cd build 28 - mkdir build && cd build
28 - cmake .. 29 - cmake ..
29 - make -j3 30 - make -j3
31# build docs separately
32 - make docs
30 33
31notifications: 34notifications:
32 email: false 35 email: false
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9b7db143..bf709e72 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,3 +48,4 @@ cmake_policy(SET CMP0011 NEW)
48add_subdirectory(core) 48add_subdirectory(core)
49add_subdirectory(testing) 49add_subdirectory(testing)
50add_subdirectory(other) 50add_subdirectory(other)
51add_subdirectory(docs)
diff --git a/INSTALL.md b/INSTALL.md
index a0c4165d..87451948 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -6,7 +6,6 @@
6 - [Homebrew](#homebrew) 6 - [Homebrew](#homebrew)
7 - [Non-Homebrew](#non-homebrew) 7 - [Non-Homebrew](#non-homebrew)
8 - [Windows](#windows) 8 - [Windows](#windows)
9- [Usage](#usage)
10 9
11<a name="installation" /> 10<a name="installation" />
12##Installation 11##Installation
@@ -32,11 +31,14 @@ sudo checkinstall --install --pkgname libsodium --pkgversion 0.4.2 --nodoc
32sudo ldconfig 31sudo ldconfig
33``` 32```
34 33
35Then clone this repo and run: 34Then clone this repo and generate makefile:
36```bash 35```bash
36git clone git://github.com/irungentoo/ProjectTox-Core.git
37cd ProjectTox-Core
37mkdir build && cd build 38mkdir build && cd build
38cmake .. 39cmake ..
39``` 40```
41Note that you should call cmake on the root [`CMakeLists.txt`](/CMakeLists.txt) file only.
40 42
41Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running: 43Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running:
42```bash 44```bash
@@ -102,6 +104,7 @@ Navigate in `cmd` to this repo and run:
102mkdir build && cd build 104mkdir build && cd build
103cmake -G "MinGW Makefiles" .. 105cmake -G "MinGW Makefiles" ..
104``` 106```
107Note that you should call cmake on the root [`CMakeLists.txt`](/CMakeLists.txt) file only.
105 108
106Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running: 109Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running:
107```cmd 110```cmd
@@ -117,7 +120,3 @@ Or you could just build everything that is supported on your platform by running
117mingw32-make 120mingw32-make
118``` 121```
119 122
120<a name="usage" />
121## Usage
122
123- [Start Guide](start_guide.md)
diff --git a/README.md b/README.md
index 092fe2f6..56160ce2 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ With the rise of governmental monitoring programs, Tox aims to be an easy to use
13 13
14**How to build Tox on Linux**: [YouTube video](http://www.youtube.com/watch?v=M4WXE4VKmyg)<br /> 14**How to build Tox on Linux**: [YouTube video](http://www.youtube.com/watch?v=M4WXE4VKmyg)<br />
15**How to use Tox on Windows**: [YouTube video](http://www.youtube.com/watch?v=qg_j_sDb6WQ)<br /> 15**How to use Tox on Windows**: [YouTube video](http://www.youtube.com/watch?v=qg_j_sDb6WQ)<br />
16**For Mac OSX read INSTALL.md** 16**For Mac OSX read** [INSTALL.md](INSTALL.md)
17 17
18### Objectives: 18### Objectives:
19 19
@@ -35,13 +35,13 @@ Keep everything really simple.
35- [ ] Streaming media 35- [ ] Streaming media
36- [ ] ??? 36- [ ] ???
37 37
38For further information, check our [To-do list](https://github.com/irungentoo/ProjectTox-Core/wiki/TODO) 38For further information, check our [To-do list](http://wiki.tox.im/index.php/TODO)
39 39
40### Why are you doing this? There are already a bunch of free skype alternatives. 40### Why are you doing this? There are already a bunch of free skype alternatives.
41The goal of this project is to create a configuration-free P2P skype 41The goal of this project is to create a configuration-free P2P skype
42replacement. Configuration-free means that the user will simply have to open the program and 42replacement. Configuration-free means that the user will simply have to open the program and
43without any account configuration will be capable of adding people to his 43without any account configuration will be capable of adding people to his
44friends list and start conversing with them. There are many so called skype replacements and all of them are either hard to 44friends list and start conversing with them. There are many so-called skype replacements and all of them are either hard to
45configure for the normal user or suffer from being way too centralized. 45configure for the normal user or suffer from being way too centralized.
46 46
47### Documentation: 47### Documentation:
diff --git a/_vimrc_local.vim b/_vimrc_local.vim
deleted file mode 100644
index 32c73763..00000000
--- a/_vimrc_local.vim
+++ /dev/null
@@ -1,9 +0,0 @@
1"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2" => Text, tab and indent related
3"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
4" Use spaces instead of tabs
5set expandtab
6
7" 1 tab == 4 spaces
8set shiftwidth=4
9set tabstop=4
diff --git a/cmake/FindSphinx.cmake b/cmake/FindSphinx.cmake
new file mode 100644
index 00000000..833bfd4d
--- /dev/null
+++ b/cmake/FindSphinx.cmake
@@ -0,0 +1,16 @@
1find_program(SPHINX_EXECUTABLE NAMES sphinx-build
2 HINTS
3 $ENV{SPHINX_DIR}
4 PATH_SUFFIXES bin
5 DOC "Sphinx documentation generator"
6)
7
8include(FindPackageHandleStandardArgs)
9
10find_package_handle_standard_args(Sphinx DEFAULT_MSG
11 SPHINX_EXECUTABLE
12)
13
14mark_as_advanced(
15 SPHINX_EXECUTABLE
16)
diff --git a/core/DHT.c b/core/DHT.c
index 5a362ecc..f779ef18 100644
--- a/core/DHT.c
+++ b/core/DHT.c
@@ -85,7 +85,7 @@ typedef struct {
85 uint8_t hole_punching; 85 uint8_t hole_punching;
86 uint32_t punching_index; 86 uint32_t punching_index;
87 uint32_t punching_timestamp; 87 uint32_t punching_timestamp;
88 uint32_t recvNATping_timestamp; 88 int64_t recvNATping_timestamp;
89 uint64_t NATping_id; 89 uint64_t NATping_id;
90 uint32_t NATping_timestamp; 90 uint32_t NATping_timestamp;
91} Friend; 91} Friend;
@@ -98,7 +98,7 @@ typedef struct {
98typedef struct { 98typedef struct {
99 IP_Port ip_port; 99 IP_Port ip_port;
100 uint64_t ping_id; 100 uint64_t ping_id;
101 uint32_t timestamp; 101 int64_t timestamp;
102} Pinged; 102} Pinged;
103 103
104/*----------------------------------------------------------------------------------*/ 104/*----------------------------------------------------------------------------------*/
@@ -145,7 +145,8 @@ int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2)
145 */ 145 */
146int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port) 146int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port)
147{ 147{
148 uint32_t i, temp_time = unix_time(); 148 uint32_t i;
149 int64_t temp_time = unix_time();
149 150
150 for(i = 0; i < length; ++i) { 151 for(i = 0; i < length; ++i) {
151 /*If ip_port is assigned to a different client_id replace it*/ 152 /*If ip_port is assigned to a different client_id replace it*/
@@ -197,7 +198,8 @@ static int friend_number(uint8_t * client_id)
197 */ 198 */
198int get_close_nodes(uint8_t * client_id, Node_format * nodes_list) 199int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
199{ 200{
200 uint32_t i, j, k, temp_time = unix_time(); 201 uint32_t i, j, k;
202 int64_t temp_time = unix_time();
201 int num_nodes = 0, closest, tout, inlist; 203 int num_nodes = 0, closest, tout, inlist;
202 204
203 for (i = 0; i < LCLIENT_LIST; ++i) { 205 for (i = 0; i < LCLIENT_LIST; ++i) {
@@ -283,7 +285,7 @@ int replace_bad( Client_data * list,
283 IP_Port ip_port ) 285 IP_Port ip_port )
284{ 286{
285 uint32_t i; 287 uint32_t i;
286 uint32_t temp_time = unix_time(); 288 int64_t temp_time = unix_time();
287 for(i = 0; i < length; ++i) { 289 for(i = 0; i < length; ++i) {
288 /* if node is bad */ 290 /* if node is bad */
289 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) { 291 if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) {
@@ -308,7 +310,7 @@ int replace_good( Client_data * list,
308 uint8_t * comp_client_id ) 310 uint8_t * comp_client_id )
309{ 311{
310 uint32_t i; 312 uint32_t i;
311 uint32_t temp_time = unix_time(); 313 int64_t temp_time = unix_time();
312 314
313 for(i = 0; i < length; ++i) 315 for(i = 0; i < length; ++i)
314 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) { 316 if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
@@ -371,7 +373,8 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
371 */ 373 */
372void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id) 374void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id)
373{ 375{
374 uint32_t i, j, temp_time = unix_time(); 376 uint32_t i, j;
377 int64_t temp_time = unix_time();
375 378
376 if (memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) { 379 if (memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) {
377 for (i = 0; i < LCLIENT_LIST; ++i) { 380 for (i = 0; i < LCLIENT_LIST; ++i) {
@@ -411,8 +414,9 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
411 */ 414 */
412int is_pinging(IP_Port ip_port, uint64_t ping_id) 415int is_pinging(IP_Port ip_port, uint64_t ping_id)
413{ 416{
414 uint32_t i, temp_time = unix_time(); 417 uint32_t i;
415 uint8_t pinging; 418 uint8_t pinging;
419 int64_t temp_time = unix_time();
416 420
417 for (i = 0; i < LPING_ARRAY; ++i ) { 421 for (i = 0; i < LPING_ARRAY; ++i ) {
418 if ((pings[i].timestamp + PING_TIMEOUT) > temp_time) { 422 if ((pings[i].timestamp + PING_TIMEOUT) > temp_time) {
@@ -434,8 +438,9 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
434/* Same as last function but for get_node requests. */ 438/* Same as last function but for get_node requests. */
435int is_gettingnodes(IP_Port ip_port, uint64_t ping_id) 439int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
436{ 440{
437 uint32_t i, temp_time = unix_time(); 441 uint32_t i;
438 uint8_t pinging; 442 uint8_t pinging;
443 int64_t temp_time = unix_time();
439 444
440 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) { 445 for(i = 0; i < LSEND_NODES_ARRAY; ++i ) {
441 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) { 446 if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) {
@@ -462,8 +467,10 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
462 */ 467 */
463uint64_t add_pinging(IP_Port ip_port) 468uint64_t add_pinging(IP_Port ip_port)
464{ 469{
465 uint32_t i, j, temp_time = unix_time(); 470 uint32_t i, j;
466 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 471 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
472 int64_t temp_time = unix_time();
473
467 474
468 for(i = 0; i < PING_TIMEOUT; ++i ) { 475 for(i = 0; i < PING_TIMEOUT; ++i ) {
469 for(j = 0; j < LPING_ARRAY; ++j ) { 476 for(j = 0; j < LPING_ARRAY; ++j ) {
@@ -484,7 +491,7 @@ uint64_t add_gettingnodes(IP_Port ip_port)
484{ 491{
485 uint32_t i, j; 492 uint32_t i, j;
486 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int(); 493 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
487 uint32_t temp_time = unix_time(); 494 int64_t temp_time = unix_time();
488 495
489 for(i = 0; i < PING_TIMEOUT; ++i ) { 496 for(i = 0; i < PING_TIMEOUT; ++i ) {
490 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) { 497 for(j = 0; j < LSEND_NODES_ARRAY; ++j ) {
@@ -823,7 +830,8 @@ int DHT_delfriend(uint8_t * client_id)
823/* TODO: Optimize this. */ 830/* TODO: Optimize this. */
824IP_Port DHT_getfriendip(uint8_t * client_id) 831IP_Port DHT_getfriendip(uint8_t * client_id)
825{ 832{
826 uint32_t i, j, temp_time = unix_time(); 833 uint32_t i, j;
834 int64_t temp_time = unix_time();
827 IP_Port empty = {{{0}}, 0}; 835 IP_Port empty = {{{0}}, 0};
828 836
829 for (i = 0; i < num_friends; ++i) { 837 for (i = 0; i < num_friends; ++i) {
@@ -849,7 +857,7 @@ IP_Port DHT_getfriendip(uint8_t * client_id)
849void doDHTFriends() 857void doDHTFriends()
850{ 858{
851 uint32_t i, j; 859 uint32_t i, j;
852 uint32_t temp_time = unix_time(); 860 int64_t temp_time = unix_time();
853 uint32_t rand_node; 861 uint32_t rand_node;
854 uint32_t index[MAX_FRIEND_CLIENTS]; 862 uint32_t index[MAX_FRIEND_CLIENTS];
855 863
@@ -888,7 +896,7 @@ static uint32_t close_lastgetnodes;
888void doClose() 896void doClose()
889{ 897{
890 uint32_t i; 898 uint32_t i;
891 uint32_t temp_time = unix_time(); 899 int64_t temp_time = unix_time();
892 uint32_t num_nodes = 0; 900 uint32_t num_nodes = 0;
893 uint32_t rand_node; 901 uint32_t rand_node;
894 uint32_t index[LCLIENT_LIST]; 902 uint32_t index[LCLIENT_LIST];
@@ -945,8 +953,9 @@ int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
945static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num) 953static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
946{ 954{
947 int num_ips = 0; 955 int num_ips = 0;
948 uint32_t i, temp_time = unix_time(); 956 uint32_t i;
949 957 int64_t temp_time = unix_time();
958
950 if (friend_num >= num_friends) 959 if (friend_num >= num_friends)
951 return -1; 960 return -1;
952 961
@@ -979,7 +988,8 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
979 if (num == -1) 988 if (num == -1)
980 return 0; 989 return 0;
981 990
982 uint32_t i, sent = 0, temp_time = unix_time(); 991 uint32_t i, sent = 0;
992 int64_t temp_time = unix_time();
983 Friend * friend = &friends_list[num]; 993 Friend * friend = &friends_list[num];
984 Client_data * client; 994 Client_data * client;
985 995
@@ -1012,6 +1022,7 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
1012 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 1022 IP_Port ip_list[MAX_FRIEND_CLIENTS];
1013 int n = 0; 1023 int n = 0;
1014 uint32_t i, temp_time = unix_time(); 1024 uint32_t i, temp_time = unix_time();
1025 int64_t temp_time = unix_time();
1015 1026
1016 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) { 1027 for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
1017 client = &friend->client_list[i]; 1028 client = &friend->client_list[i];
@@ -1184,7 +1195,8 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t
1184 1195
1185static void doNAT() 1196static void doNAT()
1186{ 1197{
1187 uint32_t i, temp_time = unix_time(); 1198 uint32_t i;
1199 int64_t temp_time = unix_time();
1188 1200
1189 for (i = 0; i < num_friends; ++i) { 1201 for (i = 0; i < num_friends; ++i) {
1190 IP_Port ip_list[MAX_FRIEND_CLIENTS]; 1202 IP_Port ip_list[MAX_FRIEND_CLIENTS];
@@ -1279,7 +1291,7 @@ int DHT_load(uint8_t * data, uint32_t size)
1279 1291
1280 uint32_t i, j; 1292 uint32_t i, j;
1281 uint16_t temp; 1293 uint16_t temp;
1282 /* uint32_t temp_time = unix_time(); */ 1294 /* int64_t temp_time = unix_time(); */
1283 1295
1284 Client_data * client; 1296 Client_data * client;
1285 1297
@@ -1314,6 +1326,7 @@ int DHT_load(uint8_t * data, uint32_t size)
1314int DHT_isconnected() 1326int DHT_isconnected()
1315{ 1327{
1316 uint32_t i, temp_time = unix_time(); 1328 uint32_t i, temp_time = unix_time();
1329 int64_t temp_time = unix_time();
1317 1330
1318 for(i = 0; i < LCLIENT_LIST; ++i) { 1331 for(i = 0; i < LCLIENT_LIST; ++i) {
1319 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time) 1332 if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)
diff --git a/core/DHT.h b/core/DHT.h
index dbb640a5..5e1fd0a5 100644
--- a/core/DHT.h
+++ b/core/DHT.h
@@ -31,7 +31,7 @@ extern "C" {
31#endif 31#endif
32 32
33/* Current time, unix format */ 33/* Current time, unix format */
34#define unix_time() ((uint32_t)time(NULL)) 34#define unix_time() ((int64_t)time(NULL))
35 35
36/* size of the client_id in bytes */ 36/* size of the client_id in bytes */
37#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES 37#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c
index 0a23914d..72e00d32 100644
--- a/core/LAN_discovery.c
+++ b/core/LAN_discovery.c
@@ -23,13 +23,70 @@
23 23
24#include "LAN_discovery.h" 24#include "LAN_discovery.h"
25 25
26#define MAX_INTERFACES 16
26 27
27/*Return the broadcast ip 28#ifdef __linux
28 TODO: make it return the real one, not the 255.255.255.255 one.*/ 29/* get the first working broadcast address that's not from "lo"
30 * returns higher than 0 on success
31 * returns 0 on error */
32uint32_t get_broadcast(void)
33{
34 /* not sure how many platforms this will
35 * run on, so it's wrapped in __linux for now */
36 struct sockaddr_in *sock_holder = NULL;
37 struct ifreq i_faces[MAX_INTERFACES];
38 struct ifconf ifconf;
39 int count = 0;
40 int sock = 0;
41 int i = 0;
42
43 /* configure ifconf for the ioctl call */
44 if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
45 perror("[!] get_broadcast: socket() error");
46 return 0;
47 }
48
49 memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES);
50
51 ifconf.ifc_buf = (char *)i_faces;
52 ifconf.ifc_len = sizeof(i_faces);
53 count = ifconf.ifc_len / sizeof(struct ifreq);
54 if(ioctl(sock, SIOCGIFCONF, &ifconf) < 0) {
55 perror("get_broadcast: ioctl() error");
56 return 0;
57 }
58
59 for(i = 0; i < count; i++) {
60 /* skip the loopback interface, as it's useless */
61 if(strcmp(i_faces[i].ifr_name, "lo") != 0) {
62 if(ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) {
63 perror("[!] get_broadcast: ioctl error");
64 return 0;
65 }
66
67 /* just to clarify where we're getting the values from */
68 sock_holder = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr;
69 break;
70 }
71 }
72 close(sock);
73
74 return sock_holder->sin_addr.s_addr;
75}
76#endif
77
78/* Return the broadcast ip */
29IP broadcast_ip() 79IP broadcast_ip()
30{ 80{
31 IP ip; 81 IP ip;
82 #ifdef __linux
83 ip.i = get_broadcast();
84 if(ip.i == 0)
85 /* error errored, but try anyway? */
86 ip.i = ~0;
87 #else
32 ip.i = ~0; 88 ip.i = ~0;
89 #endif
33 return ip; 90 return ip;
34} 91}
35 92
diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h
index 4ca65c03..96a6e6ad 100644
--- a/core/LAN_discovery.h
+++ b/core/LAN_discovery.h
@@ -28,6 +28,13 @@
28 28
29#include "DHT.h" 29#include "DHT.h"
30 30
31/* used for get_broadcast() */
32#ifdef __linux
33#include <sys/ioctl.h>
34#include <arpa/inet.h>
35#include <linux/netdevice.h>
36#endif
37
31#ifdef __cplusplus 38#ifdef __cplusplus
32extern "C" { 39extern "C" {
33#endif 40#endif
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c
index 6be8328f..4affc38f 100644
--- a/core/Lossless_UDP.c
+++ b/core/Lossless_UDP.c
@@ -21,67 +21,95 @@
21 * 21 *
22 */ 22 */
23 23
24/* TODO: clean this file a bit. 24/*
25 There are a couple of useless variables to get rid of. */ 25 * TODO: clean this file a bit.
26 * There are a couple of useless variables to get rid of.
27 */
28
26#include "Lossless_UDP.h" 29#include "Lossless_UDP.h"
27 30
28/* maximum data packets in sent and receive queues. */ 31/* maximum data packets in sent and receive queues. */
29#define MAX_QUEUE_NUM 16 32#define MAX_QUEUE_NUM 16
30
31/* maximum length of the data in the data packets */
32/* #define MAX_DATA_SIZE 1024 */ /* defined in Lossless_UDP.h */
33 33
34/* maximum number of data packets in the buffer */ 34/* maximum number of data packets in the buffer */
35#define BUFFER_PACKET_NUM (16-1) 35#define BUFFER_PACKET_NUM (16-1)
36 36
37/* Lossless UDP connection timeout. 37/* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */
38timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */
39#define CONNEXION_TIMEOUT 5 38#define CONNEXION_TIMEOUT 5
40 39
41/* initial amount of sync/hanshake packets to send per second. */ 40/* initial amount of sync/hanshake packets to send per second. */
42#define SYNC_RATE 2 41#define SYNC_RATE 2
43 42
44/* initial send rate of data. */ 43/* initial send rate of data. */
45#define DATA_SYNC_RATE 30 44#define DATA_SYNC_RATE 30
46 45
47typedef struct { 46typedef struct {
48 uint8_t data[MAX_DATA_SIZE]; 47 uint8_t data[MAX_DATA_SIZE];
49 uint16_t size; 48 uint16_t size;
50} Data; 49} Data;
51 50
52typedef struct { 51typedef struct {
53 IP_Port ip_port; 52 IP_Port ip_port;
54 uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, 53
55 2 if handshake is done (we start sending SYNC packets) 54 /*
56 3 if we are sending SYNC packets and can send data 55 * 0 if connection is dead, 1 if attempting handshake,
57 4 if the connection has timed out. */ 56 * 2 if handshake is done (we start sending SYNC packets)
58 57 * 3 if we are sending SYNC packets and can send data
59 uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not. 58 * 4 if the connection has timed out.
60 2 if incoming_connection() has not returned it yet, 1 if it has. */ 59 */
61 60 uint8_t status;
62 uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ 61
63 uint16_t data_rate; /* current data packet send rate packets per second. */ 62 /*
64 uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */ 63 * 1 or 2 if connection was initiated by someone else, 0 if not.
65 uint64_t last_sent; /* time at which our last data or handshake packet was sent. */ 64 * 2 if incoming_connection() has not returned it yet, 1 if it has.
66 uint64_t last_recvSYNC; /* time at which we last received a SYNC packet from the other */ 65 */
67 uint64_t last_recvdata; /* time at which we last received a DATA packet from the other */ 66 uint8_t inbound;
68 uint64_t killat; /* time at which to kill the connection */ 67
69 Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ 68 uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */
70 Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ 69 uint16_t data_rate; /* current data packet send rate packets per second. */
71 uint32_t handshake_id1; 70
72 uint32_t handshake_id2; 71 uint64_t last_SYNC; /* time our last SYNC packet was sent. */
73 uint32_t recv_packetnum; /* number of data packets received (also used as handshake_id1) */ 72 uint64_t last_sent; /* time our last data or handshake packet was sent. */
74 uint32_t orecv_packetnum; /* number of packets received by the other peer */ 73 uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */
75 uint32_t sent_packetnum; /* number of data packets sent */ 74 uint64_t last_recvdata; /* time we last received a DATA packet from the other */
76 uint32_t osent_packetnum; /* number of packets sent by the other peer. */ 75 uint64_t killat; /* time to kill the connection */
77 uint32_t sendbuff_packetnum; /* number of latest packet written onto the sendbuffer */ 76
78 uint32_t successful_sent; /* we know all packets before that number were successfully sent */ 77 Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */
79 uint32_t successful_read; /* packet number of last packet read with the read_packet function */ 78 Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */
80 uint32_t req_packets[BUFFER_PACKET_NUM]; /* list of currently requested packet numbers(by the other person) */ 79
81 uint16_t num_req_paquets; /* total number of currently requested packets(by the other person) */ 80 uint32_t handshake_id1;
82 uint8_t recv_counter; 81 uint32_t handshake_id2;
83 uint8_t send_counter; 82
84 uint8_t timeout; /* connection timeout in seconds. */ 83 /* number of data packets received (also used as handshake_id1) */
84 uint32_t recv_packetnum;
85
86 /* number of packets received by the other peer */
87 uint32_t orecv_packetnum;
88
89 /* number of data packets sent */
90 uint32_t sent_packetnum;
91
92 /* number of packets sent by the other peer. */
93 uint32_t osent_packetnum;
94
95 /* number of latest packet written onto the sendbuffer */
96 uint32_t sendbuff_packetnum;
97
98 /* we know all packets before that number were successfully sent */
99 uint32_t successful_sent;
100
101 /* packet number of last packet read with the read_packet function */
102 uint32_t successful_read;
103
104 /* list of currently requested packet numbers(by the other person) */
105 uint32_t req_packets[BUFFER_PACKET_NUM];
106
107 /* total number of currently requested packets(by the other person) */
108 uint16_t num_req_paquets;
109
110 uint8_t recv_counter;
111 uint8_t send_counter;
112 uint8_t timeout; /* connection timeout in seconds. */
85} Connection; 113} Connection;
86 114
87 115
@@ -94,26 +122,33 @@ static uint32_t connections_number; /* Number of connections in connections arra
94 122
95/* Functions */ 123/* Functions */
96 124
97/* get connection id from IP_Port 125/*
98 return -1 if there are no connections like we are looking for 126 * Get connection id from IP_Port
99 return id if it found it */ 127 * Return -1 if there are no connections like we are looking for
128 * Return id if it found it
129 */
100int getconnection_id(IP_Port ip_port) 130int getconnection_id(IP_Port ip_port)
101{ 131{
102 uint32_t i; 132 uint32_t i;
103 for (i = 0; i < MAX_CONNECTIONS; ++i) { 133 for (i = 0; i < MAX_CONNECTIONS; ++i) {
104 if (connections[i].ip_port.ip.i == ip_port.ip.i && 134 if (connections[i].ip_port.ip.i == ip_port.ip.i &&
105 connections[i].ip_port.port == ip_port.port && connections[i].status > 0) 135 connections[i].ip_port.port == ip_port.port &&
136 connections[i].status > 0)
106 return i; 137 return i;
107 } 138 }
139
108 return -1; 140 return -1;
109} 141}
110 142
111/* table of random numbers used below. */ 143/* table of random numbers used below. */
112static uint32_t randtable[6][256]; 144static uint32_t randtable[6][256];
113 145
114/* generate a handshake_id which depends on the ip_port. 146/*
115 this function will always give one unique handshake_id per ip_port. 147 * Generate a handshake_id which depends on the ip_port.
116 TODO: make this better */ 148 * This function will always give one unique handshake_id per ip_port.
149 *
150 * TODO: make this better
151 */
117uint32_t handshake_id(IP_Port source) 152uint32_t handshake_id(IP_Port source)
118{ 153{
119 uint32_t id = 0, i; 154 uint32_t id = 0, i;
@@ -124,21 +159,27 @@ uint32_t handshake_id(IP_Port source)
124 } 159 }
125 if (id == 0) /* id can't be zero */ 160 if (id == 0) /* id can't be zero */
126 id = 1; 161 id = 1;
162
127 return id; 163 return id;
128} 164}
129 165
130/* change the hnshake id associated with that ip_port 166/*
131 TODO: make this better */ 167 * Change the hanshake id associated with that ip_port
168 *
169 * TODO: make this better
170 */
132void change_handshake(IP_Port source) 171void change_handshake(IP_Port source)
133{ 172{
134 uint8_t rand = random_int() % 4; 173 uint8_t rand = random_int() % 4;
135 randtable[rand][((uint8_t *)&source)[rand]] = random_int(); 174 randtable[rand][((uint8_t *)&source)[rand]] = random_int();
136} 175}
137 176
138/* initialize a new connection to ip_port 177/*
139 returns an integer corresponding to the connection id. 178 * Initialize a new connection to ip_port
140 return -1 if it could not initialize the connection. 179 * Returns an integer corresponding to the connection idt
141 if there already was an existing connection to that ip_port return its number. */ 180 * Return -1 if it could not initialize the connectiont
181 * If there already was an existing connection to that ip_port return its number.
182 */
142int new_connection(IP_Port ip_port) 183int new_connection(IP_Port ip_port)
143{ 184{
144 int connect = getconnection_id(ip_port); 185 int connect = getconnection_id(ip_port);
@@ -148,8 +189,10 @@ int new_connection(IP_Port ip_port)
148 if(connections_number == connections_length) { 189 if(connections_number == connections_length) {
149 Connection * temp; 190 Connection * temp;
150 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 191 temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
192
151 if(temp == NULL) 193 if(temp == NULL)
152 return -1; 194 return -1;
195
153 memset(&temp[connections_length], 0, sizeof(Connection)); 196 memset(&temp[connections_length], 0, sizeof(Connection));
154 ++connections_length; 197 ++connections_length;
155 connections = temp; 198 connections = temp;
@@ -159,31 +202,37 @@ int new_connection(IP_Port ip_port)
159 for (i = 0; i < MAX_CONNECTIONS; ++i) { 202 for (i = 0; i < MAX_CONNECTIONS; ++i) {
160 if(connections[i].status == 0) { 203 if(connections[i].status == 0) {
161 memset(&connections[i], 0, sizeof(Connection)); 204 memset(&connections[i], 0, sizeof(Connection));
162 connections[i].ip_port = ip_port; 205
163 connections[i].status = 1; 206 connections[i] = (Connection) {
164 connections[i].inbound = 0; 207 .ip_port = ip_port,
165 connections[i].handshake_id1 = handshake_id(ip_port); 208 .status = 1,
166 connections[i].sent_packetnum = connections[i].handshake_id1; 209 .inbound = 0,
167 connections[i].sendbuff_packetnum = connections[i].handshake_id1; 210 .handshake_id1 = handshake_id(ip_port),
168 connections[i].successful_sent = connections[i].handshake_id1; 211 .sent_packetnum = connections[i].handshake_id1,
169 connections[i].SYNC_rate = SYNC_RATE; 212 .sendbuff_packetnum = connections[i].handshake_id1,
170 connections[i].data_rate = DATA_SYNC_RATE; 213 .successful_sent = connections[i].handshake_id1,
171 connections[i].last_recvSYNC = current_time(); 214 .SYNC_rate = SYNC_RATE,
172 connections[i].last_sent = current_time(); 215 .data_rate = DATA_SYNC_RATE,
173 connections[i].killat = ~0; 216 .last_recvSYNC = current_time(),
174 connections[i].send_counter = 0; 217 .last_sent = current_time(),
175 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 218 .killat = ~0,
176 connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; 219 .send_counter = 0,
220 /* add randomness to timeout to prevent connections getting stuck in a loop. */
221 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
222 };
177 ++connections_number; 223 ++connections_number;
224
178 return i; 225 return i;
179 } 226 }
180 } 227 }
181 return -1; 228 return -1;
182} 229}
183 230
184/* initialize a new inbound connection from ip_port 231/*
185 returns an integer corresponding to the connection id. 232 * Initialize a new inbound connection from ip_port
186 return -1 if it could not initialize the connection. */ 233 * Returns an integer corresponding to the connection id.
234 * Return -1 if it could not initialize the connection.
235 */
187int new_inconnection(IP_Port ip_port) 236int new_inconnection(IP_Port ip_port)
188{ 237{
189 if (getconnection_id(ip_port) != -1) 238 if (getconnection_id(ip_port) != -1)
@@ -192,8 +241,10 @@ int new_inconnection(IP_Port ip_port)
192 if(connections_number == connections_length) { 241 if(connections_number == connections_length) {
193 Connection * temp; 242 Connection * temp;
194 temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); 243 temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
244
195 if(temp == NULL) 245 if(temp == NULL)
196 return -1; 246 return -1;
247
197 memset(&temp[connections_length], 0, sizeof(Connection)); 248 memset(&temp[connections_length], 0, sizeof(Connection));
198 ++connections_length; 249 ++connections_length;
199 connections = temp; 250 connections = temp;
@@ -203,18 +254,23 @@ int new_inconnection(IP_Port ip_port)
203 for (i = 0; i < MAX_CONNECTIONS; ++i) { 254 for (i = 0; i < MAX_CONNECTIONS; ++i) {
204 if (connections[i].status == 0) { 255 if (connections[i].status == 0) {
205 memset(&connections[i], 0, sizeof(Connection)); 256 memset(&connections[i], 0, sizeof(Connection));
206 connections[i].ip_port = ip_port; 257
207 connections[i].status = 2; 258 connections[i] = (Connection){
208 connections[i].inbound = 2; 259 .ip_port = ip_port,
209 connections[i].SYNC_rate = SYNC_RATE; 260 .status = 2,
210 connections[i].data_rate = DATA_SYNC_RATE; 261 .inbound = 2,
211 connections[i].last_recvSYNC = current_time(); 262 .SYNC_rate = SYNC_RATE,
212 connections[i].last_sent = current_time(); 263 .data_rate = DATA_SYNC_RATE,
213 /* add randomness to timeout to prevent connections getting stuck in a loop. */ 264 .last_recvSYNC = current_time(),
214 connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; 265 .last_sent = current_time(),
215 /* if this connection isn't handled within the timeout kill it. */ 266 .send_counter = 127,
216 connections[i].killat = current_time() + 1000000UL*connections[i].timeout; 267
217 connections[i].send_counter = 127; 268 /* add randomness to timeout to prevent connections getting stuck in a loop. */
269 .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT,
270
271 /* if this connection isn't handled within the timeout kill it. */
272 .killat = current_time() + 1000000UL*connections[i].timeout
273 };
218 ++connections_number; 274 ++connections_number;
219 return i; 275 return i;
220 } 276 }
@@ -222,8 +278,10 @@ int new_inconnection(IP_Port ip_port)
222 return -1; 278 return -1;
223} 279}
224 280
225/* returns an integer corresponding to the next connection in our incoming connection list 281/*
226 return -1 if there are no new incoming connections in the list. */ 282 * Returns an integer corresponding to the next connection in our incoming connection list.
283 * Return -1 if there are no new incoming connections in the list.
284 */
227int incoming_connection() 285int incoming_connection()
228{ 286{
229 uint32_t i; 287 uint32_t i;
@@ -233,9 +291,11 @@ int incoming_connection()
233 return i; 291 return i;
234 } 292 }
235 } 293 }
294
236 return -1; 295 return -1;
237} 296}
238/*Try to free some memory from the connections array.*/ 297
298/* Try to free some memory from the connections array. */
239static void free_connections() 299static void free_connections()
240{ 300{
241 uint32_t i; 301 uint32_t i;
@@ -245,16 +305,20 @@ static void free_connections()
245 305
246 if(connections_length == i) 306 if(connections_length == i)
247 return; 307 return;
308
248 Connection * temp; 309 Connection * temp;
249 temp = realloc(connections, sizeof(Connection) * i); 310 temp = realloc(connections, sizeof(Connection) * i);
250 if(temp == NULL && i != 0) 311 if(temp == NULL && i != 0)
251 return; 312 return;
313
252 connections = temp; 314 connections = temp;
253 connections_length = i; 315 connections_length = i;
254} 316}
255 317
256/* return -1 if it could not kill the connection. 318/*
257 return 0 if killed successfully */ 319 * Return -1 if it could not kill the connection.
320 * Return 0 if killed successfully
321 */
258int kill_connection(int connection_id) 322int kill_connection(int connection_id)
259{ 323{
260 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { 324 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) {
@@ -269,9 +333,11 @@ int kill_connection(int connection_id)
269 return -1; 333 return -1;
270} 334}
271 335
272/* kill connection in seconds seconds. 336/*
273 return -1 if it can not kill the connection. 337 * Kill connection in seconds.
274 return 0 if it will kill it */ 338 * Return -1 if it can not kill the connection.
339 * Return 0 if it will kill it.
340 */
275int kill_connection_in(int connection_id, uint32_t seconds) 341int kill_connection_in(int connection_id, uint32_t seconds)
276{ 342{
277 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { 343 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) {
@@ -283,12 +349,14 @@ int kill_connection_in(int connection_id, uint32_t seconds)
283 return -1; 349 return -1;
284} 350}
285 351
286/* check if connection is connected 352/*
287 return 0 no. 353 * Check if connection is connected:
288 return 1 if attempting handshake 354 * Return 0 no.
289 return 2 if handshake is done 355 * Return 1 if attempting handshake.
290 return 3 if fully connected 356 * Return 2 if handshake is done.
291 return 4 if timed out and waiting to be killed */ 357 * Return 3 if fully connected.
358 * Return 4 if timed out and waiting to be killed.
359 */
292int is_connected(int connection_id) 360int is_connected(int connection_id)
293{ 361{
294 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) 362 if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
@@ -327,8 +395,10 @@ char id_packet(int connection_id)
327{ 395{
328 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) 396 if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
329 return -1; 397 return -1;
398
330 if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) 399 if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0)
331 return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; 400 return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0];
401
332 return -1; 402 return -1;
333} 403}
334 404
@@ -338,7 +408,7 @@ int read_packet(int connection_id, uint8_t * data)
338{ 408{
339 if (recvqueue(connection_id) != 0) { 409 if (recvqueue(connection_id) != 0) {
340 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; 410 uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM;
341 uint16_t size = connections[connection_id].recvbuffer[index].size; 411 uint16_t size = connections[connection_id].recvbuffer[index].size;
342 memcpy(data, connections[connection_id].recvbuffer[index].data, size); 412 memcpy(data, connections[connection_id].recvbuffer[index].data, size);
343 ++connections[connection_id].successful_read; 413 ++connections[connection_id].successful_read;
344 connections[connection_id].recvbuffer[index].size = 0; 414 connections[connection_id].recvbuffer[index].size = 0;
@@ -347,14 +417,15 @@ int read_packet(int connection_id, uint8_t * data)
347 return 0; 417 return 0;
348} 418}
349 419
350/* return 0 if data could not be put in packet queue 420/*
351 return 1 if data was put into the queue */ 421 * Return 0 if data could not be put in packet queue
422 * Return 1 if data was put into the queue
423 */
352int write_packet(int connection_id, uint8_t * data, uint32_t length) 424int write_packet(int connection_id, uint8_t * data, uint32_t length)
353{ 425{
354 if (length > MAX_DATA_SIZE) 426 if (length > MAX_DATA_SIZE || length == 0)
355 return 0;
356 if (length == 0)
357 return 0; 427 return 0;
428
358 if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { 429 if (sendqueue(connection_id) < BUFFER_PACKET_NUM) {
359 uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; 430 uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM;
360 memcpy(connections[connection_id].sendbuffer[index].data, data, length); 431 memcpy(connections[connection_id].sendbuffer[index].data, data, length);
@@ -362,6 +433,7 @@ int write_packet(int connection_id, uint8_t * data, uint32_t length)
362 connections[connection_id].sendbuff_packetnum++; 433 connections[connection_id].sendbuff_packetnum++;
363 return 1; 434 return 1;
364 } 435 }
436
365 return 0; 437 return 0;
366} 438}
367 439
@@ -371,8 +443,11 @@ uint32_t missing_packets(int connection_id, uint32_t * requested)
371 uint32_t number = 0; 443 uint32_t number = 0;
372 uint32_t i; 444 uint32_t i;
373 uint32_t temp; 445 uint32_t temp;
374 if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */ 446
447 /* don't request packets if the buffer is full. */
448 if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1))
375 return 0; 449 return 0;
450
376 for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { 451 for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) {
377 if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { 452 if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) {
378 temp = htonl(i); 453 temp = htonl(i);
@@ -380,14 +455,19 @@ uint32_t missing_packets(int connection_id, uint32_t * requested)
380 ++number; 455 ++number;
381 } 456 }
382 } 457 }
458
383 if(number == 0) 459 if(number == 0)
384 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; 460 connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum;
461
385 return number; 462 return number;
386} 463}
387 464
388/* Packet sending functions 465/*
389 One per packet type. 466 * BEGIN Packet sending functions
390 see docs/Lossless_UDP.txt for more information. */ 467 * One per packet type.
468 * see docs/Lossless_UDP.txt for more information.
469 */
470
391int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) 471int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2)
392{ 472{
393 uint8_t packet[1 + 4 + 4]; 473 uint8_t packet[1 + 4 + 4];
@@ -398,21 +478,22 @@ int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_i
398 memcpy(packet + 1, &temp, 4); 478 memcpy(packet + 1, &temp, 4);
399 temp = htonl(handshake_id2); 479 temp = htonl(handshake_id2);
400 memcpy(packet + 5, &temp, 4); 480 memcpy(packet + 5, &temp, 4);
481
401 return sendpacket(ip_port, packet, sizeof(packet)); 482 return sendpacket(ip_port, packet, sizeof(packet));
402} 483}
403 484
404int send_SYNC(uint32_t connection_id) 485int send_SYNC(uint32_t connection_id)
405{ 486{
406
407 uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; 487 uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)];
408 uint16_t index = 0; 488 uint16_t index = 0;
409 489
410 IP_Port ip_port = connections[connection_id].ip_port; 490 IP_Port ip_port = connections[connection_id].ip_port;
411 uint8_t counter = connections[connection_id].send_counter; 491 uint8_t counter = connections[connection_id].send_counter;
412 uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); 492 uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum);
413 uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); 493 uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum);
494
414 uint32_t requested[BUFFER_PACKET_NUM]; 495 uint32_t requested[BUFFER_PACKET_NUM];
415 uint32_t number = missing_packets(connection_id, requested); 496 uint32_t number = missing_packets(connection_id, requested);
416 497
417 packet[0] = 17; 498 packet[0] = 17;
418 index += 1; 499 index += 1;
@@ -462,17 +543,24 @@ int send_DATA(uint32_t connection_id)
462 return 0; 543 return 0;
463} 544}
464 545
465/* END of packet sending functions */ 546/*
547 * END of packet sending functions
548 *
549 *
550 * BEGIN Packet handling functions
551 * One to handle each type of packets we receive
552 */
553
466 554
467/* Packet handling functions 555/* Return 0 if handled correctly, 1 if packet is bad. */
468 One to handle each type of packets we receive
469 return 0 if handled correctly, 1 if packet is bad. */
470int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) 556int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
471{ 557{
472 if (length != (1 + 4 + 4)) 558 if (length != (1 + 4 + 4))
473 return 1; 559 return 1;
560
474 uint32_t temp; 561 uint32_t temp;
475 uint32_t handshake_id1, handshake_id2; 562 uint32_t handshake_id1, handshake_id2;
563
476 int connection = getconnection_id(source); 564 int connection = getconnection_id(source);
477 memcpy(&temp, packet + 1, 4); 565 memcpy(&temp, packet + 1, 4);
478 handshake_id1 = ntohl(temp); 566 handshake_id1 = ntohl(temp);
@@ -485,21 +573,22 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
485 } 573 }
486 if (is_connected(connection) != 1) 574 if (is_connected(connection) != 1)
487 return 1; 575 return 1;
488 if (handshake_id2 == connections[connection].handshake_id1) { /* if handshake_id2 is what we sent previously as handshake_id1 */ 576
577 /* if handshake_id2 is what we sent previously as handshake_id1 */
578 if (handshake_id2 == connections[connection].handshake_id1) {
489 connections[connection].status = 2; 579 connections[connection].status = 2;
490 /* NOTE: is this necessary? 580 /* NOTE: is this necessary?
491 connections[connection].handshake_id2 = handshake_id1; */ 581 connections[connection].handshake_id2 = handshake_id1; */
492 connections[connection].orecv_packetnum = handshake_id2; 582 connections[connection].orecv_packetnum = handshake_id2;
493 connections[connection].osent_packetnum = handshake_id1; 583 connections[connection].osent_packetnum = handshake_id1;
494 connections[connection].recv_packetnum = handshake_id1; 584 connections[connection].recv_packetnum = handshake_id1;
495 connections[connection].successful_read = handshake_id1; 585 connections[connection].successful_read = handshake_id1;
496 } 586 }
497 return 0;
498 587
588 return 0;
499} 589}
500 590
501/* returns 1 if sync packet is valid 591/* returns 1 if sync packet is valid 0 if not. */
502 0 if not. */
503int SYNC_valid(uint32_t length) 592int SYNC_valid(uint32_t length)
504{ 593{
505 if (length < 4 + 4 + 2) 594 if (length < 4 + 4 + 2)
@@ -510,19 +599,19 @@ int SYNC_valid(uint32_t length)
510 return 1; 599 return 1;
511} 600}
512 601
513/* case 1: */ 602/* case 1 in handle_SYNC: */
514int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) 603int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum)
515{ 604{
516 if (handshake_id(source) == recv_packetnum) { 605 if (handshake_id(source) == recv_packetnum) {
517 int x = new_inconnection(source); 606 int x = new_inconnection(source);
518 if (x != -1) { 607 if (x != -1) {
519 connections[x].orecv_packetnum = recv_packetnum; 608 connections[x].orecv_packetnum = recv_packetnum;
520 connections[x].sent_packetnum = recv_packetnum; 609 connections[x].sent_packetnum = recv_packetnum;
521 connections[x].sendbuff_packetnum = recv_packetnum; 610 connections[x].sendbuff_packetnum = recv_packetnum;
522 connections[x].successful_sent = recv_packetnum; 611 connections[x].successful_sent = recv_packetnum;
523 connections[x].osent_packetnum = sent_packetnum; 612 connections[x].osent_packetnum = sent_packetnum;
524 connections[x].recv_packetnum = sent_packetnum; 613 connections[x].recv_packetnum = sent_packetnum;
525 connections[x].successful_read = sent_packetnum; 614 connections[x].successful_read = sent_packetnum;
526 615
527 return x; 616 return x;
528 } 617 }
@@ -530,7 +619,7 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu
530 return -1; 619 return -1;
531} 620}
532 621
533/* case 2: */ 622/* case 2 in handle_SYNC: */
534int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) 623int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum)
535{ 624{
536 if (recv_packetnum == connections[connection_id].orecv_packetnum) { 625 if (recv_packetnum == connections[connection_id].orecv_packetnum) {
@@ -543,7 +632,7 @@ int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui
543 } 632 }
544 return 1; 633 return 1;
545} 634}
546/* case 3: */ 635/* case 3 in handle_SYNC: */
547int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, 636int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets,
548 uint16_t number) 637 uint16_t number)
549{ 638{
@@ -553,17 +642,25 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui
553 uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ 642 uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */
554 uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); 643 uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum);
555 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); 644 uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum);
556 if (comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) { /* packet valid */ 645
646 /* packet valid */
647 if (comp_1 <= BUFFER_PACKET_NUM &&
648 comp_2 <= BUFFER_PACKET_NUM &&
649 comp_counter < 10 && comp_counter != 0) {
650
557 connections[connection_id].orecv_packetnum = recv_packetnum; 651 connections[connection_id].orecv_packetnum = recv_packetnum;
558 connections[connection_id].osent_packetnum = sent_packetnum; 652 connections[connection_id].osent_packetnum = sent_packetnum;
559 connections[connection_id].successful_sent = recv_packetnum; 653 connections[connection_id].successful_sent = recv_packetnum;
560 connections[connection_id].last_recvSYNC = current_time(); 654 connections[connection_id].last_recvSYNC = current_time();
561 connections[connection_id].recv_counter = counter; 655 connections[connection_id].recv_counter = counter;
656
562 ++connections[connection_id].send_counter; 657 ++connections[connection_id].send_counter;
658
563 for (i = 0; i < number; ++i) { 659 for (i = 0; i < number; ++i) {
564 temp = ntohl(req_packets[i]); 660 temp = ntohl(req_packets[i]);
565 memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); 661 memcpy(connections[connection_id].req_packets + i, &temp, 4 * number);
566 } 662 }
663
567 connections[connection_id].num_req_paquets = number; 664 connections[connection_id].num_req_paquets = number;
568 return 0; 665 return 0;
569 } 666 }
@@ -575,6 +672,7 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source)
575 672
576 if (!SYNC_valid(length)) 673 if (!SYNC_valid(length))
577 return 1; 674 return 1;
675
578 int connection = getconnection_id(source); 676 int connection = getconnection_id(source);
579 uint8_t counter; 677 uint8_t counter;
580 uint32_t temp; 678 uint32_t temp;
@@ -587,19 +685,27 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source)
587 recv_packetnum = ntohl(temp); 685 recv_packetnum = ntohl(temp);
588 memcpy(&temp,packet + 6, 4); 686 memcpy(&temp,packet + 6, 4);
589 sent_packetnum = ntohl(temp); 687 sent_packetnum = ntohl(temp);
688
590 if (number != 0) 689 if (number != 0)
591 memcpy(req_packets, packet + 10, 4 * number); 690 memcpy(req_packets, packet + 10, 4 * number);
691
592 if (connection == -1) 692 if (connection == -1)
593 return handle_SYNC1(source, recv_packetnum, sent_packetnum); 693 return handle_SYNC1(source, recv_packetnum, sent_packetnum);
694
594 if (connections[connection].status == 2) 695 if (connections[connection].status == 2)
595 return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum); 696 return handle_SYNC2(connection, counter,
697 recv_packetnum, sent_packetnum);
698
596 if (connections[connection].status == 3) 699 if (connections[connection].status == 3)
597 return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number); 700 return handle_SYNC3(connection, counter, recv_packetnum,
701 sent_packetnum, req_packets, number);
598 return 0; 702 return 0;
599} 703}
600 704
601/* add a packet to the received buffer and set the recv_packetnum of the connection to its proper value. 705/*
602 return 1 if data was too big, 0 if not. */ 706 * Add a packet to the received buffer and set the recv_packetnum of the
707 * connection to its proper value. Return 1 if data was too big, 0 if not.
708 */
603int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) 709int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
604{ 710{
605 if (size > MAX_DATA_SIZE) 711 if (size > MAX_DATA_SIZE)
@@ -608,16 +714,22 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
608 uint32_t i; 714 uint32_t i;
609 uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; 715 uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM;
610 uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; 716 uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum;
717
611 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { 718 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
612 if (i == data_num) { 719 if (i == data_num) {
613 memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); 720 memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size);
721
614 connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; 722 connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size;
615 connections[connection_id].last_recvdata = current_time(); 723 connections[connection_id].last_recvdata = current_time();
616 if (sent_packet < BUFFER_PACKET_NUM) 724
725 if (sent_packet < BUFFER_PACKET_NUM) {
617 connections[connection_id].osent_packetnum = data_num; 726 connections[connection_id].osent_packetnum = data_num;
727 }
728
618 break; 729 break;
619 } 730 }
620 } 731 }
732
621 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { 733 for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
622 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) 734 if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0)
623 connections[connection_id].recv_packetnum = i; 735 connections[connection_id].recv_packetnum = i;
@@ -635,25 +747,30 @@ int handle_data(uint8_t *packet, uint32_t length, IP_Port source)
635 if (connection == -1) 747 if (connection == -1)
636 return 1; 748 return 1;
637 749
638 if (connections[connection].status != 3) /* Drop the data packet if connection is not connected. */ 750 /* Drop the data packet if connection is not connected. */
751 if (connections[connection].status != 3)
639 return 1; 752 return 1;
640 753
641 if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) 754 if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1)
642 return 1; 755 return 1;
756
643 uint32_t temp; 757 uint32_t temp;
644 uint32_t number; 758 uint32_t number;
645 uint16_t size = length - 1 - 4; 759 uint16_t size = length - 1 - 4;
646 760
647 memcpy(&temp, packet + 1, 4); 761 memcpy(&temp, packet + 1, 4);
648 number = ntohl(temp); 762 number = ntohl(temp);
763
649 return add_recv(connection, number, packet + 5, size); 764 return add_recv(connection, number, packet + 5, size);
650} 765}
651 766
652/* END of packet handling functions */ 767/*
768 * END of packet handling functions
769 */
653 770
654int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) 771int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
655{ 772{
656 switch (packet[0]) { //TODO: check if no break statement is correct??? 773 switch (packet[0]) {
657 case 16: 774 case 16:
658 return handle_handshake(packet, length, source); 775 return handle_handshake(packet, length, source);
659 776
@@ -670,8 +787,10 @@ int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
670 return 0; 787 return 0;
671} 788}
672 789
673/* Send handshake requests 790/*
674 handshake packets are sent at the same rate as SYNC packets */ 791 * Send handshake requests
792 * handshake packets are sent at the same rate as SYNC packets
793 */
675void doNew() 794void doNew()
676{ 795{
677 uint32_t i; 796 uint32_t i;
@@ -684,10 +803,13 @@ void doNew()
684 } 803 }
685 804
686 /* kill all timed out connections */ 805 /* kill all timed out connections */
687 if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && 806 if (connections[i].status > 0 &&
688 connections[i].status != 4) 807 (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
689 /* kill_connection(i); */ 808 connections[i].status != 4) {
690 connections[i].status = 4; 809 connections[i].status = 4;
810 /* kill_connection(i); */
811 }
812
691 if (connections[i].status > 0 && connections[i].killat < temp_time) 813 if (connections[i].status > 0 && connections[i].killat < temp_time)
692 kill_connection(i); 814 kill_connection(i);
693 } 815 }
@@ -720,11 +842,13 @@ void doData()
720 } 842 }
721} 843}
722 844
723/* TODO: flow control.
724 automatically adjusts send rates of packets for optimal transmission. */
725
726#define MAX_SYNC_RATE 10 845#define MAX_SYNC_RATE 10
727 846
847/*
848 * Automatically adjusts send rates of packets for optimal transmission.
849 *
850 * TODO: flow control.
851 */
728void adjustRates() 852void adjustRates()
729{ 853{
730 uint32_t i; 854 uint32_t i;
@@ -744,8 +868,7 @@ void adjustRates()
744 } 868 }
745} 869}
746 870
747/* Call this function a couple times per second 871/* Call this function a couple times per second It's the main loop. */
748 It's the main loop. */
749void doLossless_UDP() 872void doLossless_UDP()
750{ 873{
751 doNew(); 874 doNew();
diff --git a/core/Lossless_UDP.h b/core/Lossless_UDP.h
index 033bc480..573e1ab9 100644
--- a/core/Lossless_UDP.h
+++ b/core/Lossless_UDP.h
@@ -33,70 +33,90 @@ extern "C" {
33/* maximum length of the data in the data packets */ 33/* maximum length of the data in the data packets */
34#define MAX_DATA_SIZE 1024 34#define MAX_DATA_SIZE 1024
35 35
36/* Functions */ 36/*
37 37 * Initialize a new connection to ip_port
38/* initialize a new connection to ip_port 38 * Returns an integer corresponding to the connection id.
39 returns an integer corresponding to the connection id. 39 * Return -1 if it could not initialize the connection.
40 return -1 if it could not initialize the connection. 40 * Return number if there already was an existing connection to that ip_port.
41 if there already was an existing connection to that ip_port return its number. */ 41 */
42int new_connection(IP_Port ip_port); 42int new_connection(IP_Port ip_port);
43 43
44/* get connection id from IP_Port 44/*
45 return -1 if there are no connections like we are looking for 45 * Get connection id from IP_Port.
46 return id if it found it */ 46 * Return -1 if there are no connections like we are looking for.
47 * Return id if it found it .
48 */
47int getconnection_id(IP_Port ip_port); 49int getconnection_id(IP_Port ip_port);
48 50
49/* returns an integer corresponding to the next connection in our imcoming connection list 51/*
50 return -1 if there are no new incoming connections in the list. */ 52 * Returns an int corresponding to the next connection in our imcoming connection list
53 * Return -1 if there are no new incoming connections in the list.
54 */
51int incoming_connection(); 55int incoming_connection();
52 56
53/* return -1 if it could not kill the connection. 57/*
54 return 0 if killed successfully */ 58 * Return -1 if it could not kill the connection.
59 * Return 0 if killed successfully
60 */
55int kill_connection(int connection_id); 61int kill_connection(int connection_id);
56 62
57/* kill connection in seconds seconds. 63/*
58 return -1 if it can not kill the connection. 64 * Kill connection in seconds seconds.
59 return 0 if it will kill it */ 65 * Return -1 if it can not kill the connection.
66 * Return 0 if it will kill it
67 */
60int kill_connection_in(int connection_id, uint32_t seconds); 68int kill_connection_in(int connection_id, uint32_t seconds);
61 69
62/* returns the ip_port of the corresponding connection. 70/*
63 return 0 if there is no such connection. */ 71 * Returns the ip_port of the corresponding connection.
72 * Return 0 if there is no such connection.
73 */
64IP_Port connection_ip(int connection_id); 74IP_Port connection_ip(int connection_id);
65 75
66/* returns the id of the next packet in the queue 76/*
67 return -1 if no packet in queue */ 77 * Returns the id of the next packet in the queue
78 * Return -1 if no packet in queue
79 */
68char id_packet(int connection_id); 80char id_packet(int connection_id);
69 81
70/* return 0 if there is no received data in the buffer. 82/*
71 return length of received packet if successful */ 83 * Return 0 if there is no received data in the buffer.
84 * Return length of received packet if successful
85 */
72int read_packet(int connection_id, uint8_t *data); 86int read_packet(int connection_id, uint8_t *data);
73 87
74/* return 0 if data could not be put in packet queue 88/*
75 return 1 if data was put into the queue */ 89 * Return 0 if data could not be put in packet queue
90 * Return 1 if data was put into the queue
91 */
76int write_packet(int connection_id, uint8_t *data, uint32_t length); 92int write_packet(int connection_id, uint8_t *data, uint32_t length);
77 93
78/* returns the number of packets in the queue waiting to be successfully sent. */ 94/* Returns the number of packets in the queue waiting to be successfully sent. */
79uint32_t sendqueue(int connection_id); 95uint32_t sendqueue(int connection_id);
80 96
81/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */ 97/*
98 * returns the number of packets in the queue waiting to be successfully
99 * read with read_packet(...)
100 */
82uint32_t recvqueue(int connection_id); 101uint32_t recvqueue(int connection_id);
83 102
84/* check if connection is connected 103/* Check if connection is connected:
85 return 0 no. 104 * Return 0 no.
86 return 1 if attempting handshake 105 * Return 1 if attempting handshake.
87 return 2 if handshake is done 106 * Return 2 if handshake is done.
88 return 3 if fully connected 107 * Return 3 if fully connected.
89 return 4 if timed out and wating to be killed */ 108 * Return 4 if timed out and wating to be killed.
109 */
90int is_connected(int connection_id); 110int is_connected(int connection_id);
91 111
92/* Call this function a couple times per second 112/* Call this function a couple times per second It's the main loop. */
93 It's the main loop. */
94void doLossless_UDP(); 113void doLossless_UDP();
95 114
96 115/*
97/* if we receive a Lossless_UDP packet we call this function so it can be handled. 116 * If we receive a Lossless_UDP packet, call this function so it can be handled.
98 return 0 if packet is handled correctly. 117 * Return 0 if packet is handled correctly.
99 return 1 if it didn't handle the packet or if the packet was shit. */ 118 * Return 1 if it didn't handle the packet or if the packet was shit.
119 */
100int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); 120int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
101 121
102#ifdef __cplusplus 122#ifdef __cplusplus
diff --git a/core/Messenger.c b/core/Messenger.c
index eb59b81a..30f3f658 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -27,7 +27,7 @@
27typedef struct { 27typedef struct {
28 uint8_t client_id[CLIENT_ID_SIZE]; 28 uint8_t client_id[CLIENT_ID_SIZE];
29 int crypt_connection_id; 29 int crypt_connection_id;
30 int friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */ 30 int64_t friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */
31 uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */ 31 uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */
32 uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */ 32 uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */
33 uint8_t name[MAX_NAME_LENGTH]; 33 uint8_t name[MAX_NAME_LENGTH];
@@ -94,24 +94,31 @@ int getclient_id(int friend_id, uint8_t *client_id)
94 return -1; 94 return -1;
95} 95}
96 96
97/* add a friend 97/*
98 set the data that will be sent along with friend request 98 * add a friend
99 client_id is the client id of the friend 99 * set the data that will be sent along with friend request
100 data is the data and length is the length 100 * client_id is the client id of the friend
101 returns the friend number if success 101 * data is the data and length is the length
102 return -1 if key length is wrong. 102 * returns the friend number if success
103 return -2 if user's own key 103 * return -1 if message length is too long
104 return -3 if already a friend 104 * return -2 if no message (message length must be >= 1 byte)
105 return -4 for other*/ 105 * return -3 if user's own key
106 * return -4 if friend request already sent or already a friend
107 * return -5 for unknown error
108 */
106int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) 109int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
107{ 110{
108 if (length == 0 || length >= 111 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
109 (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) 112 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
113 + crypto_box_ZEROBYTES))
110 return -1; 114 return -1;
111 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 115 if (length < 1)
112 return -2; 116 return -2;
113 if (getfriend_id(client_id) != -1) 117 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
114 return -3; 118 return -3;
119 if (getfriend_id(client_id) != -1)
120 return -4;
121
115 uint32_t i; 122 uint32_t i;
116 for (i = 0; i <= numfriends; ++i) { /*TODO: dynamic memory allocation, this will segfault if there are more than MAX_NUM_FRIENDS*/ 123 for (i = 0; i <= numfriends; ++i) { /*TODO: dynamic memory allocation, this will segfault if there are more than MAX_NUM_FRIENDS*/
117 if(friendlist[i].status == 0) { 124 if(friendlist[i].status == 0) {
@@ -129,7 +136,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
129 return i; 136 return i;
130 } 137 }
131 } 138 }
132 return -4; 139 return -5;
133} 140}
134 141
135int m_addfriend_norequest(uint8_t * client_id) 142int m_addfriend_norequest(uint8_t * client_id)
@@ -484,7 +491,7 @@ static void doInbound()
484/*Interval in seconds between LAN discovery packet sending*/ 491/*Interval in seconds between LAN discovery packet sending*/
485#define LAN_DISCOVERY_INTERVAL 60 492#define LAN_DISCOVERY_INTERVAL 60
486 493
487static uint32_t last_LANdiscovery; 494static int64_t last_LANdiscovery;
488 495
489/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ 496/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
490static void LANdiscovery() 497static void LANdiscovery()
diff --git a/core/Messenger.h b/core/Messenger.h
index 9ce96fb4..3f144ff4 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -45,15 +45,18 @@ extern "C" {
45/* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased 45/* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased
46 to an absurdly large number later */ 46 to an absurdly large number later */
47 47
48/* add a friend 48/*
49 set the data that will be sent along with friend request 49 * add a friend
50 client_id is the client id of the friend 50 * set the data that will be sent along with friend request
51 data is the data and length is the length 51 * client_id is the client id of the friend
52 returns the friend number if success 52 * data is the data and length is the length
53 return -1 if key length is wrong. 53 * returns the friend number if success
54 return -2 if user's own key 54 * return -1 if message length is too long
55 return -3 if already a friend 55 * return -2 if no message (message length must be >= 1 byte)
56 return -4 for other*/ 56 * return -3 if user's own key
57 * return -4 if friend request already sent or already a friend
58 * return -5 for unknown error
59 */
57int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); 60int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length);
58 61
59 62
diff --git a/core/net_crypto.c b/core/net_crypto.c
index 83cb20a2..31fb24be 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -48,6 +48,12 @@ typedef struct {
48 48
49static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS]; 49static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS];
50 50
51#define CONN_NO_CONNECTION 0
52#define CONN_HANDSHAKE_SENT 1
53#define CONN_NOT_CONFIRMED 2
54#define CONN_ESTABLISHED 3
55#define CONN_TIMED_OUT 4
56
51#define MAX_INCOMING 64 57#define MAX_INCOMING 64
52 58
53/* keeps track of the connection numbers for friends request so we can check later if they were sent */ 59/* keeps track of the connection numbers for friends request so we can check later if they were sent */
@@ -75,10 +81,9 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
75 uint32_t i; 81 uint32_t i;
76 uint32_t check = 0; 82 uint32_t check = 0;
77 for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) { 83 for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) {
78 if (temp_encrypted[i] != 0) 84 check |= temp_encrypted[i] ^ 0;
79 check = 1;
80 } 85 }
81 if(check == 1) 86 if(check != 0)
82 return -1; 87 return -1;
83 88
84 /* unpad the encrypted message */ 89 /* unpad the encrypted message */
@@ -110,10 +115,9 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
110 uint32_t i; 115 uint32_t i;
111 uint32_t check = 0; 116 uint32_t check = 0;
112 for(i = 0; i < crypto_box_ZEROBYTES; ++i) { 117 for(i = 0; i < crypto_box_ZEROBYTES; ++i) {
113 if (temp_plain[i] != 0) 118 check |= temp_plain[i] ^ 0;
114 check = 1;
115 } 119 }
116 if(check == 1) 120 if(check != 0)
117 return -1; 121 return -1;
118 122
119 /* unpad the plain message */ 123 /* unpad the plain message */
@@ -149,7 +153,7 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
149{ 153{
150 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 154 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
151 return 0; 155 return 0;
152 if (crypto_connections[crypt_connection_id].status != 3) 156 if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
153 return 0; 157 return 0;
154 uint8_t temp_data[MAX_DATA_SIZE]; 158 uint8_t temp_data[MAX_DATA_SIZE];
155 int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data); 159 int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data);
@@ -175,7 +179,7 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length)
175 return 0; 179 return 0;
176 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1) 180 if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
177 return 0; 181 return 0;
178 if (crypto_connections[crypt_connection_id].status != 3) 182 if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
179 return 0; 183 return 0;
180 uint8_t temp_data[MAX_DATA_SIZE]; 184 uint8_t temp_data[MAX_DATA_SIZE];
181 int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key, 185 int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
@@ -295,7 +299,7 @@ int getcryptconnection_id(uint8_t *public_key)
295{ 299{
296 uint32_t i; 300 uint32_t i;
297 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 301 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
298 if (crypto_connections[i].status > 0) 302 if (crypto_connections[i].status != CONN_NO_CONNECTION)
299 if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) 303 if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
300 return i; 304 return i;
301 } 305 }
@@ -315,12 +319,12 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
315 return -1; 319 return -1;
316 } 320 }
317 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 321 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
318 if (crypto_connections[i].status == 0) { 322 if (crypto_connections[i].status == CONN_NO_CONNECTION) {
319 int id = new_connection(ip_port); 323 int id = new_connection(ip_port);
320 if (id == -1) 324 if (id == -1)
321 return -1; 325 return -1;
322 crypto_connections[i].number = id; 326 crypto_connections[i].number = id;
323 crypto_connections[i].status = 1; 327 crypto_connections[i].status = CONN_HANDSHAKE_SENT;
324 random_nonce(crypto_connections[i].recv_nonce); 328 random_nonce(crypto_connections[i].recv_nonce);
325 memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES); 329 memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
326 crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key); 330 crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key);
@@ -374,8 +378,8 @@ int crypto_kill(int crypt_connection_id)
374{ 378{
375 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS) 379 if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
376 return 1; 380 return 1;
377 if (crypto_connections[crypt_connection_id].status != 0) { 381 if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) {
378 crypto_connections[crypt_connection_id].status = 0; 382 crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION;
379 kill_connection(crypto_connections[crypt_connection_id].number); 383 kill_connection(crypto_connections[crypt_connection_id].number);
380 memset(&crypto_connections[crypt_connection_id], 0 ,sizeof(Crypto_Connection)); 384 memset(&crypto_connections[crypt_connection_id], 0 ,sizeof(Crypto_Connection));
381 crypto_connections[crypt_connection_id].number = ~0; 385 crypto_connections[crypt_connection_id].number = ~0;
@@ -398,9 +402,9 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
398 return -1; 402 return -1;
399 }*/ 403 }*/
400 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 404 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
401 if(crypto_connections[i].status == 0) { 405 if(crypto_connections[i].status == CONN_NO_CONNECTION) {
402 crypto_connections[i].number = connection_id; 406 crypto_connections[i].number = connection_id;
403 crypto_connections[i].status = 2; 407 crypto_connections[i].status = CONN_NOT_CONFIRMED;
404 random_nonce(crypto_connections[i].recv_nonce); 408 random_nonce(crypto_connections[i].recv_nonce);
405 memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES); 409 memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
406 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); 410 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
@@ -413,9 +417,9 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
413 crypto_connections[i].sessionpublic_key) == 1) { 417 crypto_connections[i].sessionpublic_key) == 1) {
414 increment_nonce(crypto_connections[i].recv_nonce); 418 increment_nonce(crypto_connections[i].recv_nonce);
415 uint32_t zero = 0; 419 uint32_t zero = 0;
416 crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */ 420 crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
417 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); 421 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
418 crypto_connections[i].status = 2; /* set it to its proper value right after. */ 422 crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */
419 return i; 423 return i;
420 } 424 }
421 return -1; /* this should never happen. */ 425 return -1; /* this should never happen. */
@@ -431,7 +435,7 @@ int is_cryptoconnected(int crypt_connection_id)
431{ 435{
432 if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS) 436 if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS)
433 return crypto_connections[crypt_connection_id].status; 437 return crypto_connections[crypt_connection_id].status;
434 return 0; 438 return CONN_NO_CONNECTION;
435} 439}
436 440
437/* Generate our public and private keys 441/* Generate our public and private keys
@@ -490,7 +494,7 @@ static void receive_crypto()
490{ 494{
491 uint32_t i; 495 uint32_t i;
492 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 496 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
493 if (crypto_connections[i].status == 1) { 497 if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) {
494 uint8_t temp_data[MAX_DATA_SIZE]; 498 uint8_t temp_data[MAX_DATA_SIZE];
495 uint8_t secret_nonce[crypto_box_NONCEBYTES]; 499 uint8_t secret_nonce[crypto_box_NONCEBYTES];
496 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 500 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
@@ -507,17 +511,17 @@ static void receive_crypto()
507 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES); 511 memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
508 increment_nonce(crypto_connections[i].sent_nonce); 512 increment_nonce(crypto_connections[i].sent_nonce);
509 uint32_t zero = 0; 513 uint32_t zero = 0;
510 crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */ 514 crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
511 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero)); 515 write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
512 crypto_connections[i].status = 2; /* set it to its proper value right after. */ 516 crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */
513 } 517 }
514 } 518 }
515 } else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does 519 } else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does
516 crypto_kill(crypto_connections[i].number); 520 crypto_kill(crypto_connections[i].number);
517 521
518 } 522 }
519 if (crypto_connections[i].status == 2) { 523 if (crypto_connections[i].status == CONN_NOT_CONFIRMED) {
520 if (id_packet(crypto_connections[i].number) == 3) { 524 if (id_packet(crypto_connections[i].number) == CONN_ESTABLISHED) {
521 uint8_t temp_data[MAX_DATA_SIZE]; 525 uint8_t temp_data[MAX_DATA_SIZE];
522 uint8_t data[MAX_DATA_SIZE]; 526 uint8_t data[MAX_DATA_SIZE];
523 int length = read_packet(crypto_connections[i].number, temp_data); 527 int length = read_packet(crypto_connections[i].number, temp_data);
@@ -527,7 +531,7 @@ static void receive_crypto()
527 uint32_t zero = 0; 531 uint32_t zero = 0;
528 if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) { 532 if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
529 increment_nonce(crypto_connections[i].recv_nonce); 533 increment_nonce(crypto_connections[i].recv_nonce);
530 crypto_connections[i].status = 3; 534 crypto_connections[i].status = CONN_ESTABLISHED;
531 535
532 /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */ 536 /* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */
533 kill_connection_in(crypto_connections[i].number, 3000000); 537 kill_connection_in(crypto_connections[i].number, 3000000);
@@ -556,8 +560,8 @@ static void killTimedout()
556{ 560{
557 uint32_t i; 561 uint32_t i;
558 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) { 562 for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
559 if (crypto_connections[i].status != 0 && is_connected(crypto_connections[i].number) == 4) 563 if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4)
560 crypto_connections[i].status = 4; 564 crypto_connections[i].status = CONN_TIMED_OUT;
561 else if (is_connected(crypto_connections[i].number) == 4) { 565 else if (is_connected(crypto_connections[i].number) == 4) {
562 kill_connection(crypto_connections[i].number); 566 kill_connection(crypto_connections[i].number);
563 crypto_connections[i].number = ~0; 567 crypto_connections[i].number = ~0;
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
new file mode 100644
index 00000000..14126cfd
--- /dev/null
+++ b/docs/CMakeLists.txt
@@ -0,0 +1,40 @@
1# cmake should not fail if sphinx is missing
2find_package(Sphinx)
3
4if(SPHINX_EXECUTABLE)
5
6 if(NOT DEFINED SPHINX_THEME)
7 set(SPHINX_THEME default)
8 endif()
9
10 if(NOT DEFINED SPHINX_THEME_DIR)
11 set(SPHINX_THEME_DIR)
12 endif()
13
14 # configured documentation tools and intermediate build results
15 set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_build")
16
17 # Sphinx cache with pickled ReST documents
18 set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees")
19
20 # HTML output directory
21 set(SPHINX_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/html")
22
23 configure_file(
24 "${CMAKE_CURRENT_SOURCE_DIR}/conf.py"
25 "${BINARY_BUILD_DIR}/conf.py"
26 @ONLY)
27
28 add_custom_target(docs
29 ${SPHINX_EXECUTABLE}
30 -b html
31 -c "${BINARY_BUILD_DIR}"
32 "${CMAKE_CURRENT_SOURCE_DIR}"
33 "${SPHINX_HTML_DIR}"
34 COMMENT "Building HTML documentation with Sphinx")
35else()
36 add_custom_target(docs
37 echo
38 "Please install python-sphinx to build the docs or read the docs online: https://projecttox.readthedocs.org/en/latest"
39 COMMENT "No sphinx executebale found")
40endif()
diff --git a/docs/commands.md b/docs/commands.md
deleted file mode 100644
index 8669bb9b..00000000
--- a/docs/commands.md
+++ /dev/null
@@ -1,25 +0,0 @@
1# Tox User Commands
2Here's a list of commands that nTox accepts,
3which can all be used by starting your line with
4a */*. Currently there can be no spaces before this.
5
6* */f* [ID]
7 + Add a friend with ID [ID].
8* */d*
9 + Call doMessenger() which does...something?
10* */m* \[FRIEND\_NUM\] \[MESSAGE\]
11 + Message \[FRIEND\_NUM\] \[MESSAGE\].
12* */n* \[NAME\]
13 + Change your username to \[NAME\].
14* */l*
15 + Print your list of friends. (like you have any)
16* */s* \[STATUS\]
17 + Set your status to \[STATUS\].
18* */a* \[ID\]
19 + Accept friend request from \[ID\].
20* */i*
21 + Print useful info about your client.
22* */h*
23 + Print some help.
24* */q/*
25 + Quit Tox. (why ;_;)
diff --git a/docs/commands.rst b/docs/commands.rst
new file mode 100644
index 00000000..ab7e60d1
--- /dev/null
+++ b/docs/commands.rst
@@ -0,0 +1,48 @@
1Tox User Commands
2=================
3
4Here's a list of commands that nTox accepts, which can all be used by
5starting your line with a */*. Currently there can be no spaces before
6this.
7
8- */f* [ID]
9
10 - Add a friend with ID [ID].
11
12- */d*
13
14 - Call doMessenger() which does...something?
15
16- */m* [FRIEND\_NUM] [MESSAGE]
17
18 - Message [FRIEND\_NUM] [MESSAGE].
19
20- */n* [NAME]
21
22 - Change your username to [NAME].
23
24- */l*
25
26 - Print your list of friends. (like you have any)
27
28- */s* [STATUS]
29
30 - Set your status to [STATUS].
31
32- */a* [ID]
33
34 - Accept friend request from [ID].
35
36- */i*
37
38 - Print useful info about your client.
39
40- */h*
41
42 - Print some help.
43
44- */q/*
45
46 - Quit Tox. (why ;\_;)
47
48
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 00000000..afebb632
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,242 @@
1# -*- coding: utf-8 -*-
2#
3# ProjectTox documentation build configuration file, created by
4# sphinx-quickstart on Wed Jul 31 23:07:35 2013.
5#
6# This file is execfile()d with the current directory set to its containing dir.
7#
8# Note that not all possible configuration values are present in this
9# autogenerated file.
10#
11# All configuration values have a default; values that are commented out
12# serve to show the default.
13
14import sys, os
15
16# If extensions (or modules to document with autodoc) are in another directory,
17# add these directories to sys.path here. If the directory is relative to the
18# documentation root, use os.path.abspath to make it absolute, like shown here.
19#sys.path.insert(0, os.path.abspath('.'))
20
21# -- General configuration -----------------------------------------------------
22
23# If your documentation needs a minimal Sphinx version, state it here.
24#needs_sphinx = '1.0'
25
26# Add any Sphinx extension module names here, as strings. They can be extensions
27# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
28extensions = []
29
30# Add any paths that contain templates here, relative to this directory.
31templates_path = ['_templates']
32
33# The suffix of source filenames.
34source_suffix = '.rst'
35
36# The encoding of source files.
37#source_encoding = 'utf-8-sig'
38
39# The master toctree document.
40master_doc = 'index'
41
42# General information about the project.
43project = u'ProjectTox'
44copyright = u'2013, Tox Team'
45
46# The version info for the project you're documenting, acts as replacement for
47# |version| and |release|, also used in various other places throughout the
48# built documents.
49#
50# The short X.Y version.
51version = '0.1'
52# The full version, including alpha/beta/rc tags.
53release = '0.1'
54
55# The language for content autogenerated by Sphinx. Refer to documentation
56# for a list of supported languages.
57#language = None
58
59# There are two options for replacing |today|: either, you set today to some
60# non-false value, then it is used:
61#today = ''
62# Else, today_fmt is used as the format for a strftime call.
63#today_fmt = '%B %d, %Y'
64
65# List of patterns, relative to source directory, that match files and
66# directories to ignore when looking for source files.
67exclude_patterns = ['_build']
68
69# The reST default role (used for this markup: `text`) to use for all documents.
70#default_role = None
71
72# If true, '()' will be appended to :func: etc. cross-reference text.
73#add_function_parentheses = True
74
75# If true, the current module name will be prepended to all description
76# unit titles (such as .. function::).
77#add_module_names = True
78
79# If true, sectionauthor and moduleauthor directives will be shown in the
80# output. They are ignored by default.
81#show_authors = False
82
83# The name of the Pygments (syntax highlighting) style to use.
84pygments_style = 'sphinx'
85
86# A list of ignored prefixes for module index sorting.
87#modindex_common_prefix = []
88
89
90# -- Options for HTML output ---------------------------------------------------
91
92# The theme to use for HTML and HTML Help pages. See the documentation for
93# a list of builtin themes.
94html_theme = 'default'
95
96# Theme options are theme-specific and customize the look and feel of a theme
97# further. For a list of options available for each theme, see the
98# documentation.
99#html_theme_options = {}
100
101# Add any paths that contain custom themes here, relative to this directory.
102#html_theme_path = []
103
104# The name for this set of Sphinx documents. If None, it defaults to
105# "<project> v<release> documentation".
106#html_title = None
107
108# A shorter title for the navigation bar. Default is the same as html_title.
109#html_short_title = None
110
111# The name of an image file (relative to this directory) to place at the top
112# of the sidebar.
113#html_logo = None
114
115# The name of an image file (within the static path) to use as favicon of the
116# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
117# pixels large.
118#html_favicon = None
119
120# Add any paths that contain custom static files (such as style sheets) here,
121# relative to this directory. They are copied after the builtin static files,
122# so a file named "default.css" will overwrite the builtin "default.css".
123html_static_path = ['_static']
124
125# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
126# using the given strftime format.
127#html_last_updated_fmt = '%b %d, %Y'
128
129# If true, SmartyPants will be used to convert quotes and dashes to
130# typographically correct entities.
131#html_use_smartypants = True
132
133# Custom sidebar templates, maps document names to template names.
134#html_sidebars = {}
135
136# Additional templates that should be rendered to pages, maps page names to
137# template names.
138#html_additional_pages = {}
139
140# If false, no module index is generated.
141#html_domain_indices = True
142
143# If false, no index is generated.
144#html_use_index = True
145
146# If true, the index is split into individual pages for each letter.
147#html_split_index = False
148
149# If true, links to the reST sources are added to the pages.
150#html_show_sourcelink = True
151
152# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
153#html_show_sphinx = True
154
155# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
156#html_show_copyright = True
157
158# If true, an OpenSearch description file will be output, and all pages will
159# contain a <link> tag referring to it. The value of this option must be the
160# base URL from which the finished HTML is served.
161#html_use_opensearch = ''
162
163# This is the file name suffix for HTML files (e.g. ".xhtml").
164#html_file_suffix = None
165
166# Output file base name for HTML help builder.
167htmlhelp_basename = 'ProjectToxdoc'
168
169
170# -- Options for LaTeX output --------------------------------------------------
171
172latex_elements = {
173# The paper size ('letterpaper' or 'a4paper').
174#'papersize': 'letterpaper',
175
176# The font size ('10pt', '11pt' or '12pt').
177#'pointsize': '10pt',
178
179# Additional stuff for the LaTeX preamble.
180#'preamble': '',
181}
182
183# Grouping the document tree into LaTeX files. List of tuples
184# (source start file, target name, title, author, documentclass [howto/manual]).
185latex_documents = [
186 ('index', 'ProjectTox.tex', u'ProjectTox Documentation',
187 u'Tox Team', 'manual'),
188]
189
190# The name of an image file (relative to this directory) to place at the top of
191# the title page.
192#latex_logo = None
193
194# For "manual" documents, if this is true, then toplevel headings are parts,
195# not chapters.
196#latex_use_parts = False
197
198# If true, show page references after internal links.
199#latex_show_pagerefs = False
200
201# If true, show URL addresses after external links.
202#latex_show_urls = False
203
204# Documents to append as an appendix to all manuals.
205#latex_appendices = []
206
207# If false, no module index is generated.
208#latex_domain_indices = True
209
210
211# -- Options for manual page output --------------------------------------------
212
213# One entry per manual page. List of tuples
214# (source start file, name, description, authors, manual section).
215man_pages = [
216 ('index', 'projecttox', u'ProjectTox Documentation',
217 [u'Tox Team'], 1)
218]
219
220# If true, show URL addresses after external links.
221#man_show_urls = False
222
223
224# -- Options for Texinfo output ------------------------------------------------
225
226# Grouping the document tree into Texinfo files. List of tuples
227# (source start file, target name, title, author,
228# dir menu entry, description, category)
229texinfo_documents = [
230 ('index', 'ProjectTox', u'ProjectTox Documentation',
231 u'Tox Team', 'ProjectTox', 'One line description of project.',
232 'Miscellaneous'),
233]
234
235# Documents to append as an appendix to all manuals.
236#texinfo_appendices = []
237
238# If false, no module index is generated.
239#texinfo_domain_indices = True
240
241# How to display URL addresses: 'footnote', 'no', or 'inline'.
242#texinfo_show_urls = 'footnote'
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 00000000..10e0d1d2
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,25 @@
1.. ProjectTox documentation master file, created by
2 sphinx-quickstart on Wed Jul 31 23:07:35 2013.
3 You can adapt this file completely to your liking, but it should at least
4 contain the root `toctree` directive.
5
6Welcome to ProjectTox's documentation!
7======================================
8
9Contents:
10
11.. toctree::
12 start_guide.rst
13 install.rst
14 commands.rst
15 :maxdepth: 2
16
17
18
19Indices and tables
20==================
21
22* :ref:`genindex`
23* :ref:`modindex`
24* :ref:`search`
25
diff --git a/docs/install.rst b/docs/install.rst
new file mode 100644
index 00000000..c5fea5d1
--- /dev/null
+++ b/docs/install.rst
@@ -0,0 +1,129 @@
1Install Instructions
2====================
3
4Linux
5---------
6
7First, install the build dependencies ::
8
9 bash apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev cmake checkinstall
10
11.. note :: ``libconfig-dev`` should be >= 1.4.
12
13
14Then you'll need a recent version of `libsodium <https://github.com/jedisct1/libsodium>`_ ::
15
16 git clone git://github.com/jedisct1/libsodium.git
17 cd libsodium
18 git checkout tags/0.4.2
19 ./autogen.sh
20 ./configure && make check
21 sudo checkinstall --install --pkgname libsodium --pkgversion 0.4.2 --nodoc
22 sudo ldconfig``
23
24Finally, fetch the Tox source code and run cmake ::
25
26 git clone git://github.com/irungentoo/ProjectTox-Core.git
27 cd ProjectTox-Core && mkdir build && cd build
28 cmake ..
29
30Then you can build any of the files in `/testing`_ and `/other`_ that are currently
31supported on your platform by running ::
32
33 make name_of_c_file
34
35For example, to build `Messenger_test.c`_ you would run ::
36
37 make Messenger_test
38
39
40Or you could just build everything that is supported on your platform by
41running ::
42 bash make
43
44OS X
45------
46
47Homebrew
48~~~~~~~~~~
49::
50
51 brew install libtool automake autoconf libconfig libsodium cmake
52 cmake .
53 make
54 sudo make install
55
56Non-homebrew
57~~~~~~~~~~~~
58
59Much the same as Linux, remember to install the latest XCode and the
60developer tools (Preferences -> Downloads -> Command Line Tools). Users
61running Mountain Lion and the latest version of XCode (4.6.3) will also
62need to install libtool, automake and autoconf. They are easy enough to
63install, grab them from http://www.gnu.org/software/libtool/,
64http://www.gnu.org/software/autoconf/ and
65http://www.gnu.org/software/automake/, then follow these steps for each:
66
67::
68
69 ./configure
70 make
71 sudo make install
72
73Do not install them from macports (or any dependencies for that matter)
74as they get shoved in the wrong directory and make your life more
75annoying.
76
77Another thing you may want to install is the latest gcc, this caused me
78a few problems as XCode from 4.3 no longer includes gcc and instead uses
79LLVM-GCC, a nice install guide can be found at
80http://caiustheory.com/install-gcc-421-apple-build-56663-with-xcode-42
81
82Windows
83---------
84
85You should install:
86
87* `MinGW <http://sourceforge.net/projects/mingw/>`_'s C compiler
88* `CMake <http://www.cmake.org/cmake/resources/software.html>`_
89
90You have to `modify your PATH environment
91variable <http://www.computerhope.com/issues/ch000549.htm>`_ so that it
92contains MinGW's bin folder path. With default settings, the bin folder
93is located at ``C:\MinGW\bin``, which means that you would have to
94append ``;C:\MinGW\bin`` to the PATH variable.
95
96Then you should either clone this repo by using git, or just download a
97`zip of current Master
98branch <https://github.com/irungentoo/ProjectTox-Core/archive/master.zip>`_
99and extract it somewhere.
100
101After that you should get precompiled package of libsodium from
102`here <https://download.libsodium.org/libsodium/releases/libsodium-win32-0.4.2.tar.gz>`_
103and extract the archive into this repo's root. That is, ``sodium``
104folder should be along with ``core``, ``testing`` and other folders.
105
106Navigate in ``cmd`` to this repo and run::
107
108 mkdir build && cd build
109 cmake -G "MinGW Makefiles" ..
110
111Then you can build any of the `/testing`_ and `/other`_ that are currently
112supported on your platform by running::
113
114 mingw32-make name_of_c_file
115
116For example, to build `Messenger_test.c`_ you would run::
117
118 mingw32-make Messenger_test``
119
120Or you could just build everything that is supported on your platform by
121running::
122
123 mingw32-make
124
125
126.. _/testing: https://github.com/irungentoo/ProjectTox-Core/tree/master/testing
127.. _/other: https://github.com/irungentoo/ProjectTox-Core/tree/master/other
128
129.. _Messenger_test.c: https://github.com/irungentoo/ProjectTox-Core/tree/master/other/Messanger_test.c
diff --git a/docs/start_guide.de.md b/docs/start_guide.de.md
deleted file mode 100644
index 7dfd52ca..00000000
--- a/docs/start_guide.de.md
+++ /dev/null
@@ -1,40 +0,0 @@
1# Tox nutzen
21. Tox erstellen
32. Fehler korrigieren
43. Im IRC nach Hilfe fragen
54. Auf Debug-Reise für Entwickler
65. Tox wirklich erstellen
76. ???
8
9Trotz der ganzen Arbeit, die wir bisher in Tox
10gesteckt haben, gibt es noch keine richtige
11Anleitung, wie man Tox _benutzt_.
12Dies ist ein anwenderfreundlicher Versuch.
13
141. Verbinde dich zum Netzwerk!
15 + Du musst dich zu einem Bootstrap-Server verbinden, um einen öffentlichen Schlüssel zu erhalten.
16 + Wo finde ich einen öffentlichen Server? Zur Zeit hier:
17 (die Hilfe-Nachricht von nTox ohne Kommandos hilft auch)
18 + 198.46.136.167 33445 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854
19 + 192.81.133.111 33445 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858
20 + 66.175.223.88 33445 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D
21 + 192.184.81.118 33445 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143
222. Finde einen Freund!
23 + Jetzt, da du im Netzwerk bist, brauchst du einen Freund. Um einen zu bekommen,
24 musst du eine Anfrage senden oder erhalten. Was eine Anfrage ist?
25 Es ist wie eine Freundschaftsanfrage, jedoch benutzen wir unglaublich schaurige
26 und kryptische Nummern anstatt Namen. When nTox startet, erscheint _deine_ lange,
27 schaurige Nummer, auch *öffentlicher Schlüssel* genannt. Diesen kannst du an
28 andere Personen weitergeben und sie können dich als "Freund" hinzufügen. Oder du
29 fügst andere Personen mit dem */f*-Befehl hinzu, wenn du möchtest.
303. Chatte drauf los!
31 + Benutze nun den */m*-Befehl, um eine Nachricht an jemanden zu senden. Wow, du chattest!
324. Mach etwas kaputt!
33 + Jep, pre-alpha-alpha-Software stürzt manchmal ab. Wir arbeiten daran.
34 + Bitte melde alle Abstürze entweder an die GitHub-Seite oder #tox-dev im freenode-IRC.
355. Nichts ist kaputt, aber was bedeutet */f*?
36 + nTox liest einen Text als Befehl, wenn das erste Zeichen ein Schrägstrich ist ('/').
37 Du kannst alle Befehle in commands.md nachlesen.
386. Benutze und unterstütze Tox!
39 + Programmiere, debugge, dokumentiere, übersetze für uns, oder sprich einfach über uns!
40 + Je mehr Interesse wir erhalten, desto mehr Arbeit wird getan und desto besser wird Tox.
diff --git a/docs/start_guide.de.rst b/docs/start_guide.de.rst
new file mode 100644
index 00000000..4ebe7dc6
--- /dev/null
+++ b/docs/start_guide.de.rst
@@ -0,0 +1,66 @@
1Tox nutzen
2==========
3
41. :doc:`Tox erstellen <install>`
52. Fehler korrigieren
63. Im IRC nach Hilfe fragen
74. Auf Debug-Reise für Entwickler
85. Tox wirklich erstellen
96. ???
10
11Trotz der ganzen Arbeit, die wir bisher in Tox gesteckt haben, gibt es
12noch keine richtige Anleitung, wie man Tox *benutzt*. Dies ist ein
13anwenderfreundlicher Versuch.
14
151. Verbinde dich zum Netzwerk!
16
17 - Du musst dich zu einem Bootstrap-Server verbinden, um einen
18 öffentlichen Schlüssel zu erhalten.
19 - Wo finde ich einen öffentlichen Server? Zur Zeit hier: (die
20 Hilfe-Nachricht von nTox ohne Kommandos hilft auch)
21
22 - 198.46.136.167 33445
23 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854
24 - 192.81.133.111 33445
25 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858
26 - 66.175.223.88 33445
27 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D
28 - 192.184.81.118 33445
29 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143
30
312. Finde einen Freund!
32
33 - Jetzt, da du im Netzwerk bist, brauchst du einen Freund. Um einen
34 zu bekommen, musst du eine Anfrage senden oder erhalten. Was eine
35 Anfrage ist? Es ist wie eine Freundschaftsanfrage, jedoch benutzen
36 wir unglaublich schaurige und kryptische Nummern anstatt Namen.
37 When nTox startet, erscheint *deine* lange, schaurige Nummer, auch
38 *öffentlicher Schlüssel* genannt. Diesen kannst du an andere
39 Personen weitergeben und sie können dich als "Freund" hinzufügen.
40 Oder du fügst andere Personen mit dem */f*-Befehl hinzu, wenn du
41 möchtest.
42
433. Chatte drauf los!
44
45 - Benutze nun den */m*-Befehl, um eine Nachricht an jemanden zu
46 senden. Wow, du chattest!
47
484. Mach etwas kaputt!
49
50 - Jep, pre-alpha-alpha-Software stürzt manchmal ab. Wir arbeiten
51 daran.
52 - Bitte melde alle Abstürze entweder an die GitHub-Seite oder
53 #tox-dev im freenode-IRC.
54
555. Nichts ist kaputt, aber was bedeutet */f*?
56
57 - nTox liest einen Text als Befehl, wenn das erste Zeichen ein
58 Schrägstrich ist ('/'). Du kannst alle Befehle in commands.md
59 nachlesen.
60
616. Benutze und unterstütze Tox!
62
63 - Programmiere, debugge, dokumentiere, übersetze für uns, oder
64 sprich einfach über uns!
65 - Je mehr Interesse wir erhalten, desto mehr Arbeit wird getan und
66 desto besser wird Tox.
diff --git a/docs/start_guide.md b/docs/start_guide.md
deleted file mode 100644
index 9ced4078..00000000
--- a/docs/start_guide.md
+++ /dev/null
@@ -1,38 +0,0 @@
1# Using Tox
21. [Build Tox](../INSTALL.md)
32. Fix errors
43. Consult IRC for help
54. Go on debugging journey for devs
65. Build Tox for real
76. ???
8
9For all the work we've put into Tox so far,
10there isn't yet a decent guide for how you _use_
11Tox. Here's a user-friendly attempt at it.
12
131. Connect to the network!
14 + You need to connect to a bootstrapping server, to give you a public key.
15 + Where can I find a public server? Right here, as of now:
16 (the help message from running `nTox` with no args will help)
17 + `198.46.136.167 33445 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854`
18 + `192.81.133.111 33445 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858`
19 + `66.175.223.88 33445 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D`
20 + `192.184.81.118 33445 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143`
212. Find a friend!
22 + Now that you're on the network, you need a friend. To get one of those,
23 you need to to send or receive a request. What's a request, you ask?
24 It's like a friend request, but we use really scary and cryptic numbers
25 instead of names. When `nTox` starts, it shows _your_ long, scary number,
26 called your *public key*. Give that to people, and they can add you as
27 a "friend". Or, you can add someone else, with the `/f` command, if you like.
283. Chat it up!
29 + Now use the `/m` command to send a message to someone. Wow, you're chatting!
304. But something broke!
31 + Yeah, pre-alpha-alpha software tends to do that. We're working on it.
32 + Please report all crashes to either the GitHub page, or `#tox-dev` on freenode.
335. Nothing broke, but what does `/f` mean?
34 + `nTox` parses text as a command if the first character is a forward-slash (`/`).
35 You can check all commands in commands.md.
366. Use and support Tox!
37 + Code for us, debug for us, document for us, translate for us, even just talk about us!
38 + The more interest we get, the more work gets done, the better Tox is.
diff --git a/docs/start_guide.rst b/docs/start_guide.rst
new file mode 100644
index 00000000..19ef982e
--- /dev/null
+++ b/docs/start_guide.rst
@@ -0,0 +1,63 @@
1Using Tox
2=========
3
4.. note:: There is a German version of this page available: :doc:`start_guide.de`
5
6
71. :doc:`Build Tox <install>`
82. Fix errors
93. Consult IRC for help
104. Go on debugging journey for devs
115. Build Tox for real
126. ???
13
14For all the work we've put into Tox so far, there isn't yet a decent
15guide for how you *use* Tox. Here's a user-friendly attempt at it.
16
171. Connect to the network!
18
19 - You need to connect to a bootstrapping server, to give you a
20 public key.
21 - Where can I find a public server? Right here, as of now: (the help
22 message from running ``nTox`` with no args will help)
23
24 - ``198.46.136.167 33445 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854``
25 - ``192.81.133.111 33445 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858``
26 - ``66.175.223.88 33445 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D``
27 - ``192.184.81.118 33445 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143``
28
292. Find a friend!
30
31 - Now that you're on the network, you need a friend. To get one of
32 those, you need to to send or receive a request. What's a request,
33 you ask? It's like a friend request, but we use really scary and
34 cryptic numbers instead of names. When ``nTox`` starts, it shows
35 *your* long, scary number, called your *public key*. Give that to
36 people, and they can add you as a "friend". Or, you can add
37 someone else, with the ``/f`` command, if you like.
38
393. Chat it up!
40
41 - Now use the ``/m`` command to send a message to someone. Wow,
42 you're chatting!
43
444. But something broke!
45
46 - Yeah, pre-alpha-alpha software tends to do that. We're working on
47 it.
48 - Please report all crashes to either the GitHub page, or
49 ``#tox-dev`` on freenode.
50
515. Nothing broke, but what does ``/f`` mean?
52
53 - ``nTox`` parses text as a command if the first character is a
54 forward-slash (``/``). You can check all commands in commands.md.
55
566. Use and support Tox!
57
58 - Code for us, debug for us, document for us, translate for us, even
59 just talk about us!
60 - The more interest we get, the more work gets done, the better Tox
61 is.
62
63
diff --git a/testing/nTox.c b/testing/nTox.c
index f87a2a25..81cac0b6 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -89,7 +89,12 @@ char *format_message(char *message, int friendnum)
89 char* time = asctime(timeinfo); 89 char* time = asctime(timeinfo);
90 size_t len = strlen(time); 90 size_t len = strlen(time);
91 time[len-1] = '\0'; 91 time[len-1] = '\0';
92 sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message); // timestamp 92 if (friendnum != -1) {
93 sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message);
94 } else {
95 // This message came from ourselves
96 sprintf(msg, "%s <%s> %s", time, name, message);
97 }
93 return msg; 98 return msg;
94} 99}
95 100
@@ -106,24 +111,28 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
106 char temp_id[128]; 111 char temp_id[128];
107 for (i = 0; i < 128; i++) 112 for (i = 0; i < 128; i++)
108 temp_id[i] = line[i+prompt_offset]; 113 temp_id[i] = line[i+prompt_offset];
114
109 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); 115 int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
110 char numstring[100]; 116 char numstring[100];
111 switch (num) { 117 switch (num) {
112 case -1: 118 case -1:
113 sprintf(numstring, "[i] Incorrect key length"); 119 sprintf(numstring, "[i] Message is too long.");
114 break; 120 break;
115 case -2: 121 case -2:
116 sprintf(numstring, "[i] That appears to be your own key"); 122 sprintf(numstring, "[i] Please add a message to your request.");
117 break; 123 break;
118 case -3: 124 case -3:
119 sprintf(numstring, "[i] Friend request already sent"); 125 sprintf(numstring, "[i] That appears to be your own ID.");
120 break; 126 break;
121 case -4: 127 case -4:
122 sprintf(numstring, "[i] Could not add friend"); 128 sprintf(numstring, "[i] Friend request already sent.");
123 break; 129 break;
124 default: 130 case -5:
125 sprintf(numstring, "[i] Added friend %d", num); 131 sprintf(numstring, "[i] Undefined error when adding friend.");
126 break; 132 break;
133 default:
134 sprintf(numstring, "[i] Added friend as %d.", num);
135 break;
127 } 136 }
128 new_lines(numstring); 137 new_lines(numstring);
129 do_refresh(); 138 do_refresh();
@@ -133,6 +142,9 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
133 } 142 }
134 else if (inpt_command == 'm') { //message command: /m friendnumber messsage 143 else if (inpt_command == 'm') { //message command: /m friendnumber messsage
135 size_t len = strlen(line); 144 size_t len = strlen(line);
145 if(len < 3)
146 return;
147
136 char numstring[len-3]; 148 char numstring[len-3];
137 char message[len-3]; 149 char message[len-3];
138 int i; 150 int i;
@@ -141,13 +153,13 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
141 numstring[i] = line[i+3]; 153 numstring[i] = line[i+3];
142 } else { 154 } else {
143 int j; 155 int j;
144 for (j = (i+1); j < len; j++) 156 for (j = (i+1); j < (len+1); j++)
145 message[j-i-1] = line[j+3]; 157 message[j-i-1] = line[j+3];
146 break; 158 break;
147 } 159 }
148 } 160 }
149 int num = atoi(numstring); 161 int num = atoi(numstring);
150 if (m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1) { 162 if (m_sendmessage(num, (uint8_t*) message, strlen(message) + 1) != 1) {
151 new_lines("[i] could not send message"); 163 new_lines("[i] could not send message");
152 } else { 164 } else {
153 new_lines(format_message(message, -1)); 165 new_lines(format_message(message, -1));
@@ -162,7 +174,7 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
162 name[i-3] = line[i]; 174 name[i-3] = line[i];
163 } 175 }
164 name[i-3] = 0; 176 name[i-3] = 0;
165 setname(name, i); 177 setname(name, i - 2);
166 char numstring[100]; 178 char numstring[100];
167 sprintf(numstring, "[i] changed nick to %s", (char*)name); 179 sprintf(numstring, "[i] changed nick to %s", (char*)name);
168 new_lines(numstring); 180 new_lines(numstring);
@@ -179,7 +191,7 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
179 status[i-3] = line[i]; 191 status[i-3] = line[i];
180 } 192 }
181 status[i-3] = 0; 193 status[i-3] = 0;
182 m_set_userstatus(status, strlen((char*)status)); 194 m_set_userstatus(status, strlen((char*)status) + 1);
183 char numstring[100]; 195 char numstring[100];
184 sprintf(numstring, "[i] changed status to %s", (char*)status); 196 sprintf(numstring, "[i] changed status to %s", (char*)status);
185 new_lines(numstring); 197 new_lines(numstring);
@@ -313,17 +325,6 @@ void print_request(uint8_t *public_key, uint8_t *data, uint16_t length)
313 325
314void print_message(int friendnumber, uint8_t * string, uint16_t length) 326void print_message(int friendnumber, uint8_t * string, uint16_t length)
315{ 327{
316 char name[MAX_NAME_LENGTH];
317 getname(friendnumber, (uint8_t*)name);
318 char msg[100+length+strlen(name)+1];
319 time_t rawtime;
320 struct tm * timeinfo;
321 time ( &rawtime );
322 timeinfo = localtime ( &rawtime );
323 char* temp = asctime(timeinfo);
324 size_t len = strlen(temp);
325 temp[len-1] = '\0';
326 sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // timestamp
327 new_lines(format_message((char*)string, friendnumber)); 328 new_lines(format_message((char*)string, friendnumber));
328} 329}
329 330
diff --git a/testing/nTox_win32.c b/testing/nTox_win32.c
index 2394877f..42780923 100644
--- a/testing/nTox_win32.c
+++ b/testing/nTox_win32.c
@@ -132,13 +132,15 @@ void line_eval(char* line)
132 printf(numstring); 132 printf(numstring);
133 } 133 }
134 else if (num == -1) 134 else if (num == -1)
135 printf("\nWrong key size\n\n"); 135 printf("\n[i] Message is too long.\n\n");
136 else if (num == -2) 136 else if (num == -2)
137 printf("\nYou can't add yourself\n\n"); 137 printf("\n[i] Please add a message to your friend request.\n\n");
138 else if (num == -3) 138 else if (num == -3)
139 printf("\nYou already have this person added\n\n"); 139 printf("\n[i] That appears to be your own ID.\n\n");
140 else if (num == -4) 140 else if (num == -4)
141 printf("\nUndefined error when adding friend"); 141 printf("\n[i] Friend request already sent.\n\n");
142 else if (num == -5)
143 printf("\n[i] Undefined error when adding friend\n\n");
142 } 144 }
143 145
144 else if (inpt_command == 'r') { 146 else if (inpt_command == 'r') {
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index cdc6dc16..c596b708 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -280,6 +280,26 @@ void prepare_window(WINDOW* w) {
280 wresize(w, LINES-2, COLS); 280 wresize(w, LINES-2, COLS);
281} 281}
282 282
283/*
284 * Draws cursor relative to input on prompt window.
285 * Removes cursor on friends window and chat windows.
286 *
287 * TODO: Make it work for chat windows
288 */
289void position_cursor(WINDOW* w, char* title)
290{
291 curs_set(1);
292 if (strcmp(title, "[prompt]") == 0) { // main/prompt window
293 int x, y;
294 getyx(w, y, x);
295 move(y, x);
296 }
297 else if (strcmp(title, "[friends]") == 0) // friends window
298 curs_set(0);
299 else // any other window (i.e chat)
300 curs_set(0);
301}
302
283int main(int argc, char* argv[]) { 303int main(int argc, char* argv[]) {
284 int ch; 304 int ch;
285 ToxWindow* a; 305 ToxWindow* a;
@@ -299,6 +319,7 @@ int main(int argc, char* argv[]) {
299 a->blink = false; 319 a->blink = false;
300 a->onDraw(a); 320 a->onDraw(a);
301 draw_bar(); 321 draw_bar();
322 position_cursor(a->window, a->title);
302 323
303 // Handle input. 324 // Handle input.
304 ch = getch(); 325 ch = getch();
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index a3cf2d94..b0f83811 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -134,10 +134,28 @@ static void execute(ToxWindow* self, char* cmd) {
134 } 134 }
135 135
136 num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1); 136 num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1);
137 137 switch (num) {
138 wprintw(self->window, "Friend added as %d.\n", num); 138 case -1:
139 on_friendadded(num); 139 wprintw(self->window, "Message is too long.\n");
140 break;
141 case -2:
142 wprintw(self->window, "Please add a message to your request.\n");
143 case -3:
144 wprintw(self->window, "That appears to be your own ID.\n");
145 break;
146 case -4:
147 wprintw(self->window, "Friend request already sent.\n");
148 break;
149 case -5:
150 wprintw(self->window, "[i] Undefined error when adding friend.\n");
151 break;
152 default:
153 wprintw(self->window, "Friend added as %d.\n", num);
154 on_friendadded(num);
155 break;
156 }
140 } 157 }
158
141 else if(!strcmp(cmd, "help")) { 159 else if(!strcmp(cmd, "help")) {
142 print_usage(self); 160 print_usage(self);
143 } 161 }