summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rwxr-xr-xCMakeLists.txt1
-rw-r--r--INSTALL.md11
-rw-r--r--README.md2
-rw-r--r--cmake/FindSphinx.cmake16
-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/net_crypto.c10
-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.c29
21 files changed, 1056 insertions, 325 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..5785e9cb 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ For further information, check our [To-do list](https://github.com/irungentoo/Pr
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/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/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/net_crypto.c b/core/net_crypto.c
index 83cb20a2..2dbaa87c 100644
--- a/core/net_crypto.c
+++ b/core/net_crypto.c
@@ -75,10 +75,9 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
75 uint32_t i; 75 uint32_t i;
76 uint32_t check = 0; 76 uint32_t check = 0;
77 for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) { 77 for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) {
78 if (temp_encrypted[i] != 0) 78 check |= temp_encrypted[i] ^ 0;
79 check = 1;
80 } 79 }
81 if(check == 1) 80 if(check != 0)
82 return -1; 81 return -1;
83 82
84 /* unpad the encrypted message */ 83 /* unpad the encrypted message */
@@ -110,10 +109,9 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
110 uint32_t i; 109 uint32_t i;
111 uint32_t check = 0; 110 uint32_t check = 0;
112 for(i = 0; i < crypto_box_ZEROBYTES; ++i) { 111 for(i = 0; i < crypto_box_ZEROBYTES; ++i) {
113 if (temp_plain[i] != 0) 112 check |= temp_plain[i] ^ 0;
114 check = 1;
115 } 113 }
116 if(check == 1) 114 if(check != 0)
117 return -1; 115 return -1;
118 116
119 /* unpad the plain message */ 117 /* unpad the plain message */
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..34d74d5a 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
@@ -133,6 +138,9 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
133 } 138 }
134 else if (inpt_command == 'm') { //message command: /m friendnumber messsage 139 else if (inpt_command == 'm') { //message command: /m friendnumber messsage
135 size_t len = strlen(line); 140 size_t len = strlen(line);
141 if(len < 3)
142 return;
143
136 char numstring[len-3]; 144 char numstring[len-3];
137 char message[len-3]; 145 char message[len-3];
138 int i; 146 int i;
@@ -141,13 +149,13 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
141 numstring[i] = line[i+3]; 149 numstring[i] = line[i+3];
142 } else { 150 } else {
143 int j; 151 int j;
144 for (j = (i+1); j < len; j++) 152 for (j = (i+1); j < (len+1); j++)
145 message[j-i-1] = line[j+3]; 153 message[j-i-1] = line[j+3];
146 break; 154 break;
147 } 155 }
148 } 156 }
149 int num = atoi(numstring); 157 int num = atoi(numstring);
150 if (m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1) { 158 if (m_sendmessage(num, (uint8_t*) message, strlen(message) + 1) != 1) {
151 new_lines("[i] could not send message"); 159 new_lines("[i] could not send message");
152 } else { 160 } else {
153 new_lines(format_message(message, -1)); 161 new_lines(format_message(message, -1));
@@ -162,7 +170,7 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
162 name[i-3] = line[i]; 170 name[i-3] = line[i];
163 } 171 }
164 name[i-3] = 0; 172 name[i-3] = 0;
165 setname(name, i); 173 setname(name, i - 2);
166 char numstring[100]; 174 char numstring[100];
167 sprintf(numstring, "[i] changed nick to %s", (char*)name); 175 sprintf(numstring, "[i] changed nick to %s", (char*)name);
168 new_lines(numstring); 176 new_lines(numstring);
@@ -179,7 +187,7 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
179 status[i-3] = line[i]; 187 status[i-3] = line[i];
180 } 188 }
181 status[i-3] = 0; 189 status[i-3] = 0;
182 m_set_userstatus(status, strlen((char*)status)); 190 m_set_userstatus(status, strlen((char*)status) + 1);
183 char numstring[100]; 191 char numstring[100];
184 sprintf(numstring, "[i] changed status to %s", (char*)status); 192 sprintf(numstring, "[i] changed status to %s", (char*)status);
185 new_lines(numstring); 193 new_lines(numstring);
@@ -313,17 +321,6 @@ void print_request(uint8_t *public_key, uint8_t *data, uint16_t length)
313 321
314void print_message(int friendnumber, uint8_t * string, uint16_t length) 322void print_message(int friendnumber, uint8_t * string, uint16_t length)
315{ 323{
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)); 324 new_lines(format_message((char*)string, friendnumber));
328} 325}
329 326