diff options
-rw-r--r-- | .travis.yml | 5 | ||||
-rwxr-xr-x | CMakeLists.txt | 1 | ||||
-rw-r--r-- | INSTALL.md | 11 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | cmake/FindSphinx.cmake | 16 | ||||
-rw-r--r-- | core/LAN_discovery.c | 61 | ||||
-rw-r--r-- | core/LAN_discovery.h | 7 | ||||
-rw-r--r-- | core/Lossless_UDP.c | 427 | ||||
-rw-r--r-- | core/Lossless_UDP.h | 96 | ||||
-rw-r--r-- | core/net_crypto.c | 10 | ||||
-rw-r--r-- | docs/CMakeLists.txt | 40 | ||||
-rw-r--r-- | docs/commands.md | 25 | ||||
-rw-r--r-- | docs/commands.rst | 48 | ||||
-rw-r--r-- | docs/conf.py | 242 | ||||
-rw-r--r-- | docs/index.rst | 25 | ||||
-rw-r--r-- | docs/install.rst | 129 | ||||
-rw-r--r-- | docs/start_guide.de.md | 40 | ||||
-rw-r--r-- | docs/start_guide.de.rst | 66 | ||||
-rw-r--r-- | docs/start_guide.md | 38 | ||||
-rw-r--r-- | docs/start_guide.rst | 63 | ||||
-rw-r--r-- | testing/nTox.c | 29 |
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 | ||
26 | script: | 27 | script: |
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 | ||
31 | notifications: | 34 | notifications: |
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) | |||
48 | add_subdirectory(core) | 48 | add_subdirectory(core) |
49 | add_subdirectory(testing) | 49 | add_subdirectory(testing) |
50 | add_subdirectory(other) | 50 | add_subdirectory(other) |
51 | add_subdirectory(docs) | ||
@@ -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 | |||
32 | sudo ldconfig | 31 | sudo ldconfig |
33 | ``` | 32 | ``` |
34 | 33 | ||
35 | Then clone this repo and run: | 34 | Then clone this repo and generate makefile: |
36 | ```bash | 35 | ```bash |
36 | git clone git://github.com/irungentoo/ProjectTox-Core.git | ||
37 | cd ProjectTox-Core | ||
37 | mkdir build && cd build | 38 | mkdir build && cd build |
38 | cmake .. | 39 | cmake .. |
39 | ``` | 40 | ``` |
41 | Note that you should call cmake on the root [`CMakeLists.txt`](/CMakeLists.txt) file only. | ||
40 | 42 | ||
41 | Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running: | 43 | Then 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: | |||
102 | mkdir build && cd build | 104 | mkdir build && cd build |
103 | cmake -G "MinGW Makefiles" .. | 105 | cmake -G "MinGW Makefiles" .. |
104 | ``` | 106 | ``` |
107 | Note that you should call cmake on the root [`CMakeLists.txt`](/CMakeLists.txt) file only. | ||
105 | 108 | ||
106 | Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running: | 109 | Then 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 | |||
117 | mingw32-make | 120 | mingw32-make |
118 | ``` | 121 | ``` |
119 | 122 | ||
120 | <a name="usage" /> | ||
121 | ## Usage | ||
122 | |||
123 | - [Start Guide](start_guide.md) | ||
@@ -41,7 +41,7 @@ For further information, check our [To-do list](https://github.com/irungentoo/Pr | |||
41 | The goal of this project is to create a configuration-free P2P skype | 41 | The goal of this project is to create a configuration-free P2P skype |
42 | replacement. Configuration-free means that the user will simply have to open the program and | 42 | replacement. Configuration-free means that the user will simply have to open the program and |
43 | without any account configuration will be capable of adding people to his | 43 | without any account configuration will be capable of adding people to his |
44 | friends list and start conversing with them. There are many so called skype replacements and all of them are either hard to | 44 | friends list and start conversing with them. There are many so-called skype replacements and all of them are either hard to |
45 | configure for the normal user or suffer from being way too centralized. | 45 | configure 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 @@ | |||
1 | find_program(SPHINX_EXECUTABLE NAMES sphinx-build | ||
2 | HINTS | ||
3 | $ENV{SPHINX_DIR} | ||
4 | PATH_SUFFIXES bin | ||
5 | DOC "Sphinx documentation generator" | ||
6 | ) | ||
7 | |||
8 | include(FindPackageHandleStandardArgs) | ||
9 | |||
10 | find_package_handle_standard_args(Sphinx DEFAULT_MSG | ||
11 | SPHINX_EXECUTABLE | ||
12 | ) | ||
13 | |||
14 | mark_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 */ | ||
32 | uint32_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 */ | ||
29 | IP broadcast_ip() | 79 | IP 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 |
32 | extern "C" { | 39 | extern "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 */ |
38 | timeout 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 | ||
47 | typedef struct { | 46 | typedef 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 | ||
52 | typedef struct { | 51 | typedef 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 | */ | ||
100 | int getconnection_id(IP_Port ip_port) | 130 | int 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. */ |
112 | static uint32_t randtable[6][256]; | 144 | static 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 | */ | ||
117 | uint32_t handshake_id(IP_Port source) | 152 | uint32_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 | */ | ||
132 | void change_handshake(IP_Port source) | 171 | void 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 | */ | ||
142 | int new_connection(IP_Port ip_port) | 183 | int 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 | */ | ||
187 | int new_inconnection(IP_Port ip_port) | 236 | int 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 | */ | ||
227 | int incoming_connection() | 285 | int 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. */ | ||
239 | static void free_connections() | 299 | static 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 | */ | ||
258 | int kill_connection(int connection_id) | 322 | int 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 | */ | ||
275 | int kill_connection_in(int connection_id, uint32_t seconds) | 341 | int 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 | */ | ||
292 | int is_connected(int connection_id) | 360 | int 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 | */ | ||
352 | int write_packet(int connection_id, uint8_t * data, uint32_t length) | 424 | int 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 | |||
391 | int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) | 471 | int 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 | ||
404 | int send_SYNC(uint32_t connection_id) | 485 | int 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. */ | ||
470 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | 556 | int 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. */ | ||
503 | int SYNC_valid(uint32_t length) | 592 | int 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: */ |
514 | int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) | 603 | int 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: */ |
534 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 623 | int 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: */ |
547 | int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, | 636 | int 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 | */ | ||
603 | int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | 709 | int 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 | ||
654 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) | 771 | int 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 | */ | ||
675 | void doNew() | 794 | void 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 | */ | ||
728 | void adjustRates() | 852 | void 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. */ | ||
749 | void doLossless_UDP() | 872 | void 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 | */ |
42 | int new_connection(IP_Port ip_port); | 42 | int 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 | */ | ||
47 | int getconnection_id(IP_Port ip_port); | 49 | int 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 | */ | ||
51 | int incoming_connection(); | 55 | int 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 | */ | ||
55 | int kill_connection(int connection_id); | 61 | int 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 | */ | ||
60 | int kill_connection_in(int connection_id, uint32_t seconds); | 68 | int 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 | */ | ||
64 | IP_Port connection_ip(int connection_id); | 74 | IP_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 | */ | ||
68 | char id_packet(int connection_id); | 80 | char 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 | */ | ||
72 | int read_packet(int connection_id, uint8_t *data); | 86 | int 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 | */ | ||
76 | int write_packet(int connection_id, uint8_t *data, uint32_t length); | 92 | int 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. */ |
79 | uint32_t sendqueue(int connection_id); | 95 | uint32_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 | */ | ||
82 | uint32_t recvqueue(int connection_id); | 101 | uint32_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 | */ | ||
90 | int is_connected(int connection_id); | 110 | int 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. */ | ||
94 | void doLossless_UDP(); | 113 | void 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 | */ | ||
100 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source); | 120 | int 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 | ||
2 | find_package(Sphinx) | ||
3 | |||
4 | if(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") | ||
35 | else() | ||
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") | ||
40 | endif() | ||
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 | ||
2 | Here's a list of commands that nTox accepts, | ||
3 | which can all be used by starting your line with | ||
4 | a */*. 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 @@ | |||
1 | Tox User Commands | ||
2 | ================= | ||
3 | |||
4 | Here's a list of commands that nTox accepts, which can all be used by | ||
5 | starting your line with a */*. Currently there can be no spaces before | ||
6 | this. | ||
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 | |||
14 | import 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. | ||
28 | extensions = [] | ||
29 | |||
30 | # Add any paths that contain templates here, relative to this directory. | ||
31 | templates_path = ['_templates'] | ||
32 | |||
33 | # The suffix of source filenames. | ||
34 | source_suffix = '.rst' | ||
35 | |||
36 | # The encoding of source files. | ||
37 | #source_encoding = 'utf-8-sig' | ||
38 | |||
39 | # The master toctree document. | ||
40 | master_doc = 'index' | ||
41 | |||
42 | # General information about the project. | ||
43 | project = u'ProjectTox' | ||
44 | copyright = 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. | ||
51 | version = '0.1' | ||
52 | # The full version, including alpha/beta/rc tags. | ||
53 | release = '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. | ||
67 | exclude_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. | ||
84 | pygments_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. | ||
94 | html_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". | ||
123 | html_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. | ||
167 | htmlhelp_basename = 'ProjectToxdoc' | ||
168 | |||
169 | |||
170 | # -- Options for LaTeX output -------------------------------------------------- | ||
171 | |||
172 | latex_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]). | ||
185 | latex_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). | ||
215 | man_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) | ||
229 | texinfo_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 | |||
6 | Welcome to ProjectTox's documentation! | ||
7 | ====================================== | ||
8 | |||
9 | Contents: | ||
10 | |||
11 | .. toctree:: | ||
12 | start_guide.rst | ||
13 | install.rst | ||
14 | commands.rst | ||
15 | :maxdepth: 2 | ||
16 | |||
17 | |||
18 | |||
19 | Indices 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 @@ | |||
1 | Install Instructions | ||
2 | ==================== | ||
3 | |||
4 | Linux | ||
5 | --------- | ||
6 | |||
7 | First, 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 | |||
14 | Then 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 | |||
24 | Finally, 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 | |||
30 | Then you can build any of the files in `/testing`_ and `/other`_ that are currently | ||
31 | supported on your platform by running :: | ||
32 | |||
33 | make name_of_c_file | ||
34 | |||
35 | For example, to build `Messenger_test.c`_ you would run :: | ||
36 | |||
37 | make Messenger_test | ||
38 | |||
39 | |||
40 | Or you could just build everything that is supported on your platform by | ||
41 | running :: | ||
42 | bash make | ||
43 | |||
44 | OS X | ||
45 | ------ | ||
46 | |||
47 | Homebrew | ||
48 | ~~~~~~~~~~ | ||
49 | :: | ||
50 | |||
51 | brew install libtool automake autoconf libconfig libsodium cmake | ||
52 | cmake . | ||
53 | make | ||
54 | sudo make install | ||
55 | |||
56 | Non-homebrew | ||
57 | ~~~~~~~~~~~~ | ||
58 | |||
59 | Much the same as Linux, remember to install the latest XCode and the | ||
60 | developer tools (Preferences -> Downloads -> Command Line Tools). Users | ||
61 | running Mountain Lion and the latest version of XCode (4.6.3) will also | ||
62 | need to install libtool, automake and autoconf. They are easy enough to | ||
63 | install, grab them from http://www.gnu.org/software/libtool/, | ||
64 | http://www.gnu.org/software/autoconf/ and | ||
65 | http://www.gnu.org/software/automake/, then follow these steps for each: | ||
66 | |||
67 | :: | ||
68 | |||
69 | ./configure | ||
70 | make | ||
71 | sudo make install | ||
72 | |||
73 | Do not install them from macports (or any dependencies for that matter) | ||
74 | as they get shoved in the wrong directory and make your life more | ||
75 | annoying. | ||
76 | |||
77 | Another thing you may want to install is the latest gcc, this caused me | ||
78 | a few problems as XCode from 4.3 no longer includes gcc and instead uses | ||
79 | LLVM-GCC, a nice install guide can be found at | ||
80 | http://caiustheory.com/install-gcc-421-apple-build-56663-with-xcode-42 | ||
81 | |||
82 | Windows | ||
83 | --------- | ||
84 | |||
85 | You should install: | ||
86 | |||
87 | * `MinGW <http://sourceforge.net/projects/mingw/>`_'s C compiler | ||
88 | * `CMake <http://www.cmake.org/cmake/resources/software.html>`_ | ||
89 | |||
90 | You have to `modify your PATH environment | ||
91 | variable <http://www.computerhope.com/issues/ch000549.htm>`_ so that it | ||
92 | contains MinGW's bin folder path. With default settings, the bin folder | ||
93 | is located at ``C:\MinGW\bin``, which means that you would have to | ||
94 | append ``;C:\MinGW\bin`` to the PATH variable. | ||
95 | |||
96 | Then you should either clone this repo by using git, or just download a | ||
97 | `zip of current Master | ||
98 | branch <https://github.com/irungentoo/ProjectTox-Core/archive/master.zip>`_ | ||
99 | and extract it somewhere. | ||
100 | |||
101 | After that you should get precompiled package of libsodium from | ||
102 | `here <https://download.libsodium.org/libsodium/releases/libsodium-win32-0.4.2.tar.gz>`_ | ||
103 | and extract the archive into this repo's root. That is, ``sodium`` | ||
104 | folder should be along with ``core``, ``testing`` and other folders. | ||
105 | |||
106 | Navigate in ``cmd`` to this repo and run:: | ||
107 | |||
108 | mkdir build && cd build | ||
109 | cmake -G "MinGW Makefiles" .. | ||
110 | |||
111 | Then you can build any of the `/testing`_ and `/other`_ that are currently | ||
112 | supported on your platform by running:: | ||
113 | |||
114 | mingw32-make name_of_c_file | ||
115 | |||
116 | For example, to build `Messenger_test.c`_ you would run:: | ||
117 | |||
118 | mingw32-make Messenger_test`` | ||
119 | |||
120 | Or you could just build everything that is supported on your platform by | ||
121 | running:: | ||
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 | ||
2 | 1. Tox erstellen | ||
3 | 2. Fehler korrigieren | ||
4 | 3. Im IRC nach Hilfe fragen | ||
5 | 4. Auf Debug-Reise für Entwickler | ||
6 | 5. Tox wirklich erstellen | ||
7 | 6. ??? | ||
8 | |||
9 | Trotz der ganzen Arbeit, die wir bisher in Tox | ||
10 | gesteckt haben, gibt es noch keine richtige | ||
11 | Anleitung, wie man Tox _benutzt_. | ||
12 | Dies ist ein anwenderfreundlicher Versuch. | ||
13 | |||
14 | 1. 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 | ||
22 | 2. 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. | ||
30 | 3. Chatte drauf los! | ||
31 | + Benutze nun den */m*-Befehl, um eine Nachricht an jemanden zu senden. Wow, du chattest! | ||
32 | 4. 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. | ||
35 | 5. 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. | ||
38 | 6. 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 @@ | |||
1 | Tox nutzen | ||
2 | ========== | ||
3 | |||
4 | 1. :doc:`Tox erstellen <install>` | ||
5 | 2. Fehler korrigieren | ||
6 | 3. Im IRC nach Hilfe fragen | ||
7 | 4. Auf Debug-Reise für Entwickler | ||
8 | 5. Tox wirklich erstellen | ||
9 | 6. ??? | ||
10 | |||
11 | Trotz der ganzen Arbeit, die wir bisher in Tox gesteckt haben, gibt es | ||
12 | noch keine richtige Anleitung, wie man Tox *benutzt*. Dies ist ein | ||
13 | anwenderfreundlicher Versuch. | ||
14 | |||
15 | 1. 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 | |||
31 | 2. 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 | |||
43 | 3. Chatte drauf los! | ||
44 | |||
45 | - Benutze nun den */m*-Befehl, um eine Nachricht an jemanden zu | ||
46 | senden. Wow, du chattest! | ||
47 | |||
48 | 4. 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 | |||
55 | 5. 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 | |||
61 | 6. 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 | ||
2 | 1. [Build Tox](../INSTALL.md) | ||
3 | 2. Fix errors | ||
4 | 3. Consult IRC for help | ||
5 | 4. Go on debugging journey for devs | ||
6 | 5. Build Tox for real | ||
7 | 6. ??? | ||
8 | |||
9 | For all the work we've put into Tox so far, | ||
10 | there isn't yet a decent guide for how you _use_ | ||
11 | Tox. Here's a user-friendly attempt at it. | ||
12 | |||
13 | 1. 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` | ||
21 | 2. 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. | ||
28 | 3. Chat it up! | ||
29 | + Now use the `/m` command to send a message to someone. Wow, you're chatting! | ||
30 | 4. 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. | ||
33 | 5. 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. | ||
36 | 6. 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 @@ | |||
1 | Using Tox | ||
2 | ========= | ||
3 | |||
4 | .. note:: There is a German version of this page available: :doc:`start_guide.de` | ||
5 | |||
6 | |||
7 | 1. :doc:`Build Tox <install>` | ||
8 | 2. Fix errors | ||
9 | 3. Consult IRC for help | ||
10 | 4. Go on debugging journey for devs | ||
11 | 5. Build Tox for real | ||
12 | 6. ??? | ||
13 | |||
14 | For all the work we've put into Tox so far, there isn't yet a decent | ||
15 | guide for how you *use* Tox. Here's a user-friendly attempt at it. | ||
16 | |||
17 | 1. 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 | |||
29 | 2. 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 | |||
39 | 3. Chat it up! | ||
40 | |||
41 | - Now use the ``/m`` command to send a message to someone. Wow, | ||
42 | you're chatting! | ||
43 | |||
44 | 4. 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 | |||
51 | 5. 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 | |||
56 | 6. 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 | ||
314 | void print_message(int friendnumber, uint8_t * string, uint16_t length) | 322 | void 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 | ||